Author: gadamopoulos
Date: Sun May 22 15:31:18 2011
New Revision: 51846
URL:
http://svn.reactos.org/svn/reactos?rev=51846&view=rev
Log:
[uxtheme]
- Implement handling WM_NCMOUSEMOVE, WM_NCMOUSELEAVE and WM_NCLBUTTONDOWN, needed for
painting the caption buttons when the user hovers or clicks them
Modified:
branches/GSoC_2011/ThemesSupport/dll/win32/uxtheme/nonclient.c
Modified: branches/GSoC_2011/ThemesSupport/dll/win32/uxtheme/nonclient.c
URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2011/ThemesSupport/dll/win…
==============================================================================
--- branches/GSoC_2011/ThemesSupport/dll/win32/uxtheme/nonclient.c [iso-8859-1]
(original)
+++ branches/GSoC_2011/ThemesSupport/dll/win32/uxtheme/nonclient.c [iso-8859-1] Sun May 22
15:31:18 2011
@@ -252,6 +252,48 @@
DrawThemeBackground(pcontext->theme, pcontext->hDC, iPartId, iStateId,
&rcPart, NULL);
}
+static DWORD
+ThemeGetButtonState(DWORD htCurrect, DWORD htHot, DWORD htDown, BOOL Active)
+{
+ if (htHot == htCurrect)
+ return BUTTON_HOT;
+ if (!Active)
+ return BUTTON_INACTIVE;
+ if (htDown == htCurrect)
+ return BUTTON_PRESSED;
+
+ return BUTTON_NORMAL;
+}
+
+/* Used only from mouse event handlers */
+static void
+ThemeDrawCaptionButtons(PDRAW_CONTEXT pcontext, DWORD htHot, DWORD htDown)
+{
+ RECT rcCurrent;
+
+ /* Check if the window has caption buttons */
+ if (!((pcontext->wi.dwStyle & WS_CAPTION) && (pcontext->wi.dwStyle
& WS_SYSMENU)))
+ return ;
+
+ rcCurrent.top = rcCurrent.left = 0;
+ rcCurrent.right = pcontext->wi.rcWindow.right - pcontext->wi.rcWindow.left;
+ rcCurrent.bottom = pcontext->CaptionHeight;
+
+ /* Add a padding around the objects of the caption */
+ InflateRect(&rcCurrent, -(int)pcontext->wi.cyWindowBorders-BUTTON_GAP_SIZE,
+ -(int)pcontext->wi.cyWindowBorders-BUTTON_GAP_SIZE);
+
+ /* Draw the buttons */
+ ThemeDrawCaptionButton(pcontext, &rcCurrent, CLOSEBUTTON,
+ ThemeGetButtonState(HTCLOSE, htHot, htDown,
pcontext->Active));
+ ThemeDrawCaptionButton(pcontext, &rcCurrent, MAXBUTTON,
+ ThemeGetButtonState(HTMAXBUTTON, htHot, htDown,
pcontext->Active));
+ ThemeDrawCaptionButton(pcontext, &rcCurrent, MINBUTTON,
+ ThemeGetButtonState(HTMINBUTTON, htHot, htDown,
pcontext->Active));
+ ThemeDrawCaptionButton(pcontext, &rcCurrent, HELPBUTTON,
+ ThemeGetButtonState(HTHELP, htHot, htDown,
pcontext->Active));
+}
+
static void
ThemeDrawCaption(PDRAW_CONTEXT pcontext, RECT* prcCurrent)
{
@@ -421,6 +463,105 @@
return 0;
}
+static LRESULT
+ThemeHandleNcMouseMove(HWND hWnd, DWORD ht)
+{
+ DRAW_CONTEXT context;
+ TRACKMOUSEEVENT tme;
+
+ tme.cbSize = sizeof(TRACKMOUSEEVENT);
+ tme.dwFlags = TME_QUERY;
+ tme.hwndTrack = hWnd;
+ TrackMouseEvent(&tme);
+ if (tme.dwFlags != (TME_LEAVE | TME_NONCLIENT))
+ {
+ tme.hwndTrack = hWnd;
+ tme.dwFlags = TME_LEAVE | TME_NONCLIENT;
+ TrackMouseEvent(&tme);
+ }
+
+ ThemeInitDrawContext(&context, hWnd, 0);
+ ThemeDrawCaptionButtons(&context, ht, 0);
+ ThemeCleanupDrawContext(&context);
+
+ return 0;
+}
+
+static LRESULT
+ThemeHandleNcMouseLeave(HWND hWnd)
+{
+ DRAW_CONTEXT context;
+
+ ThemeInitDrawContext(&context, hWnd, 0);
+ ThemeDrawCaptionButtons(&context, 0, 0);
+ ThemeCleanupDrawContext(&context);
+
+ return 0;
+}
+
+static VOID
+ThemeHandleButton(HWND hWnd, WPARAM wParam)
+{
+ MSG Msg;
+ BOOL Pressed = TRUE, OldState;
+ WPARAM SCMsg, ht;
+ ULONG Style;
+ DRAW_CONTEXT context;
+
+ Style = GetWindowLongW(hWnd, GWL_STYLE);
+ switch (wParam)
+ {
+ case HTCLOSE:
+ if (!(Style & WS_SYSMENU))
+ return;
+ SCMsg = SC_CLOSE;
+ break;
+ case HTMINBUTTON:
+ if (!(Style & WS_MINIMIZEBOX))
+ return;
+ SCMsg = ((Style & WS_MINIMIZE) ? SC_RESTORE : SC_MINIMIZE);
+ break;
+ case HTMAXBUTTON:
+ if (!(Style & WS_MAXIMIZEBOX))
+ return;
+ SCMsg = ((Style & WS_MAXIMIZE) ? SC_RESTORE : SC_MAXIMIZE);
+ break;
+ default :
+ return;
+ }
+
+ ThemeInitDrawContext(&context, hWnd, 0);
+ ThemeDrawCaptionButtons(&context, 0, wParam);
+
+ SetCapture(hWnd);
+
+ for (;;)
+ {
+ if (GetMessageW(&Msg, 0, WM_MOUSEFIRST, WM_MOUSELAST) <= 0)
+ break;
+
+ if (Msg.message == WM_LBUTTONUP)
+ break;
+
+ if (Msg.message != WM_MOUSEMOVE)
+ continue;
+
+ OldState = Pressed;
+ ht = SendMessage(hWnd, WM_NCHITTEST, 0, MAKELPARAM(Msg.pt.x, Msg.pt.y));
+ Pressed = (ht == wParam);
+
+ ThemeDrawCaptionButtons(&context, 0, Pressed ? wParam: 0);
+ }
+
+ ThemeDrawCaptionButtons(&context, 0, 0);
+ ThemeCleanupDrawContext(&context);
+
+ ReleaseCapture();
+
+ if (Pressed)
+ SendMessageW(hWnd, WM_SYSCOMMAND, SCMsg, 0);
+}
+
LRESULT CALLBACK
ThemeWndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam, WNDPROC DefWndProc)
{
@@ -431,6 +572,23 @@
case WM_NCACTIVATE:
ThemeHandleNCPaint(hWnd, (HRGN)1);
return TRUE;
+ case WM_NCMOUSEMOVE:
+ return ThemeHandleNcMouseMove(hWnd, wParam);
+ case WM_NCMOUSELEAVE:
+ return ThemeHandleNcMouseLeave(hWnd);
+ case WM_NCLBUTTONDOWN:
+ switch (wParam)
+ {
+ case HTMINBUTTON:
+ case HTMAXBUTTON:
+ case HTCLOSE:
+ {
+ ThemeHandleButton(hWnd, wParam);
+ return 0;
+ }
+ default:
+ return DefWndProc(hWnd, Msg, wParam, lParam);
+ }
default:
return DefWndProc(hWnd, Msg, wParam, lParam);
}