CTestDlg dlg;
dlg.DoModal();
对于模态对话框,对应有个函数EndDialog,在MSDN中的解释是这样的:
Call this member function to terminate a modal dialog box. This member function returns nResult as the return value of DoModal(DoModal的返回值作为一个参数传递给EndDialog). You must use the EndDialog function to complete processing whenever a modal dialog box is created.
You can call EndDialog at any time, even in OnInitDialog, in which case you should close the dialog box before it is shown or before the input focus is set.
EndDialog does not close the dialog box immediately. Instead, it sets a flag that directs the dialog box to close as soon as the current message handler returns.
2. 创建非模态对话框:
注:不能像声明模态对话框那样声明Dialog的局部对象,Dialog也是属于资源的一种,如果定义为局部对象,则会在函数的时候析构掉。
有两种办法解决:一种是将对话框资源声明为类的成员变量,一种是声明指针变量,申请堆内存,因为堆内存是在程序结束后才清空资源的。
CTestDlg *pDlg=new CTestDlg(); //最好还是将此行放在构造函数执行,然后在析构函数delete();
pDlg->Create(IDD_DIALOG1,this);
pDlg->ShowWindow(SW_SHOW); //参数定义了显示模式
3. 对于对话框上自动创建的OK按钮,对应的消息响应函数述OnOk,在模态对话框上该函数调用后是销毁窗口,但在非模态对话框上,该函数的调用只是隐藏对话框,在MSDN中的解释如下:
If you implement the OK button in a modeless dialog box, you must override the OnOK member function and call DestroyWindow from within it. Don’t call the base-class member function, because it calls EndDialog, which makes the dialog box invisible but does not destroy it.
4. 动态创建按钮:
添加类的成员变量:CButton btn;
//Button派生于CWnd,所以如果Create成功,成员m_hWnd会拥有该按钮的句柄,否则为空
if(btn.m_hWnd==NULL)
{
//如果成功创建一个button后,再次创建的同一个button话,即同一个资源,程序会出错。
btn.Create("test",BS_PUSHBUTTON,CRect(0,0,100,100),this,100);
btn.ShowWindow(SW_SHOW); //按钮也是一个对话框,所以也需要显示
//以上两条语句可以用一条语句代替
btn.Create("test",BS_PUSHBUTTON | WS_VISIBLE,CRect(0,0,100,100),this,100);
}
else
{
btn.DestroyWindow(); //销毁窗口,将btn.m_hWnd设置成NULL
}
5. 文本控件的七种调用方式(示例代码演示将文本框1和2中的数字相加输出到文本框3中):
CString num1,num2,num3;
GetDlgItem(IDC_NUM1)->GetWindowText(num1);
GetDlgItem(IDC_NUM2)->GetWindowText(num2);
int result=atoi(num1)+atoi(num2); //atoi函数将char*转为int
num3.Format("%d",result);
GetDlgItem(IDC_NUM3)->SetWindowText(num3);
CString num1,num2,num3;
GetDlgItemText(IDC_NUM1,num1);
GetDlgItemText(IDC_NUM2,num2);
int result=atoi(num1)+atoi(num2);
num3.Format("%d",result);
SetDlgItemText(IDC_NUM3,num3);
int num1,num2,num3;
num1=GetDlgItemInt(IDC_NUM1);
num2=GetDlgItemInt(IDC_NUM2);
m_num3=m_num1+m_num2;
SetDlgItemInt(IDC_NUM3,num3);
UpdateData(TRUE);
m_num3=m_num1+m_num2;
UpdateData(FALSE);
CString num1,num2,num3;
m_edit1.GetWindowText(num1);
m_edit2.GetWindowText(num2);
int result=atoi(num1)+atoi(num2);
num3.Format("%d",result);
m_edit3.SetWindowText(num3);
注:将整形变量或控件变量和控件ID进行关联是在函数DoDataExchange中进行的,它是由框架自动调用的一个函数。DoDataExchange函数完成对数据的交换和校验,其中是一些以DDX和DDV字符开始的函数,前者完成数据交换,后者完成数据校验,一般如设置了整型变量的最大最小值,就会出现DDV校验函数
a. Win32 API:
注:WM_GETTEXT消息将控件中的字符拷贝到指定的buffer中,WM_SETTEXT功能相反
CString num1,num2,num3;
::SendMessage(GetDlgItem(IDC_NUM1)->m_hWnd,WM_GETTEXT,10,(LPARAM)num1.GetBuffer(10));
::SendMessage(GetDlgItem(IDC_NUM2)->m_hWnd,WM_GETTEXT,10,(LPARAM)num 2.GetBuffer(10));
int result=atoi(num1)+atoi(num2);
num3.Format("%d",result);
::SendMessage(GetDlgItem(IDC_NUM3)->m_hWnd,WM_SETTEXT,0,(LPARAM)(LPCTSTR)num3);
b. MFC函数:
CString num1,num2,num3;
GetDlgItem(IDC_NUM1)->SendMessage(WM_GETTEXT,10,(LPARAM)num1.GetBuffer(10));
GetDlgItem(IDC_NUM2)->SendMessage(WM_GETTEXT,10,(LPARAM)num2.GetBuffer(10));
int result=atoi(num1)+atoi(num2);
num3.Format("%d",result);
GetDlgItem(IDC_NUM3)->SendMessage(WM_SETTEXT,0,(LPARAM)(LPCTSTR)num3);
CString num1,num2,num3;
SendDlgItemMessage(IDC_NUM1,WM_GETTEXT,10,(LPARAM)num1.GetBuffer(10));
SendDlgItemMessage(IDC_NUM2,WM_GETTEXT,10,(LPARAM)num2.GetBuffer(10));
int result=atoi(num1)+atoi(num2);
num3.Format("%d",result);
SendDlgItemMessage(IDC_NUM3,WM_SETTEXT,0,(LPARAM)(LPCTSTR)num3);
附:对文本框中的指定部分内容进行选中:消息EM_SETSEL
CString num1,num2,num3;
SendDlgItemMessage(IDC_NUM1,WM_GETTEXT,10,(LPARAM)num1.GetBuffer(10));
SendDlgItemMessage(IDC_NUM2,WM_GETTEXT,10,(LPARAM)num2.GetBuffer(10));
int result=atoi(num1)+atoi(num2);
num3.Format("%d",result);
SendDlgItemMessage(IDC_NUM3,WM_SETTEXT,0,(LPARAM)(LPCTSTR)num3);
SendDlgItemMessage(IDC_NUM3,EM_SETSEL,1,3);
GetDlgItem(IDC_NUM3)->SetFocus(); //必须将焦点移动到当前需要设置的文本框上
6. 模拟窗口的缩放功能:
static CRect oldRect;
static CRect newRect;
CString str;
if(GetDlgItem(IDC_ACTION)->GetWindowText(str),str=="收缩")
{
GetDlgItem(IDC_ACTION)->SetWindowText("放大");
// GetWindowRect以屏幕坐标的方式得到当前CWnd对象,即对话框的矩形区域
GetWindowRect(&oldRect);
CRect sepratorRect; //分隔条,用picture控件模拟
GetDlgItem(IDC_SEPRATOR)->GetWindowRect(&sepratorRect);
newRect.left=oldRect.left;
newRect.top=oldRect.top;
newRect.right=oldRect.right;
newRect.bottom=sepratorRect.bottom;
//SetWindowPos: Call this member function to change the size, position, and Z-order of child, pop-up, and top-level windows.
SetWindowPos(&wndTopMost,newRect.left,newRect.top,newRect.Width(),
newRect.Height(),SWP_SHOWWINDOW);
}
else
{
GetDlgItem(IDC_ACTION)->SetWindowText("收缩");
SetWindowPos(&wndTopMost,oldRect.left,oldRect.top,oldRect.Width(),
oldRect.Height(),SWP_SHOWWINDOW);
}
7. Z-Order
窗口的Z次序表明了重叠窗口堆中窗口的位置,这个窗口堆是按一个假想的轴定位的,这个轴就是从屏幕向外伸展的Z轴。Z次序最上面的窗口覆盖所有其它的窗口,Z次序最底层的窗口被所有其它的窗口覆盖。应用程序设置窗口在Z次序中的位置是通过把它放在一个给定窗口的后面,或是放在窗口堆的顶部或底部。
Windows系统管理三个独立的Z次序——一个用于顶层窗口、一个用于兄弟窗口,还有一个是用于最顶层窗口。最顶层窗口覆盖所有其它非最顶层窗口,而不管它是不是活动窗口或是前台窗口。应用程序通过设置WS_EX_TOPMOST风格创建最顶层窗口。
一般情况下,Windows系统把刚刚创建的窗口放在Z次序的顶部,用户可通过激活另外一个窗口来改变Z次序;Windows系统总是把活动的窗口放在Z次序的顶部,应用程序可用函数BringWindowToTop把一个窗口放置到Z次序的顶部。函数SetWindowPos和DeferWindowPos用来重排Z次序。
8. 为窗口上的控件设置Tab顺序:
查看Tab顺序Layout->Tab Order
传递控件的焦点GetNextDlgTabItem(GetFocus())->SetFocus();
9. CDialog的消息WM_INITDIALOG表示在对话框的子控件等创建好,在对话框的被显示前调用,他和WM_CREATE消息的区别是,后者调用的时候对话框上的子控件还没有创建完成。