How to hit test non-client buttons in Vista?
-
Friday, October 06, 2006 7:56 PM
The following code was added to a Win32 application's WndProc to hit test the minimize, maximize, and close buttons. The buttons are detected if Desktop Composition is disabled, but not when it is enabled. Other non-client regions are detected when Desktop Composition is enabled. Does anyone know of a work-around for this issue?
case WM_NCHITTEST:
LRESULT lResult;
lResult = DefWindowProc(hWnd, message, wParam, lParam);
if (lResult==HTCLOSE)
OutputDebugString(L"HTCLOSE\n"); //detected if Desktop composition is disabled
else if (lResult==HTMINBUTTON)
OutputDebugString(L"HTMINBUTTON\n"); //detected if Desktop composition is disabled
else if (lResult==HTMAXBUTTON)
OutputDebugString(L"HTMAXBUTTON\n"); //detected if Desktop composition is disabled
else OutputDebugString(L"HT other\n");
return lResult;
break;
All Replies
-
Saturday, October 07, 2006 6:49 PM
Instead of using DefWindowProc, when composition is enabled use DwmDefWindowProc, which will perform NC hit testing for you for the buttons only ( but works even if you've set your nc area to 0 and used DwmExtendFrameIntoClientArea to get min/max/close buttons on your client area). If it returns without detecting a btn, pass it along to DefWindowProc as well for caption, sizing, etc testing.
-
Saturday, October 07, 2006 8:42 PM
Thanks for the suggestion, but I still can't detect the buttons. I tried the following - the documentation for DwmDefWindowProc is a bit thin so I'm not sure if this is what you meant:
case WM_NCHITTEST:
LRESULT lResult;
HRESULT hr;
BOOL bDwmCompositionEnabled;
hr = DwmIsCompositionEnabled( &bDwmCompositionEnabled );
if ( SUCCEEDED( hr ) && bDwmCompositionEnabled )
{
hr = DwmDefWindowProc( hWnd, message, wParam, lParam, &lResult );
if ( SUCCEEDED( hr ) )
{
if ( lResult==HTCLOSE )
OutputDebugString( L"DWM HTCLOSE\n" ); //never detected
else
OutputDebugString( L"DWM Not HTCLOSE\n" );
}
}
else ...When desktop composition is enabled there are no WM_NCHITTEST messages when the arrow is over the buttons so the DwmDefWindowProc never gets called. There are messages over other non-client areas - DwmDefWindowProc returns S_OK but the debugger shows lResult with the uninitialized value of 0xcccccccc. (note: I am using RC1 build 5600)
-
Saturday, October 07, 2006 9:17 PM
Actually, I test for HTCLIENT rather than the return of DwmDefWindowProc, but that's pretty much exactly what I meant.
So you have the standard titlebar - you don't have the frame extended in or drawn yourself? I haven't used DwmDefWindowProc under those circumstances.
Right now, my usage is (when Dwm enabled)
1) respond to wm_nccalcsize and set nc top area to 0 (client starts at the top)
2) call DwmExtendFrameIntoClientArea, extending it down the height of a titlebar.
3) respond to wm_nchittest and pass it to DwmDefWindowProc first. if htclient is passed back I do my own testing to see if it should be htcaptionNote that step 2 above *will* show the control menu (icon), caption text, and min/max/close buttons as if it were in the standard NC area. if you pass wm_nchittest to dwmdefwindowproc it will handle the "glow" and hit testing of the buttons for you.
However, I'm not sure how to go about testing in your scenario - I'm afraid I'm stumped! sorry to lead you down the wrong path. I'm still struggling with proper handling of tricks in the NC area under vista as well (drawing, etc)
-
Sunday, October 08, 2006 12:40 AM
Thanks for the info on the usage of DwmDefWindowProc - that's the first description of its usage that I've seen.
I am getting the impression that when the buttons are in the non-client area, DWM is gobbling up the WM_NCHITTEST messages to make the buttons glow and not passing them along to the WndProc. If this is true it sounds like a design flaw to me - Vista should either pass them along or use a different message so that an app can still hit test them when desktop composition is enabled.
-
Saturday, October 14, 2006 1:44 PM
A work-around for this issue is to use WM_NCMOUSEMOVE instead of WM_NCHITTEST. wParam contains HTMINBUTTON, HTMAXBUTTON, and HTCLOSE whether desktop composition is enabled or disabled.
-
Saturday, October 14, 2006 3:19 PMThanks for the follow up with an answer!


