值类型。单击OK按钮,系统创建该成员变量,此时的“Control IDs”列表框如图2.21所示。
我们看到已经为ID为IDC_LINEWIDTH的输入框资源连接了值类型为int的数据成员变量m_LineWidth。因为当前选择的是该变量,所以可以在下面的“Minimum Value”和“Maximum Value”输入框中输入当前变量的可输入的最小
值和最大值,应用程序框架将确保用户输入值不会超出设定的范围。此处我们分别输入1和20,即最小线宽为1,最大线宽为20。单击OK按钮关闭类向导,即可以在类面板中看到CSetStyleDlg类已经增加了成员变量m_LineWidth。
我们看一下代码是如何实现的,打开CSetStyleDlg类的头文件,我们会发现如下代码:
// Dialog Data
//{{AFX_DATA(CSetStyleDlg) enum { IDD = IDD_SETSTYLE }; int m_LineWidth; //}}AFX_DATA
此段代码第一句完成对话框类与对话框资源的连接。第二句声明了int类型的成员变量m_LineWidth。然后看DoDataExchange函数,里面添加了如下代码:
//{{AFX_DATA_MAP(CSetStyleDlg)
DDX_Text(pDX, IDC_LINEWIDTH, m_LineWidth); DDV_MinMaxInt(pDX, m_LineWidth, 1, 20); //}}AFX_DATA_MAP
DDX_Text完成了成员变量和输入框资源的连接,而DDV_MinMaxInt完成了成员变量取值范围的设定。
同时在对话框类的构造函数中对成员变量m_LineWidth进行了初始化,代码如下:
//{{AFX_DATA_INIT(CSetStyleDlg) m_LineWidth = 0; //}}AFX_DATA_INIT
以上代码都是系统自动添加的,只要使用类向导创建对话框类和添加成员变量,就不需要手动输入这些代码。不过我们可以根据需要修改这些代码,比如修
改成员变量的初始值。
在本对话框中除了创建上面的变量m_LineWidth,还需要创建对应下拉框的控制成员变量,这些我们将在后面介绍下拉框时介绍。 2.4.3 完成颜色和示例的实时显示
在设置线型和区域填充模式对话框中,我们希望点击“...”按钮后可以显示“颜色”设置对话框,让用户选择想要使用的颜色,然后可以在对应的按钮上显示出用户选择的颜色,并且可以在示例中的按钮上用当前用户选择的线型和填充模式绘制一个示例图形。下面我们介绍如何实现这些功能。
首先,为了记录用户选择的线型,颜色,填充方式等信息,需要在对话框类中增加如下的成员变量:
public:
int m_LineStyle;//线型
COLORREF m_LineColor;//画线颜色 int m_FillStyle;//区域填充方式
COLORREF m_FillForeColor;//区域填充前景色 COLORREF m_FillBackColor;//区域填充背景色 以上成员变量不连接对话框中的控件资源,不用像添加m_LineWidth成员变量那样添加。这些成员变量(包括m_LineWidth)的值需要在调用该对话框时设置为当前用户使用的线型和填充方式,所以添加成员函数SetStyle,用于设置相应的数值,其函数声明如下:
//设置线型和区域填充方式为当前使用的
void SetStyle(int lineStyle, int lineWidth, COLORREF lineColor, int fillStyle, COLORREF ffColor,COLORREF fbColor); 函数代码如下:
void CSetStyleDlg::SetStyle(int lineStyle, int lineWidth, COLORREF lineColor, int fillStyle, COLORREF ffColor, COLORREF fbColor)
{
m_LineStyle = lineStyle;//设置线型 m_LineWidth = lineWidth;//设置线宽 m_LineColor = lineColor;//设置画线颜色 m_FillStyle = fillStyle;//设置区域填充方式
m_FillForeColor = ffColor;//设置区域填充前景色 m_FillBackColor = fbColor;//设置区域填充背景色 }
打开类向导,选择为CSetStyleDlg类添加WM_DRAWITEM消息的处理函数,处理函数名为系统的默认的OnDrawItem。该函数用于完成对话框中各个控件的绘制,其函数声明如下:
afx_msg void OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct); 其中参数nIDCtl为要绘制的控件的ID;参数lpDrawItemStruct指向LPDRAWITEMSTRUCT结构体,该结构体中存放了传入ID对应的控件的相关信息,我们需要用到的是其中的hDC成员变量,该变量是用户绘制控件的设备环境句柄。我们使用该函数的思想是:该函数用于绘制传入的ID所指定的控件资源,我们在函数中判断传入的ID是我们要用于显示颜色或示例的控件的ID,则自行编码完成绘制,并不调用系统默认的绘制该种控件的函数,而其它控件则仍然调
用系统的默认绘制控件函数。根据以上思想,我们在OnDrawItem函数中输入如下代码:
void CSetStyleDlg::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct)
{
// TODO: Add your message handler code here and/or call default //设备环境对象 CDC dc;
//根据ID判断是显示画线颜色的控件,实时显示画线颜色 if (nIDCtl == IDC_LCSAMPLE) { //将控件的设备环境句柄设置到设备环境对象中 dc.Attach(lpDrawItemStruct->hDC); //获得控件指针 CWnd* pWnd=GetDlgItem(IDC_LCSAMPLE); //获得控件所处位置的矩形区域 CRect rect; pWnd->GetClientRect(&rect); //构造画笔和画刷对象 CPen Pen; CPen *OldPen; CBrush Brush; CBrush *OldBrush; //创建空画笔,即不绘制矩形边界 Pen.CreatePen(PS_NULL,0,RGB(0,0,0)); //创建以指定画线颜色为填充颜色的画刷 Brush.CreateSolidBrush(m_LineColor); //选择画笔和画刷并返回原有画笔和画刷 OldPen=dc.SelectObject(&Pen); OldBrush=dc.SelectObject(&Brush); //在控件的位置绘制填充矩形 dc.Rectangle(&rect); //选回原有的画笔和画刷 dc.SelectObject(OldPen); dc.SelectObject(OldBrush); //删除自定义的画笔和画刷 Pen.DeleteObject(); Brush.DeleteObject(); }
//根据ID判断是显示区域填充前景色颜色的控件,实时显示区域填充前景色
else if (nIDCtl == IDC_FFCSAMPLE) { //将控件的设备环境句柄设置到设备环境对象中
景色
dc.Attach(lpDrawItemStruct->hDC); //获得控件指针 CWnd* pWnd=GetDlgItem(IDC_FFCSAMPLE); //获得控件所处位置的矩形区域 CRect rect; pWnd->GetClientRect(&rect); //构造画笔和画刷对象 CPen Pen; CPen *OldPen; CBrush Brush; CBrush *OldBrush; //创建空画笔,即不绘制矩形边界 Pen.CreatePen(PS_NULL,0,RGB(0,0,0)); //创建以指定区域填充前景色为填充颜色的画刷 Brush.CreateSolidBrush(m_FillForeColor); //选择画笔和画刷并返回原有画笔和画刷 OldPen=dc.SelectObject(&Pen); OldBrush=dc.SelectObject(&Brush); //在控件的位置绘制填充矩形 dc.Rectangle(&rect); //选回原有的画笔和画刷 dc.SelectObject(OldPen); dc.SelectObject(OldBrush); //删除自定义的画笔和画刷 Pen.DeleteObject(); Brush.DeleteObject(); }
//根据ID判断是显示区域填充背景色颜色的控件,实时显示区域填充背else if (nIDCtl == IDC_FBCSAMPLE) { //将控件的设备环境句柄设置到设备环境对象中 dc.Attach(lpDrawItemStruct->hDC); //获得控件指针 CWnd* pWnd=GetDlgItem(IDC_FBCSAMPLE); //获得控件所处位置的矩形区域 CRect rect; pWnd->GetClientRect(&rect); //构造画笔和画刷对象 CPen Pen; CPen *OldPen; CBrush Brush; CBrush *OldBrush; //创建空画笔,即不绘制矩形边界