Lesson 7
对话框用户界面程序的编写:
1、在MFC中,对一个资源进行操作,通常都是通过与资源相关的一个类来完成的。 2、CDialog : CWnd : CComTarget : CObject。 3、模态对话框
CDialog::DoModal
virtual int DoModal(); //返回值是作为CDialog::EndDialog的一个参数,用来关闭对话框的
CDialog TestDialog;
TestDialog.DoModal(); //创建一个模态对话框,程序在此停止了 当我们点击ok或者cancel时,对话框销毁了 4、非模态对话框
CDialog::Create //初始化一个对话框对象,创建一个非模态对话框,并把它和对话框对象相关联
BOOL Create(LPCTSTR lpszTemplateName,CWnd* pPatentWnd=NULL); //对话框名字,父窗口指针
BOOL Create(UINT nIDTemplate, CWnd* pParentWnd=NULL); //对话框模板的id号,父窗口指针如果为NULL则父窗口为主应用程序窗口 CTestDlg dlg;
dlg.Create(IDD_DIALOG1,this); //父窗口为当前所在类的窗口 dlg.ShowWindow(SW_SHOW);
此时窗口并没有显示出来,因为dlg是一个局部变量,离开函数就自动销毁了,怎么办呢:
一种方式是把dlg定义为类的成员变量or静态变量
另一种方式,可以将dlg定义为一个指针,在堆栈分配一个内存,堆上的内存和程序的生命周期一致
CTestDlg* pdlg=new CTestDlg(); //将dlg定义为一个指针,在堆栈分配一个内存 pdlg->Create(IDD_DIALOG1,this); //父窗口为当前所在类的窗口 pdlg->ShowWindow(SW_SHOW);
当我们点击ok或者cancel时,对话框并不是销毁了,而是隐藏了,如果没有重载,则由基类ok()响应,基类对话框的ok()作用是让对话框不可见,而并不是销毁它
如果是非模态对话框,必须重载这个ok()函数,用DestroyWindow()销毁对话框,不用EndDialog(),它是给模态对话框用的
CDialog::OnOk virtual void OnOk();
5、对话框上动态创建一个按钮。建一个按钮,点一下建立一个新按钮,再一下消失,再一下出现。
CButton m_btn; //定义一个按钮成员变量
BOOL m_bIsCreate; //定义为一个BOOL成员变量,用来判断是建立按钮还是销毁按钮 m_bIsCreate=FALSE; //对话框建立的时候初始化为FALSE
if(m_bIsCreate==FALSE) {
m_btn.Create(\维新\| WS_VISIBLE |WS_CHILD,CRect(0,0,10,10),this,123); m_bIsCreate=TRUE; } else {
m_btn.DestroyWindow(); m_bIsCreate=FALSE; }
或者:用静态变量来作为判断,这样不用建立成员变量
static BOOL bIsCreate=FALSE; //定义为一个BOOL静态变量,用来判断是建立按钮还是销毁按钮
if(bIsCreate==FALSE) {
m_btn.Create(\维新\| WS_VISIBLE |WS_CHILD,CRect(0,0,10,10),this,123); bIsCreate=TRUE; } else {
m_btn.DestroyWindow(); bIsCreate=FALSE; }
或者:更简单,直接判断按钮这个窗口的句柄
if(!m_htn.m_hWnd) {
m_btn.Create(\维新\| WS_VISIBLE |WS_CHILD,CRect(0,0,10,10),this,123); } else {
m_btn.DestroyWindow(); //窗口销毁了,句柄就被清空了 }
6、静态文本框,只要改变了id号,就可以在类向导中为它添加消息响应了,但好象默认只有一个消息BN_CLIck
7、获取窗口文本,静态文本框也是一个窗口
CWnd::GetWindowText
int GetWindowText(LPTSTR lpszStringBuf,int nMaxCount)const;
void GetWindowText(CString& rString)const; //获取窗口文本,保存在传入的参数中
8、获取窗口上一个控件的指针
CWnd::GetDlgItem //这个函数一般用于对话框类当中 CWnd* GetDlgItem(int nID) const;
void CWnd::GetDlgItem(int nID, HWND* phWnd) const;
9、设置窗口文本
CWnd::SetWindowText
void SetWindowText(LPCTSTR lpszString);
10、一般静态文本框是不能接受通告消息的,必须在属性styles中勾选Notify,才能够响应点击操作
11、改变窗口文本 CString str;
if(GetDlgItem(IDC_NUMBER1)->GetWindowText(str),str==\逗号运算符,取后者值 {
GetDlgItem(IDC_NUMBER1)->SetWindowText(\数值1:\ }
GetDlgItem(**)->GetWindowText(**)
GetDlgItem(**)->SetWindowText(**) 甚至可以对editBox操作,以前我一直是用定义变量实现的
12、获取控件文本的另一个方式,相当于GetDlgItem(**)->GetWindowText(**)的结合 CWnd::GetDlgItemText
int GetDlgItemText(int nID,LPTSTR lpStr,int nMaxCount)const; int GetDlgItemText(int nID,CString& rString)const;
改变窗口文本
CWnd::SetDlgItemText
void SetDlgItemText(int nID,LPTSTR lpszString);
13、第三种访问控件的方法
CWnd::GetDlgItemInt //获取一个文本并转换为一个整型返回
UINT GetDlgItemInt(int nID,BOOL* lpTrans=NULL,BOOL bSigned=TRUE)const; 控件id号 错误 是否有符号
CWnd::SetDlgItemInt
void SetDlgItemInt(int nID,UINT nValue,BOOL bSigned=TRUE);
是否有符号
14、第四种访问控件的方法,用成员变量 用类向导对editbox添加int变量,则该变量会在.h中定义 .cpp构造函数中初始化为0,在DoDataExchange()中通过函数DDX_Text()完成变量和控件之间的关联
DDX_有许多个函数DDX_Radio,DDX_Scroll等等,可完成变量与不同的控件相关联
DoDataExchange()主要被框架类调用,用来交换和校验对话框中的数据,但并不是给我们直接调用的,必须用updatedata()函数间接调用,完成数据交换功能 CWnd::UpdateData
BOOL UpdateData(BOOL bSaveAndValidate = TRUE);
TRUE 获取数据, FALSE 输出数据
数据校验的功能是怎么完成的呢?给我们的editbox添加int变量后设定取值范围0-100后,会在DoDataExchange()中添加几个函数 DDV_MinMaxInt(pDX,m_num1,0,100);
15、第五种访问控件的方法,用控件变量,控件变量代表了控件本身
定义控件变量后,就可以对该变量直接用GetWindowText()SetWindowText()进行操作 m_edit1.GetWindowText(ch1,10);
16、第六种访问控件的方法,通过发送消息的方式来访问 通过发送一个消息来获取文本WM_GETTEXT
SendMessage((HWND) hWnd,WM_GETTEXT,(WPARAM) wParam,(LPARAM) lParam); 多少个字符 保存文本的buffer 拷贝一个窗口的文本到调用者的buffer当中
::SenMessage(GetDlgItem(IDE_EDIT1)->m_hWnd,WM_GETTEXT,10,(LPARAM)ch1); 或者
::SenMessage(m_edit1.m_hWnd,WM_GETTEXT,10,(LPARAM)ch1);
不用这个api函数,也可以用cwnd的成员函数发送这样的消息
GetDlgItem(IDE_EDIT1)->SenMessage(WM_GETTEXT,10,(LPARAM)ch1); //对象内自有维护的句柄
或者直接用成员对象发送消息
m_edit1.SenMessage(WM_GETTEXT,10,(LPARAM)ch1); //对象内自有维护的句柄,不用填了,方便
设置输出文本就可以用WM_SETTEXT消息完成,使用和WM_GETTEXT完全一样 m_edit3.SenMessage(WM_SETTEXT,0,(LPARAM)ch3); //这里wParam没有使用,必须为0
17、第七种访问控件的方法,直接给对话框的子控件发送消息
CWnd::SendDlgItemMessage //在本对话框当中发送消息
LRESULT SendDlgItemMessage(int nID,UINT message,WPARAM wParam = 0,LPARAM lParam=0);
等价于GetDlgItem(**)->SenMessage(**);
SendDlgItemMessage(IDE_EDIT1,WM_GETTEXT,10,(LPARAM)ch1); SendDlgItemMessage(IDE_EDIT3,WM_SETTEXT,0,(LPARAM)ch3);
18、获取复选控件文字内容EM_GETSEL
SendMessage((HWND) hWnd,EM_GETSEL,(WPARAM) wParam,(LPARAM) lParam); 开始位置 结束位置
设置复选控件文字内容EM_SETSEL,就是让指定内容处在被选择状态
SendMessage((HWND) hWnd,EM_SETSEL,(WPARAM) wParam,(LPARAM) lParam); 开始位置 结束位置 开始位置为0,结束位置为-1,则选择所有文字
19、设置窗口焦点 CWnd::SetFocus CWnd* SetFocus();
SendDlgItemMessage(IDE_EDIT3,EM_SETSEL,1,3); //把第二至第四个字符复选 m_edit3.SetFocus(); //设置编辑框3为焦点,这样才能看到字符被选择的样子
20、对话框控件访问七种方式总结 GetDlgItem()->Get(Set)WindowText() GetDlgItemText()/SetDlgItemText() GetDlgItemInt()/SetDlgItemInt() 将控件和整型变量相关联 将控件和控件变量相关联 SendMessage()
SendDlgItemMessage()
21、判断一个矩形是否为空 CRect::ISRectEmpty
BOOL IsRectEmpty() const; //判断一个区域的长宽是否为0,0/0/0/0=35/35/35/35=真,1/2/3/4=假
CRect::IsRectNull
BOOL IsRectNull() const; //判断一个区域四个坐标是否为0,0/0/0/0=真,35/35/35/35=1/2/3/4=假
22、获取一个窗口的矩形区域