GetWindowInfo(hWnd, &pcontext->wi);
pcontext->hWnd = hWnd;
pcontext->Active = IsWindowActive(hWnd, pcontext->wi.dwExStyle);
- pcontext->hPrevTheme = GetPropW(hWnd, (LPCWSTR)MAKEINTATOM(atWindowTheme));
- pcontext->theme = OpenThemeData(pcontext->hWnd, L"WINDOW");
- pcontext->scrolltheme = OpenThemeData(pcontext->hWnd, L"SCROLLBAR");
+ pcontext->theme = MSSTYLES_OpenThemeClass(ActiveThemeFile, NULL, L"WINDOW");
+ pcontext->scrolltheme = MSSTYLES_OpenThemeClass(ActiveThemeFile, NULL, L"SCROLLBAR");
pcontext->CaptionHeight = pcontext->wi.cyWindowBorders;
pcontext->CaptionHeight += GetSystemMetrics(pcontext->wi.dwExStyle & WS_EX_TOOLWINDOW ? SM_CYSMCAPTION : SM_CYCAPTION );
CloseThemeData (pcontext->theme);
CloseThemeData (pcontext->scrolltheme);
- SetPropW(pcontext->hWnd, (LPCWSTR)MAKEINTATOM(atWindowTheme), pcontext->hPrevTheme);
-
if(pcontext->hRgn != NULL)
{
DeleteObject(pcontext->hRgn);
{
RECT rcCurrent;
- /* Check if the window has caption buttons */
- if (!((pcontext->wi.dwStyle & WS_CAPTION) && (pcontext->wi.dwStyle & WS_SYSMENU)))
- return ;
-
+ /* Calculate the area of the caption */
rcCurrent.top = rcCurrent.left = 0;
rcCurrent.right = pcontext->wi.rcWindow.right - pcontext->wi.rcWindow.left;
rcCurrent.bottom = pcontext->CaptionHeight;
/* Draw the caption background*/
rcPart = *prcCurrent;
- rcPart.bottom = pcontext->CaptionHeight;
+ rcPart.bottom = rcPart.top + pcontext->CaptionHeight;
prcCurrent->top = rcPart.bottom;
DrawThemeBackground(pcontext->theme, pcontext->hDC,iPart,iState,&rcPart,NULL);
/* Draw the left border */
rcPart = *prcCurrent;
- rcPart.right = pcontext->wi.cxWindowBorders ;
+ rcPart.right = rcPart.left + pcontext->wi.cxWindowBorders ;
prcCurrent->left = rcPart.right;
DrawThemeBackground(pcontext->theme, pcontext->hDC,WP_FRAMELEFT, iState, &rcPart, NULL);
{
DRAW_CONTEXT context;
TRACKMOUSEEVENT tme;
+ DWORD style;
+ PWND_CONTEXT pcontext;
+ /* First of all check if we have something to do here */
+ style = GetWindowLongW(hWnd, GWL_STYLE);
+ if((style & (WS_CAPTION|WS_HSCROLL|WS_VSCROLL))==0)
+ return 0;
+
+ /* Get theme data for this window */
+ pcontext = ThemeGetWndContext(hWnd);
+ if (pcontext == NULL)
+ return 0;
+
+ /* Begin tracking in the non client area if we are not tracking yet */
tme.cbSize = sizeof(TRACKMOUSEEVENT);
tme.dwFlags = TME_QUERY;
tme.hwndTrack = hWnd;
TrackMouseEvent(&tme);
- if (tme.dwFlags != (TME_LEAVE | TME_NONCLIENT))
+ 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);
+ /* Dont do any drawing if the hit test wasn't changed */
+ if (ht == pcontext->lastHitTest)
+ return 0;
- if(context.wi.dwStyle & WS_HSCROLL)
- ThemeDrawScrollBar(&context, SB_HORZ , ht == HTHSCROLL ? pt : NULL);
+ ThemeInitDrawContext(&context, hWnd, 0);
+ if (context.wi.dwStyle & WS_SYSMENU)
+ {
+ if (HT_ISBUTTON(ht) || HT_ISBUTTON(pcontext->lastHitTest))
+ ThemeDrawCaptionButtons(&context, ht, 0);
+ }
- if(context.wi.dwStyle & WS_VSCROLL)
- ThemeDrawScrollBar(&context, SB_VERT, ht == HTVSCROLL ? pt : NULL);
+ if (context.wi.dwStyle & WS_HSCROLL)
+ {
+ if (ht == HTHSCROLL || pcontext->lastHitTest == HTHSCROLL)
+ ThemeDrawScrollBar(&context, SB_HORZ , ht == HTHSCROLL ? pt : NULL);
+ }
+ if (context.wi.dwStyle & WS_VSCROLL)
+ {
+ if (ht == HTVSCROLL || pcontext->lastHitTest == HTVSCROLL)
+ ThemeDrawScrollBar(&context, SB_VERT, ht == HTVSCROLL ? pt : NULL);
+ }
ThemeCleanupDrawContext(&context);
+ pcontext->lastHitTest = ht;
+
return 0;
}
ThemeHandleNcMouseLeave(HWND hWnd)
{
DRAW_CONTEXT context;
+ DWORD style;
+ PWND_CONTEXT pWndContext;
+
+ /* First of all check if we have something to do here */
+ style = GetWindowLongW(hWnd, GWL_STYLE);
+ if((style & (WS_CAPTION|WS_HSCROLL|WS_VSCROLL))==0)
+ return 0;
+
+ /* Get theme data for this window */
+ pWndContext = ThemeGetWndContext(hWnd);
+ if (pWndContext == NULL)
+ return 0;
ThemeInitDrawContext(&context, hWnd, 0);
- ThemeDrawCaptionButtons(&context, 0, 0);
+ if (context.wi.dwStyle & WS_SYSMENU && HT_ISBUTTON(pWndContext->lastHitTest))
+ ThemeDrawCaptionButtons(&context, 0, 0);
- if(context.wi.dwStyle & WS_HSCROLL)
- ThemeDrawScrollBar(&context, SB_HORZ, NULL);
+ if (context.wi.dwStyle & WS_HSCROLL && pWndContext->lastHitTest == HTHSCROLL)
+ ThemeDrawScrollBar(&context, SB_HORZ, NULL);
- if(context.wi.dwStyle & WS_VSCROLL)
+ if (context.wi.dwStyle & WS_VSCROLL && pWndContext->lastHitTest == HTVSCROLL)
ThemeDrawScrollBar(&context, SB_VERT, NULL);
ThemeCleanupDrawContext(&context);
+ pWndContext->lastHitTest = HTNOWHERE;
+
return 0;
}
ThemeHandleButton(HWND hWnd, WPARAM wParam)
{
MSG Msg;
- BOOL Pressed = TRUE; // , OldState;
+ BOOL Pressed = TRUE;
WPARAM SCMsg, ht;
ULONG Style;
DRAW_CONTEXT context;
+ PWND_CONTEXT pWndContext;
Style = GetWindowLongW(hWnd, GWL_STYLE);
+ if (!((Style & WS_CAPTION) && (Style & WS_SYSMENU)))
+ return ;
+
switch (wParam)
{
case HTCLOSE:
- if (!(Style & WS_SYSMENU))
- return;
SCMsg = SC_CLOSE;
break;
case HTMINBUTTON:
return;
}
+ /* Get theme data for this window */
+ pWndContext = ThemeGetWndContext(hWnd);
+ if (pWndContext == NULL)
+ return;
+
ThemeInitDrawContext(&context, hWnd, 0);
ThemeDrawCaptionButtons(&context, 0, wParam);
+ pWndContext->lastHitTest = wParam;
SetCapture(hWnd);
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);
+ /* Only draw the buttons if the hit test changed */
+ if (ht != pWndContext->lastHitTest &&
+ (HT_ISBUTTON(ht) || HT_ISBUTTON(pWndContext->lastHitTest)))
+ {
+ ThemeDrawCaptionButtons(&context, 0, Pressed ? wParam: 0);
+ pWndContext->lastHitTest = ht;
+ }
}
- ThemeDrawCaptionButtons(&context, 0, 0);
+ ThemeDrawCaptionButtons(&context, ht, 0);
ThemeCleanupDrawContext(&context);
ReleaseCapture();
return TRUE;
}
-void SetThemeRegion(HWND hWnd, PWND_CONTEXT pcontext)
+void SetThemeRegion(HWND hWnd)
{
HTHEME hTheme;
RECT rcWindow;
int CaptionHeight, iPart;
WINDOWINFO wi;
- if(!IsAppThemed())
- {
- if(pcontext->HasThemeRgn)
- {
- pcontext->HasThemeRgn = FALSE;
- user32ApiHook.SetWindowRgn(hWnd, 0, TRUE);
- }
- return;
- }
+ TRACE("SetThemeRegion %d\n", hWnd);
wi.cbSize = sizeof(wi);
-
GetWindowInfo(hWnd, &wi);
-
- if((wi.dwStyle & WS_CAPTION)!=WS_CAPTION)
- {
- return;
- }
/* Get the caption part id */
if (wi.dwExStyle & WS_EX_TOOLWINDOW)
else
iPart = WP_CAPTION;
- pcontext->HasThemeRgn = TRUE;
-
CaptionHeight = wi.cyWindowBorders;
CaptionHeight += GetSystemMetrics(wi.dwExStyle & WS_EX_TOOLWINDOW ? SM_CYSMCAPTION : SM_CYCAPTION );
rcWindow.top = 0;
rcWindow.left = 0;
- hTheme = OpenThemeData (hWnd, L"WINDOW");
-
+ hTheme = MSSTYLES_OpenThemeClass(ActiveThemeFile, NULL, L"WINDOW");
GetThemeBackgroundRegion(hTheme, 0, iPart, FS_ACTIVE, &rcWindow, &hrgn);
-
CloseThemeData(hTheme);
GetWindowRect(hWnd, &rcWindow);
user32ApiHook.SetWindowRgn(hWnd, hrgn, TRUE);
}
-int OnPostWinPosChanged(HWND hWnd)
+int OnPostWinPosChanged(HWND hWnd, WINDOWPOS* pWinPos)
{
- PWND_CONTEXT pcontext = ThemeGetWndContext(hWnd);
+ PWND_CONTEXT pcontext;
+ DWORD style;
+
+ /* We only proceed to change the window shape if it has a caption */
+ style = GetWindowLongW(hWnd, GWL_STYLE);
+ if((style & WS_CAPTION)!=WS_CAPTION)
+ return 0;
- if(pcontext &&
- pcontext->HasAppDefinedRgn == FALSE &&
- pcontext->UpdatingRgn == FALSE)
+ /* Get theme data for this window */
+ pcontext = ThemeGetWndContext(hWnd);
+ if (pcontext == NULL)
+ return 0;
+
+ /* Do not change the region of the window if its size wasn't changed */
+ if ((pWinPos->flags & SWP_NOSIZE) != 0 && pcontext->DirtyThemeRegion == FALSE)
+ return 0;
+
+ /* We don't touch the shape of the window if the application sets it on its own */
+ if (pcontext->HasAppDefinedRgn == TRUE)
+ return 0;
+
+ /* Calling SetWindowRgn will call SetWindowPos again so we need to avoid this recursion */
+ if (pcontext->UpdatingRgn == TRUE)
+ return 0;
+
+ if(!IsAppThemed())
{
- pcontext->UpdatingRgn = TRUE;
- SetThemeRegion(hWnd, pcontext);
- pcontext = ThemeGetWndContext(hWnd);
- pcontext->UpdatingRgn = FALSE;
+ if(pcontext->HasThemeRgn)
+ {
+ pcontext->HasThemeRgn = FALSE;
+ user32ApiHook.SetWindowRgn(hWnd, 0, TRUE);
+ }
+ return 0;
}
- return 0;
-}
+
+ pcontext->DirtyThemeRegion = FALSE;
+ pcontext->HasThemeRgn = TRUE;
+ pcontext->UpdatingRgn = TRUE;
+ SetThemeRegion(hWnd);
+ pcontext->UpdatingRgn = FALSE;
+
+ return 0;
+ }
/**********************************************************************
* Hook Functions
static LRESULT CALLBACK
ThemeDefWindowProcW(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
- if(!IsThemeActive())
+ if(!IsAppThemed())
{
return user32ApiHook.DefWindowProcW(hWnd,
Msg,
static LRESULT CALLBACK
ThemeDefWindowProcA(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
- if(!IsThemeActive())
+ if(!IsAppThemed())
{
return user32ApiHook.DefWindowProcA(hWnd,
Msg,
switch(Msg)
{
case WM_THEMECHANGED:
- UXTHEME_LoadTheme(TRUE);
- return 0;
+ if (GetAncestor(hWnd, GA_PARENT) == GetDesktopWindow())
+ UXTHEME_LoadTheme(TRUE);
+ case WM_NCCREATE:
+ {
+ PWND_CONTEXT pcontext = ThemeGetWndContext(hWnd);
+ if (pcontext == NULL)
+ return 0;
+ pcontext->DirtyThemeRegion = TRUE;
+ }
}
return 0;
{
case WM_WINDOWPOSCHANGED:
{
- return OnPostWinPosChanged(hWnd);
+ return OnPostWinPosChanged(hWnd, (WINDOWPOS*)lParam);
}
case WM_DESTROY:
{