对话框的种类
有两种类型的对话框:模态对话框和非模态对话框.
模态对话框时指当其显示时,程序会暂停执行,直到关闭这个模态对话框后,才能继续执行程序中的其他任务。
非模态对话框显示时,允许转而执行程序中其他任务,而不用关闭这个对话框。
创建模态对话框
1.在资源编辑器里面新建一个对话框资源,ID采用默认值为:IDD_DIALOG1
2.双击该对话框,为该对话框添加一个关联的类,命名为CtestDlg
3.创建一个菜单项
4.为该菜单项添加COMMAND命令消息响应函数,让视类来捕获它
5.在实现函数中调用Cdialog类的成员函数:DoModal,添加如下两行代码:
CTestDlg dlg;
dlg.DoModal();
6.在视类中添加CtestDlg 类的头文件
创建非模态对话框
1.在资源编辑器里面新建一个对话框资源,ID采用默认值为:IDD_DIALOG1
2.双击该对话框,为该对话框添加一个关联的类,命名为CtestDlg
3.创建一个菜单项
4.为该菜单项添加COMMAND命令消息响应函数,让视类来捕获它
5. .在实现函数中添加如下两行代码:
CTestDlg *dlg = new CTestDlg;
dlg->Create(IDD_DIALOG1,this);
dlg->ShowWindow(SW_SHOW);
6.在工程视类的析构函数中调用delete函数:
delete this;
7.在视类中添加CtestDlg 类的头文件
动态创建按钮
1. 为对话框资源新建一个按钮,Caption属性设为Add;
2. 在CTestDlg类中添加一个CButton类的成员变量m_btn;
3. 在CTestDlg类中响应这个按钮单击的消息,在函数体中写入如下代码:
void CTestDlg::OnBnClickedButton1()
{
static BOOL b = FALSE;
if (FALSE == b)
{
m_btn.Create(TEXT("New"), BS_DEFPUSHBUTTON | WS_VISIBLE | WS_CHILD, CRect(0,0,100,100), this, 123);
b = TRUE;
}
else
{
m_btn.DestroyWindow();
b= FALSE;
}
4. 以上我们是创建了一个变量来判断是否已经创建了一个按钮窗口并与按钮对象相关联,下面介绍一种更直接的方法来实现判断。我们知道,CWnd对象都有一个成员变量m_hWnd,用来保存于窗口对象相关联的窗口句柄。如果窗口对象没有与任何一个窗口相关联,这个句柄就为NULL;
void CTestDlg::OnBnClickedButton1()
{
if (!m_btn.m_hWnd)
{
m_btn.Create(TEXT("New"), BS_DEFPUSHBUTTON | WS_VISIBLE | WS_CHILD, CRect(0,0,100,100), this, 123);
}
else
m_btn.DestroyWindow();
}
静态文本控件响应鼠标单击事件
静态文本框的主要作用是起提示作用,默认情况下不能响应鼠标消息。
我们可以通过下面两步就可以实现响应
1.改变它的默认ID;
2.在它的属性对话框中选择Notify选项。
文本框控件与成员变量相关联
1.创建一个对话框,并在对话框上放一个文本框
2.右键文本框添加添加变量,类别为Value,变量类型int,变量名m_edit;
3.再添加2个编辑框控件,并与成员变量关联,方法同上
4.在按钮的方法中写下如下代码:
void CTestDlg::OnBnClickedButton1()
{
UpdateData(TRUE); //开始获取对话框中的数据
m_edit3 = m_edit1 + m_edit2;
UpdateData(FALSE); //用变量的值来初始化对话框控件
}
对话框伸缩功能
1. 用图像控件在对话框的底部画出一条分割线。
2. 改变图像控件的ID,stytle属性设为向下凹陷。
3. 代码如下:
CString str;
if (GetDlgItemText(IDC_BUTTON1, str), str == TEXT("收缩<<"))
{
SetDlgItemText(IDC_BUTTON1, TEXT("展开>>"));
}
else
{
SetDlgItemText(IDC_BUTTON1, TEXT("收缩<<"));
}
static CRect rectBig;
static CRect rectSmall;
if (rectBig.IsRectNull())
{
CRect rectTemp;
GetWindowRect(rectBig);
GetDlgItem(IDC_SEPERATOR)->GetWindowRect(rectTemp);
rectSmall.left = rectBig.left;
rectSmall.top = rectBig.top;
rectSmall.right = rectBig.right;
rectSmall.bottom = rectTemp.bottom;
}
if (str == TEXT("收缩<<"))
{
SetWindowPos(NULL, 0, 0, rectSmall.Width(), rectSmall.Height(),
SWP_NOMOVE | SWP_NOZORDER);
}
else
{
SetWindowPos(NULL, 0, 0, rectBig.Width(), rectBig.Height(),
SWP_NOMOVE | SWP_NOZORDER);
}
修改控件的窗口过程
要改变窗口的属性,我们可以调用如下函数:
LONG SetWindowLong(
HWND hWnd, // 指定想要改变属性的窗口的句柄
int nIndex, // 指定要设置的属性值的偏移地址
LONG dwNewLong // 新的窗口过程函数地址
);
当hWnd参数指定的是一个对话框,那么nIndex参数就可以可以取值为DWL_DLGRROC,利用这个参数,我们就可以设置新的对话框过程。
例如:
首先在cpp文件的开头
WNDPROC prevProc;
LRESULT CALLBACK EditNewProc(
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));
return 1;
}
else
{
return prevProc(hwnd, uMsg, wParam, lParam);
}
}
在程序运行时,当对话框及其上子控件创建完成,将要显示之前会发送一个消息:WM_INITDIALOG。因此,我们可以再此消息的响应函数中修改控件的窗口过程。
例如:
BOOL CTestDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// TODO: Add extra initialization here
prevProc=(WNDPROC)SetWindowLong(GetDlgItem(IDC_EDIT1)->m_hWnd, GWL_WNDPROC, (LONG)EditNewProc);
return TRUE;
}
输入焦点的传递
在MFC中,默认情况下,当在对话框窗口中按下回车键时,会调用对话框的默认按钮的响应函数。我们可以利用这个特性,使焦点依次向下传递。
void CTestDlg::OnOK()
{
// TODO: Add extra validation here
GetNextDlgTabItem(GetFocus())->SetFocus();
// CDialog::OnOK(); //把这句注释起来,否者会调用基类的OnOk函数。
}
编辑TAB顺序:
1. 在资源编辑器中选中要排序的对话框
2. 在菜单中选择布局
3. TAB顺序