在环境VC6.0完成
新建一个MFC单文档应用程序工程,取名MyDlg,然后插入一个新Dialog,对话框资源也有一个类CDialog.
CDialog
The CDialog 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.
A CDialog object is a combination of a dialog template and a CDialog-derived class. Use the dialog editor to create the dialog template and store it in a resource, then use ClassWizard to create a class derived from CDialog.
A dialog box, like any other window, receives messages from Windows. In a dialog box, you are particularly interested in handling notification messages from the dialog box's controls since that is how the user interacts with your dialog box. ClassWizard browses through the potential messages generated by each control in your dialog box, and you can select which messages you wish to handle. ClassWizard then adds the appropriate message-map entries and message-handler member functions to the new class for you. You only need to write application-specific code in the handler member functions.
If you prefer, you can always write message-map entries and member functions yourself instead of using ClassWizard.
In all but the most trivial dialog box, you add member variables to your derived dialog class to store data entered in the dialog box's controls by the user or to display data for the user. ClassWizard browses through those controls in your dialog box that can be mapped to data and prompts you to create a member variable for each control. At the same time, you choose a variable type and permissible range of values for each variable. ClassWizard adds the member variables to your derived dialog class.
ClassWizard then writes a data map to automatically handle the exchange of data between the member variables and the dialog box's controls. The data map provides functions that initialize the controls in the dialog box with the proper values, retrieve the data, and validate the data.
To create a modal dialog box, construct an object on the stack using the constructor for your derived dialog class and then call DoModal to create the dialog window and its controls. If you wish to create a modeless dialog, call Create in the constructor of your dialog class.
You can also create a template in memory by using a DLGTEMPLATE data structure as described in the Win32 SDK documentation. After you construct a CDialog object, call CreateIndirect to create a modeless dialog box, or call InitModalIndirect and DoModal to create a modal dialog box.
ClassWizard writes the exchange and validation data map in an override of CWnd::DoDataExchange that ClassWizard adds to your new dialog class. See the DoDataExchange member function in CWnd for more on the exchange and validation functionality.
Both the programmer and the framework call DoDataExchange indirectly through a call to CWnd::UpdateData.
The framework calls UpdateData when the user clicks the OK button to close a modal dialog box. (The data is not retrieved if the Cancel button is clicked.) The default implementation of OnInitDialog also calls UpdateData to set the initial values of the controls. You typically override OnInitDialog to further initialize controls. OnInitDialog is called after all the dialog controls are created and just before the dialog box is displayed.
You can call CWnd::UpdateData at any time during the execution of a modal or modeless dialog box.
If you develop a dialog box by hand, you add the necessary member variables to the derived dialog-box class yourself, and you add member functions to set or get these values.
For more on ClassWizard, see Using ClassWizard in the Visual C++ Programmer's Guide.
Call CWinApp::SetDialogBkColor to set the background color for dialog boxes in your application.
A modal dialog box closes automatically when the user presses the OK or Cancel buttons or when your code calls the EndDialog member function.
When you implement a modeless dialog box, always override the OnCancel member function and call DestroyWindow from within it. Don't call the base class CDialog::OnCancel, because it calls EndDialog, which will make the dialog box invisible but will not destroy it. You should also override PostNcDestroy for modeless dialog boxes in order to delete this, since modeless dialog boxes are usually allocated with new. Modal dialog boxes are usually constructed on the frame and do not need PostNcDestroy cleanup.
双击刚创建的IDD_DIALOG1,选择创建一个新的类,给类取名CTestDlg ,这里可以用change按钮改变文件名。在Classes view中可以看到一个新的类。
在菜单上新建一个菜单项,取名"对话框",ID:IDM_DIALOG;右键classwizard,在CMyDlgView类上,添加COMMAND消息函数。
1.创建模态对话框;
CDialog::DoModal
virtual int DoModal( );
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.
Remarks
Call this member function to invoke the modal dialog box and return the dialog-box result when done. This member function handles all interaction with the user while the dialog box is active. This is what makes the dialog box modal; that is, the user cannot interact with other windows until the dialog box is closed.
If the user clicks one of the pushbuttons in the dialog box, such as OK or Cancel, a message-handler member function, such as OnOK or OnCancel, is called to attempt to close the dialog box. The default OnOK member function will validate and update the dialog-box data and close the dialog box with result IDOK, and the default OnCancel member function will close the dialog box with result IDCANCEL without validating or updating the dialog-box data. You can override these message-handler functions to alter their behavior.
在void CMyDlgView::OnDialog()添加:
CTestDlg dlg;
dlg.DoModal(); //创建一个模态对话框
并在MyDlgView.cpp中,添加头文件#include "TestDlg.h",运行,可以看到创建 了一个模态 对话框。,
2.创建非模态对话框
CDialog::Create
BOOL Create( LPCTSTR lpszTemplateName, CWnd* pParentWnd = NULL );
BOOL Create( UINT nIDTemplate, CWnd* pParentWnd = NULL );
Return Value
Both forms return nonzero if dialog-box creation and initialization were successful; otherwise 0.
Parameters
lpszTemplateName
Contains a null-terminated string that is the name of a dialog-box template resource.
pParentWnd
Points to the parent window object (of type CWnd) to which the dialog object belongs. If it is NULL, the dialog object's parent window is set to the main application window.
nIDTemplate
Contains the ID number of a dialog-box template resource.
Remarks
Call Create to create a modeless dialog box using a dialog-box template from a resource. You can put the call to Create inside the constructor or call it after the constructor is invoked.
Two forms of the Create member function are provided for access to the dialog-box template resource by either template name or template ID number (for example, IDD_DIALOG1).
For either form, pass a pointer to the parent window object. If pParentWnd is NULL, the dialog box will be created with its parent or owner window set to the main application window.
The Create member function returns immediately after it creates the dialog box.
Use the WS_VISIBLE style in the dialog-box template if the dialog box should appear when the parent window is created. Otherwise, you must call ShowWindow. For further dialog-box styles and their application, see the DLGTEMPLATE structure in the Win32 SDK documentation and Window Styles in the Class Library Reference.
Use the CWnd::DestroyWindow function to destroy a dialog box created by the Create function.
利用Create创建一个非模态对话框,注释OnDialog()函数中前面的两句话,并添加:
//CTestDlg dlg;//这里是局部变量将不能显示
//有两种方法解决,1.将其定义成view类的成员变量
//2.定义指针,在堆上分配一个内存,因为在堆上分配的内存是和整个应用程序的生命周期一致的
CTestDlg *pDlg=new CTestDlg();//定义一个指针,在堆上分配一个内存了
pDlg->Create(IDD_DIALOG1,this);//创建一个非模态对话框
pDlg->ShowWindow(SW_SHOW);//显示非模态对话框
注:这里定义的指针变量本身也是一个局部变量,当它的生命周期结束的时候,它所保存的内存地址也就丢失了,而它所指向的这块内存,我们也没有办法再引用到了,所以,我们在这地方可以将它变成一个成员变量,然后在析构函数中用delete去释放这个指针所指向的内存。对于一个模态对话框,点击ok或cancle后,这个对话框就被销毁了;对于一个非模态对话框,点击ok或cancle后,这对话框窗口并没有被销毁,而只是被 隐藏了。
CDialog::OnOK
virtual void OnOK( );
Remarks
Called when the user clicks the OK button (the button with an ID of IDOK).
Override this member function to perform the OK button action. If the dialog box includes automatic data validation and exchange, the default implementation of this member function validates the dialog-box data and updates the appropriate variables in your application.
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.
运行,可以看到创建了一个非模态对话框。
3.实现点击ADD这个按钮后就在对话框中增加一个按钮的功能。
因为非模态对话框比较麻烦,这里仍旧用模态对话框 ,在对话框上添加一个按钮,ID取IDC_BTN_ADD ,取名ADD。
对ADD按钮点击右键,classwizard… ,对它在CTestDlg类上添加一个BN_CLICKED消息响应函数。编辑代码:
先对CTestDlg类点右键,在CTestDlg类中添加一个类型为CButton的私有的成员变量m_btn;
void CTestDlg::OnBtnAdd()
{
//方法一:
// TODO: Add your control notification handler code here
//在在CTestDlg类中添加一个BOOL类型的有的成员变量m_bIsCreate,并在构造函数中初始化为FALSE
if(m_bIsCreate==FALSE)//判断按钮是否创建
{
m_btn.Create("新按钮",BS_DEFPUSHBUTTON|WS_VISIBLE|WS_CHILD,
CRect(0,10,100,30),this,123);//创建一个button控件
m_bIsCreate=TRUE;
}
else
{
m_btn.DestroyWindow();
m_bIsCreate=FALSE;
}
}
Button Styles
BS_DEFPUSHBUTTON Creates a button that has a heavy black border. The user can select this button by pressing the ENTER key. This style enables the user to quickly select the most likely option (the default option).
void CTestDlg::OnBtnAdd()
{
//方法二:
// TODO: Add your control notification handler code here
static BOOL bIsCreate=FALSE;//定义一个静态局部变量判断
if(bIsCreate==FALSE)
{
m_btn.Create("新按钮",BS_DEFPUSHBUTTON|WS_VISIBLE|WS_CHILD,
CRect(0,10,100,30),this,123);//创建一个button控件
bIsCreate=TRUE;
}
else
{
m_btn.DestroyWindow();
bIsCreate=FALSE;
}
}
因为m_hWnd与Button窗口关联,可以实现,这种方式也是最简单的一种,如下面
void CTestDlg::OnBtnAdd()
{
//方法三:
//对于一个CWindow派生的类其内部都有一个下划线m_hwnd保存了与这个窗口相关的句柄
if(m_btn.m_hWnd)
{
m_btn.Create("新按钮",BS_DEFPUSHBUTTON||WS_VISIBLE|WS_CHILD,
CRect(0,20,100,30),this,123);
}
else
{
m_btn.DestroyWindow();
}
}
4.对静态文本控件的操作
在对话框控件中添加三个静态文本与三个编辑框控件。
其中静态文本控件取名如下:
注:ID分别取:IDC_NUMBER1,IDC_NUMBER2,IDC_NUMBER3 ;
Caption分别取:Number1,Number2,Number3 ;
编辑框控件如下:
ID分别取:IDC_EDIT1,IDC_EDIT1,IDC_EDIT1;
对Number1选择ClassWizard… ,在CTestDlg类中添加一个BN_CLICKED消息响应函数,编辑代码:
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:");
}
}
注:因为静态文本控件默认是不能接受通告消息的,所以要在静态文件的属性->styles 选中复选框Notify,才能接受通告消息。
CWnd::GetDlgItem
CWnd* GetDlgItem( int nID ) const;
void CWnd::GetDlgItem( int nID, HWND* phWnd ) const;
Return Value
A pointer to the given control or child window. If no control with the integer ID given by the nID parameter exists, the value is NULL.
The returned pointer may be temporary and should not be stored for later use.
Parameters
nID
Specifies the identifier of the control or child window to be retrieved.
phWnd
A pointer to a child window.
Remarks
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.
CWnd::GetWindowText
int GetWindowText( LPTSTR lpszStringBuf, int nMaxCount ) const;
void GetWindowText( CString& rString ) const;
Return Value
Specifies the length, in bytes, of the copied string, not including the terminating null character. It is 0 if CWnd has no caption or if the caption is empty.
Parameters
lpszStringBuf
Points to the buffer that is to receive the copied string of the window's title.
nMaxCount
Specifies the maximum number of characters to be copied to the buffer. If the string is longer than the number of characters specified in nMaxCount, it is truncated.
rString
A CString object that is to receive the copied string of the window's title.
Remarks
Copies the CWnd caption title (if it has one) into the buffer pointed to by lpszStringBuf or into the destination string rString. If the CWnd object is a control, the GetWindowText member function copies the text within the control instead of copying the caption.
This member function causes the WM_GETTEXT message to be sent to the CWnd object.
5.点击ADD按钮实现加法运算功能
将编辑框1与编辑框2的内容相加,得到的结果 存到第3个编辑框当中。
在CTestDlg::OnBtnAdd()函数中添加:
//第一种访问控件的方式
//计算编辑框1+编辑框2的结果
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);
//将计算结果放到第三个编辑框中
atof, atoi, _atoi64, atol
Convert strings to double (atof), integer (atoi, _atoi64), or long (atol).
double atof( const char *string );
int atoi( const char *string );
__int64 _atoi64( const char *string );
long atol( const char *string );
For additional compatibility information, see Compatibility in the Introduction.
Libraries
LIBC.LIB | Single thread static library, retail version |
LIBCMT.LIB | Multithread static library, retail version |
MSVCRT.LIB | Import library for MSVCRT.DLL, retail version |
Return Value
Each function returns the double, int, __int64 or long value produced by interpreting the input characters as a number. The return value is 0 (for atoi and _atoi64), 0L (for atol), or 0.0 (for atof) if the input cannot be converted to a value of that type. The return value is undefined in case of overflow.
Parameter
string
String to be converted
Remarks
These functions convert a character string to a double-precision floating-point value (atof), an integer value (atoi and _atoi64), or a long integer value (atol). The input string is a sequence of characters that can be interpreted as a numerical value of the specified type. The output value is affected by the setting of the LC_NUMERIC category in the current locale. For more information on the LC_NUMERIC category, see setlocale. The longest string size that atof can handle is 100 characters. The function stops reading the input string at the first character that it cannot recognize as part of a number. This character may be the null character ('\0') terminating the string.
The string argument to atof has the following form:
[whitespace] [sign] [digits] [.digits] [ {d | D | e | E }[sign]digits]
A whitespace consists of space and/or tab characters, which are ignored; sign is either plus (+) or minus ( – ); and digits are one or more decimal digits. If no digits appear before the decimal point, at least one must appear after the decimal point. The decimal digits may be followed by an exponent, which consists of an introductory letter ( d, D, e, or E) and an optionally signed decimal integer.
atoi, _atoi64, and atol do not recognize decimal points or exponents. The string argument for these functions has the form:
[whitespace] [sign]digits
where whitespace, sign, and digits are exactly as described above for atof.
---------------------------------------------------------------------------------------------------------
_itoa, _i64toa, _ui64toa, _itow, _i64tow, _ui64tow
Convert an integer to a string.
char *_itoa( int value, char *string, int radix );
char *_i64toa( __int64 value, char *string, int radix );
char * _ui64toa( unsigned _int64 value, char *string, int radix );
wchar_t * _itow( int value, wchar_t *string, int radix );
wchar_t * _i64tow( __int64 value, wchar_t *string, int radix );
wchar_t * _ui64tow( unsigned __int64 value, wchar_t *string, int radix );
Return Value
Each of these functions returns a pointer to string. There is no error return.
Parameters
value
Number to be converted
string
String result
radix
Base of value; must be in the range 2 – 36
Remarks
The _itoa, _i64toa, and _ui64toa function convert the digits of the given value argument to a null-terminated character string and stores the result (up to 33 bytes) in string. If radix equals 10 and value is negative, the first character of the stored string is the minus sign ( – ). _itow, _i64tow, and _ui64tow are wide-character versions of _itoa, _i64toa, and _ui64toa respectively.
//方法二:
int num1,num2,num3;
char ch1[10],ch2[10],ch3[10];
GetDlgItemText(IDC_EDIT1,ch1,10);
GetDlgItemText(IDC_EDIT2,ch2,10);
num1=atoi(ch1);//字符串转换成整型
num2=atoi(ch2);
num3=num1+num2;
itoa(num3,ch3,10);//将整型转换成字符串
SetDlgItemText(IDC_EDIT3,ch3);
CWnd::GetDlgItemText
int GetDlgItemText( int nID, LPTSTR lpStr, int nMaxCount ) const;
int GetDlgItemText( int nID, CString& rString ) const;
Return Value
Specifies the actual number of bytes copied to the buffer, not including the terminating null character. The value is 0 if no text is copied.
Parameters
nID
Specifies the integer identifier of the control whose title is to be retrieved.
lpStr
Points to the buffer to receive the control's title or text.
nMaxCount
Specifies the maximum length (in bytes) of the string to be copied to lpStr. If the string is longer than nMaxCount, it is truncated.
rString
A reference to a CString.
Remarks
Call this member function to retrieve the title or text associated with a control in a dialog box. The GetDlgItemText member function copies the text to the location pointed to by lpStr and returns a count of the number of bytes it copies.
---------------------------------------------------------------------------------------------------
CWnd::SetDlgItemText
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.
void SetDlgItemText(
int nID,
LPCTSTR lpszString );
Parameters
nID
Identifies the control whose text is to be set.
lpszString
Points to a CString object or null-terminated string that contains the text to be copied to the control.
//第三种访问控件的方法
int num1,num2,num3;
num1=GetDlgItemInt(IDC_EDIT1);
num2=GetDlgItemInt(IDC_EDIT2);
num3=num1+num2;
SetDlgItemInt(IDC_EDIT3,num3);
CWnd::GetDlgItemInt
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.
UINT GetDlgItemInt(
int nID,
BOOL* lpTrans = NULL,
BOOL bSigned = TRUE )
const;
Parameters
nID
Specifies the integer identifier of the dialog-box control to be translated.
lpTrans
Points to the Boolean variable that is to receive the translated flag.
bSigned
Specifies whether the value to be retrieved is signed.
Return Value
Specifies the translated value of the dialog-box item text. Since zero is a valid return value, lpTrans must be used to detect errors. If a signed return value is desired, cast it as an int type.
The function returns zero if the translated number is greater than 32,767, for signed numbers, or 65,535, for unsigned numbers.
When errors occur, such as encountering nonnumeric characters and exceeding the above maximum, GetDlgItemInt copies zero to the location pointed to by lpTrans. If there are no errors, lpTrans receives a nonzero value. If lpTrans is NULL, GetDlgItemInt does not warn about errors.
Remarks
If bSigned is TRUE, GetDlgItemInt checks for a minus sign (–) at the beginning of the text and translates the text into a signed number. Otherwise, it creates an unsigned value.
It sends a WM_GETTEXT message to the control.
In Windows CE, the CDialog::GetDlgItemInt method can only translate text strings with 48 characters or fewer.
-------------------------------------------------------------------------------------------------
CWnd::SetDlgItemInt
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.
void SetDlgItemInt(
int nID,
UINT nValue,
BOOL bSigned = TRUE );
Parameters
nID
Specifies the integer ID of the control to be changed.
nValue
Specifies the integer value used to generate the item text.
bSigned
Specifies whether the integer value is signed or unsigned. If this parameter is TRUE, nValue is signed. If this parameter is TRUE and nValue is less than zero, a minus sign is placed before the first digit in the string. If this parameter is FALSE, nValue is unsigned.
Remarks
In Windows CE, the bSigned parameter is not used. All values passed in the nValue parameter are assumed to be signed.
Example
This is the example from the CWnd::SetDlgItemText method.
BOOL CDataDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Initialize dialog controls.
SetDlgItemText(IDC_EDIT_NAME,"Type in text");
SetDlgItemInt(IDC_EDIT_NUM, 100);
return TRUE; // Return TRUE unless you set the focus to a control.
}
//第三种访问控件的方法
/*将三个编辑框控件分别关联三个成员变量,选择View -> classwizard ,在Member Variables下分别对IDC_EDDIT1、IDC_EDDIT2、IDC_EDDIT3,添加3个int型的成员变量(Add Variable…),分别取名为:m_num1、m_num2、m_num3,变量类型选择value,表示它是一个值的变量。*/
说明:上面的操作系统自动做了三件事,在头文件中声明了以上3个变量:
public:
CTestDlg(CWnd* pParent = NULL); // standard constructor
// Dialog Data
//{{AFX_DATA(CTestDlg)
enum { IDD = IDD_DIALOG1 };
CEdit m_edit3;//这是后边添加的控件变量
CEdit m_edit2;
CEdit m_edit1;
int m_num1;
int m_num2;
int m_num3;
//}}AFX_DATA
在构造函数中赋了初值:
CTestDlg::CTestDlg(CWnd* pParent /*=NULL*/)
: CDialog(CTestDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CTestDlg)
m_num1 = 0;
m_num2 = 0;
m_num3 = 0;
//}}AFX_DATA_INIT
m_bIsCreate=FALSE;
}
在DoDataExchange()函数中将3个成员变量与编辑框控件进行了关联:
void CTestDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CTestDlg)
DDX_Control(pDX, IDC_EDIT3, m_edit3);
DDX_Control(pDX, IDC_EDIT2, m_edit2);
DDX_Control(pDX, IDC_EDIT1, m_edit1);
//DDV_MinMaxInt(pDX, m_num1, 0, 100);//DDV表示dialog data validation对话框的数据校验,下面在设置m_num1的取值范围时就会生成这个。
DDX_Text(pDX, IDC_EDIT1, m_num1);//将控件与成员变量进行关联
DDX_Text(pDX, IDC_EDIT2, m_num2);//DDX代表dialog data exchange
DDX_Text(pDX, IDC_EDIT3, m_num3);
//}}AFX_DATA_MAP
}
int num1,num2,num3;
num1=GetDlgItemInt(IDC_EDIT1);
num2=GetDlgItemInt(IDC_EDIT2);
num3=num1+num2;
SetDlgItemInt(IDC_EDIT3,num3);
//第四种访问控件的方法
/*因为m_num1、m_num2、m_num3已经与控件关联起来,所以我们在这可以直接使它进行计算。*/
UpdateData();//缺省值为真,为假时,对话框被初始化;为真时,数据被获取到对话框当中。
m_num3=m_num1+m_num2;
UpdateData(FALSE);//进行数据交换,将m_num3存放的值放置到编辑框当中
在这里,还可以对输入的数值设定一个范围,选择V iew -> classwizard… ,选择一个编辑框ID,如这里选IDC_EDIT1带有m_num1的变量,然后在下边Minimum Value输入最小的值,在Maximun Value输入最大的值,其它编辑框控件同样设置。设置后会在数据交换函数(DoDataExchange)中生成一个DDV_MinMaxInt校验函数,运行,可以看到设置的编辑框控件只能输入指定范围内的值了。
CWnd::UpdateData
This method initializes data in a dialog box, or retrieves and validates dialog data.
BOOL UpdateData(
BOOL bSaveAndValidate = TRUE );
Parameters
bSaveAndValidate
Specifies a flag that indicates whether dialog box is being initialized (FALSE) or data is being retrieved (TRUE).
Return Value
Nonzero if the operation is successful; otherwise, it is 0. If bSaveAndValidate is TRUE, then a return value of nonzero means that the data is successfully validated.
Remarks
The framework automatically calls UpdateData with bSaveAndValidate set to FALSE when a modal dialog box is created in the default implementation of CDialog::OnInitDialog. The call occurs before the dialog box is visible. The default implementation of CDialog::OnOK calls this method with bSaveAndValidate set to TRUE to retrieve the data, and if successful, will close the dialog box. If the Cancel button is clicked in the dialog box, the dialog box is closed without the data being retrieved.
//方法五
/*再将前面三个编辑框控件分别添加三个关联的成员变量,选择View -> classwizard… ,在Member Variables下分别对IDC_EDDIT1、IDC_EDDIT2、IDC_EDDIT3,添加3个CEdit型的成员变量(Add Variable…),分别取名为:m_edit1、m_edit2、m_edit3,变量类型选择control,表示这是一个控件变量。*/
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);
由于window应用程序都是一个基于消息的的程序,所以可以通过消息对控件进行操作。
//方法六
//通过获取文本的消息
int num1,num2,num3;
char ch1[10],ch2[10],ch3[10];
//下面是几种发送消息的方法:
//::SendMessage(GetDlgItem(IDC_EDIT1)->m_hWnd,WM_GETTEXT,10,(LPARAM)ch1);//发送一个消息来获取文本
//::SendMessage(m_edit1.m_hWnd,WM_GETTEXT,10,(LPARAM)ch1);//因为m_edit1与控件已经关联
//加上两个冒号表明是win32的API函数,而不是我们类的成员函数;下面用CWnd的成员函数
//GetDlgItem(IDC_EDIT1)->SendMessage(WM_GETTEXT,10,(LPARAM)ch1);
//也可以直接用已经关联的这个控件变量(m_edit1~3)去发送这个消息
//这里直接就利用所关联的这个控件变量去发送消息
m_edit1.SendMessage(WM_GETTEXT,10,(LPARAM)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);
注:所有跟窗口相关的类,都有一个类成员,上面的m_hWnd,就是所指定控件的类成员。
WM_GETTEXT
An application sends a WM_GETTEXT message to copy the text that corresponds to a window into a buffer provided by the caller.
To send this message, call the SendMessage function with the following parameters.
SendMessage(
(HWND) hWnd, // handle to destination window
WM_GETTEXT, // message to send
(WPARAM) wParam, // number of characters to copy
(LPARAM) lParam // text buffer
);
Parameters
wParam
Specifies the maximum number of TCHARs to be copied, including the terminating null character.
Windows NT/2000/XP: ANSI applications may have the string in the buffer reduced in size (to a minimum of half that of the wParam value) due to conversion from ANSI to Unicode.
lParam
Pointer to the buffer that is to receive the text.
Return Values
The return value is the number of TCHARs copied, not including the terminating null character.
Remarks
The DefWindowProc function copies the text associated with the window into the specified buffer and returns the number of characters copied. Note, for non-text static controls this gives you the text with which the control was originally created, that is, the ID number. However, it gives you the ID of the non-text static control as originally created. That is, if you subsequently used a STM_SETIMAGE to change it the original ID would still be returned.
For an edit control, the text to be copied is the content of the edit control. For a combo box, the text is the content of the edit control (or static-text) portion of the combo box. For a button, the text is the button name. For other windows, the text is the window title. To copy the text of an item in a list box, an application can use the LB_GETTEXT message.
When the WM_GETTEXT message is sent to a static control with the SS_ICON style, a handle to the icon will be returned in the first four bytes of the buffer pointed to by lParam. This is true only if the WM_SETTEXT message has been used to set the icon.
Rich Edit: If the text to be copied exceeds 64K, use either the EM_STREAMOUT or EM_GETSELTEXT message.
Windows 2000/XP: Sending a WM_GETTEXT message to a non-text static control, such as a static bitmap or static icon control, does not return a string value. Instead, it returns zero. In addition, in previous versions of Windows and Windows NT, applications could send a WM_GETTEXT message to a non-text static control to retrieve the control's ID. To retrieve a control's ID in Windows 2000/XP, applications can use GetWindowLong passing GWL_ID as the index value or GetWindowLongPtr using GWLP_ID.
-------------------------------------------------------------------------------------------
WM_SETTEXT
An application sends a WM_SETTEXT message to set the text of a window.
To send this message, call the SendMessage function with the following parameters.
SendMessage(
(HWND) hWnd, // handle to destination window
WM_SETTEXT, // message to send
(WPARAM) wParam, // not used; must be zero
(LPARAM) lParam // window-text string (LPCTSTR)
);
Parameters
wParam
This parameter is not used.
lParam
Pointer to a null-terminated string that is the window text.
Return Values
The return value is TRUE if the text is set. It is FALSE (for an edit control), LB_ERRSPACE (for a list box), or CB_ERRSPACE (for a combo box) if insufficient space is available to set the text in the edit control. It is CB_ERR if this message is sent to a combo box without an edit control.
Remarks
The DefWindowProc function sets and displays the window text. For an edit control, the text is the contents of the edit control. For a combo box, the text is the contents of the edit-control portion of the combo box. For a button, the text is the button name. For other windows, the text is the window title.
This message does not change the current selection in the list box of a combo box. An application should use the CB_SELECTSTRING message to select the item in a list box that matches the text in the edit control.
//方法七
//直接给对话框的子控件发送消息
/*由于这个函数本身就是给这个对话框的子控件发送消息,所以这里就不需要像上面那样先获取编辑框的指针,然后再用消息发送函数了*/
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(num3,ch3,10);//将整型转换成字符串
SendDlgItemMessage(IDC_EDIT3,WM_SETTEXT,10,(LPARAM)ch3);
//SendDlgItemMessage(IDC_EDIT3,EM_SETSEL,1,3);
//EM_GETSEL获取文本复选消息,EM_SETSEL设置文本复选消息
//如果将开始位置设为0,结束位置设为1,是选中所有文本,如下:
SendDlgItemMessage(IDC_EDIT3,EM_SETSEL,0,-1);
//将焦点转移到第三个编辑框
m_edit3.SetFocus();
SendDlgItemMessage
The SendDlgItemMessage function sends a message to the specified control in a dialog box.
LRESULT SendDlgItemMessage(
HWND hDlg, // handle to dialog box
int nIDDlgItem, // control identifier
UINT Msg, // message to send
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
);
Parameters
hDlg
[in] Handle to the dialog box that contains the control.
nIDDlgItem
[in] Specifies the identifier of the control that receives the message.
Msg
[in] Specifies the message to be sent.
wParam
[in] Specifies additional message-specific information.
lParam
[in] Specifies additional message-specific information.
Return Values
The return value specifies the result of the message processing and depends on the message sent.
Remarks
The SendDlgItemMessage function does not return until the message has been processed.
Using SendDlgItemMessage is identical to retrieving a handle to the specified control and calling the SendMessage function.
Windows 95/98/Me: SendDlgItemMessageW is supported by the Microsoft Layer for Unicode. To use this, you must add certain files to your application, as outlined in Microsoft Layer for Unicode on Windows 95/98/Me Systems.
---------------------------------------------------------------------------------------------------------------------
EM_SETSEL
The EM_SETSEL message selects a range of characters in an edit control. You can send this message to either an edit control or a rich edit control.
To send this message, call the SendMessage function with the following parameters.
SendMessage(
(HWND) hWnd, // handle to destination window
EM_SETSEL, // message to send
(WPARAM) wParam, // starting position
(LPARAM) lParam // ending position
);
Parameters
wParam
Specifies the starting character position of the selection.
lParam
Specifies the ending character position of the selection.
Return Values
This message does not return a value.
Remarks
The start value can be greater than the end value. The lower of the two values specifies the character position of the first character in the selection. The higher value specifies the position of the first character beyond the selection.
The start value is the anchor point of the selection, and the end value is the active end. If the user uses the SHIFT key to adjust the size of the selection, the active end can move but the anchor point remains the same.
If the start is 0 and the end is –1, all the text in the edit control is selected. If the start is –1, any current selection is deselected.
Example Code--------------------------------------------------------------------------------------------------------
Creating a Modeless Dialog Box
You create a modeless dialog box by using the CreateDialog function, specifying the identifier or name of a dialog box template resource and a pointer to the dialog box procedure. CreateDialog loads the template, creates the dialog box, and optionally displays it. Your application is responsible for retrieving and dispatching user input messages to the dialog box procedure.
In the following example, the application displays a modeless dialog box — if it is not already displayed — when the user clicks Go To from an application menu. The dialog box contains an edit control, a check box, and OK and Cancel buttons. The dialog box template is a resource in the application's executable file and has the resource identifier DLG_GOTO. The user enters a line number in the edit control and checks the check box to specify that the line number is relative to the current line. The control identifiers are ID_LINE, ID_ABSREL, IDOK, and IDCANCEL.
The statements in the first part of the example create the modeless dialog box. These statements, in the window procedure for the application's main window, create the dialog box when the window procedure receives a WM_COMMAND message having the IDM_GOTO menu identifier, but only if the global variable hwndGoto does not already contain a valid handle. The second part of the example is the application's main message loop. The loop includes the IsDialogMessage function to ensure that the user can use the dialog box keyboard interface in this modeless dialog box. The third part of the example is the dialog box procedure. The procedure retrieves the contents of the edit control and check box when the user clicks the OK button. The procedure destroys the dialog box when the user clicks the Cancel button.
HWND hwndGoto = NULL; // window handle of dialog box
.
.
.
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDM_GOTO:
if (!IsWindow(hwndGoto))
{
hwndGoto = CreateDialog(hinst,
MAKEINTRESOURCE(DLG_GOTO),
hwnd, (DLGPROC) GoToProc);
ShowWindow(hwndGoto, SW_SHOW);
}
break;
}
return 0L;
In the preceding statements, CreateDialog is called only if hwndGoto does not contain a valid window handle. This ensures that the application does not display two dialog boxes at the same time. To support this method of checking, the dialog procedure must set hwndGoto to NULL when it destroys the dialog box.
The message loop for an application consists of the following statements:
BOOL bRet;
while ( (bRet = GetMessage(&msg, NULL, 0, 0)) != 0 )
{
if (bRet == -1 )
{
// handle the error and possibly exit
}
else if (!IsWindow(hwndGoto) || !IsDialogMessage(hwndGoto, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
The loop checks the validity of the window handle for the dialog box and only calls the IsDialogMessage function if the handle is valid. IsDialogMessage only processes the message if it belongs to the dialog box. Otherwise, it returns FALSE and the loop dispatches the message to the appropriate window.
The following statements define the dialog box procedure:
int iLine; // receives line number
BOOL fRelative; // receives check box status
BOOL CALLBACK GoToProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
BOOL fError;
switch (message)
{
case WM_INITDIALOG:
CheckDlgButton(hwndDlg, ID_ABSREL, fRelative);
return TRUE;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDOK:
fRelative = IsDlgButtonChecked(hwndDlg,
ID_ABSREL);
iLine = GetDlgItemInt(hwndDlg, ID_LINE,
&fError, fRelative);
if (fError)
{
MessageBox(hwndDlg, SZINVALIDNUMBER,
SZGOTOERR, MB_OK);
SendDlgItemMessage(hwndDlg, ID_LINE,
EM_SETSEL, 0, -1L);
}
else
// Notify the owner window to carry out the task.
return TRUE;
case IDCANCEL:
DestroyWindow(hwndDlg);
hwndGoto = NULL;
return TRUE;
}
}
return FALSE;
}
In the preceding statements, the procedure processes the WM_INITDIALOG and WM_COMMAND messages. During WM_INITDIALOG processing, the procedure initializes the check box by passing the current value of the global variable fRelative to CheckDlgButton. The procedure then returns TRUE to direct the system to set the default input focus.
During WM_COMMAND processing, the procedure closes the dialog box only if the user clicks the Cancel button — that is, the button having the IDCANCEL identifier. The procedure must call DestroyWindow to close a modeless dialog box. Notice that the procedure also sets the hwndGoto variable to NULL to ensure that other statements that depend on this variable operate correctly.
If the user clicks the OK button, the procedure retrieves the current state of the check box and assigns it to the fRelative variable. It then uses the variable to retrieve the line number from the edit control. GetDlgItemInt translates the text in the edit control into an integer. The value of fRelative determines whether the function interprets the number as a signed or unsigned value. If the edit control text is not a valid number, GetDlgItemInt sets the value of the fError variable to nonzero. The procedure checks this value to determine whether to display an error message or carry out the task. In the event of an error, the dialog box procedure sends a message to the edit control, directing it to select the text in the control so that the user can easily replace it. If GetDlgItemInt does not return an error, the procedure can either carry out the requested task itself or send a message to the owner window, directing it to carry out the operation.
6.实现对话框的收缩与扩展
给按钮添加文本变换
添加一个button,ID为IDC_BUTTON2,Caption改为:收缩<<,再给按钮增加一个点击消息响应函数,双击这个按键,点"OK"即可。再添加以下代码:
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,"收缩<<");
}
}
运行,OK!
添加分隔符及实现收缩扩展
可以用图像控件代替,在对话框上将它拉成一条线,ID改为:IDC_SEPARATOR,Caption不改,取消Visible复选框(这样图像控件在对话框中就不可见了),在styles选项卡中选中Sunken 。
在CTestDlg::OnButton2()函数中继续添加:
//定义两个矩形对象,来存放对话框矩形
static CRect rectLarge;//用于保存还原后的对话框的尺寸
static CRect rectSmall;//切割之后的尺寸
//由于这个尺寸要一直保存下来的,所以在这里将它设为静态的
//IsRectEmpty检测矩形区域是否为空
//IsRectNull检测矩形的四个坐标是否是0
if(rectLarge.IsRectNull())
{
CRect rectSeparator;//定义一CRect对象,用来存放图像窗口的矩形区域
GetWindowRect(&rectLarge);//用这个函数获取对话框窗口的矩形区域
GetDlgItem(IDC_SEPARATOR)->GetWindowRect(&rectSeparator);
//GetDlgItem获取图像窗口的指针,GetWindowRect获取图像窗口的矩形区域
//给切割后剩余区域的矩形区域赋值
rectSmall.left=rectLarge.left;
rectSmall.top=rectLarge.top;
rectSmall.right=rectLarge.right;
rectSmall.bottom=rectSeparator.bottom;
}
注:IsRectNull判断四个坐标是否都全为零。
CRect::IsRectNull
This method determines whether the top, left, bottom, and right values of CRect are all equal to 0. This method differs from IsRectEmpty, which determines whether the rectangle is empty.
BOOL IsRectNull( )
const;
Return Value
Nonzero if the CRect top, left, bottom, and right values are all equal to zero; otherwise, it is zero.
CRect::IsRectEmpty
This method determines whether a CRect object is empty. A rectangle is empty if the width and/or height are 0 or negative. Differs from IsRectNull, which determines whether all coordinates of the rectangle are zero.
The rectangle must be normalized or this method may fail. You can call NormalizeRect to normalize the rectangle before calling this method.
BOOL IsRectEmpty( )
const;
Return Value
Nonzero if CRect is empty; zero if CRect is not empty.
CWnd::GetWindowRect
void GetWindowRect( LPRECT lpRect ) const;
Parameters
lpRect
Points to a CRect object or a RECT structure that will receive the screen coordinates of the upper-left and lower-right corners.
Remarks
Copies the dimensions of the bounding rectangle of the CWnd object to the structure pointed to by lpRect. The dimensions are given in screen coordinates relative to the upper-left corner of the display screen. The dimensions of the caption, border, and scroll bars, if present, are included.
//完成伸缩与扩展的功能
if(str=="收缩<<")
{
//sets the window size, position, and z-order.
SetWindowPos(NULL,0,0,rectSmall.Width(),rectSmall.Height(),SWP_NOMOVE|SWP_NOZORDER);
//SetWindowPos函数完成对话框的收缩与扩展的功能
}
else
{
SetWindowPos(NULL,0,0,rectLarge.Width(),rectLarge.Height(),SWP_NOMOVE|SWP_NOZORDER);
}
CWnd::SetWindowPos
This method changes the size, position, and z-order of child, pop-up, and top-level windows.
BOOL SetWindowPos (
const CWnd* pWndInsertAfter,
int x,
int y,
int cx,
int cy,
UINT nFlags );
Parameters
pWndInsertAfter
Identifies the CWnd object that will precede this CWnd object in the Z-order. This parameter can be a pointer to a CWnd or a Pointer to one of the following values:
- wndBottom Places the window at the bottom of the Z-order. If this CWnd is a topmost window, the window loses its topmost status; the system places the window at the bottom of all other windows.
- wndTop Places the window at the top of the Z-order.
- wndTopMost Places the window above all nontopmost windows. The window maintains its topmost position even when it is deactivated.
- wndNoTopMost Repositions the window to the top of all nontopmost windows, that is, behind all topmost windows. This flag has no effect if the window is already a nontopmost window.
See the Remarks section for this function for rules about how this parameter is used.
x
Specifies the new position of the left side of the window.
y
Specifies the new position of the top of the window.
cx
Specifies the new width of the window.
cy
Specifies the new height of the window.
nFlags
Specifies sizing and positioning options. This parameter can be a combination of the following:
- SWP_DRAWFRAME Draws a frame around the window, this is defined when the window is created.
- SWP_FRAMECHANGED Sends a WM_NCCALCSIZE message to the window, even if the window size is not being changed. If this flag is not specified, WM_NCCALCSIZE is sent only when the window size is being changed.
- SWP_HIDEWINDOW Hides the window.
- SWP_NOACTIVATE Does not activate the window. If this flag is not set, the window is activated and moved to the top of either the topmost or the nontopmost group, depending on the setting of the pWndInsertAfter parameter.
- SWP_NOCOPYBITS Discards the entire contents of the client area. If this flag is not specified, the valid contents of the client area are saved and copied back into the client area after the window is sized or repositioned.
- SWP_NOMOVE Retains current position, it ignores the x and y parameters.
- SWP_NOOWNERZORDER Does not change the position in the Z-order of the owner window.
- SWP_NOREDRAW Does not redraw changes. If this flag is set, no repainting of any kind occurs. This applies to the client area, the nonclient area, including the title and scroll bars, and any part of the parent window uncovered as a result of the moved window. When this flag is set, the application must explicitly invalidate or redraw any parts of the window and parent window that must be redrawn.
- SWP_NOREPOSITION Same as SWP_NOOWNERZORDER.
- SWP_NOSENDCHANGING Prevents the window from receiving the WM_WINDOWPOSCHANGING message.
- SWP_NOSIZE Retains current size, and ignores the cx and cy parameters.
- SWP_NOZORDER Retains current ordering, and ignores pWndInsertAfter.
- SWP_SHOWWINDOW Displays the window.
Return Value
Nonzero if the function is successful; otherwise, it is zero.
Remarks
Windows are ordered on the screen according to their Z-order; the window at the top of the Z-order appears on top of all other windows in the order.
All coordinates for child windows are client coordinates (relative to the upper-left corner of the parent window client area).
A window can be moved to the top of the Z-order either by setting the pWndInsertAfter parameter to &wndTopMost and ensuring that the SWP_NOZORDER flag is not set or by setting a Z-order for the window so that it is above any existing topmost windows. When a nontopmost window is made topmost, its owned windows are also made topmost. Its owners are not changed.
A topmost window is no longer topmost if it is repositioned to the bottom (&wndBottom) of the Z-order or after any nontopmost window. When a topmost window is made nontopmost, all of its owners and its owned windows are also made nontopmost windows.
If neither SWP_NOACTIVATE nor SWP_NOZORDER is specified, that is, when the application requests that a window be simultaneously activated and placed in the specified Z-order, the value specified in pWndInsertAfter is used only in the following circumstances:
- Neither &wndTopMost nor &wndNoTopMost is specified in the pWndInsertAfter parameter.
- This window is not the active window.
An application cannot activate an inactive window without also bringing it to the top of the Z-order. Applications can change the Z-order of an activated window without restrictions.
A nontopmost window may own a topmost window, but not vice versa. Any window, such as, a dialog box, owned by a topmost window is itself made a topmost window to ensure that all owned windows stay above their owner.
To create a topmost window, call SetWindowPos with the pWndInsertAfter parameter equal to &wndTopMost, or set the WS_EX_TOPMOST style when you create the window.
If the Z-order contains any windows with the WS_EX_TOPMOST style, a window moved with the &wndTopMost value is placed at the top of all nontopmost windows, but below any topmost windows. When an application activates an inactive window without the WS_EX_TOPMOST bit, the window is moved above all nontopmost windows but below any topmost windows.
If SetWindowPos is called when the pWndInsertAfter parameter is &wndBottom and CWnd is a topmost window, the window loses its topmost status, WS_EX_TOPMOST is cleared, and the system places the window at the bottom of the Z-order.
If this is a visible top-level window, and you do not specify the SWP_NOACTIVATE flag in the nFlags parameter, this method will activate the window. If this is the currently active window, and you specify either the SWP_NOACTIVATE flag or the SWP_HIDEWINDOW flag, the activation is passed on to another visible top-level window.
When you set the SWP_FRAMECHANGED flag in the nFlags parameter, Windows CE redraws the entire non-client area of the window, which may change the size of the client area.
Windows CE 1.0 does not support the HWND_TOPMOST and HWND_NOTOPMOST constants in the hwndInsertAfter parameter, or the SWP_DRAWFRAME or SWP_NOCOPYBITS flags in the fuFlags parameter.
Z_oder
窗口
对编辑框的焦点控制
改变编辑框的窗口过程
由于OK按钮是一个缺省的按钮,当按下键盘上的回车键之后,就会由这个缺省按钮的响应函数对它进行响应,所以一但按下回车键之后对话框就被关闭了,所以可以在子类当中覆盖这个OnOk函数来解决。
这里双击这个OK按键,选择确定在子类当中添加一个OnOK消息响应函数,并注释子类当中的OnOK函数里的CDialog::OnOK(); 这个仍然调用基类的OnOK函数语句。运行可以发现,按回键后,对话框没有被关闭。
接下来解决当按下回车键后让输入焦点移到下一编辑框。对于键盘上的按键消息,可以通过去捕获这个消息,然后在消息响应函数中,将它的输入焦点移动到下一编辑框控件,当然也可以对这个编辑框控件去生成相关的类来完成这个功能。当然还可以通过另外一种方式来完成,就是去修改这个编辑框控件原先的窗口过程,也就是说自己去编写一个窗口过程去替换MFC给我们准备的编辑框窗口过程。因为所有的消息都要到窗口过程去报到,那么在自己所写的窗口过程当中,就可以判断一下,如果这个字符消息是回车,那么就可以将这个输入焦点移动到下一编辑框控件。
窗口过程的设置是在设计这个窗口类的时候去指定的,但要在这个窗口已经创建完成之后去修改这个窗口类当中所指定的窗口过程,就要用到一个函数SetWindowLong ,相当于创建另一个线程。而这个修改窗口过程放在哪个函数当中比较合适?有一个消息叫WN_INITDIALOG,这个消息是在对话框和它的子控件创建完成之后和这个对话框将要显示之前发送的一个消息,所以下面就对这个消息进行一个消息响应。
在CDialog类上,点右键 -> Add Windows Message Hander… -> WM_INITDIALOG,添加处理,编辑:
我们可不可以改变这个编辑框的操作,在响应WM_CREATE消息响应函数中,对它进行处理?分析一下,如果说只是对对话框进行操作,那么我们将它放到OnCreate函数当中去处理也可以,但是现在是要改变这个编辑框的窗口过程,而在OnCreate函数中,编辑框控件并没有产生,它要到OnCreate函数执行完成之后在对话框显示之前才会完成它的子控件的工作,所以我们放到OnCreate这个函数当中去完成的时候,那么获取的这个编辑框窗口指针就是一个空指针,所以要在OnInitDialog函数中去改变这个窗口过程。
先在OnInitDialog函数之前定义一个先前的窗口过程,如下:
//定义一个先前的编辑框的窗口过程
WNDPROC prevProc;
// WNDPROC A 32-bit pointer to a window procedure.
BOOL CTestDlg::OnInitDialog() //在这里来改变编辑框的窗口过程
{
CDialog::OnInitDialog();
// TODO: Add extra initialization here
prevProc=(WNDPROC)SetWindowLong(GetDlgItem(IDC_EDIT1)->m_hWnd/*获取编辑框控件句柄*/,GWL_WNDPROC,(LONG)NewProc/*自己写的窗口过程的地址,强制转换成Long型*/);//让prevProc接收返回的先前的窗口过程
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
CDialog::OnOK
virtual void OnOK( );
Remarks
Called when the user clicks the OK button (the button with an ID of IDOK).
Override this member function to perform the OK button action. If the dialog box includes automatic data validation and exchange, the default implementation of this member function validates the dialog-box data and updates the appropriate variables in your application.
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.
SetWindowLong
The SetWindowLong function changes an attribute of the specified window. The function also sets the 32-bit (long) value at the specified offset into the extra window memory.
Note This function has been superseded by the SetWindowLongPtr function. To write code that is compatible with both 32-bit and 64-bit versions of Windows, use SetWindowLongPtr.
LONG SetWindowLong(
HWND hWnd, // handle to window
int nIndex, // offset of value to set
LONG dwNewLong // new value
);
Parameters
hWnd
[in] Handle to the window and, indirectly, the class to which the window belongs.
Windows 95/98/Me: The SetWindowLong function may fail if the window specified by the hWnd parameter does not belong to the same process as the calling thread.
nIndex
[in] Specifies the zero-based offset to the value to be set. Valid values are in the range zero through the number of bytes of extra window memory, minus the size of an integer. To set any other value, specify one of the following values.
Value | Action |
GWL_EXSTYLE | Sets a new extended window style. For more information, see CreateWindowEx. |
GWL_STYLE | Sets a new window style. |
GWL_WNDPROC | Sets a new address for the window procedure. Windows NT/2000/XP: You cannot change this attribute if the window does not belong to the same process as the calling thread. |
GWL_HINSTANCE | Sets a new application instance handle. |
GWL_ID | Sets a new identifier of the window. |
GWL_USERDATA | Sets the user data associated with the window. This data is intended for use by the application that created the window. Its value is initially zero. |
The following values are also available when the hWnd parameter identifies a dialog box.
Value | Action |
DWL_DLGPROC | Sets the new address of the dialog box procedure. |
DWL_MSGRESULT | Sets the return value of a message processed in the dialog box procedure. |
DWL_USER | Sets new extra information that is private to the application, such as handles or pointers. |
dwNewLong
[in] Specifies the replacement value.
Return Values
If the function succeeds, the return value is the previous value of the specified 32-bit integer.
If the function fails, the return value is zero. To get extended error information, call GetLastError.
If the previous value of the specified 32-bit integer is zero, and the function succeeds, the return value is zero, but the function does not clear the last error information. This makes it difficult to determine success or failure. To deal with this, you should clear the last error information by calling SetLastError(0) before calling SetWindowLong. Then, function failure will be indicated by a return value of zero and a GetLastError result that is nonzero.
Remarks
Certain window data is cached, so changes you make using SetWindowLong will not take effect until you call the SetWindowPos function. Specifically, if you change any of the frame styles, you must call SetWindowPos with the SWP_FRAMECHANGED flag for the cache to be updated properly.
If you use SetWindowLong with the GWL_WNDPROC index to replace the window procedure, the window procedure must conform to the guidelines specified in the description of the WindowProc callback function.
If you use SetWindowLong with the DWL_MSGRESULT index to set the return value for a message processed by a dialog procedure, you should return TRUE directly afterwards. Otherwise, if you call any function that results in your dialog procedure receiving a window message, the nested window message could overwrite the return value you set using DWL_MSGRESULT.
Calling SetWindowLong with the GWL_WNDPROC index creates a subclass of the window class used to create the window. An application can subclass a system class, but should not subclass a window class created by another process. The SetWindowLong function creates the window subclass by changing the window procedure associated with a particular window class, causing the system to call the new window procedure instead of the previous one. An application must pass any messages not processed by the new window procedure to the previous window procedure by calling CallWindowProc. This allows the application to create a chain of window procedures.
Reserve extra window memory by specifying a nonzero value in the cbWndExtra member of the WNDCLASSEX structure used with the RegisterClassEx function.
You must not call SetWindowLong with the GWL_HWNDPARENT index to change the parent of a child window. Instead, use the SetParent function.
If the window has a class style of CS_CLASSDC or CS_OWNDC, do not set the extended window styles WS_EX_COMPOSITED or WS_EX_LAYERED.
Windows 95/98/Me: SetWindowLongW is supported by the Microsoft Layer for Unicode. SetWindowLongA is also supported to provide more consistent behavior across all Windows operating systems. To use these versions, you must add certain files to your application, as outlined in Microsoft Layer for Unicode on Windows 95/98/Me Systems.
编写窗口过程函数
在CTestDlg::OnInitDialog()函数上面写:
LRESULT CALLBACK NewProc(
HWND hwnd, // handle to window
UINT uMsg, // message identifier
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
)
{
//注:这个函数是一个全局函数,不能用CWindow的成员函数来完成,
//所以只能用win32的API函数来完成
if(uMsg==WM_CHAR && wParam==0x0d)//如果是回车
{
//::SetFocus(::GetNextWindow(hwnd,GW_HWNDNEXT));
//加两冒号表明它是平台SDK的函数(即win32API)
//另外一个获取窗口句柄(编辑框窗口)的函数
//SetFocus(::GetWindow(hwnd,GW_HWNDNEXT));
//第三种方式获取窗口句柄
::SetFocus(::GetNextDlgTabItem(::GetParent(hwnd),hwnd,FALSE));
return 1;
}
else
{
return prevProc(hwnd,uMsg,wParam,lParam);//用先前的过程处理
}
}
注:在前两种方法当中,要给编辑框选中Multiline,按回车后才能跳到下一编辑框,因为编辑框不接受多行。编辑框控件默认Tab Stop 是被选中的,而静态文本初始时Tab Stop 没有被选中。
WindowProc
The WindowProc function is an application-defined function that processes messages sent to a window. The WNDPROC type defines a pointer to this callback function. WindowProc is a placeholder for the application-defined function name.
LRESULT CALLBACK WindowProc(
HWND hwnd, // handle to window
UINT uMsg, // message identifier
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
);
Parameters
hwnd
[in] Handle to the window.
uMsg
[in] Specifies the message.
wParam
[in] Specifies additional message information. The contents of this parameter depend on the value of the uMsg parameter.
lParam
[in] Specifies additional message information. The contents of this parameter depend on the value of the uMsg parameter.
Return Values
The return value is the result of the message processing and depends on the message sent.
SetFocus
The SetFocus function sets the keyboard focus to the specified window. The window must be attached to the calling thread's message queue.
HWND SetFocus(
HWND hWnd // handle to window
);
Parameters
hWnd
[in] Handle to the window that will receive the keyboard input. If this parameter is NULL, keystrokes are ignored.
Return Values
If the function succeeds, the return value is the handle to the window that previously had the keyboard focus. If the hWnd parameter is invalid or the window is not attached to the calling thread's message queue, the return value is NULL. To get extended error information, call GetLastError.
Remarks
The SetFocus function sends a WM_KILLFOCUS message to the window that loses the keyboard focus and a WM_SETFOCUS message to the window that receives the keyboard focus. It also activates either the window that receives the focus or the parent of the window that receives the focus.
If a window is active but does not have the focus, any key pressed will produce the WM_SYSCHAR, WM_SYSKEYDOWN, or WM_SYSKEYUP message. If the VK_MENU key is also pressed, the lParam parameter of the message will have bit 30 set. Otherwise, the messages produced do not have this bit set.
By using the AttachThreadInput function, a thread can attach its input processing to another thread. This allows a thread to call SetFocus to set the keyboard focus to a window attached to another thread's message queue.
GetNextWindow
The GetNextWindow function retrieves a handle to the next or previous window in the Z order. The next window is below the specified window; the previous window is above. If the specified window is a topmost window, the function retrieves a handle to the next (or previous) topmost window. If the specified window is a top-level window, the function retrieves a handle to the next (or previous) top-level window. If the specified window is a child window, the function searches for a handle to the next (or previous) child window.
HWND GetNextWindow(
HWND hWnd, // handle to current window
UINT wCmd // direction
);
Parameters
hWnd
[in] Handle to a window. The window handle retrieved is relative to this window, based on the value of the wCmd parameter.
wCmd
[in] Specifies whether the function returns a handle to the next window or of the previous window. This parameter can be either of the following values.
Value | Meaning |
GW_HWNDNEXT | Returns a handle to the window below the given window. |
GW_HWNDPREV | Returns a handle to the window above the given window. |
Return Values
If the function succeeds, the return value is a handle to the next (or previous) window. If there is no next (or previous) window, the return value is NULL. To get extended error information, call GetLastError.
Remarks
Using this function is the same as calling the GetWindow function with the GW_HWNDNEXT or GW_HWNDPREV flag set.
GetWindow
The GetWindow function retrieves a handle to a window that has the specified relationship (Z order or owner) to the specified window.
HWND GetWindow(
HWND hWnd, // handle to original window
UINT uCmd // relationship
);
Parameters
hWnd
[in] Handle to a window. The window handle retrieved is relative to this window, based on the value of the uCmd parameter.
uCmd
[in] Specifies the relationship between the specified window and the window whose handle is to be retrieved. This parameter can be one of the following values.
Value | Meaning |
GW_CHILD | The retrieved handle identifies the child window at the top of the Z order, if the specified window is a parent window; otherwise, the retrieved handle is NULL. The function examines only child windows of the specified window. It does not examine descendant windows. |
GW_ENABLEDPOPUP | Windows 2000/XP: The retrieved handle identifies the enabled popup window owned by the specified window (the search uses the first such window found using GW_HWNDNEXT); otherwise, if there are no enabled popup windows, the retrieved handle is that of the specified window. |
GW_HWNDFIRST | The retrieved handle identifies the window of the same type that is highest in the Z order. If the specified window is a topmost window, the handle identifies the topmost window that is highest in the Z order. If the specified window is a top-level window, the handle identifies the top-level window that is highest in the Z order. If the specified window is a child window, the handle identifies the sibling window that is highest in the Z order. |
GW_HWNDLAST | The retrieved handle identifies the window of the same type that is lowest in the Z order. If the specified window is a topmost window, the handle identifies the topmost window that is lowest in the Z order. If the specified window is a top-level window, the handle identifies the top-level window that is lowest in the Z order. If the specified window is a child window, the handle identifies the sibling window that is lowest in the Z order. |
GW_HWNDNEXT | The retrieved handle identifies the window below the specified window in the Z order. If the specified window is a topmost window, the handle identifies the topmost window below the specified window. If the specified window is a top-level window, the handle identifies the top-level window below the specified window. If the specified window is a child window, the handle identifies the sibling window below the specified window. |
GW_HWNDPREV | The retrieved handle identifies the window above the specified window in the Z order. If the specified window is a topmost window, the handle identifies the topmost window above the specified window. If the specified window is a top-level window, the handle identifies the top-level window above the specified window. If the specified window is a child window, the handle identifies the sibling window above the specified window. |
GW_OWNER | The retrieved handle identifies the specified window's owner window, if any. For more information, see Owned Windows. |
Return Values
If the function succeeds, the return value is a window handle. If no window exists with the specified relationship to the specified window, the return value is NULL. To get extended error information, call GetLastError.
Remarks
The EnumChildWindows function is more reliable than calling GetWindow in a loop. An application that calls GetWindow to perform this task risks being caught in an infinite loop or referencing a handle to a window that has been destroyed.
GetNextDlgTabItem
The GetNextDlgTabItem function retrieves a handle to the first control that has the WS_TABSTOP style that precedes (or follows) the specified control.
HWND GetNextDlgTabItem(
HWND hDlg, // handle to dialog box
HWND hCtl, // handle to known control
BOOL bPrevious // direction flag
);
Parameters
hDlg
[in] Handle to the dialog box to be searched.
hCtl
[in] Handle to the control to be used as the starting point for the search. If this parameter is NULL, the function uses the last (or first) control in the dialog box as the starting point for the search.
bPrevious
[in] Specifies how the function is to search the dialog box. If this parameter is TRUE, the function searches for the previous control in the dialog box. If this parameter is FALSE, the function searches for the next control in the dialog box.
Return Values
If the function succeeds, the return value is the window handle of the previous (or next) control that has the WS_TABSTOP style set.
If the function fails, the return value is NULL. To get extended error information, call GetLastError.
Remarks
The GetNextDlgTabItem function searches controls in the order (or reverse order) they were created in the dialog box template. The function returns the first control it locates that is visible, not disabled, and has the WS_TABSTOP style. If no such control exists, the function returns hCtl.
If the search for the next control with the WS_TABSTOP style encounters a window with the WS_EX_CONTROLPARENT style, the system recursively searches the window's children.
让焦点在依次传递
用缺省按钮的响应函数来完成,先将编辑框1的Multiline的复选给取消,然后在OnOK这个函数当中来完成。
void CTestDlg::OnOK()
{
// TODO: Add extra validation here
//获取第一个编辑框的指针
//GetDlgItem(IDC_EDIT1)->GetNextWindow()->SetFocus();//获取编辑框指针后,将焦点传给下一编辑框
/*注意在这地方是先获取编辑框指针,再把焦点设置到下一个编辑框窗口,当再次按回车后,仍然由OnOK进行响应,仍然获取的是第一个编辑框的指针, 然后调用下一个窗口设置Focus,所以始终都无法传递到第三个编辑框上。*/
//GetFocus()->GetNextWindow()->SetFocus();//GetFocus得到焦点
//用GetWindow来调用也一样,一直按回车,就出现了错误
//GetFocus()->GetWindow(GW_HWNDNEXT)->SetFocus();//当遇到返回空指针时,也同样会发生错误
//方法四,利用GetNextDlgTabItem函数解决
GetNextDlgTabItem(GetFocus())->SetFocus();
//这个函数是按控件的顺序,依次往下查找,点击在Layout下有一个Tab_oder,可以看到每一个控件的顺序,点击控件上的序号可以改变它的顺序
//修改编辑框控件的窗口过程
//CDialog::OnOK();这里调用基类的OnOK函数
}
注:1.如果将 收缩<< 设置成缺省的按钮,运行,点回车就不会对这个OnOK消息事件进行响应了。2.不管这个OK按钮存不存在在对话框上面,都会调用这个OnOK函数,删除这个OK按钮后,运行,在对话框上点击回车仍就会对这个OnOK消息事件进行响应。3.在编程的过程中如果我们忘了添加OnOK消息响应函数了,就可以自己添加一个OK按钮,但要注意自己添加的OK按钮ID号一定要取为:IDOK ,而不是IDC_OK,因为初始的OK按钮的ID号是IDOK,否则自己添加的按钮将不能响应对应的OnOK函数。
GetFocus
The GetFocus function retrieves the handle to the window that has the keyboard focus, if the window is attached to the calling thread's message queue.
HWND GetFocus(VOID);
Parameters
This function has no parameters.
Return Values
The return value is the handle to the window with the keyboard focus. If the calling thread's message queue does not have an associated window with the keyboard focus, the return value is NULL.
Remarks
GetFocus returns the window with the keyboard focus for the current thread's message queue. If GetFocus returns NULL, another thread's queue may be attached to a window that has the keyboard focus.
Use the GetForegroundWindow function to retrieve the handle to the window with which the user is currently working. You can associate your thread's message queue with the windows owned by another thread by using the AttachThreadInput function.
Windows 98/Me and Windows NT 4.0 SP3 and later: To get the window with the keyboard focus on the foreground queue or the queue of another thread, use the GetGUIThreadInfo function.
OK , ^_^
来源:https://www.cnblogs.com/luowei010101/archive/2011/09/07/2170117.html