第八课:对话框
一、概念
1.对话框可以在资源面板中的对话框编辑器中设计,添加各种控件,改变它们的外观,属性。对话框也用一个ID来标识,可以用ClassWizard生成类(从CDialog派生)来管理对话框。
1. 模态对话框:
模态对话框是主程序窗口打开的临时窗口,用于显示消息及取得用户数据,用户要关闭对话框才能恢复主窗口的工作。模态对话框可定义为局部变量
CMyDlg dlg; // CMyDlg是一个管理对话框的类,从CDialog派生
dlg.DoModal();//可以想象在此函数完成了对话框的显示,销毁操作。
注意,如果对话框中我们需要将某些变量取出,不能用
GetDlgItem(ID_..)->GetWindowText(),因为当DoMadle()返回时,对话框已经不存在了。
2.非模态对话框:
对话框不返回,可以切换到其他窗口,所以非模态对话框必须定义为全局变量或用 new产生,然后
dlg.Create(IDD_DIALOG1);
dlg.ShowWindow(SW_SHOW);
二、若你想在对话框上加几个控件,应在OnCreate()中加入代码,这时对话框刚刚产生,若想对控件操作,则应加在OnInitDialog()(若在OnCreate()会产生错误,因为子控件还不一定存在)。
注意:若你想改变主窗口的标题,应加在App的InitInstance()中,加在MainFrame和View中的PreCreateWindow()和OnCreate()中都不可以,因为当程序打开无标题文件时,主窗口标题被覆盖了。
三、对话框中的函数:
CWnd::GetDlgItem(nID); //得到指定控件临时对象的指针
CWnd::SetFocus(); //得到焦点
(Cedit*)GetDlgItem(IDC_EDIT1)->SetSel(0,3);//选择前4个字符
因为要用CEdit类中的SetSel()函数,所以要将得到指针进行类型转换。
使用前要得到焦点否则看不出显示效果。
CWnd::EnableWindow(false); //使得窗口失效
也可以采用发消息的方式实现:
GetDlgItem(IDC_EDIT1)->SendMessage(WM_SETTEXT,0,(LPARAM)“123456”);
<==>GetDlgItem(IDC_EDIT1)->SetWindowText(“123456”);
GetDlgItem(IDC_EDIT1)->SendMessage(WM_SETFOCUS);
GetDlgItem(IDC_EDIT1)->SendMessage(EM_SETSEL,0,-1);//选择全部文本
上句也可以SendDlgItemMessage(IDC_EDIT1,EM_SETSEL,0,-1);
但GetDlgItem(IDC_EDIT1)->SendMessage(WM_ENABLE,false,0);并不等效于EnableWindow(false);
注意:Windows消息可以分为两类,一种是发出消息指示去干什么。比如,WM_SETFOCUS,WM_SETTEXT,另一种是干了什么事之后发出消息,表明已干了什么,比如WM_ENABLE。
另外:从另一种角度来看,窗口类所共有的消息,叫WM_XXX,而一些类有特有的消息,比如EDIT类EM_SETSEL,同理Cbotton类特有的消息BM_XXX,ListBox特有的消息LB_XXX,etc.
四、数据交换:
为了和控件交换数据可以定义一个变量与某一个控件关联。
为了控制控件可以定义一个对象与一个控件相关联。
注意:一个控件只能和一个对象,一个变量相联,多了会产生错误。
UpdateData(true); //控件的值刷新至关联的变量
UpdateData(false); //变量的值刷新至控件
CDialog在OnInitDialog中,系统调用UpdataData(false);
CDialog::OnOk中系统调用UpdateData(true);
BTW:将某些类中常用的常量,定义为该类中的枚举。
如:CFile::中的enum OpenFlags
五、变量的存储:
1、堆:全局变量和用new产生的变量 手工释放
栈:局部变量{int x;…;}自动释放。
2、MFC中,关闭程序流程:
用户关闭主窗口->OnClose()->DestroyWindow()(销毁窗口,先销毁所有的子窗口,再销毁自己)->OnNcDestroy()->PostNcDestroy()->delete C++窗口对象
对于一个窗口,你一定要用DestroyWindow()不要用delete.
3、(1)MFC自动清除的类:(它们通常被分配在堆上)。
MainFrame窗口(直接或间接从CframeWnd派生)
View窗口(直接或间接从Cview派生)
(2)MFC不自动清除的类:(它们通常嵌入到别的C++对象,或者存放在栈上)
i. 标准Window控件(CStatic,CEdit,CListBox等)
ii. 从CWnd派生的子窗口。
iii.切分CSplitterWnd
iv. 缺省的控制条(从CControlBar派生)
v. 模态对话框,标准对话框(除了CFindReplateDialog),ClassWizard创建的默认对话框。
4、对于不自动清除的对象在调用DestroyWindow()后,C++对象依然存在,但m_hWnd=NULL;
对于自动清除的对象,C++对象已被清除(在PostNcDestroy()中被delete).
评论