《VC++深入详解》学习笔记[6]——第7章 对话框(一)

 

第7章 对话框(一)

1.对话框基本知识

       在MFC中所有的控件类都是由CWnd类派生来的,因此控件实际上也是窗口,控件通常是作为对话框的子窗口而创建的。另外控件也可以出现在视类窗口、工具栏和状态条中。控件是独立的小部件,在对话框与用户的交互过程中担任着主要角色。

对话框的种类:

       ①模态对话框:当其显示时程序会暂停执行,直到关闭这个模态对话框后,才能继续执行程序中的其他任务;

       ②非模态对话框:非模态对话框显示时允许程序转而执行其他任务,而不用关闭这个对话框。

2.对话框的创建和显示

对话框作为资源插入到项目中。在MFC中,对资源的操作通常都是通过一个与资源相关的类来完成的,对话框资源也有一个相应的基类:CDialog,他派生自CWnd类。可以通过类向导为对话框资源新建相关联的类。例如为资源ID号为IDD_DIALOG1的对话框新建了一个CTestDlg类,则在该类中有两个成员函数,其一为构造函数:

       CTestDlg::CTestDlg(CWnd* pParent /*=NULL*/)

              : CDialog(CTestDlg::IDD, pParent)

       {

              //{{AFX_DATA_INIT(CTestDlg)

                     //NOTE:the ClassWizard will add member initialization here

              //}}AFX_DATA_INIT

       }

由CTestDlg的头文件中可知,IDD即为IDD_DIALOG1:

              //{{AFX_DATA(CTestDlg)

                     enum { IDD = IDD_DIALOG1 };

              //}}AFX_DATA

另一个函数为DoDataExchange,主要用来完成对话框数据的交换和校验:    

       void CTestDlg::DoDataExchange(CDataExchange* pDX)

       {

              CDialog::DoDataExchange(pDX);

              //{{AFX_DATA_MAP(CTestDlg)

                     //NOTE:the ClassWizard will add DDX and DDV calls here

              //}}AFX_DATA_MAP

       }

模态对话框的创建:

       CTestDlg dlg;

       dlg.DoModal();

       dlg.EndDialog();

非模态对话框的创建:

       CTestDlg *pDlg=new CTestDlg;

       pDlg->Create(IDD_DIALOG1,this);

       pDlg->ShowWindow(SW_SHOW);

在创建非模态对话框时不能把对话框对象定义为局部变量,解决方法有两种:一是把对话框变量定义为视类的成员变量;第二种方法是将其定义为指针,在堆上分配内存,在堆上分配的内存与程序的整个生命周期是一致的。对于模态对话框则不存在这个问题,因为在调用DoModal函数显示时,程序会暂时停止执行,直到模态对话框关闭以后程序才继续向下执行。

当点击对话框上的OK按钮时,对于模态对话框而言,此时对话框窗口对象被销毁了,但是对于非模态对话框而言,对话框窗口对象并未被销毁,只是隐藏起来了。因此对于非模态对话框来说,必须重写响应的按钮响应函数,并在重写的函数中调用DestroyWindow函数,同时注意不要再调用基类的相应函数。

控件的访问

为了使一个静态文本控件能够响应鼠标单击事件,需要进行两个特殊的步骤:首先改变它的ID,使其不为默认的IDC_STATIC,其次在它的属性对话框中选中Notify。

对话框控件访问的七种方式

①GetDlgItem(ID)->Get(Set)WindowText()

②GetDlgItemText()/SetDlgItemText()

③GetDlgItemInt()/SetDlgItemInt()

