Lesson6:对话框
对话框是MFC程序设计中一个重要的角色,本文主要讲解了对话框的使用方法,包括讲解了模态对话框和非模态对话框,并通过一个例子讲述了对话框中静态文本框控件的文字改变,对话框大小切换和简单的加法计算实现。
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); //显示窗口 }
在工具箱中添加相应控件,其中包括静态文本框控件,编辑框控件,按钮控件,图片控件,实现加法运算,最后的图示如下。
在静态文本控件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:");//重新设置文本框类容 } }
修改控件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); } }
点击按钮后,将编辑框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,用现在的值进行编辑框的值进行初始化 }
对于控件颜色的改变,有一个消息响应,添加这个消息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; //使用默认的画刷 }
程序最终截图: