mirror of
https://github.com/reactos/reactos.git
synced 2025-06-14 10:28:32 +00:00
[uxtheme]
- Greatly reduce needless repaints in the non client area but remembering the last hittest of the mouse events to redraw it only when it is needed - Do not reset the theme region every time we move a window, also make sure we try to set a theme region only when it is needed - Do not use OpenThemeData but use MSSTYLES_OpenThemeClass directly - Do not reload the active theme every time we get a WM_THEMECHANGED message, make sure to see if the active theme was already loaded before trying to load it again - See CORE-7775 svn path=/trunk/; revision=61654
This commit is contained in:
parent
f895117bca
commit
e5825e6426
4 changed files with 187 additions and 69 deletions
|
@ -155,9 +155,8 @@ ThemeInitDrawContext(PDRAW_CONTEXT pcontext,
|
||||||
GetWindowInfo(hWnd, &pcontext->wi);
|
GetWindowInfo(hWnd, &pcontext->wi);
|
||||||
pcontext->hWnd = hWnd;
|
pcontext->hWnd = hWnd;
|
||||||
pcontext->Active = IsWindowActive(hWnd, pcontext->wi.dwExStyle);
|
pcontext->Active = IsWindowActive(hWnd, pcontext->wi.dwExStyle);
|
||||||
pcontext->hPrevTheme = GetPropW(hWnd, (LPCWSTR)MAKEINTATOM(atWindowTheme));
|
pcontext->theme = MSSTYLES_OpenThemeClass(ActiveThemeFile, NULL, L"WINDOW");
|
||||||
pcontext->theme = OpenThemeData(pcontext->hWnd, L"WINDOW");
|
pcontext->scrolltheme = MSSTYLES_OpenThemeClass(ActiveThemeFile, NULL, L"SCROLLBAR");
|
||||||
pcontext->scrolltheme = OpenThemeData(pcontext->hWnd, L"SCROLLBAR");
|
|
||||||
|
|
||||||
pcontext->CaptionHeight = pcontext->wi.cyWindowBorders;
|
pcontext->CaptionHeight = pcontext->wi.cyWindowBorders;
|
||||||
pcontext->CaptionHeight += GetSystemMetrics(pcontext->wi.dwExStyle & WS_EX_TOOLWINDOW ? SM_CYSMCAPTION : SM_CYCAPTION );
|
pcontext->CaptionHeight += GetSystemMetrics(pcontext->wi.dwExStyle & WS_EX_TOOLWINDOW ? SM_CYSMCAPTION : SM_CYCAPTION );
|
||||||
|
@ -179,8 +178,6 @@ ThemeCleanupDrawContext(PDRAW_CONTEXT pcontext)
|
||||||
CloseThemeData (pcontext->theme);
|
CloseThemeData (pcontext->theme);
|
||||||
CloseThemeData (pcontext->scrolltheme);
|
CloseThemeData (pcontext->scrolltheme);
|
||||||
|
|
||||||
SetPropW(pcontext->hWnd, (LPCWSTR)MAKEINTATOM(atWindowTheme), pcontext->hPrevTheme);
|
|
||||||
|
|
||||||
if(pcontext->hRgn != NULL)
|
if(pcontext->hRgn != NULL)
|
||||||
{
|
{
|
||||||
DeleteObject(pcontext->hRgn);
|
DeleteObject(pcontext->hRgn);
|
||||||
|
@ -289,10 +286,7 @@ ThemeDrawCaptionButtons(PDRAW_CONTEXT pcontext, DWORD htHot, DWORD htDown)
|
||||||
{
|
{
|
||||||
RECT rcCurrent;
|
RECT rcCurrent;
|
||||||
|
|
||||||
/* Check if the window has caption buttons */
|
/* Calculate the area of the caption */
|
||||||
if (!((pcontext->wi.dwStyle & WS_CAPTION) && (pcontext->wi.dwStyle & WS_SYSMENU)))
|
|
||||||
return ;
|
|
||||||
|
|
||||||
rcCurrent.top = rcCurrent.left = 0;
|
rcCurrent.top = rcCurrent.left = 0;
|
||||||
rcCurrent.right = pcontext->wi.rcWindow.right - pcontext->wi.rcWindow.left;
|
rcCurrent.right = pcontext->wi.rcWindow.right - pcontext->wi.rcWindow.left;
|
||||||
rcCurrent.bottom = pcontext->CaptionHeight;
|
rcCurrent.bottom = pcontext->CaptionHeight;
|
||||||
|
@ -336,7 +330,7 @@ ThemeDrawCaption(PDRAW_CONTEXT pcontext, RECT* prcCurrent)
|
||||||
|
|
||||||
/* Draw the caption background*/
|
/* Draw the caption background*/
|
||||||
rcPart = *prcCurrent;
|
rcPart = *prcCurrent;
|
||||||
rcPart.bottom = pcontext->CaptionHeight;
|
rcPart.bottom = rcPart.top + pcontext->CaptionHeight;
|
||||||
prcCurrent->top = rcPart.bottom;
|
prcCurrent->top = rcPart.bottom;
|
||||||
DrawThemeBackground(pcontext->theme, pcontext->hDC,iPart,iState,&rcPart,NULL);
|
DrawThemeBackground(pcontext->theme, pcontext->hDC,iPart,iState,&rcPart,NULL);
|
||||||
|
|
||||||
|
@ -400,7 +394,7 @@ ThemeDrawBorders(PDRAW_CONTEXT pcontext, RECT* prcCurrent)
|
||||||
|
|
||||||
/* Draw the left border */
|
/* Draw the left border */
|
||||||
rcPart = *prcCurrent;
|
rcPart = *prcCurrent;
|
||||||
rcPart.right = pcontext->wi.cxWindowBorders ;
|
rcPart.right = rcPart.left + pcontext->wi.cxWindowBorders ;
|
||||||
prcCurrent->left = rcPart.right;
|
prcCurrent->left = rcPart.right;
|
||||||
DrawThemeBackground(pcontext->theme, pcontext->hDC,WP_FRAMELEFT, iState, &rcPart, NULL);
|
DrawThemeBackground(pcontext->theme, pcontext->hDC,WP_FRAMELEFT, iState, &rcPart, NULL);
|
||||||
|
|
||||||
|
@ -684,29 +678,57 @@ ThemeHandleNcMouseMove(HWND hWnd, DWORD ht, POINT* pt)
|
||||||
{
|
{
|
||||||
DRAW_CONTEXT context;
|
DRAW_CONTEXT context;
|
||||||
TRACKMOUSEEVENT tme;
|
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.cbSize = sizeof(TRACKMOUSEEVENT);
|
||||||
tme.dwFlags = TME_QUERY;
|
tme.dwFlags = TME_QUERY;
|
||||||
tme.hwndTrack = hWnd;
|
tme.hwndTrack = hWnd;
|
||||||
TrackMouseEvent(&tme);
|
TrackMouseEvent(&tme);
|
||||||
if (tme.dwFlags != (TME_LEAVE | TME_NONCLIENT))
|
if (tme.dwFlags != (TME_LEAVE | TME_NONCLIENT))
|
||||||
{
|
{
|
||||||
tme.hwndTrack = hWnd;
|
tme.hwndTrack = hWnd;
|
||||||
tme.dwFlags = TME_LEAVE | TME_NONCLIENT;
|
tme.dwFlags = TME_LEAVE | TME_NONCLIENT;
|
||||||
TrackMouseEvent(&tme);
|
TrackMouseEvent(&tme);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Dont do any drawing if the hit test wasn't changed */
|
||||||
|
if (ht == pcontext->lastHitTest)
|
||||||
|
return 0;
|
||||||
|
|
||||||
ThemeInitDrawContext(&context, hWnd, 0);
|
ThemeInitDrawContext(&context, hWnd, 0);
|
||||||
ThemeDrawCaptionButtons(&context, ht, 0);
|
if (context.wi.dwStyle & WS_SYSMENU)
|
||||||
|
{
|
||||||
|
if (HT_ISBUTTON(ht) || HT_ISBUTTON(pcontext->lastHitTest))
|
||||||
|
ThemeDrawCaptionButtons(&context, ht, 0);
|
||||||
|
}
|
||||||
|
|
||||||
if(context.wi.dwStyle & WS_HSCROLL)
|
if (context.wi.dwStyle & WS_HSCROLL)
|
||||||
ThemeDrawScrollBar(&context, SB_HORZ , ht == HTHSCROLL ? pt : NULL);
|
{
|
||||||
|
if (ht == HTHSCROLL || pcontext->lastHitTest == HTHSCROLL)
|
||||||
if(context.wi.dwStyle & WS_VSCROLL)
|
ThemeDrawScrollBar(&context, SB_HORZ , ht == HTHSCROLL ? pt : NULL);
|
||||||
ThemeDrawScrollBar(&context, SB_VERT, ht == HTVSCROLL ? pt : NULL);
|
}
|
||||||
|
|
||||||
|
if (context.wi.dwStyle & WS_VSCROLL)
|
||||||
|
{
|
||||||
|
if (ht == HTVSCROLL || pcontext->lastHitTest == HTVSCROLL)
|
||||||
|
ThemeDrawScrollBar(&context, SB_VERT, ht == HTVSCROLL ? pt : NULL);
|
||||||
|
}
|
||||||
ThemeCleanupDrawContext(&context);
|
ThemeCleanupDrawContext(&context);
|
||||||
|
|
||||||
|
pcontext->lastHitTest = ht;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -714,18 +736,33 @@ static LRESULT
|
||||||
ThemeHandleNcMouseLeave(HWND hWnd)
|
ThemeHandleNcMouseLeave(HWND hWnd)
|
||||||
{
|
{
|
||||||
DRAW_CONTEXT context;
|
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);
|
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)
|
if (context.wi.dwStyle & WS_HSCROLL && pWndContext->lastHitTest == HTHSCROLL)
|
||||||
ThemeDrawScrollBar(&context, SB_HORZ, NULL);
|
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);
|
ThemeDrawScrollBar(&context, SB_VERT, NULL);
|
||||||
|
|
||||||
ThemeCleanupDrawContext(&context);
|
ThemeCleanupDrawContext(&context);
|
||||||
|
|
||||||
|
pWndContext->lastHitTest = HTNOWHERE;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -733,17 +770,19 @@ static VOID
|
||||||
ThemeHandleButton(HWND hWnd, WPARAM wParam)
|
ThemeHandleButton(HWND hWnd, WPARAM wParam)
|
||||||
{
|
{
|
||||||
MSG Msg;
|
MSG Msg;
|
||||||
BOOL Pressed = TRUE; // , OldState;
|
BOOL Pressed = TRUE;
|
||||||
WPARAM SCMsg, ht;
|
WPARAM SCMsg, ht;
|
||||||
ULONG Style;
|
ULONG Style;
|
||||||
DRAW_CONTEXT context;
|
DRAW_CONTEXT context;
|
||||||
|
PWND_CONTEXT pWndContext;
|
||||||
|
|
||||||
Style = GetWindowLongW(hWnd, GWL_STYLE);
|
Style = GetWindowLongW(hWnd, GWL_STYLE);
|
||||||
|
if (!((Style & WS_CAPTION) && (Style & WS_SYSMENU)))
|
||||||
|
return ;
|
||||||
|
|
||||||
switch (wParam)
|
switch (wParam)
|
||||||
{
|
{
|
||||||
case HTCLOSE:
|
case HTCLOSE:
|
||||||
if (!(Style & WS_SYSMENU))
|
|
||||||
return;
|
|
||||||
SCMsg = SC_CLOSE;
|
SCMsg = SC_CLOSE;
|
||||||
break;
|
break;
|
||||||
case HTMINBUTTON:
|
case HTMINBUTTON:
|
||||||
|
@ -760,8 +799,14 @@ ThemeHandleButton(HWND hWnd, WPARAM wParam)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Get theme data for this window */
|
||||||
|
pWndContext = ThemeGetWndContext(hWnd);
|
||||||
|
if (pWndContext == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
ThemeInitDrawContext(&context, hWnd, 0);
|
ThemeInitDrawContext(&context, hWnd, 0);
|
||||||
ThemeDrawCaptionButtons(&context, 0, wParam);
|
ThemeDrawCaptionButtons(&context, 0, wParam);
|
||||||
|
pWndContext->lastHitTest = wParam;
|
||||||
|
|
||||||
SetCapture(hWnd);
|
SetCapture(hWnd);
|
||||||
|
|
||||||
|
@ -776,14 +821,19 @@ ThemeHandleButton(HWND hWnd, WPARAM wParam)
|
||||||
if (Msg.message != WM_MOUSEMOVE)
|
if (Msg.message != WM_MOUSEMOVE)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
//OldState = Pressed;
|
|
||||||
ht = SendMessage(hWnd, WM_NCHITTEST, 0, MAKELPARAM(Msg.pt.x, Msg.pt.y));
|
ht = SendMessage(hWnd, WM_NCHITTEST, 0, MAKELPARAM(Msg.pt.x, Msg.pt.y));
|
||||||
Pressed = (ht == wParam);
|
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);
|
ThemeCleanupDrawContext(&context);
|
||||||
|
|
||||||
ReleaseCapture();
|
ReleaseCapture();
|
||||||
|
|
|
@ -50,7 +50,7 @@ static ATOM atSubAppName;
|
||||||
static ATOM atSubIdList;
|
static ATOM atSubIdList;
|
||||||
ATOM atWndContrext;
|
ATOM atWndContrext;
|
||||||
|
|
||||||
static PTHEME_FILE ActiveThemeFile;
|
PTHEME_FILE ActiveThemeFile;
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
|
||||||
|
@ -138,6 +138,39 @@ static HRESULT UXTHEME_SetActiveTheme(PTHEME_FILE tf)
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static BOOL bIsThemeActive(LPCWSTR pszTheme, LPCWSTR pszColor, LPCWSTR pszSize)
|
||||||
|
{
|
||||||
|
if (ActiveThemeFile == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (wcscmp(pszTheme, ActiveThemeFile->szThemeFile) != 0)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (!pszColor[0])
|
||||||
|
{
|
||||||
|
if (ActiveThemeFile->pszAvailColors != ActiveThemeFile->pszSelectedColor)
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (wcscmp(pszColor, ActiveThemeFile->pszSelectedColor) != 0)
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pszSize[0])
|
||||||
|
{
|
||||||
|
if (ActiveThemeFile->pszAvailSizes != ActiveThemeFile->pszSelectedSize)
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (wcscmp(pszSize, ActiveThemeFile->pszSelectedSize) != 0)
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* UXTHEME_LoadTheme
|
* UXTHEME_LoadTheme
|
||||||
*
|
*
|
||||||
|
@ -186,7 +219,14 @@ void UXTHEME_LoadTheme(BOOL bLoad)
|
||||||
bThemeActive = FALSE;
|
bThemeActive = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(bThemeActive) {
|
if(bThemeActive)
|
||||||
|
{
|
||||||
|
if( bIsThemeActive(szCurrentTheme, szCurrentColor, szCurrentSize) )
|
||||||
|
{
|
||||||
|
TRACE("Tried to load active theme again\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Make sure the theme requested is actually valid */
|
/* Make sure the theme requested is actually valid */
|
||||||
hr = MSSTYLES_OpenThemeFile(szCurrentTheme,
|
hr = MSSTYLES_OpenThemeFile(szCurrentTheme,
|
||||||
szCurrentColor[0]?szCurrentColor:NULL,
|
szCurrentColor[0]?szCurrentColor:NULL,
|
||||||
|
@ -471,6 +511,8 @@ static HRESULT UXTHEME_ApplyTheme(PTHEME_FILE tf)
|
||||||
WCHAR tmp[2];
|
WCHAR tmp[2];
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
|
TRACE("UXTHEME_ApplyTheme\n");
|
||||||
|
|
||||||
if (tf && !ActiveThemeFile)
|
if (tf && !ActiveThemeFile)
|
||||||
{
|
{
|
||||||
UXTHEME_BackupSystemMetrics();
|
UXTHEME_BackupSystemMetrics();
|
||||||
|
@ -562,7 +604,7 @@ BOOL WINAPI IsThemeActive(void)
|
||||||
WCHAR tmp[10];
|
WCHAR tmp[10];
|
||||||
DWORD buffsize;
|
DWORD buffsize;
|
||||||
|
|
||||||
TRACE("\n");
|
TRACE("IsThemeActive\n");
|
||||||
SetLastError(ERROR_SUCCESS);
|
SetLastError(ERROR_SUCCESS);
|
||||||
|
|
||||||
if (ActiveThemeFile)
|
if (ActiveThemeFile)
|
||||||
|
|
|
@ -83,7 +83,7 @@ static BOOL CALLBACK ThemeCleanupWndContext(HWND hWnd, LPARAM msg)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetThemeRegion(HWND hWnd, PWND_CONTEXT pcontext)
|
void SetThemeRegion(HWND hWnd)
|
||||||
{
|
{
|
||||||
HTHEME hTheme;
|
HTHEME hTheme;
|
||||||
RECT rcWindow;
|
RECT rcWindow;
|
||||||
|
@ -91,25 +91,11 @@ void SetThemeRegion(HWND hWnd, PWND_CONTEXT pcontext)
|
||||||
int CaptionHeight, iPart;
|
int CaptionHeight, iPart;
|
||||||
WINDOWINFO wi;
|
WINDOWINFO wi;
|
||||||
|
|
||||||
if(!IsAppThemed())
|
TRACE("SetThemeRegion %d\n", hWnd);
|
||||||
{
|
|
||||||
if(pcontext->HasThemeRgn)
|
|
||||||
{
|
|
||||||
pcontext->HasThemeRgn = FALSE;
|
|
||||||
user32ApiHook.SetWindowRgn(hWnd, 0, TRUE);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
wi.cbSize = sizeof(wi);
|
wi.cbSize = sizeof(wi);
|
||||||
|
|
||||||
GetWindowInfo(hWnd, &wi);
|
GetWindowInfo(hWnd, &wi);
|
||||||
|
|
||||||
if((wi.dwStyle & WS_CAPTION)!=WS_CAPTION)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get the caption part id */
|
/* Get the caption part id */
|
||||||
if (wi.dwExStyle & WS_EX_TOOLWINDOW)
|
if (wi.dwExStyle & WS_EX_TOOLWINDOW)
|
||||||
iPart = WP_SMALLCAPTION;
|
iPart = WP_SMALLCAPTION;
|
||||||
|
@ -118,8 +104,6 @@ void SetThemeRegion(HWND hWnd, PWND_CONTEXT pcontext)
|
||||||
else
|
else
|
||||||
iPart = WP_CAPTION;
|
iPart = WP_CAPTION;
|
||||||
|
|
||||||
pcontext->HasThemeRgn = TRUE;
|
|
||||||
|
|
||||||
CaptionHeight = wi.cyWindowBorders;
|
CaptionHeight = wi.cyWindowBorders;
|
||||||
CaptionHeight += GetSystemMetrics(wi.dwExStyle & WS_EX_TOOLWINDOW ? SM_CYSMCAPTION : SM_CYCAPTION );
|
CaptionHeight += GetSystemMetrics(wi.dwExStyle & WS_EX_TOOLWINDOW ? SM_CYSMCAPTION : SM_CYCAPTION );
|
||||||
|
|
||||||
|
@ -129,10 +113,8 @@ void SetThemeRegion(HWND hWnd, PWND_CONTEXT pcontext)
|
||||||
rcWindow.top = 0;
|
rcWindow.top = 0;
|
||||||
rcWindow.left = 0;
|
rcWindow.left = 0;
|
||||||
|
|
||||||
hTheme = OpenThemeData (hWnd, L"WINDOW");
|
hTheme = MSSTYLES_OpenThemeClass(ActiveThemeFile, NULL, L"WINDOW");
|
||||||
|
|
||||||
GetThemeBackgroundRegion(hTheme, 0, iPart, FS_ACTIVE, &rcWindow, &hrgn);
|
GetThemeBackgroundRegion(hTheme, 0, iPart, FS_ACTIVE, &rcWindow, &hrgn);
|
||||||
|
|
||||||
CloseThemeData(hTheme);
|
CloseThemeData(hTheme);
|
||||||
|
|
||||||
GetWindowRect(hWnd, &rcWindow);
|
GetWindowRect(hWnd, &rcWindow);
|
||||||
|
@ -149,21 +131,51 @@ void SetThemeRegion(HWND hWnd, PWND_CONTEXT pcontext)
|
||||||
user32ApiHook.SetWindowRgn(hWnd, hrgn, TRUE);
|
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;
|
||||||
|
|
||||||
if(pcontext &&
|
/* We only proceed to change the window shape if it has a caption */
|
||||||
pcontext->HasAppDefinedRgn == FALSE &&
|
style = GetWindowLongW(hWnd, GWL_STYLE);
|
||||||
pcontext->UpdatingRgn == FALSE)
|
if((style & WS_CAPTION)!=WS_CAPTION)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* 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;
|
if(pcontext->HasThemeRgn)
|
||||||
SetThemeRegion(hWnd, pcontext);
|
{
|
||||||
pcontext = ThemeGetWndContext(hWnd);
|
pcontext->HasThemeRgn = FALSE;
|
||||||
pcontext->UpdatingRgn = 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
|
* Hook Functions
|
||||||
|
@ -172,7 +184,7 @@ int OnPostWinPosChanged(HWND hWnd)
|
||||||
static LRESULT CALLBACK
|
static LRESULT CALLBACK
|
||||||
ThemeDefWindowProcW(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
|
ThemeDefWindowProcW(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
if(!IsThemeActive())
|
if(!IsAppThemed())
|
||||||
{
|
{
|
||||||
return user32ApiHook.DefWindowProcW(hWnd,
|
return user32ApiHook.DefWindowProcW(hWnd,
|
||||||
Msg,
|
Msg,
|
||||||
|
@ -190,7 +202,7 @@ ThemeDefWindowProcW(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
|
||||||
static LRESULT CALLBACK
|
static LRESULT CALLBACK
|
||||||
ThemeDefWindowProcA(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
|
ThemeDefWindowProcA(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
if(!IsThemeActive())
|
if(!IsAppThemed())
|
||||||
{
|
{
|
||||||
return user32ApiHook.DefWindowProcA(hWnd,
|
return user32ApiHook.DefWindowProcA(hWnd,
|
||||||
Msg,
|
Msg,
|
||||||
|
@ -211,8 +223,15 @@ ThemePreWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam, ULONG_PTR
|
||||||
switch(Msg)
|
switch(Msg)
|
||||||
{
|
{
|
||||||
case WM_THEMECHANGED:
|
case WM_THEMECHANGED:
|
||||||
UXTHEME_LoadTheme(TRUE);
|
if (GetAncestor(hWnd, GA_PARENT) == GetDesktopWindow())
|
||||||
return 0;
|
UXTHEME_LoadTheme(TRUE);
|
||||||
|
case WM_NCCREATE:
|
||||||
|
{
|
||||||
|
PWND_CONTEXT pcontext = ThemeGetWndContext(hWnd);
|
||||||
|
if (pcontext == NULL)
|
||||||
|
return 0;
|
||||||
|
pcontext->DirtyThemeRegion = TRUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -226,7 +245,7 @@ ThemePostWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam, ULONG_PTR
|
||||||
{
|
{
|
||||||
case WM_WINDOWPOSCHANGED:
|
case WM_WINDOWPOSCHANGED:
|
||||||
{
|
{
|
||||||
return OnPostWinPosChanged(hWnd);
|
return OnPostWinPosChanged(hWnd, (WINDOWPOS*)lParam);
|
||||||
}
|
}
|
||||||
case WM_DESTROY:
|
case WM_DESTROY:
|
||||||
{
|
{
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include <windowsx.h>
|
#include <windowsx.h>
|
||||||
#include <undocuser.h>
|
#include <undocuser.h>
|
||||||
#include <uxtheme.h>
|
#include <uxtheme.h>
|
||||||
|
#include <uxundoc.h>
|
||||||
#include <vfwmsgs.h>
|
#include <vfwmsgs.h>
|
||||||
#include <tmschema.h>
|
#include <tmschema.h>
|
||||||
|
|
||||||
|
@ -111,14 +112,17 @@ LPCWSTR UXINI_GetNextValue(PUXINI_FILE uf, DWORD *dwNameLen, LPCWSTR *lpValue, D
|
||||||
BOOL UXINI_FindValue(PUXINI_FILE uf, LPCWSTR lpName, LPCWSTR *lpValue, DWORD *dwValueLen);
|
BOOL UXINI_FindValue(PUXINI_FILE uf, LPCWSTR lpName, LPCWSTR *lpValue, DWORD *dwValueLen);
|
||||||
|
|
||||||
|
|
||||||
|
/* The window context stores data for the window needed through the life of the window */
|
||||||
typedef struct _WND_CONTEXT
|
typedef struct _WND_CONTEXT
|
||||||
{
|
{
|
||||||
|
UINT lastHitTest;
|
||||||
BOOL HasAppDefinedRgn;
|
BOOL HasAppDefinedRgn;
|
||||||
BOOL HasThemeRgn;
|
BOOL HasThemeRgn;
|
||||||
BOOL UpdatingRgn;
|
BOOL UpdatingRgn;
|
||||||
|
BOOL DirtyThemeRegion;
|
||||||
} WND_CONTEXT, *PWND_CONTEXT;
|
} WND_CONTEXT, *PWND_CONTEXT;
|
||||||
|
|
||||||
|
/* The draw context stores data that are needed by the drawing operations in the non client area of the window */
|
||||||
typedef struct _DRAW_CONTEXT
|
typedef struct _DRAW_CONTEXT
|
||||||
{
|
{
|
||||||
HWND hWnd;
|
HWND hWnd;
|
||||||
|
@ -168,6 +172,8 @@ enum SCROLL_HITTEST
|
||||||
SCROLL_BOTTOM_ARROW /* Bottom or right arrow */
|
SCROLL_BOTTOM_ARROW /* Bottom or right arrow */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define HT_ISBUTTON(ht) ((ht) == HTMINBUTTON || (ht) == HTMAXBUTTON || (ht) == HTCLOSE || (ht) == HTHELP)
|
||||||
|
|
||||||
#define HASSIZEGRIP(Style, ExStyle, ParentStyle, WindowRect, ParentClientRect) \
|
#define HASSIZEGRIP(Style, ExStyle, ParentStyle, WindowRect, ParentClientRect) \
|
||||||
((!(Style & WS_CHILD) && (Style & WS_THICKFRAME) && !(Style & WS_MAXIMIZE)) || \
|
((!(Style & WS_CHILD) && (Style & WS_THICKFRAME) && !(Style & WS_MAXIMIZE)) || \
|
||||||
((Style & WS_CHILD) && (ParentStyle & WS_THICKFRAME) && !(ParentStyle & WS_MAXIMIZE) && \
|
((Style & WS_CHILD) && (ParentStyle & WS_THICKFRAME) && !(ParentStyle & WS_MAXIMIZE) && \
|
||||||
|
@ -208,6 +214,7 @@ extern HINSTANCE hDllInst;
|
||||||
extern ATOM atWindowTheme;
|
extern ATOM atWindowTheme;
|
||||||
extern ATOM atWndContrext;
|
extern ATOM atWndContrext;
|
||||||
extern BOOL gbThemeHooksActive;
|
extern BOOL gbThemeHooksActive;
|
||||||
|
extern PTHEME_FILE ActiveThemeFile;
|
||||||
|
|
||||||
void UXTHEME_InitSystem(HINSTANCE hInst);
|
void UXTHEME_InitSystem(HINSTANCE hInst);
|
||||||
void UXTHEME_LoadTheme(BOOL bLoad);
|
void UXTHEME_LoadTheme(BOOL bLoad);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue