第十二课: 对话框综合应用
在第六课的基础上,我们添加功能。增加一个用于设置笔的样式和宽度的对话框,和用于设置颜色的对话框。
一、设置笔的样式和宽度的对话框
1. 在资源面板中添加一个对话框,在上面添加一个文本框用于改变笔的宽度,三个单选框用于选择笔的样式,一个组框用于画一条演示的线。完成后的对话框如下图:
2. 为对话框生成一个从Cdialog派生的类CsetDlg,将三个单选框设置为一组,分别为文本框和这组单选框设置一个捆绑变量。
UINT m_nWidth;
int m_nStyle;
在对话框的构造函数中为它们赋初值:
m_nWidth = 0;
m_nStyle = 0;
3. 为文本框添加EN_CHANGE消息的响应函数OnChangeEdit1(),这个函数将在文本框的文字发生改变时被调用。在其中加入下列代码:
UpdateData();
CPen newpen(m_nStyle,m_nWidth,RGB(0,0,255));
CclinetDC dc(this);
dc.SelectObject(&newpen);
CRect rect;
GetDlgItem(IDC_EXAMPLE)->GetWindowRect(&rect);
ScreenToClient(&rect);
dc.MoveTo(rect.left,rect.top+rect.Height()/2);
dc.LineTo(rect.right,rect.top +rect.Height()/2);
这段文字生成一个用户定制的笔,然后在示例的组框上画一条演示的线。其中IDC_EXAMPLE是组框的ID。
注意:
a. 在生成新笔之前,一定要UpdateData()将控件的值刷新到它们的捆绑变量中去,否则产生的笔将不正确。
b. GetWindowRect函数得到的是相对于屏幕的坐标,而DC中的坐标总是相对于窗口的。因此要用ScreenToClient转换一下。否则画出的线的位置将不正确,而且有时可能看不到。
4. 此时运行程序,在用户输入一个比较大的宽度(比如5),再输入一个较小的宽度(比如1)时,将看不到细线,因为细线在粗线的上面画出,根本看不到效果。应将以上代码剪切至OnPaint()中(把其中的CclinetDC dc(this);语句注释,然后在OnChangeEdit1()调用Invalidate()函数。
5. 分别为三个单选按钮添加响应函数,OnRadio1(),OnRadio2(),OnRadi,3(),调用Invalidate()函数。
6. 在View中添加一个菜单响应函数OnDrawSetmode(),加入代码:
CSetDlg dlg;
dlg.m_nStyle=m_nStyle;
dlg.m_nWidth=m_nWidth;
dlg.m_clrDraw=m_clrDraw;
if(IDOK==dlg.DoModal())
{
m_nStyle=dlg.m_nStyle;
m_nWidth=dlg.m_nWidth;
}
7. 在OnLButtonUp中加入:
CClientDC dc(this);
CPen newpen(m_nStyle,m_nWidth,RGB(0,0,255));
CPen *oldpen=dc.SelectObject(&newpen);
switch(m_nDrawMode)
{
case 0:
dc.SetPixel(point.x,point.y, RGB(0,0,255));
break;
case 1:
dc.SetROP2(R2_MERGEPENNOT);
dc.MoveTo(m_ptOrigin);
dc.LineTo(m_ptEnd);
dc.MoveTo(m_ptOrigin);
dc.LineTo(point);
m_ptEnd=point;
break;
case 2:
dc.SetROP2(R2_MERGEPENNOT);
dc.Rectangle(m_ptOrigin.x,m_ptOrigin.y,m_ptEnd.x,m_ptEnd.y);
dc.Rectangle(m_ptOrigin.x,m_ptOrigin.y,point.x,point.y);
m_ptEnd=point;
break;
case 3:
dc.SetROP2(R2_MERGEPENNOT);
dc.Ellipse(m_ptOrigin.x,m_ptOrigin.y,m_ptEnd.x,m_ptEnd.y);
dc.Ellipse(m_ptOrigin.x,m_ptOrigin.y,point.x,point.y);
m_ptEnd=point;
break;
default:
break;
}
8. 在View的cpp文件中加入#include "setdlg.h"。
二、设置笔的颜色的对话框
MFC为我们提供了标准的颜色对话框CcolorDialog,可以用它来生成设置颜色对话框。
1. 在View中加入一个用于记录颜色的成员变量:
COLORREF m_clrDraw;
在View的构造函数中将其初始化:
m_clrDraw=RGB(0,0,255);
2. 在View中添加一个菜单响应函数OnDrawSetcolor(),加入代码:
CColorDialog dlg;
dlg.m_cc.Flags |= CC_FULLOPEN | CC_RGBINIT;
dlg.m_cc.rgbResult = m_clrDraw;
if(IDOK==dlg.DoModal())
{
m_clrDraw=dlg.GetColor();
}
3. 在OnLButtonUp中将生成笔的代码改为:
CPen newpen(m_nStyle,m_nWidth,m_clrDraw);
4. 在CsetDlg中加入一个用于记录颜色的成员变量,在OnDrawSetmode() 中对话框显示之前为其赋值,
dlg.m_clrDraw=m_clrDraw;
5. 将CsetDlg的OnPaint()中的生成笔的代码改为:
CPen newpen(m_nStyle,m_nWidth,m_clrDraw);
三、设置对话框中的控件的字体,颜色等
1. 在CsetDlg中加入成员变量fn,br,在构造函数中对它们进行初始化
br.CreateSolidBrush(RGB(0,0,255));
fn.CreatePointFont(300,"宋体");
2. 在CsetDlg中WM_CTLCOLOR消息的响应函数OnCtlColor,加入下列代码:
if(pWnd->GetDlgCtrlID()==IDC_SAMPLE)
pDC->SetTextColor(RGB(0,0,255));
else if(pWnd->GetDlgCtrlID()==IDC_EDIT1)
{
pDC->SetBkMode(TRANSPARENT);
return (HBRUSH)br.m_hObject;
}
else if(pWnd->GetDlgCtrlID()==IDC_TEST)
{
pDC->SelectObject(&fn);
}
说明:
a. 这段代码将示例组框(IDC_SAMPLE)的文本颜色设置为蓝色,将文本框(IDC_EDIT1)的背景设置为蓝色,将标签按钮设置为宋体300。如下图:
b. 判断当前正在画哪个控件应该用
if(pWnd->GetDlgCtrlID()==IDC_SAMPLE)
若改为
if(pWnd==GetDlgItem(IDC_SAMPLE))
将不起作用,因为OnCtlColor传入的参数pWnd和GetDlgItem返回的都是临时的窗口指针。
c. 修改窗口的背景应在OnCtlColor中返回一个刷子的句柄,
return (HBRUSH)br.m_hObject;
而不应该用
pDC->SelectObject(&br);
四、使用CbuttonST
1. 将CbuttonST类的两个文件BtnST.cpp和BtnST.h复制到当前工程的目录下,并通过ProjectàAdd To ProjectàFiles菜单加入到工程中。
2. 为“确定”按钮捆绑一个控制变量m_btnOk,其类型定义为CbuttonST。
3. 在OnInitDialog()中加入代码,调用CbuttonST的函数:
m_btnOk.SetActiveBgColor(RGB(0,0,255));
m_btnOk.SetActiveFgColor(RGB(255,0,0));
评论