1. 利用VisualC++新建一个对话框
2. 对话框类的继承特性:
cobject
ccmdtarget
cwnd //由cwnd派生,是一个窗口类
cdialog
在VC++ 中,一个窗口与一个C++类进行关联,对话框的基类为CDialog 类。
对话框分为模态对话框与非模态对话框,模态对话框在应用程序能进行其它操作之前必须关闭,非模态的对话框允许不关闭对话框而进行应用程序操作.
MSDN中的说明:
This class is the base class used for displaying dialog boxes on the screen. Dialog boxes are of two types: modal and modeless. A modal dialog box must be closed by the user before the application continues. A modeless dialog box allows the user to display the dialog box and return to another task without canceling or removing the dialog box.
3. 创建对话框类
确定选中新添加的对话框,View ---> ClassWizard 创建一个基于CDialog 的类与本对话框关联,输入类名,文件名,基类名,对话框ID , 此时,我们在工程中添加了一个类。
4. 创建对话框
a.模态对话框
利用DoModal() //调用domodal()创建一个模态的对话框,它的返回值是做为cdialog::enddailog成员函数的参数,这个参数用来关闭对话框 Calls a modal dialog box and returns when done.
//Return Value:An int value that specifies the value of the nResult parameter that was passed to the CDialog::EndDialog member function, which is used to close the dialog box. The return value is –1 if the function could not create the dialog box, or IDABORT if some other error occurred, in which case the Output window will contain error information from GetLastError.
备注:cdialog::enddailog //用来关闭模态的对话框
用法:
为菜单项加入响应对话框
(1)新建一个对话框,双击该对话框,为该对话框新建一个类CTestDlg,基类为CDialog。
(2)在菜单中加入一个新的菜单项,然后用ClassWizard加入一个基于View类的Command命令函数,在该命令函数中写入代码:
CTestDlg dlg;
dlg.DoModal();
(3)在***View.Cpp开头中加入#include “CTestDlg.h” ,再链接。
b.非模态对话框:
利用CDialog::Create()。
virtual BOOL Create(
UINT nIDTemplate, //对话框ID号
CWnd* pParentWnd = NULL //对话框父窗口C++对象指针); //Initializes the CDialog object. Creates a modeless dialog box and attaches it to the CDialog object.
注意:在调用Create()之后,必须调用ShowWindow()函数将其显示出来,
BOOL ShowWindow(int nCmdShow ); //Sets the visibility state of the window
注意,在创建非模态对话框是,必须注意对话框对象的生命周期,因为在显示对话框时,程序是一直在运行的,但是如果定义为局部的非模态对话框,在其生命周期结束之后就会被销毁。
用法:
在***View.App类中,加入成员变量: CTestDlg dlg;
同上例,在菜单中加入一个新的菜单项,然后用ClassWizard加入一个基于View类的Command命令函数,在该命令函数中写入代码:
dlg.Create(IDM_Dialog1,this);
dlg.ShowWindow(SW_SHOW);
另一种方法,为对话框变量分配堆内存。
CTestDialog *pDlg=new CTestDialog();
pDlg->Create(IDD_DIALOG1,this);
pDlg->ShowWindow(SW_SHOW);
注意:在模态对话框中,点击OK按钮,将销毁对话框;在非模态对话框中,点击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.
5. 在对话框中创建动态按钮:
例子:在对话框中加入一个按钮,按下该按钮,将自动创建一个新的按钮
(1)在C***View类中加入一个成员变量:CButton m_btn;
(2)在对话框类中添加一个BOOL型成员变量m_bIsCreate,并且初始化为FALSE。
在对话框的按钮中添加响应函数,加入代码:
if(m_bIsCreate==FALSE) //如果没有创建
{
m_btn.Create("Mickor.Guo",BS_DEFPUSHBUTTON |WS_CHILD|WS_VISIBLE,
CRect(0,10,100,30),this,123);
m_bIsCreate=TRUE;
}
else
{
m_btn.DestroyWindow(); //消毁窗口
m_bIsCreate=FALSE;
}
//该if-else处理是为了防止重复按下该按钮时,出现错误。还有另外一种处理方法,就是不用设置m_bIsCreate为成员变量,而是设置为静态的局部变量,在if语句之间加上:static BOOL m_bIsCreate=FALSE;
最直接的方法,运用m_hWnd句柄的情况来创建:
if(!m_btn.m_hWnd) //如果没有创建
{
m_btn.Create("Mickor.Guo",BS_DEFPUSHBUTTON |WS_CHILD|WS_VISIBLE,
CRect(0,10,100,30),this,123);
}
else
{
m_btn.DestroyWindow(); //消毁窗口
}
备注(按钮创建函数):
virtual BOOL CButton::Create(
LPCTSTR lpszCaption, //Specifies the button control's text. 按钮文本
DWORD dwStyle, //按钮样式 Specifies the button control's style. Apply any combination of button styles to the button.
const RECT& rect, //按钮位置与大小 Specifies the button control's size and position.
CWnd* pParentWnd, //父窗口指针
UINT nID //按钮ID
); //Creates the Windows button control and attaches it to the CButton object.
6. 静态文本框编程:
CString str;
if(GetDlgItem(IDC_NUMBER1)->GetWindowText(str),str=="Number1")
{
GetDlgItem(IDC_NUMBER1)->SetWindowText("数字1");
}
函数说明:
a. CWnd* GetDlgItem ( int nID ) const; //通过控件ID 获得控件C++对象指针
//This method retrieves a pointer to the specified control or child window in a dialog box or other window. The pointer returned is usually cast to the type of control identified by nID.
b. void GetWindowText(CString& rString )const; //获得窗口文本
//This method copies the CWnd caption title into the buffer pointed to by lpszStringBuf or into the destination string rString. If the CWnd object is a control, the GetWindowText method copies the text within the control instead of copying the caption.
c. void SetWindowText( LPCTSTR lpszString ); //设置窗口文本
//This method sets the window title to the specified text. If the window is a control, the text within the control is set. This method causes a WM_SETTEXT message to be sent to this window.
注意:逗号(",")运算符的应用
注意:在此之前,要设置静态文本控件的Notify 属性为真
7. EditBox 编辑框编程:
对话框控件的七种访问方式:
A. GetDlgItem()->Get(Set)WindowText()
B. GetDlgItemText()/SetDlgItemText()
C. GetDlgItemInt()/SetDlgItemInt()
D. 将控件和整型变量相关联
E. 将控件和控件变量相关联
F. SendMessage()
G. SendDlgItemMessage()
例:为一个按钮添加加法的功能,按下,则将第一个edit控件和第二个edit控件的值相加,结果输出到第三个edit控件中。
方法1:利用GetWindowText()和SetWindowText()实现。
在按钮响应函数中添加如下代码:
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);
num2=atoi(ch2);
num3=num1+num2;
itoa(num3,ch3,10);
GetDlgItem(IDC_EDIT3)->SetWindowText(ch3);
方法2:利用GetDlgItemText()和SetDlgItemText()实现
函数说明:
int GetDlgItemText( int nID, // 控件ID
LPTSTR lpStr, //字符串数组
int nMaxCount //最大的字符数
) const; //在一个窗口控件中读取文本到字符数组中
//This method retrieves the title or text associated with a control in a dialog box. This method copies the text to the location pointed to by lpStr and returns a count of the number of bytes it copies.
void SetDlgItemText(
int nID, //控件ID
LPCTSTR lpszString ); //字符串
// 设置控件的文本内容 This method sets the caption or text of a control owned by a window or dialog box. SetDlgItemText sends a WM_SETTEXT message to the given control
用法 :可以将上面的代码换成:
int num1,num2,num3;
char ch1[10],ch2[10],ch3[10];
GetDlgItemText(IDC_EDIT1,ch1,10);
GetDlgItemText(IDC_EDIT1,ch2,10);
num1=atoi(ch1);
num2=atoi(ch2);
num3=num1+num2;
itoa(num3,ch3,10);
SetDlgItemText(IDC_EDIT3,ch3);
方法3:GetDlgItemInt()和SetDlgItemInt()实现
函数说明:
UINT GetDlgItemInt(
int nID, //控件ID
BOOL* lpTrans = NULL, //控件文本是否有非数字字符,当设为NULL 时,不进行报错
BOOL bSigned = TRUE ) //是否为有符号数值
const; //获得控件文本,并转换成数值类型 The CWnd::GetDlgItemInt method retrieves the text of the control identified by the nID parameter. This method translates the text into an integer value by stripping any extra spaces at the beginning of the text and converting decimal digits. It stops the translation when it reaches the end of the text or encounters any nonnumeric character.
void SetDlgItemInt(
int nID, //控件ID
UINT nValue, //数值
BOOL bSigned = TRUE //是否为有符号数值
); //把一个数值设置成控件文本 This method sets the text of a specified control in a dialog box to the string representation of a specified integer value. SetDlgItemInt sends a WM_SETTEXT message to the given control.
用法:
int num1,num2,num3;
num1=GetDlgItemInt(IDC_EDIT1);
num2=GetDlgItemInt(IDC_EDIT2);
num3=num1+num2;
SetDlgItemInt(IDC_EDIT3,num3);
备注:
int atoi( const char *string ); // 把一个字符串转为INT 类型的数值
char *_itoa(
int value, //要换的数值
char *string, //转换成的字符串
int radix //数值的进制 2--36
); //把一个数值转换成字符串
方法4:利用数据交换与较验
A. View ---> ClassWizard ---> Member Variables 在此界面添加数据成员与控件的数据关联操作(即为各个控件添加成员变量),类名,控件名,数据成员名,数据类型,数据范围等
B. 这里为3个EDIT控件设置3个成员变量:m_num1,m_num2,m_num3。此时,ClassWizard 在程序中添加了如下代码:
在该对话框类的头文件中:
//{{AFX_DATA(CTestDialog)
enum { IDD = IDD_DIALOG1 };
int m_num1; //可知添加了3个成员变量
int m_num2;
int m_num3;
//}}AFX_DATA
在类的构造函数中,添加了3个成员变量的初始化:
C***Dlg::C***Dlg(……)
{…
m_num1=0;
m_num2=0;
m_num3=0;
}
在对话框类的DoDataExchange 函数中,将成员变量和控件进行了关联:
//}}AFX_DATA_MAP(C***Dlg)
DDX_Text(pDX, IDC_EDIT1, m_num1);
DDV_MinMaxInt(pDX, m_num1, 0, 100);
DDX_Text(pDX, IDC_EDIT2, m_num2);
DDX_Text(pDX, IDC_EDIT3, m_num3);
//}}AFX_DATA_MAP
备注:MSDN中NOTE:
virtual void DoDataExchange( CDataExchange* pDX );
//This method is called by the framework to exchange and validate dialog data
C. 想要在程序中进行数据交互,必须调用 UpdateData() 函数
BOOL UpdateData(BOOL bSaveAndValidate = TRUE ); //当参数为TRUE时,将控件的值传给成员变量,当参数为FALSE时,将成员变量的值传给控件
//NOTE:This method initializes data in a dialog box, or retrieves and validates dialog data.Specifies a flag that indicates whether dialog box is being initialized (FALSE) or data is being retrieved (TRUE).
用法:
在按钮的命令实现函数中,加入如下代码:
UpdateData();
m_num3=m_num1+m_num2;
UpdateData(FALSE);
方法5:通过控件对象进行数据交互与关联
A. 如同上面一样,在 Add Member Variables 界面的Category 下拉列表框中,选择Control ,进行控件关联操作。(为EDIT1关联m_edit1, 为EDIT2关联m_edit2, 为EDIT3关联m_edit3)
B. 利用控件的成员函数进行操作,在按钮命令实现函数中加入代码:
int num1,num2,num3;
char ch1[10],ch2[10],ch3[10];
m_edit1.GetWindowText(ch1,10);
m_edit2.GetWindowText(ch2,10);
num1=atoi(ch1);
num2=atoi(ch2);
num3=num1+num2;
itoa(num3,ch3,10);
m_edit3.SetWindowText(ch3);
方法6:通过Windows 消息进行数据交互
A. 想要获得一个控件文本,可以有以下四种方式:
::SendMessage(GetDlgItem(IDC_EDIT1)->m_hWnd,WM_GETTEXT,10,(LPARAM)ch1);// 利用Win32函数SendMessage发送一个获取文本的消息
::SendMessage(m_edit1.m_hWnd,WM_GETTEXT,10,(LPARAM)ch1);//利用控件变量
GetDlgItem(IDC_EDIT1)->SendMessage(WM_GETTEXT,10,(LPARAM)ch1);//直接用CWnd的成员函数SendMessage去发送消息
m_edit1.SendMessage(WM_GETTEXT,10,(LPARAM)ch1);//利用控件变量的成员函数SendMessage去发送消息
B. 设置控件文本可以:
m_edit1.SendMessage(WM_SETTEXT,0,(LPARAM)ch1);
或::SendMessage(GetDlgItem(IDC_EDIT1)->m_hWnd,WM_SETTEXT,0,(LPARAM)ch1);
用法:
在按钮命令响应函数中,添加代码:
m_edit1.SendMessage(WM_GETTEXT,10,(LAPRAM)ch1);
m_edit2.SendMessage(WM_GETTEXT,10,(LPARAM)ch2);
num1=atoi(ch1);
num2=atoi(ch2);
num3=num1+num2;
itoa(num3,ch3,10);
m_edit3.SendMessage(WM_SETTEXT,0,(LPARAM)ch3);
备注:
LRESULT SendMessage(
HWND hWnd, //控件句柄
UINT Msg, //Windows 消息 , 这里为WM_GETTEXT 获得文本/WM_SETTEXT 设置文本
WPARAM wParam, //WM_GETTEXT 时,为最大字符数量 ,WM_SETTEXT 时,要设为0
LPARAM lParam //要获得或设置的文本
); //发送一个Windows 消息
方法7:利用SendDlgItemMessage()函数,直接给对话框子控件发送消息
函数说明:
LRESULT SendDlgItemMessage(
int nID, //控件ID
UINT message,
WPARAM wParam = 0,
LPARAM lParam = 0
); //This method sends a message to a control. 参数同上
用法:
SendDlgItemMessage(IDC_EDIT1,WM_GETTEXT,10,(LAPRAM)ch1);
SendDlgItemMessage(IDC_EDIT2,WM_GETTEXT,10,(LAPRAM)ch2);
num1=atoi(ch1);
num2=atoi(ch2);
num3=num1+num2;;
itoa(num3,ch3,10);
SendDlgItemMessage(IDC_EDIT2,WM_SETTEXT,0,(LPARAM)ch3);