07- 对话框一

更新时间:2024-05-04 11:29:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

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、获取一个窗口的矩形区域

CWnd::GetWindowRect

void GetWindowRect(LPRECT lpRect) const;

CRect rect;

GetWindowRect(&rect);

GetDlgItem(IDC_****)->GetWindowRect(&rect);

23、设置一个窗口的大小 CWnd::SetWiondowPos

BOOL SetWindowPos(const CWnd* pWndInsertAfter,int x,int y,int cx,int cy,UINT nFlags);

z次序 改变后的坐标 宽高 改变类型

改变类型:SWP_NOMOVE 保留当前位置不移动,会把x,y忽略掉

SWP_NOZORDER 保留当前的z顺序,会把第一个参数忽略掉

SetWindowPos(NULL,0,0,rectsmall.Width(),rectsmall.Height(),SWP_NOMOVE|SWP_NOZORDER);

SetWindowPos(NULL,0,0,rectlarge.Width(),rectlarge.Height(),SWP_NOMOVE|SWP_NOZORDER);

设置了rect的四个点后,直接用rect的width()\\height()即可获取宽高

设置WS_EX_TOPMOST风格创建最顶层窗口

BringWindowToTop() 把一个窗口放置在z次序的顶部 SetWindowPos()和DeferWindowPos()可以重排z次序

兄弟窗口:共享同一个父窗口的多个子窗口叫兄弟窗口。

活动窗口:活动窗口是应用程序的顶层窗口,也就是当前使用的窗口。只有一个顶层窗口可以是活动窗口,如果用户使用的是一个子窗口,Windows系统就激活与这个子窗口相应的顶层窗口。

任何时候系统中只能有一个顶层窗口是活动的。用户通过单击窗口(或其中的一个子窗口)、使用ALT+TAB或ALT+ESC组合键来激活一个顶层窗口,应用程序则调用函数SetActiveWindow来激活一个顶层窗口。

前台窗口和后台窗口:在Windows系统中,每一个进程可运行多个线程,每个线程都能创建窗口。创建正在使用窗口的线程称之为前台线程,这个窗口就称之为前台窗口。所有其它的线程都是后台线程,由后台线程所创建的窗口叫后台窗口。

用户通过单击一个窗口、使用ALT+TAB或ALT+ESC组合键来设置前台窗口,应用程序则用函数SetForegroundWindow设置前台窗口。如果新的前台窗口是一个顶层窗口,那么Windows系统就激活它,换句话说,Windows系统激活相应的顶层窗口。

24、改变窗口过程,这个太有用了

LONG SetWindowLong(HWND hWnd,int nIndex,LONG dwNewLong); //sdk函数,改变指

定窗口的属性

要改变的窗口的句柄 你要改变的属性 新的值

通过设置改变的属性为GWL_WNDPROC,并给出一个新的窗口过程,可以改变默认的窗口过程

返回的先前的指定的32位的整型值,也就是,如果改变的是窗口过程,则返回原先的窗口过程地址

窗口内的控件是在OnCreate()之后,OnInitDialog()之前创建的,对控件操作,应在OnInitDialog()中

sdk平台的焦点设置函数,可以不通过cwnd对象的SetFocus()函数设置窗口焦点 HWND SetFocus(HWND hWnd); //参数为你要设置的窗口的句柄

sdk平台的获取当前窗口的下一个窗口句柄

HWND GetNextWindow(HWND hWnd,UINT wCmd); //当前焦点窗口的句柄,移动方向 //GWL_HWNDNEXT向下,GWL_HWNDPREV向上

有cwnd的获取当前窗口的下一个窗口句柄函数

CWnd* GetNextWindow(UINT nFlag=GW_HWNDNEXT)const; //默认获取下一个

editBox控件默认属性不接受多行,要把stylec-Multiline勾上才能接受按键消息

sdk平台获取窗口句柄的另一个函数

HWND GetWindow(HWND hWnd,UINT wCmd); //开始查找的窗口句柄,查找方向、位置

//GW_HWNDNEXT下一个 有cwnd的获取窗口句柄的另一个函数 CWnd::GetWindow

CWnd* GetWindow(UINT nCmd)const; //参数为查找方向标志

查找具有tab stop属性的控件函数,按照tab顺序查找

HWND GetNextDlgTabItem(HWND hDlg,HWND hCtl,BOOL hPrevious);

所在对话框即父窗口 从哪个控件开始查找 方向标记,TRUE前,FALSE下一个 CWnd::GetNextDlgTabItem(CWnd* pWndCtl,BOOL hPrevious=FALSE)const; 开始控件 查找方向

删了窗口中的ok按钮,但窗口仍然可以响应ok函数,手动建立一个ok按钮只需要把id改为idok

void CTestDlg::OnOK() {

//GetDlgItem(IDC_EDIT1)->GetNextWindow()->SetFocus();//老是从第一个编辑框开始

//GetFocus()->GetNextWindow()->SetFocus(); //先获取当前焦点,下个完了会传回空指针错误 //GetFocus()->GetWindow(GW_HWNDNEXT)->SetFocus(); //同样会出现空指针错误

GetNextDlgTabItem(GetFocus())->SetFocus(); //从焦点控件开始,避免了空指针错误 //CDialog::OnOK(); }

WNDPROC prevProc; //自定义的窗口过程 LRESULT CALLBACK WinSunProc(

HWND hwnd, // handle to window UINT uMsg, // message identifier

WPARAM wParam, // first message parameter LPARAM lParam // second message parameter ) {

if(uMsg==WM_CHAR && wParam==0x0d) {

//::SetFocus(::GetNextWindow(hwnd,GW_HWNDNEXT));//调用sdk函数 //SetFocus(::GetWindow(hwnd,GW_HWNDNEXT));

SetFocus(::GetNextDlgTabItem(::GetParent(hwnd),hwnd,FALSE)); return 1; } else {

return prevProc(hwnd,uMsg,wParam,lParam); } }

BOOL CTestDlg::OnInitDialog() {

CDialog::OnInitDialog();

prevProc=(WNDPROC)SetWindowLong(GetDlgItem(IDC_EDIT1)->m_hWnd,GWL_WNDPROC,

(LONG)WinSunProc); //改变IDC_EDIT1的窗口过程为自定义窗口过程,保存原先窗口过程

return TRUE; }

本文来源:https://www.bwwdw.com/article/42hg.html

Top