④将控件和整型变量(Value)相关联:将编辑框与对话框的成员变量相关联,然后通过成员变量来检索和设置编辑框的文本。

       当为ID为IDC_EDIT1的编辑框控件添加了一个关联的int型成员变量m_num1后,ClassWizard添加了以下内容:

       1)在CTestDlg类的头文件中两个AFX_DATA注释宏之间增加了一个成员变量:

              // Dialog Data

              //{{AFX_DATA(CTestDlg)

                     enum { IDD = IDD_DIALOG1 };

                     int          m_num1;

              //}}AFX_DATA

       2)在CTestDlg类的构造函数中对其进行了初始化,赋值为0:

              CTestDlg::CTestDlg(CWnd* pParent /*=NULL*/)

                     : CDialog(CTestDlg::IDD, pParent)

              {

                     //{{AFX_DATA_INIT(CTestDlg)

                            m_num1 = 0;

                     //}}AFX_DATA_INIT

              }

       3)在DoDataExchange函数内部实现了对话框控件与类成员变量的关联:

              void CTestDlg::DoDataExchange(CDataExchange* pDX)

              {//CDataExchange提供了DDX、DDV运行所需的上下文信息

                     CDialog::DoDataExchange(pDX);

                     //{{AFX_DATA_MAP(CTestDlg)

                            DDX_Text(pDX, IDC_EDIT1, m_num1);

                     //}}AFX_DATA_MAP

              }

       DoDataExchange函数由程序框架调用,以完成对话框数据的交换和校验。DDX_Text函数的功能就是将ID指定的控件与特定的类成员变量相关联。MFC提供了许多以DDX_为前缀的函数,这些函数分别用于不同控件的数据交换。在程序中从来不直接调用DoDataExchange函数,而是通过CWnd类的另一个函数UpdateData来调用。UpdateData函数有一个BOOL参数,如果其值为TRUE,则说明该函数正在获取对话框的数据,如果其值为FALSE,则说明该函数正在初始化对话框的控件,参数默认值为TRUE。

       可以在类向导窗口中设置关联变量的取值范围,此时ClassWizard将自动添加数据校验函数。

⑤将控件和控件变量(Control)相关联

       1)头文件:

              //{{AFX_DATA(CTestDlg)

                     enum { IDD = IDD_DIALOG1 };

                     CEdit      m_edit1;

       2)DoDataExchange函数:

              DDX_Control(pDX, IDC_EDIT1, m_edit1);

       然后就可以像操纵控件本身一样来使用控件变量了。

⑥SendMessage()

       Windows程序都是基于消息的系统,在Windows系统中获取窗口文本的消息是WM_GETTEXT、设置窗口文本的消息是WM_SETTEXT。可以利用SDK提供的SendMessage函数发送WM_GETTEXT消息获取文本,再发送WM_SETTEXT消息设置文本:

       void CTestDlg::OnBtnAdd()

       {    

              int num1,num2,num3;

              char ch1[10],ch2[10],ch3[10];

              SendMessage(GetDlgItem(IDC_EDIT1)->m_hWnd,WM_GETTEXT,10,(LPARAM)ch1);

              SendMessage(GetDlgItem(IDC_EDIT2)->m_hWnd,WM_GETTEXT,10,(LPARAM)ch2);

              num1 = atoi(ch1);

              num2 = atoi(ch2);

              num3 = num1 + num2;

              itoa(num3,ch3,10);

              ::SendMessage(GetDlgItem(IDC_EDIT3)->m_hWnd,WM_SETTEXT,0,(LPARAM)ch3);

       }//ENDOF CTestDlg::OnBtnAdd()

       字符串与数值的转换:C语言提供了这样的转换函数atoi可以将一个由数字组成的字符串转换为响应的数值;itoa函数可以将一个数值转换为文本。

⑦SendDlgItemMessage():直接向对话框的子控件发送消息;

       SendDlgItemMessage(IDC_EDIT1,WM_GETTEXT,10,(LPARAM)ch1);

获取窗口的大小和位置:GetWindowRect;

设置窗口的大小和位置:SetWindowPos;

当一个窗口已经创建之后,可以通过SetWindowLong函数来修改该窗口以指定的过程函数。当对话框及其上的子控件创建完成,将要显示之前会发送一个消息:WM_INITDIALOG。因此,在此消息的响应函数中修改窗口过程比较合适。SetWindowLong可用来修改窗口的诸多属性。

输入焦点的传递。。。

 

你可能感兴趣的:(VC,MFC,Win32SDK)