图形的绘制,如何使用自定义画笔(颜色,线宽,线形)。如何为程序中添加选项菜单和选项设置对话框,如何使用标准颜色对话框,如何使用字体对话框,在选项对话框中实现预览功能。实现选项对话框和窗口类中的数据交换。如何改变对话框和控件的背景色,如何改变控件的文本颜色,对按钮控件的特殊处理。如何在窗口中显示一幅位图。
1.图形的绘制:通过菜单项的选择来绘制用户所需要的图形(点,直线,矩形,椭圆):
a.首先需要一个变量来保存用户的选择和坐标的位置:在view类中添加一个变量m_nDrawType和m_ptOrigin;
b.为各个菜单项添加消息响应函数;
void CID102View::OnDot() { // TODO: 在此添加命令处理程序代码 m_nDrawType = 1;//当用户选择为点的时候,这个值就为1! } void CID102View::OnLine() { // TODO: 在此添加命令处理程序代码 m_nDrawType = 2;//当用户选择为直线的时候,这个值就为2! } void CID102View::OnRectangle() { // TODO: 在此添加命令处理程序代码 m_nDrawType = 3;//当用户选择为矩形的时候,这个值就为3! } void CID102View::OnEllipse() { // TODO: 在此添加命令处理程序代码 m_nDrawType = 4;//当用户选择为椭圆的时候,这个值就为4! } void CID102View::OnLButtonDown(UINT nFlags, CPoint point) { // TODO: 在此添加消息处理程序代码和/或调用默认值 m_ptOrigin = point; CView::OnLButtonDown(nFlags, point); }
c. 通过对鼠标的消息捕获来实现画图的功能:
void CID102View::OnLButtonDown(UINT nFlags, CPoint point) { // TODO: 在此添加消息处理程序代码和/或调用默认值 m_ptOrigin = point; CView::OnLButtonDown(nFlags, point); } void CID102View::OnLButtonUp(UINT nFlags, CPoint point) { // TODO: 在此添加消息处理程序代码和/或调用默认值 CClientDC dc(this); CPen pen(PS_SOLID, 1, RGB(255, 0, 0));//创建一个红色的画笔 dc.SelectObject(&pen);//将画笔选入设备描述表中 CBrush *pBrush = CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));//创建一个透明的画刷 dc.SelectObject(pBrush);//将画刷选入设备描述表中 switch(m_nDrawType) { case 1://完成画点功能 dc.SetPixel(point, RGB(255, 0, 0)); break; case 2://完成画直线功能 dc.MoveTo(m_ptOrigin); dc.LineTo(point); break; case 3://完成画矩形功能 dc.Rectangle(CRect(m_ptOrigin, point)); break; case 4://完成画椭圆功能 dc.Ellipse(CRect(m_ptOrigin, point)); break; default: break; } CView::OnLButtonUp(nFlags, point); }
2.设置对话框的创建:
a.首先需要插入一个对话框资源;然后再为对话框资源添加一个新类;
b.通过菜单项的按钮来调出对话框,然后在对话框上面设置值,需要给控件添加一个变量m_nLineWidth,而在view类中也需要设置一个变量来保存其所选择的值m_nlinewidth;
c.通过添加菜单项的消息响应函数来完成:
void CID102View::OnSetting() { // TODO: 在此添加命令处理程序代码 CSettingDlg dlg;//声明一个对话框的对象 dlg.m_nLineWidth = m_nLineWidth;//将之前设置的值传递回给对话框上面的变量! if (IDOK == dlg.DoModal())//调出对话框 { m_nLineWidth = dlg.m_nLineWidth;//将对话框上的选择值保存下来 } }
其他控件的处理与上面的处理方式差不多,所以就不在啰嗦!
3.颜色对话框的创建:主要是通过一个ccolordialog类来创建,菜单项上面的颜色按钮来作消息函数的响应!记得需要在view类中设置变量来保存颜色值的选择!
void CID102View::OnColor() { // TODO: 在此添加命令处理程序代码 CColorDialog dlg;//创建一个颜色对话框的对象 dlg.m_cc.Flags |= CC_RGBINIT | CC_FULLOPEN;//这个地方的方法需要注意! dlg.m_cc.rgbResult = m_clr; if (IDOK == dlg.DoModal())//产生一个颜色对话框! { m_clr = dlg.m_cc.rgbResult;//对用户颜色选择的保存! } }
4.字体对话框的创建:先由菜单项调出一个字体对话框,再由你选择的字体显示在view类上!与颜色对话框的创建相似!
void CID102View::OnFont() { // TODO: 在此添加命令处理程序代码 CFontDialog dlg;//字体对话框的一个类声明 if (IDOK == dlg.DoModal())//创建一个字体对话框 { if (m_font.m_hObject)//判断是否已经选择有字体 m_font.DeleteObject();//切断与对象的联系 m_font.CreateFontIndirectW(dlg.m_cf.lpLogFont);//对字体对象的初始化 m_strFontName = dlg.m_cf.lpLogFont->lfFaceName;//对所选字体的保存! Invalidate();//使窗口无效! } }
void CID102View::OnDraw(CDC* pDC) { CID102Doc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if (!pDoc) return; // TODO: 在此处为本机数据添加绘制代码 CFont *pOldFont = pDC->SelectObject(&m_font); pDC->TextOutW(0, 0, m_strFontName); pDC->SelectObject(pOldFont); }
包括了两次处理选择字体出现的错误处理:m_font.deleteobject();
5.示例对话框的创建:主要是在dlg类中的onpain()函数中完成:
void CSettingDlg::OnPaint() { CPaintDC dc(this); // device context for painting // TODO: 在此处添加消息处理程序代码 UpdateData();//由控件的值反映到变量上,必须调用! CPen pen(m_nLineStyle, m_nLineWidth, m_clr);//创建一个画笔 dc.SelectObject(&pen); CRect rect; GetDlgItem(IDC_SAMPLE)->GetWindowRect(&rect);//得到示例框的矩形区域 ScreenToClient(&rect);//由屏幕坐标转为客户区的坐标! dc.MoveTo(rect.left + 20, rect.top + rect.Height()/2);//在示例框中划出图形 dc.LineTo(rect.right - 20, rect.top + rect.Height()/2); // 不为绘图消息调用 CDialog::OnPaint() }
6.修改对话框及其控件的背景色:主要在对话框的类中来完成,在对话框类中添加一个函数onctlcolor(),在函数中完成代码:
HBRUSH CSettingDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) { HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor); // TODO: 在此更改 DC 的任何属性 //改变对话框的背景颜色! if (pWnd->GetDlgCtrlID() == IDC_LINE)//判断其ID号是否符合 { pDC->SetTextColor(RGB(255, 0, 0));//改变控件上的文本颜色! pDC->SetBkMode(TRANSPARENT);//改变背景模式,设置为透明! return m_brush; } //改变控件上的字体颜色 if (pWnd->GetDlgCtrlID() == IDC_LINE_WIDTH) { pDC->SetTextColor(RGB(255, 0, 0));//改变控件上的文本颜色! pDC->SetBkMode(TRANSPARENT);//改变背景模式,设置为透明! pDC->SetBkColor(RGB(0, 0, 255));//设置背景色为蓝色! return m_brush; } //改变控件上的字体 if (pWnd->GetDlgCtrlID() == IDC_TEXT) { pDC->SelectObject(&m_font); } // TODO: 如果默认的不是所需画笔,则返回另一个画笔 return hbr; //return m_brush;//返回由自己创建的画刷!使整个对话框的背景色发生改变! }
而修改对话框上的按钮的文本颜色和其背景色就比较麻烦,需要添加一个cbutton类,然后再为其按钮创建一个与cbutton类相关联的变量,在其cbutton类中添加一个函数drawitem():
void CTestBtn::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) { // TODO: 添加您的代码以绘制指定项 UINT uStyle = DFCS_BUTTONPUSH; // This code only works with buttons. ASSERT(lpDrawItemStruct->CtlType == ODT_BUTTON); // If drawing selected, add the pushed style to DrawFrameControl. if (lpDrawItemStruct->itemState & ODS_SELECTED) uStyle |= DFCS_PUSHED; // Draw the button frame. ::DrawFrameControl(lpDrawItemStruct->hDC, &lpDrawItemStruct->rcItem, DFC_BUTTON, uStyle); // Get the button's text. CString strText; GetWindowText(strText); // Draw the button text using the text color red. COLORREF crOldColor = ::SetTextColor(lpDrawItemStruct->hDC, RGB(255,0,0)); ::DrawText(lpDrawItemStruct->hDC, strText, strText.GetLength(), &lpDrawItemStruct->rcItem, DT_SINGLELINE|DT_VCENTER|DT_CENTER); ::SetTextColor(lpDrawItemStruct->hDC, crOldColor); }
7.如何在窗口中显示位图:可以在view类中添加函数wm_erasebkgnd()函数中根据四步来完成,也可以在对话框的ondraw函数中完成,因为在view类中的效果好,所以下面就写成在view类中完成的代码:
BOOL CID102View::OnEraseBkgnd(CDC* pDC) { // TODO: 在此添加消息处理程序代码和/或调用默认值 //创建位图 CBitmap bitmap; bitmap.LoadBitmapW(IDB_BITMAP1); BITMAP bmp; bitmap.GetBitmap(&bmp);//得到位图的结构体 //创建一个兼容dc CDC dcCompatible; dcCompatible.CreateCompatibleDC(pDC); //将位图选到兼容DC中 dcCompatible.SelectObject(&bitmap); //将兼容dc中的位图贴到当前dc中 CRect rect; GetClientRect(&rect); //pDC->BitBlt(0, 0, rect.Width(), rect.Height(), &dcCompatible, 0, 0, SRCCOPY); pDC->StretchBlt(0, 0, rect.Width(), rect.Height(), &dcCompatible, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY); return TRUE; //return CView::OnEraseBkgnd(&bitmap); }