Dynamic subclass CCOMBOBOX to get child control Edit and Listbox
Joise.li writes in 2004-4-6
ComboBox is a commonly used control, there are three styles: CBS_SIMPLE, CBS_DropDown, CBS_DropDownList (drop-down list), where the drop-down list is not allowed, and the simple style is always displayed.
ComboBox is combined by a ListBox and an Edit box. This article will limit only the telephone number as an example of the subclassification process (similar to ListBox).
Phone numbers can only have numbers and "-" and " ", subject to the ASCII table, know that the corresponding ASCII value is 48-57 and 45 and 43 a total of 12 values.
Good, gossip pause, start subclassification.
The first step first established an MFC application engineering, named UseesuperCombox (here, Sorry, because writing a X, huh).
Step 2 Newly build a MFC class, select Inherit from CEDIT, name CSUPEREDIT, this class is used to replace the Edit box in ComboBox. code show as below:
2 SupeRedit.h:
Class CSUPEREDIT: PUBLIC CEDIT
{
Declare_Dynamic (CSUPEREDIT)
PUBLIC:
Csuperedit ();
Virtual ~ csuperedit ();
protected:
Declare_message_map ()
PUBLIC:
AFX_MSG Void Onchar (uint nchar, uint nrepcnt, uint nflags);
}
2 SupeRedit.cpp:
// superedit.cpp: Implement file
//
#include "stdafx.h"
#include "UsesuperCombox.h"
#include "superedit.h"
// CSUPEREDIT
Implement_dynamic (Csuperedit, CEDIT)
Csuperedit :: csuperedit ()
{
}
CSUPEREDIT :: ~ csuperedit ()
{
}
Begin_MESSAGE_MAP (CSUPEREDIT, CEDIT)
ON_WM_CHAR ()
END_MESSAGE_MAP ()
// CSUPEREDIT message handler
Void Csupers :: onchar (uint nchar, uint nrepcnt, uint nflags)
{
IF (nchar <48 || nchar> 57) && nchar! = 45 && nchar! = 43)
{
AfxMessageBox ("You Must Type the Number or the Char '-' or the char ' ');
Return;
}
CEDIT :: OnChar (nchar, nrepcnt, nflags);
}
In the third step, create a MFC class, select inheritance from CCOMBOBOX, and name CSUPERCOMBOBOX. The code is as follows (Note: The following code originally see http://support.microsoft.com/default.aspx?scid=kb;n-us;q174667):
2 SupercomboBox.h # pragma overce
#include "superedit.h"
Class CsuperComboBox: Public CCOMBOBOX
{
Declare_dynamic (CsupercomboBox)
PUBLIC:
Csuperedit m_edit;
PUBLIC:
CsupercomboBOX ();
Virtual ~ csupercomboBOBOX ();
protected:
Declare_message_map ()
PUBLIC:
AFX_MSG Hbrush OnctLcolor (CDC * PDC, CWND * PWND, UINT NCTLCOLOR);
AFX_MSG void onDestroy ();
}
2 supercomboBOX.cpp
// supercomboBOX.cpp: Implement file
//
#include "stdafx.h"
#include "UsesuperCombox.h"
#include "supercomboBOX.H"
// SupercomboBox
Implement_dynamic (CSUPERCOMBOBOX, CCOMBOBOX)
CsupercomboBox :: CsupercomboBox ()
{
}
CsupercomboBox :: ~ csupercomboBOX ()
{
}
// SupercomboBOX message handler
Begin_MESSAGE_MAP (CsupercomboBox, CCOMBOBOX)
ON_WM_CTLCOLOR ()
ON_WM_DESTROY ()
END_MESSAGE_MAP ()
Hbrush CsupercomboBox :: ONCTLCOLOR (CDC * PDC, CWND * PWND, UINT NCTLCOLOR)
{
IF (nctlcolor == ctlcolor_edit)
{
IF (m_edit.getsafehwnd () == null)
{
m_edit.subclasswindow (pWnd-> getsafehwnd ());
}
// Such code Don't Use in this Example, But you can use it if you need the Listbox Control
// Else IF (nctlcolor == ctlcolor_listbox)
// {
/// Listbox Control
// if (m_listbox.getsafehwnd () == NULL)
// m_listbox.subclasswindow (pwnd-> getsafehwnd ());
//}
Return CCOMBOBOX :: ONCTLCOLOR (PDC, PWND, NCTLCOLOR);
}
Void CsuperComboBox :: ONDESTROY ()
{
IF (m_edit.getsafehwnd ()! = null)
{
m_EDit.unsubclasswindow ();
}
CCOMBOBOX :: ONDESTROY ();
}
note:
1. This class uses a message WM_CTLCOLOR to associate parameter PWnd with the corresponding control with the corresponding control by judging whether the parameter NCTLCOLOR is equal to CTLColor_edit, this example only needs to get an Edit box, so the code note that gets ListBox is released.
2. OnCTLColor is a message processing function for CWND for calls when the framework depicts the sub-control. Only using the message processing function can get the handle of the child control. 3. SubclassWindow can dynamically subcatenate a window and attach it to the CWND object.
4. Call SubclassWindWind needs to call unsubclassWindow before shutting down. This function can return WndProc to the initial state and disengaged from the CWND object.
5. The dialog box must first be drawn once when using this method dynamic type. If the dialog window is not depicted (if you close or hide it before the dialog is displayed), the method will not be appropriate. (Original: Note that for subclassing to occur, the dialog box must be painted at least once There are cases when the dialog box does not paint at all (for example, closing the dialog box before it is displayed, hidden dialog boxes). This method May NOT BE SuITable When Access To the Subclassed Windows Are Needed In There Cases.
Step 4 Add the following code in the OnInitDialog of the dialog box:
RECT;
Rect.top = 20;
Rect.bottom = 420;
Rect.Left = 20;
Rect.right = 180;
m_combo.create (ws_child | cbs_dropdown, rect, this, IDC_combo1);
m_combo.showwindow (sw_normal);
m_combo.updateWindow ();
The fifth step is compiled, run.
In addition, the key to this article is not to limit the input, but the sub-control EDIT or ListBox of the ComboBox control is obtained. If it is only to limit the input to use the overload CBN_Editchange code will be a faster approach (code from 9cbs netizen ymbymb (big brother) See http://expert.9cbs.net/expert/topic/2931/2931917.xml?temp =.3829462).
Void ctestdlg :: OneTChangeCombo1 ()
{
CString Str;
m_combo1.GetwindowText (STR);
INT LEN = str.getlength ();
IF (STR [LEN-1] <'0' || Str [LEN-1]> '9')
{
Str = str.Left (len-1);
m_combo1.setwindowText (STR);
}
}
to sum up:
The above is some of my understanding of subclass CCOMBOBOX, and the program runs in VS2002 (MFC7.0) WinXP Professional, compiled, and runs correctly. Thank you for reading, please refer to you.
If you need a source or any comments or suggestions, please contact me: Joise@126.com http://joise.126.com