HOWTO: Subclass CListBox and CEdit Inside of CComboBox
ID: Q174667
|
The information in this article applies to:
-
The Microsoft Foundation Classes (MFC), included with:
-
Microsoft Visual C++, 32-bit Editions, versions 4.0, 4.1, 4.2, 5.0, 6.0
SUMMARY
While it is simple to directly subclass a combo box control, it is not
simple to subclass the edit or list box inside a combo box. The problem is
that it is difficult to get the HWNDs of the child controls in a portable
manner.
One safe way to subclass the internal edit and list box controls is to
subclass them in the WM_CTLCOLORXXX messages. Because Win32 sends separate
WM_CTLCOLOREDIT and WM_CTLCOLORLISTBOX messages, these messages are safe
and easy ways to get the HWNDs of the child controls of the combo box.
Below is a CSuperComboBox class, which is an MFC implementation of this
method. Because MFC routes all the WM_CTLCOLOR messages to OnCtlColor, the
subclassing takes place there.
MORE INFORMATION
Use ClassWizard to derive a class from CComboBox and add message handlers
for WM_CTLCOLOR and WM_DESTROY. Then manually edit the header file to add
the data members, m_edit and m_listbox. Finally, copy the code from the
message handlers below:
Sample Code
// SuperComboBox.h : header file
class CSuperComboBox : public CComboBox
{
public:
CEdit m_edit;
CListBox m_listbox;
protected:
afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
afx_msg void OnDestroy();
...
};
// SuperComboBox.cpp : implementation file
HBRUSH CSuperComboBox::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
if (nCtlColor == CTLCOLOR_EDIT)
{
//[ASCII 160][ASCII 160][ASCII 160]Edit control
if (m_edit.GetSafeHwnd() == NULL)
m_edit.SubclassWindow(pWnd->GetSafeHwnd());
}
else if (nCtlColor == CTLCOLOR_LISTBOX)
{
//ListBox control
if (m_listbox.GetSafeHwnd() == NULL)
m_listbox.SubclassWindow(pWnd->GetSafeHwnd());
}
HBRUSH hbr = CComboBox::OnCtlColor(pDC, pWnd, nCtlColor);
return hbr;
}
void CSuperComboBox::OnDestroy()
{
if (m_edit.GetSafeHwnd() != NULL)
m_edit.UnsubclassWindow();
if (m_listbox.GetSafeHwnd() != NULL)
m_listbox.UnsubclassWindow();
CComboBox::OnDestroy();
}
Note that for subclassing to occur, the dialog box must be painted at least
once. There are cases when the dialog box doesn't 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 these cases.
(c) Microsoft Corporation 1997, All Rights Reserved. Contributions by Kelly
Marie Ward, Microsoft Corporation
© Microsoft Corporation 1998, All Rights Reserved.
Contributions by Kelly Marie Ward, Microsoft Corporation
Additional query words:
combobox listbox
Keywords : kbcode kbMFC KbUIDesign kbVC kbVC400 kbVC410 kbVC420 kbVC500 kbVC600
Version : WINNT:4.0,4.1,4.2,5.0,6.0
Platform : winnt
Issue type : kbhowto