Thanks in advance,
Pete DeLange
The reason you're not getting the WM_CTLCOLOR messages is that control 3d grabs these messages and does not pass them along.
What we had to do to bypass this was to subclass MFC's CDialog class, write our own DialogProc(), and in the OnInitDialog() method of our CDialog subclass we do a SetWindowLong(dlgHwnd, DWL_DLGPROC, &myDialogProc). This allows us to grab the WM_CTLCOLOR messages before CTL3D sees them and pass them along to our controls. All other messages we pass along to the original DialogProc() ( which we saved ).
A short example follows.
//------------------------------------------------------------------------------
LRESULT FAR PASCAL _export MyDialogProc(HWND hWnd, UINT m, WPARAM w,LPARAM l)
{
HBRUSH hBrush = NULL;
HWND hWndChild = (HWND)LOWORD(l);
MyDialogClass* pWnd = (MyDialogClass*)CWnd::FromHandlePermanent(hWnd);
if(m==WM_CTLCOLOR) {
// Get the ctl3d brush/text/background, then let control override
HBRUSH hBrush3d = (HBRUSH)::CallWindowProc(pWnd->m_oldDlgProc,hWnd,m,w,l);
// Handle our controls (Prop MyClass set to 1) by sending CtlColor back to the control!!
if (::GetProp(hWndChild, "MyClass")) { // prop set by our controls
switch (HIWORD(l)) {
case CTLCOLOR_EDIT:
case CTLCOLOR_STATIC:
case CTLCOLOR_LISTBOX:
case CTLCOLOR_BTN:
hBrush = (HBRUSH)::SendMessage(hWndChild,m,w,l);
break;
case CTLCOLOR_MSGBOX:
case CTLCOLOR_DLG:
break;
}
}
// brush, text and background were set above - reset brush if
// our control didn't override it (i.e. hbrush is null)
if (hBrush == NULL)
hBrush = hBrush3d;
}
else { // not WM_CTLCOLOR - process as usual
return ::CallWindowProc(pWnd->m_oldDlgProc,hWnd,m,w,l);
}
return (LRESULT)(UINT)hBrush;
}
//----------------------------------------------------------------------------
BOOL MyDialogClass::OnInitDialog()
{
// init the dialog
BOOL retval = CDialog::OnInitDialog();
// grab the DialogProc()
// m_oldDlgProc is a data memmber of MyDialogClass
m_oldDlgProc = (WNDPROC)::SetWindowLong(GetSafeHwnd(),DWL_DLGPROC,(LONG)&MyDialogProc);
return retval;
}
--
-------------------------------------------------------------------------------
Don Hardcastle |Internet Style: Don_Har...@burlington.marcam.com
UI Development, Project Zed |UUCP : ...!uunet!aruba!donh
|Compuserve : 71202,2537
-------------------------------------------------------------------------------
>pdel...@maroon.tc.umn.edu (Pete DeLange) writes:
>> Using VC++, I have a dialog box with several edit boxes. I want the
>> active edit field to be yellow, the rest white. I do this by handling the
>> WM_CTLCOLOR message and returning a yellow brush when the edit
>> gets and loses focus. When I use CTL3D.DLL's Ctl3dAutoSubclass()
>> function, I no longer recieve the WM_CTLCOLOR message. Anyone
>> have any suggestions?
>>
>> Thanks in advance,
>> Pete DeLange
>I had *exactly* the same problem, and solved it by porting to NT 3.5
>and making it a 32 bit app.
CTL3D eats the WM_CTLCOLOR message. Do not allow CTL3D to subclass your
dialog, and do the 3D look "by hand":
1. for WM_SETTEXT, WM_NCPAINT and WM_NCACTIVATE, call Ctl3dDlgFramePaint()
2. for WM_CTLCOLOR, call Ctl3dCtlColorEx()
Here is the code of a MFC-based class I use when I need a "colored" CDialog.
Derived classes can intercept WM_CTLCOLOR.
/////////////////////////////////////////////////////////////////////////
class CDialogWithExplicit3d : public CDialog {
public:
CDialogWithExplicit3d(LPCSTR lpszTemplateName, CWnd* pParentWnd = NULL) : CDialog(lpszTemplateName, pParentWnd) {};
CDialogWithExplicit3d(UINT nIDTemplate, CWnd* pParentWnd = NULL) : CDialog(nIDTemplate, pParentWnd) {};
protected:
CDialogWithExplicit3d() : CDialog() {};
//{{AFX_MSG(CDialogWithExplicit3d)
LONG OnDlgSubClass(UINT, LONG lParam);
LONG OnDlgPaint(UINT wParam, LONG lParam);
afx_msg HBRUSH OnCtlColor(CDC *, CWnd *, UINT);
//}}AFX_MSG
DECLARE_DYNAMIC(CDialogWithExplicit3d)
DECLARE_MESSAGE_MAP();
};
/////////////////////////////////////////////////////////////////////////
LONG CDialogWithExplicit3d::OnDlgSubClass(UINT, LONG lParam) {
if (lParam)
*(int FAR*)(lParam) = CTL3D_NOSUBCLASS;
return NULL;
}
// Here we intercept various messages (WM_SETTEXT, WM_NCPAINT and
// WM_NCACTIVATE) and we transfer them to Ctl3d: this gives the 3d
// look of the dialog
LONG CDialogWithExplicit3d::OnDlgPaint(UINT wParam, LONG lParam) {
if (Ctl3dEnabled()) {
UINT wm = GetCurrentMessage()->message;
Assert(wm == WM_SETTEXT || wm == WM_NCPAINT || wm == WM_NCACTIVATE);
return Ctl3dDlgFramePaint(m_hWnd, wm, wParam, lParam);
}
else
return Default();
}
HBRUSH CDialogWithExplicit3d::OnCtlColor(CDC * pDC, CWnd * pWnd, UINT nCtlColor) {
HBRUSH hBrush;
if (Ctl3dEnabled() &&
(hBrush = Ctl3dCtlColorEx(WM_CTLCOLOR,
(WPARAM)pDC->m_hDC,
MAKELONG(pWnd->m_hWnd,nCtlColor))))
return hBrush;
else
return CWnd::OnCtlColor(pDC, pWnd, nCtlColor);
}
IMPLEMENT_DYNAMIC(CDialogWithExplicit3d, CDialog)
BEGIN_MESSAGE_MAP(CDialogWithExplicit3d, CDialog)
//{{AFX_MSG_MAP(CDialogWithExplicit3d)
ON_MESSAGE(WM_DLGSUBCLASS, OnDlgSubClass)
ON_MESSAGE(WM_SETTEXT, OnDlgPaint)
ON_MESSAGE(WM_NCPAINT, OnDlgPaint)
ON_MESSAGE(WM_NCACTIVATE, OnDlgPaint)
ON_WM_CTLCOLOR()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
--
Patrick Alaerts Siemens Nixdorf Software S.A.
E-mail: a...@swn.sni.be Rue de Neverlee 11
Voice: +32 81 564 333 5020 Namur (Rhisnes)
Fax: +32 81 568 193 Belgium
I wrote a Dialogbox Function that handles the WM_CTLCOLOR message.
Without Subclassing with Ctl3d it works fine, but if I Subclass it I'll get a
Exeption during handling the WM_CTLCOLOR message.
Now my question :
How can I return a brush to the Dialogbox with Ctl3d ?
If you subclass a dialog with CTL3D, you should use the function
Ctl3dCtlColorEx() like this:
case WM_CTLCOLOR: {
HBRUSH hCtl3dBrush;
if ((hCtl3dBrush = Ctl3dCtlColorEx(nMsg, wParam, lParam)) != NULL)
return ((LRESULT) hCtl3dBrush);
}
/FE
+--------------------------------------------------------------------+
| Fredrik Ekengren #pragma message("Standard disclaimer") |
| Juristdata AB, SWEDEN Professional development for Windows NT |
| Voice +46-500 412150 Fax +46-500 412848 |
+--------------------------------------------------------------------+