又写了一遍,明明保存的草稿,到草稿箱一看,竟然没了。吐槽一下!!!
本章用到了《VC + + 图像处理程序设计》这本书中第一章的CDib类,大家可以百度一下再来看这篇博文。博文也是在学习这本书时写的。
一、首先创建一个MFC的单文档应用程序。
二、在View窗口类的WM_ERASEBKGND消息中修改代码,修改一下View背景色:
void CScanPictureView::DrawSeparator(CRect rcViewClient) { // 设置分割线位置,注意CStatic用矩形指定控件停放区域 CRect rcSeparator; rcSeparator.left = rcViewClient.left / 2 + 4; rcSeparator.top = rcViewClient.bottom * 2 / 3; rcSeparator.right = rcSeparator.left + rcViewClient.Width() - 8; rcSeparator.bottom = rcSeparator.top + 2; // 判断分割线控件是否已经创建 if(m_separator.m_hWnd == NULL) { m_separator.Create(NULL, SS_SUNKEN | WS_VISIBLE | WS_CHILD, rcSeparator, this); } else // 已创建分割线控件,移动控件停放区域 { m_separator.MoveWindow(rcSeparator); } }
三、在View窗口类中添加CStatic控件成员变量m_separator和绘制分割条成员函数void DrawSeparator(CRect rcViewClient),分割图像显示区域和按钮停放区域:
void CScanPictureView::DrawSeparator(CRect rcViewClient) { // 设置分割线位置,注意CStatic用矩形指定控件停放区域 CRect rcSeparator; rcSeparator.left = rcViewClient.left / 2 + 4; rcSeparator.top = rcViewClient.bottom * 2 / 3; rcSeparator.right = rcSeparator.left + rcViewClient.Width() - 8; rcSeparator.bottom = rcSeparator.top + 2; // 判断分割线控件是否已经创建 if(m_separator.m_hWnd == NULL) { m_separator.Create(NULL, SS_SUNKEN | WS_VISIBLE | WS_CHILD, rcSeparator, this); } else // 已创建分割线控件,移动控件停放区域 { m_separator.MoveWindow(rcSeparator); } }
四、在View窗口类中添加宏,作为按钮控件的ID:
#define IDC_SCANDOWNBTN 10001 // 向下扫描显示按钮ID #define IDC_SCANUPBTN 10002 // 向上扫描显示按钮ID #define IDC_SCANLEFTBTN 10003 // 向左扫描显示按钮ID #define IDC_SCANRIGHTBTN 10004 // 向右扫描显示按钮ID
再添加CButton控件成员变量:m_scanDownBtn, m_scanUpBtn, m_scanLeftBtn, m_scanRightBtn,并添加绘制按钮成员函数void DrawButtons(CRect rcViewClient):
void CScanPictureView::DrawButtons(CRect rcViewClient) { // 设置统一的按钮大小 static int ButtonWidth = 80; static int ButtonHeight = 24; // 计算按钮m_scanDownBtn的显示区域坐标 CRect rcScanDownBtn; rcScanDownBtn.left = rcViewClient.right / 8 - ButtonWidth / 2; rcScanDownBtn.top = rcViewClient.bottom * 2 / 3 + ButtonHeight; rcScanDownBtn.right = rcScanDownBtn.left + ButtonWidth; rcScanDownBtn.bottom = rcScanDownBtn.top + ButtonHeight; // 判断是否已经创建按钮m_scanDownBtn,已经创建就移动按钮,否则创建 if(m_scanDownBtn.m_hWnd == NULL) { m_scanDownBtn.Create("向下扫描", BS_PUSHBUTTON | WS_VISIBLE | WS_CHILD | WS_TABSTOP, rcScanDownBtn, this, IDC_SCANDOWNBTN); } else { m_scanDownBtn.MoveWindow(rcScanDownBtn); } // 计算按钮m_scanUpBtn的显示区域坐标 CRect rcScanUpBtn; rcScanUpBtn.left = rcViewClient.right / 4 - ButtonWidth / 2; rcScanUpBtn.top = rcViewClient.bottom * 2 / 3 + ButtonHeight; rcScanUpBtn.right = rcScanUpBtn.left + ButtonWidth; rcScanUpBtn.bottom = rcScanUpBtn.top + ButtonHeight; // 判断是否已经创建按钮m_scanUpBtn,已经创建就移动按钮,否则创建 if(m_scanUpBtn.m_hWnd == NULL) { m_scanUpBtn.Create("向上扫描", BS_PUSHBUTTON | WS_VISIBLE | WS_CHILD | WS_TABSTOP, rcScanUpBtn, this, IDC_SCANUPBTN); } else { m_scanUpBtn.MoveWindow(rcScanUpBtn); } // 计算按钮m_scanLeftBtn的显示区域坐标 CRect rcScanRightBtn; rcScanRightBtn.left = rcViewClient.right * 3 / 8 - ButtonWidth / 2; rcScanRightBtn.top = rcViewClient.bottom * 2 / 3 + ButtonHeight; rcScanRightBtn.right = rcScanRightBtn.left + ButtonWidth; rcScanRightBtn.bottom = rcScanRightBtn.top + ButtonHeight; // 判断是否已经创建按钮m_scanLeftBtn,已经创建就移动按钮,否则创建 if(m_scanRightBtn.m_hWnd == NULL) { m_scanRightBtn.Create("向右扫描", BS_PUSHBUTTON | WS_VISIBLE | WS_CHILD | WS_TABSTOP, rcScanRightBtn, this, IDC_SCANRIGHTBTN); } else { m_scanRightBtn.MoveWindow(rcScanRightBtn); } // 计算按钮m_scanRightBtn的显示区域坐标 CRect rcScanLeftBtn; rcScanLeftBtn.left = rcViewClient.right / 2 - ButtonWidth / 2; rcScanLeftBtn.top = rcViewClient.bottom * 2 / 3 + ButtonHeight; rcScanLeftBtn.right = rcScanLeftBtn.left + ButtonWidth; rcScanLeftBtn.bottom = rcScanLeftBtn.top + ButtonHeight; // 判断是否已经创建按钮m_scanRightBtn,已经创建就移动按钮,否则创建 if(m_scanLeftBtn.m_hWnd == NULL) { m_scanLeftBtn.Create("向左扫描", BS_PUSHBUTTON | WS_VISIBLE | WS_CHILD | WS_TABSTOP, rcScanLeftBtn, this, IDC_SCANLEFTBTN); } else { m_scanLeftBtn.MoveWindow(rcScanLeftBtn); } }
五、在View窗口类的OnDraw消息处理函数中添加代码,绘制分割条和按钮:
// 获取窗口客户区矩形 CRect rcViewClient; GetClientRect(rcViewClient); //绘制分割线和按钮 DrawSeparator(rcViewClient); DrawButtons(rcViewClient);
六、在View窗口类中添加成员函数void DrawPictureShowRect(CDC * pDC, LPRECT lpShowRect),绘制图片显示区域:
void CScanPictureView::DrawPictureShowRect(CDC * pDC, LPRECT lpShowRect) { // 获取View窗口区域 CRect rcView; GetClientRect(rcView); // 计算图像显示区域 lpShowRect->left = rcView.right / 3; lpShowRect->top = rcView.top + 5; lpShowRect->right = rcView.right * 2 / 3; lpShowRect->bottom = rcView.bottom * 2 / 3 - 10; // 填充图像显示区域背景 CBrush bkBrush(pDC->GetBkColor()); pDC->FillRect(lpShowRect, &bkBrush); }
这样基本的窗口就完成了,接下来是图像扫描显示,请看下一篇=>