第1个回答 2011-02-01
新建一个工程->MFCAppWizard[exe]->工程名Mybole->单文档应用程序
对话框有2种类型,模态和非模态
---
1 创建新对话框IDD_DIALOG1,然后创造一个新类CTestDlg(在对话框资源编辑器,双击2下),和它相关联起来。
2 新建一个菜单IDM_DIALOG(把弹出取消),标题:对话框。点击它的时候,显示我们新建的对话框。
3 在菜单资源编辑器,新建的菜单“对话框”上,右键点击类向导,做命令响应(COMMAND),VIEW类。
4 创建模态对话框
在void CMyboleView::OnDialog() 下写代码:
//view类并不知道CTestDlg,所以需要在view类.cpp包含它,#include "TestDlg.h"
CTestDlg dlg;//CTestDlg是自己新建对话框,新建的类
dlg.DoModal ();//创建摸态对话框
---
5 创建非模态对话框
BOOL Create( UINT nIDTemplate, CWnd* pParentWnd = NULL );
参数:对话框模版id;对话框父窗口的指针,如果为NULL,它的父窗口,就是框架窗口。
在void CMyboleView::OnDialog() 下写代码:
CTestDlg *pdlg=new CTestDlg();
pdlg->Create(IDD_DIALOG1,this);//创建非模态对话框,用view类作为它的父窗口,选this
pdlg->ShowWindow(SW_SHOW);//还要用ShowWindow,把它显示出来
//因为是用new操作符构建非模态对话框对象,因此必须在对话框关闭后,用delete操作符删除对话框对象
void CTestDlg::PostNcDestroy()
{
// TODO: Add your specialized code here and/or call the base class
CDialog::PostNcDestroy();
delete this; //删除对象本身
}
//覆盖OnOK这个成员函数,在OnOK内部调用DestroyWindow销毁窗口void CTestDlg::OnOK()
{
// TODO: Add extra validation here
CDialog::OnOK();
CDialog::DestroyWindow();
}
//覆盖OnCancel这个成员函数,在OnCancel内部调用DestroyWindow销毁窗口
void CTestDlg::OnCancel()
{
// TODO: Add extra cleanup here
CDialog::OnCancel();
CDialog::DestroyWindow();
}
//对话框右上角的关闭X按钮,
void CTestDlg::OnClose()
{
// TODO: Add your message handler code here and/or call default
CDialog::OnClose();
DestroyWindow();
}
===
动态创建一个按钮
先在资源编辑器,增加一个按钮,然后做消息响应void CTestDlg::OnBtnAdd()。
在CTestDlg增加成员变量(全局变量),类型CButton,名称m_btn,权限private
利用CButton的成员函数Create。
BOOL Create( LPCTSTR lpszCaption, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID );
参数:控件文本,控件类型,控件矩形区域的大小,控件父窗口,id号可以随便写。
void CTestDlg::OnBtnAdd()
{
m_btn.Create("维新",BS_DEFPUSHBUTTON | WS_VISIBLE | WS_CHILD,CRect(0,0,100,100),this,123);//动态创建按钮
}
//当我们再按按钮的时候,会发生非法错误,因为它重复创建了,所以就要判断一下,不让它多次创建。
第一个方法:
在CTestDlg增加一个成员变量,类型BOOL,名称m_blsCreate,权限private
在CTestDlg的构造函数进行初始化,m_blsCreate=FALSE;
在void CTestDlg::OnBtnAdd() 添加代码:
if(m_blsCreate==FALSE)
{
m_btn.Create("维新",BS_DEFPUSHBUTTON | WS_VISIBLE | WS_CHILD,
CRect(0,0,100,100),this,123);
m_blsCreate=TRUE;
}
else
{
m_btn.DestoryWindow();
m_blsCreate=FALSE;
}
第二个方法:
还要一个更便捷的方法,就是利用MFC里面保存的句柄
void CTestDlg::OnBtnAdd()
{
if(!m_btn.m_hWnd)//句柄没有值,创建
{
m_btn.Create("维新",BS_DEFPUSHBUTTON | WS_VISIBLE | WS_CHILD,
CRect(0,0,100,100),this,123);
}
else//否则,销毁窗口
{
m_btn.DestroyWindow();
}
}
---
动态编辑控件(static静态文本框)
需要先改变静态文本框的ID号,因为所有静态文本框的ID号都是一样的。
因为,这个控件不是用来响应鼠标点击消息的,可有些时候,我们就是想要它响应。
GetWindowText//获取文本
GetDlgItem//在对话框上面,获取控件指针。
SetWindowText//设置文本框内容
void CTestDlg::OnNumber1()
{
// TODO: Add your control notification handler code here
CString str;
if (GetDlgItem(IDC_NUMBER1)->GetWindowText(str),str=="number1:")
{
GetDlgItem(IDC_NUMBER1)->SetWindowText("数值1:");
}
else
{
GetDlgItem(IDC_NUMBER1)->SetWindowText("number1:");
}
}
备注:要让static静态文本框响应消息,需要在控件属性,复选上style(样式)->notif(通知)选项。
---
对话框控件操作
完成一个功能,将编辑框1+编辑框2的内容,放到编辑框3上面
第一种方法:
首先就要获取编辑框1和编辑框2的内容
void CTestDlg::OnBtnAdd()
{
int num1, num2, num3;
char ch1[10], ch2[10], ch3[10];
GetDlgItem(IDC_EDIT1)->GetWindowText(ch1,10);
GetDlgItem(IDC_EDIT2)->GetWindowText(ch2,10);
num1=atoi(ch1);//atoi,c语言的一个函数;把一个字符串内容转换成整型
num2=atoi(ch2);
num3=num1+num2;
itoa(num3,ch3,10);//itoa,c语言的一个函数;把一个整型内容转换成字符串
GetDlgItem(IDC_EDIT3)->SetWindowText(ch3);//把相加的结果放到编辑框3
}
第二种方法:
使用的函数:CWnd::GetDlgItemInt //获取一个控件文本,转换成整型返回
void CTestDlg::OnBtnAdd()
{
int num1, num2, num3;
num1=GetDlgItemInt(IDC_EDIT1);
num2=GetDlgItemInt(IDC_EDIT2);
num3=num1+num2;
SetDlgItemInt(IDC_EDIT3,num3);
}
第三种方法:将编辑框上的控件,关联一个成员变量
类向导(MFC ClassWizard)->成员变量(Member Variables)->Add Variables
IDC_EDIT1,名称m_num1,类型int。
IDC_EDIT2,名称m_num2,类型int。
IDC_EDIT3,名称m_num3,类型int。
void CTestDlg::OnBtnAdd()
{
UpdateData();
m_num3=m_num1+m_num2;
UpdateData(FALSE);
}
第四种方法:利用SendMessage发送一条消息获取,设置文本(WM_GETTEXT,WM_SETTEXT)
SendMessage(
HWND hWnd, //窗口句柄
UINT Msg, //WM_GETTEXT,WM_SETTEXT
WPARAM wParam, //你要拷贝多小数目的字符
LPARAM lParam //你所提供的buffer,用来保存窗口的文本
);
首先关联控件变量,也就是代表这个控件本身。
类向导(MFC ClassWizard)->成员变量(Member Variables)->Add Variables
IDC_EDIT1,名称m_edit1,Category:Control,类型CEdit。
IDC_EDIT2,名称m_edit2,Category:Control,类型CEdit。
IDC_EDIT3,名称m_edit3,Category:Control,类型CEdit。
void CTestDlg::OnBtnAdd()
{
int num1, num2, num3;
char ch1[10], ch2[10], ch3[10];
//以下方法4选1,功能是:利用WM_GETTEXT消息获取文本
::SendMessage(GetDlgItem(IDC_EDIT1)->m_hWnd,WM_GETTEXT,10,(LPARAM)ch1);
::SendMessage(m_edit1.m_hWnd,WM_GETTEXT,10,(LPARAM)ch1);
GetDlgItem(IDC_EDIT1)->SendMessage(WM_GETTEXT,10,(LPARAM)ch1);
m_edit1.SendMessage(WM_GETTEXT,10,(LPARAM)ch1);
m_edit1.SendMessage(WM_GETTEXT,10,(LPARAM)ch1);
m_edit2.SendMessage(WM_GETTEXT,10,(LPARAM)ch2);
num1=atoi(ch1);//atoi,c语言的一个函数;把一个字符串内容转换成整型
num2=atoi(ch2);
num3=num1+num2;
itoa(num3,ch3,10);//itoa,c语言的一个函数;把一个整型内容转换成字符串
m_edit3.SendMessage(WM_SETTEXT,0,(LPARAM)ch3);//利用WM_SETTEXT消息设置文本
}
===============================================
完成对话框收缩和扩展
首先增加一个button(按钮),标题改为"收缩<<"。
当我们点击"收缩<<"按钮的时候,我们要将对话框切除一部分。
然后将按钮的标题改为"扩展>>"。
再点击"扩展>>"按钮的时候,还原整个对话框。
首先要完成文本的变换,可以给按钮增加一个点击消息事件响应。
双击"收缩<<"按钮,增加点击消息事件响应OnButton2()。
void CTestDlg::OnButton2()
{
// TODO: Add your control notification handler code here
CString str;
if (GetDlgItemText(IDC_BUTTON2,str),str=="收缩<<")//获取按钮文本
{
SetDlgItemText(IDC_BUTTON2,"扩展>>");//设置按钮文本
}
else
{
SetDlgItemText(IDC_BUTTON2,"收缩<<");
}
}
下面在对话框上面增加一个分隔符,用以表示切割的部分。
分隔符可以用图象控件(picture)来代替,在对话框窗口上面,将它拉成一条线。
然后改变它的属性,将它的ID号改为IDC_SEPARATOR。
在styles(样式),复选上sunken(凹陷)。
将分隔符隐藏,把visible(可见)的勾去掉。
static CRect rectLarge; //还原后的尺寸
static CRect rectSmall;//切割后的尺寸
if (rectLarge.IsRectNull())//判断矩形区域是否为空
{
CRect rectSeparator;
GetWindowRect(&rectLarge);//获取对话框原始区域大小
GetDlgItem(IDC_SEPARATOR)->GetWindowRect(&rectSeparator);//获取图象控件矩形区域
//为对话框切割空的尺寸(左上角,右下角坐标)赋值
rectSmall.left=rectLarge.left;
rectSmall.top=rectLarge.top;
rectSmall.right=rectLarge.right;
rectSmall.bottom=rectSeparator.bottom;
}
//完成收缩扩展功能
if (str=="收缩<<")
{
SetWindowPos(NULL,0,0,rectSmall.Width(),rectSmall.Height(),
SWP_NOMOVE | SWP_NOZORDER);
}
else
{
SetWindowPos(NULL,0,0,rectLarge.Width(),rectLarge.Height(),
SWP_NOMOVE | SWP_NOZORDER);
}
===============================================
编辑框按Enter键切换的方法
方法1:很麻烦,繁琐
void CTestDlg::OnOK()
{
// TODO: Add extra validation here
//CDialog::OnOK();
}
因为ok(确定)按钮是一个缺剩按钮,为了按下ok按钮之后,对话框不关闭。
所以要"//CDialog::OnOK();",注释起来。
SetWindowLong改变指定窗口属性
LONG SetWindowLong(
HWND hWnd, //要改变的窗口句柄
int nIndex, //设定一个值的偏移量,GWL_WNDPROC,设定新的窗口过程地址。
LONG dwNewLong //新的窗口过程地址
);
在CTestDlg增加消息处理WM_INITDIALOG。
WNDPROC prevProc;
LRESULT CALLBACK WinSunProc(
HWND hwnd, // handle of 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);
}
}
BOOL CTestDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// TODO: Add extra initialization here
prevProc=(WNDPROC)SetWindowLong(GetDlgItem(IDC_EDIT1)->m_hWnd,GWL_WNDPROC,
(long)WinSunProc);//改变窗口过程
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
最后要改变编辑框1(IDC_EDIT1)的属性,样式(style)->多行(Multiline)打上勾。
方法2:简便很多
先取消编辑框1(IDC_EDIT1)属性->样式(style)->多行(Multiline)
void CTestDlg::OnOK()
{
// TODO: Add extra validation here
GetNextDlgTabItem(GetFocus())->SetFocus();//获取当前具有焦点的控件,设置焦点
//CDialog::OnOK();
}