Professional UI Solutions
Site Map   /  Register
 
 

Forum

Please Log In to post a new message or reply to an existing one. If you are not registered, please register.

NOTE: Some forums may be read-only if you are not currently subscribed to our technical support services.

Forums » Prof-UIS Tech Support » WM_GETDLGCODE and CExtButton Collapse All
Subject Author Date
Chris Anderson Feb 13, 2008 - 7:28 PM

hi,

I used CExtButton to subclass an existing button wnd proc in our legacy code. It works fine except a behavior change : in a dialog which has a few buttons and other controls, when I press TAB key to move the focus to a button, that button doesn’t become the default button - a DM_GETDEFID query doesn’t return the button which obtains the focus. Further observation shows that the button always return DLGC_BUTTON when responding WM_GETDLGCODE.

To fix this behavior change, I change the way button class handles WM_GETDLGCODE and BM_SETSTYLE message:

// CMyButton is derived from CExtButton
LRESULT CMyButton::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
// fall back to subclass wnd proc to handle WM_GETDLGCODE
if ( message == WM_GETDLGCODE )
return ::CallWindowProc(m_pfnSuper, m_hWnd, message, wParam, lParam);

// let subclass wnd proc handle BM_SETSTYLE before prof-uis take over
if ( message == BM_SETSTYLE )
lResult = ::CallWindowProc(m_pfnSuper, m_hWnd, message, wParam, lParam);

// for other message
return CExtButton::WindowProc(message,wParam,lParam);
}

Is there any consequence from this change? Do you have any comment ? Anything needs attention ?

Thanks

Technical Support Feb 14, 2008 - 5:59 AM

The only correct way of implementing skinned button controls is to make them owner-drawn. Otherwise Windows will occasionally over paint button windows with default looking buttons even if each window completely handles painting messages. So, all the buttons in Prof-UIS are owner-drawn buttons. We think it would be correct to replace the following part of the CExtButton::WindowProc() virtual method:

      case WM_GETDLGCODE:
            return DLGC_BUTTON;
with
      case WM_GETDLGCODE:
            if( GetDefault() )
                  return DLGC_DEFPUSHBUTTON;
            else
                  return DLGC_BUTTON;
But this will not affect the button behavior. The default behavior is implemented in the CExtButton::PreTranslateMessage() virtual method and it works without the above improvement. You can change the button type by sending the BM_SETSTYLE message to the button window. This allows you to make the default button a simple push button and vice versa.

Chris Anderson Feb 14, 2008 - 10:35 AM

problem solved, Thanks !

Chris Anderson Feb 13, 2008 - 10:54 PM

this shouldn’t work as BS_DEFPUSHBUTTON simply overwrites BS_OWNERDRAW, not sure why my changes still work. looks like it’s better to save a different copy of the button style and mimic the behavior of standard button