标签:
Windows-对话框编程基本技术(1)
一 对话框简介
1.对话框实际就是一个窗口。
继承层次:
class CDialog : public CWnd
2.常用控件
在MFC中,所有的控件类都派生于CWnd。如图:
3.对话框种类
(1).模态对话框
#if 1
//创建模态对话框
CTestDlg dlg;
dlg.DoModal();
#endif
(2).非模态对话框
栈上创建
#if 1
//创建局部的对话框,函数调用完毕就生命周期即结束
CTestDlg dlg;
dlg.Create(IDD_DIALOG1, this);
dlg.ShowWindow(SW_SHOW);
#endif
堆上创建
#if 1
//在堆上创建对话框对象,生命周期需要自己控制
CTestDlg* pDlg = new CTestDlg;
pDlg->Create(IDD_DIALOG1, this);
pDlg->ShowWindow(SW_SHOW);
#endif
在堆上创建的变量需要手动的释放,但是在对话框中我们可以重写一个基类的虚函数来实现delete操作,如下
void CTestDlg::PostNcDestroy()
{
// TODO: 在此添加专用代码和/或调用基类
#if 1
delete this;
#endif
CDialog::PostNcDestroy();
}
二 对话框中动态创建按钮
我们实现在对话框中单击某个按钮时,即在对话框中控件的通告消息响应函数中动态创建一个按钮。
方法一:
#if 0
//动态创建一个对话框,只能创建一个按钮,多创建会出错
this->m_btn.Create(_T("New"), BS_DEFPUSHBUTTON | WS_VISIBLE | WS_CHILD,
CRect(0, 0, 100, 100), this, 123);
#endif
方法二:
#if 0
//第一种方法,利用类的BOOL成员变量,需要将BOOL变量设置为成员变量
//没有创建就创建
if (!m_bIsCreated)
{
m_btn.Create(_T("New"), BS_DEFPUSHBUTTON | WS_VISIBLE | WS_CHILD,
CRect(0, 0, 100, 100), this, 123);
m_bIsCreated = TRUE;
}
//创建了之后就先销毁
else
{
m_btn.DestroyWindow();
m_bIsCreated = FALSE;
}
#endif
方法三:
#if 0
//第二种方法:利用静态BOOL成员变量
//局部静态变量来作为是否创建过按钮的标识
static BOOL IsCreated = FALSE;
//没有创建就创建
if (!IsCreated)
{
m_btn.Create(_T("New"), BS_DEFPUSHBUTTON | WS_VISIBLE | WS_CHILD,
CRect(0, 0, 100, 100), this, 123);
IsCreated = TRUE;
}
//创建了之后就先销毁
else
{
m_btn.DestroyWindow();
IsCreated = FALSE;
}
#endif
方法四:
#if 0
//第三种方法,最简单,最直接的方法:利用CWnd的成员变量m_hWnd
//因为每一个CWnd或者它的子类自身都有一个m_hWnd成员变量,用来保存与窗口对象相关联的窗口句柄
if (!m_btn.m_hWnd)
{
m_btn.Create(_T("New"), BS_DEFPUSHBUTTON | WS_VISIBLE | WS_CHILD,
CRect(0, 0, 100, 100), this, 123);
}
else
{
m_btn.DestroyWindow();
}
#endif
以上的几种方法,最后一种最为简单,但是要求我们需要对CWnd的成员变量m_hWnd有清晰的理解。
三 对话框中的控件的访问
1.控件的调整
如果在对话框资源中编辑了控件,并且需要将他们手动对齐,则可以利用VS提供的开发工具来完成,如下图:
2.静态文本控件
静态文本控件默认不发送通告消息,如果我们需要让他响应通告消息,需要两个步骤,第一步:改变它的ID,第二步:在属性对话框中选中notify选项。
3.编辑框控件
(1).我们实现下面的功能,前面两个编辑框输入的数据相加,结果放在第三个编辑框中。下面是VC中可行的几种方法。
第一种:
#if 0
//定义三个变量代表输入的数值
int num1(0);
int num2(0);
int num3(0);
//将输入的数值转换成字符串
CString str1;
CString str2;
CString str3;
//获取控件的文本
GetDlgItem(IDC_EDIT1)->GetWindowText(str1);
GetDlgItem(IDC_EDIT2)->GetWindowText(str2);
//转换为数字
num1 = _ttoi(str1);
num2 = _ttoi(str2);
//数值相加
num3 = num1 + num2;
//格式化到str3中
str3.Format(_T("%d"), num3);
//设置文本到第三个编辑框
GetDlgItem(IDC_EDIT3)->SetWindowText(str3);
#endif
第二种:
#if 0
//定义三个变量代表输入的数值
int num1(0);
int num2(0);
int num3(0);
//将输入的数值转换成字符串
CString str1;
CString str2;
CString str3;
GetDlgItemText(IDC_EDIT1, str1);
GetDlgItemText(IDC_EDIT2, str2);
//转换为数字
num1 = _ttoi(str1);
num2 = _ttoi(str2);
//数值相加
num3 = num1 + num2;
//格式化到str3中
str3.Format(_T("%d"), num3);
SetDlgItemText(IDC_EDIT3, str3);
#endif
第三种:
#if 0
//定义三个变量代表输入的数值
int num1(0);
int num2(0);
int num3(0);
//将输入的数值转换成字符串
CString str1;
CString str2;
CString str3;
num1 = GetDlgItemInt(IDC_EDIT1);
num2 = GetDlgItemInt(IDC_EDIT2);
//数值相加
num3 = num1 + num2;
//格式化到str3中
str3.Format(_T("%d"), num3);
SetDlgItemInt(IDC_EDIT3, num3);
#endif
第四种:
#if 0
//在对话框类中关联子控件的值对象
int m_num1;
int m_num2;
int m_num3;
#endif
#if 0
//控件关联类的值变量
//这个函数的默认参数为TRUE
UpdateData();//TRUE代表获取控件上的数据
m_num3 = m_num1 + m_num2;
UpdateData(FALSE);//FALSE代表初始化控件上的数据
#endif
第五种:
#if 0
//关联子控件到类中的控件对象
CEdit m_edit1;
CEdit m_edit2;
CEdit m_edit3;
#endif
#if 0
//控件关联类的控件变量
//定义三个变量代表输入的数值
int num1(0);
int num2(0);
int num3(0);
//将输入的数值转换成字符串
CString str1;
CString str2;
CString str3;
//利用控件对象本身的方法
m_edit1.GetWindowText(str1);
m_edit2.GetWindowText(str2);
//转换为数字
num1 = _ttoi(str1);
num2 = _ttoi(str2);
//数值相加
num3 = num1 + num2;
//格式化到str3中
str3.Format(_T("%d"), num3);
m_edit3.SetWindowText(str3);
#endif
第六种:
#if 0
//使用消息获取控件信息
//定义三个变量代表输入的数值
int num1(0);
int num2(0);
int num3(0);
char ch1[10];
char ch2[10];
char ch3[10];
//发送消息来获取控件上的文本
::SendMessage(GetDlgItem(IDC_EDIT1)->m_hWnd, WM_GETTEXT, 10, (LPARAM)ch1);
//使用控件类中的成员变量
::SendMessage(m_edit2.m_hWnd, WM_GETTEXT, 10, (LPARAM)ch2);
num1 = atoi(ch1);
num2 = atoi(ch2);
//数值相加
num3 = num1 + num2;
_itoa_s(num3, ch3, 10);
//发送消息来设置控件上的文本
m_edit3.SendMessage(WM_SETTEXT, 0, (LPARAM)ch3);
#endif
第七种:
#if 0
//使用消息获取子控件信息
//定义三个变量代表输入的数值
int num1(0);
int num2(0);
int num3(0);
char ch1[10];
char ch2[10];
char ch3[10];
//给子控件发送消息来获取子控件上的文本
SendDlgItemMessage(IDC_EDIT1, WM_GETTEXT, 10, (LPARAM)ch1);
SendDlgItemMessage(IDC_EDIT2, WM_GETTEXT, 10, (LPARAM)ch2);
num1 = atoi(ch1);
num2 = atoi(ch2);
//数值相加
num3 = num1 + num2;
_itoa_s(num3, ch3, 10);
//给子控件发送消息来设置控件上的文本
SendDlgItemMessage(IDC_EDIT3, WM_SETTEXT, 0, (LPARAM)ch3);
#endif
(2).我们在第七种方式的基础上实现编辑框内容的复选。
#if 0
//设置控件内容的复选
//定义三个变量代表输入的数值
int num1(0);
int num2(0);
int num3(0);
char ch1[10];
char ch2[10];
char ch3[10];
//给子控件发送消息来获取子控件上的文本
SendDlgItemMessage(IDC_EDIT1, WM_GETTEXT, 10, (LPARAM)ch1);
SendDlgItemMessage(IDC_EDIT2, WM_GETTEXT, 10, (LPARAM)ch2);
num1 = atoi(ch1);
num2 = atoi(ch2);
//数值相加
num3 = num1 + num2;
_itoa_s(num3, ch3, 10);
//给子控件发送消息来设置控件上的文本
SendDlgItemMessage(IDC_EDIT3, WM_SETTEXT, 0, (LPARAM)ch3);
//发送消息设置编辑框的默认复选内容
SendDlgItemMessage(IDC_EDIT3, EM_SETSEL, 0, -1);//选择控件的全部内容
/*SendDlgItemMessage(IDC_EDIT3, EM_SETSEL, 1, 4);*/
//必须给需要复选的控件设置获取焦点
m_edit3.SetFocus();
#endif
四 对话框伸缩功能
下面完成一个对话框的伸缩功能,效果如下
收缩前:
收缩后:
代码如下:
下面是为收缩按钮添加的事件响应函数
void CTestDlg::OnClickedBtnAdd2()
{
//存储按钮之前存储的字符串
CString str;
if (GetDlgItemText(IDC_BTN_ADD2, str), "收缩<<" == str)
{
SetDlgItemText(IDC_BTN_ADD2, _T("扩展>>"));
}
else
{
SetDlgItemText(IDC_BTN_ADD2, _T("收缩<<"));
}
//静态变量,只需要初始化一次
static CRect rectLarge;//对话框原始大小
static CRect rectSmall;//剪切后的对话框大小
//获取对话框的原始大小
if (rectLarge.IsRectNull())
{
//分隔线的大小
CRect rectSeparator;
//获取对话框的原始大小
GetWindowRect(&rectLarge);
//获取对话框上的分隔符的大小
GetDlgItem(IDC_SEPERATOR)->GetWindowRect(&rectSeparator);
//重新设置被分隔后的矩形大小
rectSmall.left = rectLarge.left;
rectSmall.right = rectLarge.right;
rectSmall.top = rectLarge.top;
//底部被剪切了,所以底部坐标需要变化
rectSmall.bottom = rectSeparator.bottom;
}
//如果点击的是收缩按钮
if (_T("收缩<<" == str))
{
//将对话框的大小设置为小的矩形
SetWindowPos(nullptr, 0, 0, rectSmall.Width(), rectSmall.Height(), SWP_NOMOVE | SWP_NOZORDER);
}
//点击的是扩展按钮
else
{
//将对话框的大小设置为原来的大小
SetWindowPos(nullptr, 0, 0, rectLarge.Width(), rectLarge.Height(), SWP_NOMOVE | SWP_NOZORDER);
}
}
五 对话框中输入焦点的传递
在对话框中,我们经常需要在一个编辑框中输入完毕之后通过按回车键来获取下一个编辑框的焦点来进行输入。下面使用一种简单的方式来在对话框中通过按下回车键来将焦点按照TanStop的顺序依次向下传递。
代码如下:
void CTestDlg::OnBnClickedOk()
{
// TODO: 在此添加控件通知处理程序代码
//取消默认的ok按钮的响应
#if 0
//CDialog::OnOK();
#endif
//只能将焦点从IDC_EDIT1移动到下一个控件上
#if 0
GetDlgItem(IDC_EDIT1)->GetNextWindow()->SetFocus();
#endif
//将焦点依次移动到每个控件上,获取最后一个的下一个控件会报错
#if 0
GetFocus()->GetNextWindow()->SetFocus();
#endif
//将焦点依次移动到每个控件上,获取最后一个的下一个控件会报错
#if 0
GetFocus()->GetWindow(GW_HWNDNEXT)->SetFocus();
#endif
//下面的方法是最优化的方案。
//GetNextDlgTabItem查找具有Tab Stop属性的控件
#if 1
GetNextDlgTabItem(GetFocus())->SetFocus();
#endif
}
六 对话框中的默认按钮
在对话框中按下回车键,会响应设置Default Button属性的按钮。如果我们没有设置默认按钮,并且删除默认的ID为IDOK的按钮,发现对话框仍然能够正确的传递焦点。在对话框中,当用户按下回车键的时候,Windows会查找默认的按钮来响应,如果没有,就会调用OnOk函数来响应,即使对话框没有包含默认的OK按钮。默认的OK按钮的ID是IDOK,默认的取消按钮的ID是:IDCANCEL。
七 总结
这里主要介绍了对话框的相关的基本编程技术,只是基础的知识,大家可以学习一下。下面是共享的资料,包括了思维导图等。
https://yunpan.cn/cSc6HDd7Q8RQE 访问密码 88ca
标签:
原文地址:http://blog.csdn.net/qq_22075977/article/details/51440460