Lesson6:对话框
对话框是MFC程序设计中一个重要的角色,本文主要讲解了对话框的使用方法,包括讲解了模态对话框和非模态对话框,并通过一个例子讲述了对话框中静态文本框控件的文字改变,对话框大小切换和简单的加法计算实现。
1. 模态对话框和非模态对话框
C++中对任何对象的操作都是通过类来实现的。操作对话框对象,所以我们先建一个类,命名为CTestDlg,基类为CDialogEx,这时就产生了一个新的类。然后在菜单里新建立一个菜单,命名为对话框,命令响应放在View类里完成。然后会自动在view类里添加一个OnDialog()函数。
这里对话框的创建有模态和非模态之分,在执行应用程序时,打开了模态对话框,那么必须关闭模态对话框,程序才能继续执行;非模态对话框打开时,程序可以继续执行其他任务。
void CMyboleView::OnDialog()
{
//TODO: 在此添加命令处理程序代码
/*实现模态对话框*/
CTestDlgdlg;
dlg.DoModal();
/*实现非模态对话框*/ //一般使用模态对话框,非模态对话框太麻烦
//CTestDlg*pDlg = new CTestDlg(); //定义一个指针
//pDlg->Create(IDD_DIALOG1,this); //参数是(对话框ID,父窗口对象的指针)
//pDlg->ShowWindow(SW_SHOW); //显示窗口
}
2. 对话框中实现加法运算
在工具箱中添加相应控件,其中包括静态文本框控件,编辑框控件,按钮控件,图片控件,实现加法运算,最后的图示如下。
2.1 点击静态文本框,实现中英文切换
在静态文本控件Number1:上修改控件ID 为IDC_NUMBER1,添加命令响应函数。
void CTestDlg::OnClickedNumber1() //静态文本框的操作,实现点击后文本类容变化
{
//TODO: 在此添加控件通知处理程序代码
//静态文本框进行消息响应时,首先修改ID号,然后将notify修改为true。否则接收不到点击消息
CStringstr;
if(GetDlgItem(IDC_NUMBER1)->GetWindowText(str), str =="Number1:") //获得文本框中的类容然后与字符串"Number1:"比较
{
GetDlgItem(IDC_NUMBER1)->SetWindowText("数值1:"); //重新设置文本框类容
}
else
{
GetDlgItem(IDC_NUMBER1)->SetWindowText("Number1:");//重新设置文本框类容
}
}
2.2 点击按钮“收缩<<”,实现对话框大小切换
修改控件ID,为IDC_BUTTON1,添加命令响应函数。添加一个picture 控件,拉成一条线,作为分割符,修改ID为IDC_SEPARATOR,类型里sunken选项选中,用于分割对话框。
void CTestDlg::OnClickedButton1()
{
//TODO: 在此添加控件通知处理程序代码
CStringstr;
if(GetDlgItemText(IDC_BUTTON1,str), str == "收缩<<") //获得文本框中的类容然后与字符串"Number1:"比较
{
SetDlgItemText(IDC_BUTTON1,"扩展>>"); //重新设置文本框类容
}
else
{
SetDlgItemText(IDC_BUTTON1,"收缩<<"); //重新设置文本框类容
}
/**************************点击按钮后,进行点击响应对话框大小转换操作**************************************/
staticCRect rectLarge, rectSmall; //定义两个矩形变量存放对话框尺寸大小,因为对话框两个尺寸不变,所以定义为静态的
if(rectLarge.IsRectNull()) //用CRect成员函数IsRectNull()判断矩形是否为空,因为上面定义为static,所以自动初始化都为零,所以这里为空,条件成立
//如果大矩形的尺寸为空,四个值都为0,此时条件成立
{
CRectrectSeparator; //定义一个分割线
GetWindowRect(&rectLarge); //得到大矩形窗口的尺寸,直接GetWindowRect将窗口尺寸给rectlarge所指向的指针
GetDlgItem(IDC_SEPARATOR)->GetWindowRect(&rectSeparator); //先得到控件的指针,然后GetWindowRect得到控件尺寸。得到分割线的尺寸(分割线用图片形式,看做一个对话框,所以也是一个矩形)
//得到收缩矩形的尺寸
rectSmall.left= rectLarge.left;
rectSmall.top= rectLarge.top;
rectSmall.right= rectLarge.right;
rectSmall.bottom= rectSeparator.bottom;
}
if(str == "收缩<<")
{
SetWindowPos(NULL,0, 0, rectSmall.Width(), rectSmall.Height(), SWP_NOMOVE | SWP_NOZORDER);
}
else
{
SetWindowPos(NULL,0, 0, rectLarge.Width(), rectLarge.Height(), SWP_NOMOVE | SWP_NOZORDER);
}
}
2.3 点击按钮“Add”,实现加法运算
点击按钮后,将编辑框1和编辑框2的值加起来放在编辑框3里。
void CTestDlg::OnClickedBtnAdd()
{
//TODO: 在此添加控件通知处理程序代码
/*****方法一:使用GetDlgItem 和GetWindowText 和 SetWindowText函数进行文本框类容获得操作*******/
//因为获得文本框的时候,是获得的字符串,所以先得到字符串,然后转换为数值,再进行加法计算,最后将数值又转换为字符串形式在文本框中输出
/*****************************************************************************************************
intnum1, num2, num3;
charch1[10], ch2[10], ch3[10];
GetDlgItem(IDC_EDIT1)->GetWindowText(ch1,10);
GetDlgItem(IDC_EDIT2)->GetWindowText(ch2,10);
num1= atoi(ch1); //将字符型数据转换为整型数据
num2= atoi(ch2);
num3= num1+num2;
_itoa_s(num3,ch3, 10); //将整型数据转换为字符型数据,最后的10,表示用十进制数表示
GetDlgItem(IDC_EDIT3)->SetWindowText(ch3); //将ch3的值放到编辑框3中
***************************************************************************************************/
/********************方法二:使用GetDlgItemText函数进行文本框类容获得操作**********************/
//它相当于同时有GetDlgItem和 GetWindowText 和 SetWindowText函数的功能
/*************************************************************************************************
intnum1, num2, num3;
charch1[10], ch2[10], ch3[10];
GetDlgItemText(IDC_EDIT1,ch1, 10);
GetDlgItemText(IDC_EDIT2,ch2, 10);
num1= atoi(ch1); //将字符型数据转换为整型数据
num2= atoi(ch2);
num3= num1 + num2;
_itoa_s(num3,ch3, 10); //将整型数据转换为字符型数据,最后的10,表示用十进制数表示
SetDlgItemText(IDC_EDIT3,ch3); //将ch3的值放到编辑框3中
**************************************************************************************************/
/******方法三:使用GetDlgItemInt函数进行文本框类容获得操作*******/
//它相当于同时有GetDlgItem和 GetWindowText 和 SetWindowText函数的功能
/********************************************************************************************************
intnum1, num2, num3;
num1=GetDlgItemInt(IDC_EDIT1);
num2=GetDlgItemInt(IDC_EDIT2);
num3= num1 + num2;
SetDlgItemInt(IDC_EDIT3,num3,true);
***************************************************************************************************/
/****方法四:使用控件和变量关联进行加法操作****/
//将IDC_EDIT1,2,3分别和m_num1,2,3关联,然后直接计算。 设置为整型变量关联
//在关联后在构造函数中,默认值设为0,为了获得输入的值,调用UpdateData()函数
//因为我们在空间关联的时候,关联的是一个整型的变量,所以要求输入的是一个整数
UpdateData(); //获得值之前调用函数UpdateData()默认为true,然后接受输入的值
m_num3= m_num1+ m_num2 ;
UpdateData(FALSE); //获得值之后调用函数UpdateData()参数设为false,用现在的值进行编辑框的值进行初始化
}
3. 改变对话框上控件的颜色
对于控件颜色的改变,有一个消息响应,添加这个消息OnCtlColor(),并添加一个CBrush变量m_brush,我们可以在构造函数中进行初始化为绿色:m_brush.CreateSolidBrush(RGB(0, 255, 0))。添加一个CFont变量m_font,用于后面修改字体,初始化m_font.CreatePointFont(200,"华文行楷")。
HBRUSH CTestDlg::OnCtlColor(CDC* pDC, CWnd*pWnd, UINT nCtlColor)
{
HBRUSHhbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor);
//TODO: 在此更改 DC 的任何特性
if(pWnd->GetDlgCtrlID() == IDC_CALCULATION) //选择框
{
pDC->SetTextColor(RGB(255,0, 0)); //改变文本颜色
pDC->SetBkMode(TRANSPARENT); //文字背景色为透明
returnm_brush; //控件背景
}
if(pWnd->GetDlgCtrlID() == IDC_EDIT1) //编辑框
{
pDC->SetTextColor(RGB(255,0, 0)); //改变文本颜色
//pDC->SetBkMode(TRANSPARENT); //文字背景色为透明 两种方式
pDC->SetBkColor(RGB(0,255, 0)); //文字背景色和默认的m_brush颜色一样
returnm_brush; //控件背景
}
if(pWnd->GetDlgCtrlID() == IDC_TEXT) //编辑框
{
pDC->SelectObject(&m_font); //改变文本颜色
}
//对于按钮的颜色修改,我们需要先建立一个类,通过这个类作用这个控件,CButton继承的CTestBtn
//在CTestBtn类中添加虚函数,并复制MSDN的代码,然后将其与IDOK按钮关联一个变量
if(pWnd->GetDlgCtrlID() == IDOK) //ok按钮,将ok按钮的owner draw选为true,还有复制一段MSDN的代码
{
returnm_brush; //改变文本颜色
}
if(pWnd->GetDlgCtrlID() == IDOK)
{
pDC->SelectObject(&m_font); //改变背景颜色
}
//TODO: 如果默认的不是所需画笔,则返回另一个画笔
returnhbr; //使用默认的画刷
}
程序最终截图: