分享

CLRCDlg::CLRCDlg(CWnd* pParent /*=NULL*/): CDialog(CLRCDlg::IDD, pParent)

 凌蓝苑 2014-06-19

在MFC中,对资源的操作通常都是通过一个与资源相关的类来完成的。CDialog是对话框的基类,它派生于CWnd类,所以它是一个与窗口相关的类,主要用来在屏幕上显示一个对话框。默认有IDOk和IDCancel两个函数,起作用均为关闭窗体,只是返回值不一样罢了。需关注两个函数:
1.构造函数:有两个参数:其一为CTestDlg类的IDD成员对话框的资源ID,一个是父窗口指针。 CTestDlg::CTestDlg(CWnd* pParent /*=NULL*/)
        :CDialog(CTestDlg::IDD, pParent){} // enum { IDD = IDD_DIALOG1 };
2.DoDataExchange是一个虚函数,主要用那个来完成对话框数据的交换和检验。
接下来,我们来说一下模态和非模态对话框。
1.模态对话框:当它显示时,程序会暂停执行,直到关闭这个模态对话框后,才能继续执行程序中其它任务。它实质上是垄断了用户的输入,当这个模态对话框打开时,用户只能与该对话框进行交互,而其他用户界面对象接收不到输入信息。注意模态对话框显示时,生命周期并未结束。
 CTestDlg dlg;
 dlg.DoModal();
2.非模态对话框:它在显示时,允许转而执行程序中的其他任务,而不关闭这个对话框,可以更好地进行交互。
  需要注意:不能这样定义CTestDlg dlg然后创建对话框,这涉及到一个生命周期,因为一旦CTestDlg的生命周期结束了,就会销毁与之相关联的对话框资源。两种解决方法,第一种:把这个对话框资源定义为一个成员变量,另一种方式将它定义为指针,在堆上分配内存。在堆上分配内存与程序的整个生命周期一致。
 CTestDlg* pDlg = new CTestDlg;
 pDlg->Create(IDD_DIALOG1,this);  
 //当利用Create函数创建非模态对话框时,还需要用ShowWindow函数将这个对话框显示出来。
 pDlg->ShowWindow(SW_SHOW);
 指针变量pDlg是一个局部对象,这样当它的生命周期结束时,它所保存的内存地址就丢失了,那么在程序中也就无法再引用到它所指向的那块内存了。解决办法有两种:一个是将这个指针变量定义为视类的成员变量,二是在CTestDlg类中重载PostNcDestroy虚函数,释放this指针指向的内存。
 void CTestDlg::PostNcDestroy()
 {
 delete this;
 CDialog::PostNcDestroy();
 }
 点击OK按钮,无论是模态对话框还是非模态对话框,对话框均会消失。模态对话框将对话框的窗口对象销毁了;而非模态对话框窗口对象并未销毁,而是隐藏了。由于基类的OnOk函数会调用EndDialog函数,这个函数用于终止模态对话框,而隐藏非模态对话框,但不销毁。因此,对于非模态对话框来说,如果有一个ID为IDOK的按钮,就必须重写OnOk这个虚函数,并在重写的函数调用DestroyWindow函数,以完成销毁对话框的操作,同时注意不要调用基类的OnOk函数。同理对IDCANCEL也是如此。
 Windows消息分为三类:标准消息、命令消息和通告消息。像按钮的单击、列表框的选择这类消息都属于通告消息。
 创建一个按钮的方法:
1.void CTestDlg::OnBnClickedBtnAdd(){
 // TODO: 在此添加控件通知处理程序代码
       // 可以定义一个static BOOL m_bIsCreated = FALSE;
 if(m_bIsCreated){
   m_btn.Create("New",BS_DEFPUSHBUTTON|WS_VISIBLE|WS_CHILD

,CRect(0,0,100,100),this,123);
  m_bIsCreated = true;
 }
 else{
  m_btn.DestroyWindow();
  m_bIsCreated = false;
 }
 }
