(1)绘图
新建一个工程Graphic。添加一个菜单“绘图”,在这个菜单中添加四个菜单项,分别为点(IDM_DOT)、直线(IDM_LINE)、矩形(IDM_RECTANGLE)和椭圆(IDM_ELLIPSE)。分别为这四个菜单项添加命令响应。在每个命令响应函数中保存用户的选择,定义成员变量UINT m_nDrawType private保存用户的选择。在CGraphicView的构造方法中初始化m_nDrawType=0。在OnDot、OnLine、OnRectangle和OnEllipse响应函数中分别设置这个成员变量的值为1、2、3、4。分别捕获鼠标左键按下和松开的消息WM_LBUTTONDOWN和WM_LBUTTONUP。在WM_LBUTTONDOWN中将鼠标按下的这个点保存,在View类中添加成员变量CPoint m_ptOrgin private,在构造函数中初始化为0。在OnButtonDownh函数总保存这个点到成员变量中m_ptOrigin=point。鼠标松开的响应函数ONBUTTONUP中代码如下:
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;
}
(2)设置对话框
***设置线宽
插入一个对话框:IDI_DLG_SETTING setting。在对话框上添加一个静态文本框:线宽,一个编辑框:IDC_LINE_WIDTH。双击对话框创建一个对话框的类:CSettingDlg。点右键给编辑框控件关联成员变量:m_nLineWidth UINT。增加设置菜单项:IDM_SETTING 设置,给菜单项添加命令响应OnSetting,选择view类。响应函数中的代码如下:
CSettingDlg dlg;
dlg.DoModal();
在view类中增加保存对话框中设置的线宽的成员变量:UINT m_nLineWidth private。在构造函数中初始化为0。
设置菜单项响应函数OnSetting的代码修改如下:
CSettingDlg dlg;
dlg.m_nLineWidth=m_nLineWidth;
if(IDOK==dlg.Domal())
{
m_nLineWidth=dlg.m_nLineWidth;
}
将WM_LBUTTONUP响应函数中的画笔修改为:CPen pen(PS_SOLID,m_nLineWidth,RGB(255,0,0);
***设置线型
在对话框中放置一个组框和三个单选按钮,三个单选按钮名称分别为:实线、虚线和点线。第一个勾选Group。给单选按钮关联成员变量:m_nLineStyle int。在view类中增加成员变量int m_nLineStyle private。初始化为0。在OnSetting响应函数中当用户点击Ok的时候保存起来:
CSettingDlg dlg;
dlg.m_nLineWidth=m_nLineWidth;
dlg.m_nLineWidth=m_nLineStyle;
if(IDOK==dlg.Domal())
{
m_nLineWidth=dlg.m_nLineWidth;
m_nLineStyle=dlg.m_nLineStyle;
}
将WM_LBUTTONUP响应函数中的画笔修改为:CPen pen(m_nLineStyle,m_nLineWidth,RGB(255,0,0);不需要再用switch case语句,因为三种画笔的定义和我们的定义的值是一致的。
(3)颜色对话框
增加菜单项:IDM_COLOR 颜色。添加命令响应:OnColor。在view类中增加成员变量:COLORREF m_clr private,用来保存用户的颜色选择,在构造方法中初始化m_clr=RGB(255,0,0)。
void CGraphicView::OnColor()
{
CColorDialog dlg;
dlg.m_cc.Flags | =CC_RGBINIT;
dlg.m_cc.rgbResult=m_clr;//记住用户的颜色选择
if(IDOK==dlg.DoModal())
{
m_clr=dlg.m_cc.rgbResult;
}
}
(4)字体对话框
添加菜单项:IDM_FONT 字体。增加响应函数OnFont。增加成员变量CFont m_font private。增加保存字体名字的成员变量CString m_strFontName private,并初始化。
void CGraphicView::OnFont()
{
CFontDialog dlg;
if(IDOK==dlg.DoModal())
{
if(m_font.m_hObject)
m_font.DeleteObject();
m_font.CreateFontIndirect(dlg.m_cf.lpLogFont);
m_strFontName=dlg.m_cf.lpLogFont->lfFaceName;
Invalidate();
}
}
在OnDraw响应函数中加入如下代码:
CFont *oldFont=pDC->SelectObject(&m_font);
pDC->TextOut(0,0,m_strFontName);
pDC->SelectObject(oldFont);
(5)示例功能
在设置对话框中增加一个组框:IDC_SAMPLE 示例。添加编辑框消息响应函数EN_CHANGE,三个单选按钮分别添加消息响应函数BN_CLICKED。在四个函数中调用:Invalidate(); 在CSettingDlg类中点右键,选择WM_PAINT。
void CSettingDlg::OnPaint()
{
CPaintDC dc(this);
UpdateData();
CPen pen(m_nLineStyle,m_nLineWidth,RGB(255,0,0));
dc.SelectObject(&pen);
CRect rect;
GetDlgItem(IDC_SAMPLE)->GetWindowRect(&rect);//GetWindowRect获得的是屏幕的坐标
ScreenToClient(&rect);//将屏幕坐标转换为对话框坐标。
dc.MoveTo(rect.left+20,rect.top+rect.Height()/2);
dc.LineTo(rect.right-20,rect.top+rect.Height()/2);
}
设置示例颜色,在CSettingDlg类中增加成员变量:COLORREF m_clr public,并初始化m_ctr=RGB(255,0,0)。在View类的OnSetting函数中将View类保存的颜色值传递给对话框的成员变量:dlg.m_clr=m_clr;将OnPaint函数中的画笔修改:CPen pen(m_nLineStyle,m_nLineWidth,m_clr);
(6)改变对话框背景色,对话框中控件的背景色
参考:WM_CTLCOLOR (OnCtlColor)
在CSettingDlg类中添加响应函数OnCtlColor。添加成员变量:CBrush m_brush private,并初始化:m_brush.CreateSolidBrush(RGB(0,0,255))。在OnCtrColor函数中加入代码:return m_brush;
改变组框背景色,设置组框ID:IDC_LINE_STYLE。OnCtlColor会被调用多次。
HBRUSH CSettingDlg::OnCtlColor(CDC *pDC,CWnd *pWnd,UINT nCtlColor)
{
HBRUSH hbr=CDialog::OnCtlColor(pDC,pWnd,nCtlColor);
if(pWnd->GetDlgCtlId()==IDC_LINE_STYLE)
{
pDC->SetTextColor(RGB(255,0,0));
pDC->SetBkMode(TRANSPARENT);
return m_brush;
}
if(pWnd->GetDlgCtlId()==IDC_LINE_WIDTH)
{
pDC->SetTextColor(RGB(255,0,0));
pDC->SetBkColor(RGB(0,0,255));
return m_brush;
}
return hbr;
}
对话框中的文本按照我们设定的字体显示:
在设置对话框中增加一个文本框:IDC_TEXT 程序员。在CSettingDlg类中增加成员变量:CFont m_font private,初始化:m_font.CreatePointFont(200,"华文行楷");在OnCtlColor函数中添加以下代码:
if(pWnd->GetDlgCtlId()==IDC_TEXT)
{
pDC->SelectObject(&m_font);
}
改变OK按钮的文本色:
参考:CBtton;;DrawItem
添加新类:CTestBtn ,基类选择CButton。CTestBtn->Add virtual function->DrawItem
void CTestBtn::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
UINT uStyle=DFCS_BUTTONPUSH;
ASSERT(lpDrawItemStruct->CtlType==ODT_BUTTON);
if(lpDrawItemStruct->itemState&ODS_SELECTED)
uStyle | =DFCS_PUSHED;
::DrawFrameControl(lpDrawItemStruct->hDC,&lpDrawItemStruct->rcItem,DFC_BUTTON,uStyel);
CString strText;
GetWindowText(strText);
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);
}
为设置对话框的ok按钮关联成员变量m_btnTest CTestBtn。设置对话框的OK按钮的属性styles中的Owner Draw勾选。
改变OK按钮的背景色:略
(7)如何在窗口中显示位图
1、创建位图
CBitmap bitmap;
bitmap.LoadBitmap(IDB_BITMAP1);
2、创建兼容DC
CDC dcCompatible;
dcCompatible.CreateCompatibleDC(pDC);
3、将位图选到兼容DC中
dcCompatible.SelectObject(&bitmap);
4、将兼容DC中的位图贴到当前DC中。
pDC->BitBlt(rect.left,rect.top,rect.Width(),
rect.Height(),&dcCompatible,0,0,SRCCOPY);
位图背景可以在窗口擦除OnEraseBkgnd和OnDraw响应函数中实现。
擦除窗口,增加WM_ERASE响应函数。
BOOL CGraphicView::OnEraseBkgnd(CDC* pDC)
{
// TODO: Add your message handler code here and/or call default
CBitmap bitmap;
bitmap.LoadBitmap(IDB_BITMAP1);
BITMAP bmp;
bitmap.GetBitmap(&bmp);
CDC dcCompatible;
dcCompatible.CreateCompatibleDC(pDC);
dcCompatible.SelectObject(&bitmap);
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(pDC);
}