2.void CTestDlg::OnBnClickedBtnAdd(){
       if(!m_btn.m_hWnd){
          m_btn.Create("New",BS_DEFPUSHBUTTON|WS_VISIBLE|WS_CHILD,CRect      (0,0,100,100),this,123);
 }
 else{
          m_btn.DestroyWindow();
 }
}
控件的访问:呵呵,ctrl+已有控件->拖动复制控件
静态文本控件在没人情况下是不发送通告消息的。为了使一个静态文本空间能够响应鼠标单击消息,那么需要进行两个特殊的步骤:一是改变其ID,二是修改其属性对话框中Notify选项。
GetDlgItem函数返回一个有参数ID指定的控件或窗口对象的指针。
CString str;
if(IDC_NUMBER1)->GetWindowText(str),str == "Number1"){ //这里注意逗号表达式的使用
   GetDlgItem(IDC_NUMBER1)->SetWindowText("数值一");
}
else{
   GetDlgItem(IDC_NUMBER1)->SetWindowText("Number1");
}
下面我将介绍:在前两个编辑框中输入数字,点Add按钮求和放入第三个编辑框中的七种方法,各个函数的具体参数参见MSDN。
1.GetDlgItem()->Get(Set)WindowText()
   int num1,num2,num3;
   char ch1[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(num3,ch3,10); //数字10表示十进制
   GetDlgItem(IDC_EDIT3)->SetWindowText(ch3);
2.GetDlgItemText()/SetDlgItemText()
   int num1,num2,num3;
   char ch1[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(num3,ch3,10); //数字10表示十进制
   SetDlgItemText(IDC_EDIT3,ch3);
3.GetDlgItemInt()/SetDlgItemInt()
   int num1,num2,num3;
   num1 = GetDlgItemInt(IDC_EDIT1);
   num2 = GetDlgItemInt(IDC_EDIT2);
   num3 = num1 + num2;
   SetDlgItemInt(IDC_EDIT3,num3);
4.将控件和整形变量相关联
  每一个控件与一个整形变量相关联,这个还需要在DoDataExchange函数内部实现对话框控件和类成员变量的关联。
  void CTestDlg::DoDataExchange(CDataExchange* pDX){
 CDialog::DoDataExchange(pDX);
 DDX_Control(pDX, IDC_BTN_ADD, m_btn);
       DDX_Text(pDX,IDC_EDIT1,m_num1);
 DDX_Text(pDX,IDC_EDIT2,m_num2);
 DDX_Text(pDX,IDC_EDIT3,m_num3);
       DDV_MinMaxInt(pDX, m_num1, 0, 100);
       DDV_MinMaxInt(pDX, m_num2, 0, 100); 
  }
  MFC提供多种以DDX_为前缀的函数,这些函数分别用于不同控件的数据交换;同样提供以DDV_为前缀的数据校验函数。但是在程序代码中不调用DoDataExchange实现数据交换,而是由Cwnd的成员函数UpdateData来调用。DDX(Dialog Data Exchange),DDV(Dialog Data Validation)
  BOOL UpdateData(BOOL bSaveAndValidate = TRUE);
  如果其参数为TRUE,则说明函数正在获取对话框上的控件;如果值为FALSE,则说明该函数正在初始化对话框中的控件,其默认值为TRUE。
  UpdateData();
  m_num3 = m_num1 + m_num2;
  UpdateData(FALSE);
5.将控件和控件变量相关联
  CEdit m_edit1;
  CEdit m_edit2;
  CEdit m_edit3;
  DDX_Control(pDX, IDC_EDIT1, m_edit1);
  DDX_Control(pDX, IDC_EDIT2, m_edit2);
  DDX_Control(pDX, IDC_EDIT3, m_edit3);
  int num1,num2,num3;
  char ch1[10],ch2[10],ch3[10];
  m_edit1.GetWindowText(ch1,10);
  m_edit2.GetWindowText(ch2,10);
  num1 = atoi(ch1);
  num2 = atoi(ch2);
  num3 = num1 + num2;
  m_edit3.SetWindowText(ch3);
6.SendMessage()
  Windows程序都是基于消息的系统,为了获取或设置窗口的文本,只需要获取或设置创建欧的文本信息,就可以用SendMessage来发送这条消息,从而获取或设置窗口的文本。在Windows系统中,获取窗口文本的消息是WM_GETTEXT,发送该消息以后,系统将把指定窗口的文本复制到调用者提供的一个缓存中。在这个消息的附加参数中,wParam制定复制的字符数,lParam是调用者提供的用来保存窗口文本的缓存地址。而设置窗口的文本的消息是WM_SETTEXT,这个消息的wParam参数没有用,值为0,lParam参数制定了用来设置窗口文本的字符串地址。
  int num1,num2,num3;
  char ch1[10],ch2[10],ch3[10];
  //可以采用2种方式来获得窗口句柄,编辑框也是窗口,也有有一个公共句柄成员变量m_hWnd
  ::SendMessage(GetDlgItem(IDC_EDIT1)->m_hWnd,WM_GETTEXT,10,(LPARAM)ch1);
  ::SendMessage(m_edit2.m_hWnd,WM_GETTEXT,10,(LPARAM)ch2);
  num1 = atoi(ch1);
  num2 = atoi(ch2);
  num3 = num1 + num2;
  itoa(num3,ch3,10);
  m_edit3.SendMessage(WM_SETTEXT,0,(LPARAM)ch3); //最后一个参数需要强制类型转换
7.SendDlgItemMessage()
 当发送的消息为WM_GETTEXT和WM_SETTEXT时
  int num1,num2,num3;
  char ch1[10],ch2[10],ch3[10];
  SendDlgItemMessage(IDC_EDIT1,WM_GETTEXT,10,(LPARAM)ch1);//直接给对话框的子控件发送消息
  SendDlgItemMessage(IDC_EDIT2,WM_GETTEXT,10,(LPARAM)ch2);
  num1 = atoi(ch1);
  num2 = atoi(ch2);
  num3 = num1 + num2;
  itoa(num3,ch3,10);
  SendDlgItemMessage(IDC_EDIT3,WM_SETTEXT,0,(LPARAM)ch3);
  当发送的消息为EM_GETSL和EM_SETSL时
  EM_GETSL获得编辑框复选的内容,EM_SETSL设置编辑框控件中的复选内容。
  注:EM打头的消息指的是编辑控件消息(Edit Control Message),wParam参数将接收复选内容的开始位置,lParam参数将接收复选内容的结束位置。这2个参数都要求指向DWORD类型的指针。
  SendDlgItemMessage(IDC_EDIT3,EM_SETSEL,1,3);
  SendDlgItemMessage(IDC_EDIT3,EM_SETSEL,0,-1); //编辑框控件中的所有内容都将被复选
  m_edit3.SetFocus();

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多