[UXTHEME] Greatly reduce the number of times we open the theme data for the non client area.

- Implement OTD_NONCLIENT for OpenThemeDataEx and OpenThemeDataFromFile.
- Open the WINDOW or the SCROLLBAR theme classes only when needed. Use OpenThemeDataEx instead of the internal MSSTYLES_OpenThemeClass. Cache the open theme in the WND_DATA for later use.

svn path=/trunk/; revision=74592
This commit is contained in:
Giannis Adamopoulos 2017-05-19 10:01:50 +00:00
parent 48014fdd4b
commit 94f9c1a7c1
4 changed files with 82 additions and 14 deletions

View file

@ -173,8 +173,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->theme = MSSTYLES_OpenThemeClass(ActiveThemeFile, NULL, L"WINDOW"); pcontext->theme = GetNCCaptionTheme(hWnd, pcontext->wi.dwStyle);
pcontext->scrolltheme = MSSTYLES_OpenThemeClass(ActiveThemeFile, NULL, L"SCROLLBAR"); pcontext->scrolltheme = GetNCScrollbarTheme(hWnd, pcontext->wi.dwStyle);
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 );
@ -193,9 +193,6 @@ ThemeCleanupDrawContext(PDRAW_CONTEXT pcontext)
{ {
ReleaseDC(pcontext->hWnd ,pcontext->hDC); ReleaseDC(pcontext->hWnd ,pcontext->hDC);
CloseThemeData (pcontext->theme);
CloseThemeData (pcontext->scrolltheme);
if(pcontext->hRgn != NULL) if(pcontext->hRgn != NULL)
{ {
DeleteObject(pcontext->hRgn); DeleteObject(pcontext->hRgn);
@ -1115,7 +1112,10 @@ HRESULT WINAPI DrawNCPreview(HDC hDC,
/* Paint the window on the preview hDC */ /* Paint the window on the preview hDC */
rcCurrent = context.wi.rcWindow; rcCurrent = context.wi.rcWindow;
ThemePaintWindow(&context, &rcCurrent, FALSE); ThemePaintWindow(&context, &rcCurrent, FALSE);
context.hDC = NULL; context.hDC = NULL;
CloseThemeData (context.theme);
CloseThemeData (context.scrolltheme);
ThemeCleanupDrawContext(&context); ThemeCleanupDrawContext(&context);
/* Cleanup */ /* Cleanup */

View file

@ -724,9 +724,6 @@ OpenThemeDataInternal(PTHEME_FILE ThemeFile, HWND hwnd, LPCWSTR pszClassList, DW
return NULL; return NULL;
} }
if(flags)
FIXME("unhandled flags: %x\n", flags);
if (ThemeFile) if (ThemeFile)
{ {
pszAppName = UXTHEME_GetWindowProperty(hwnd, atSubAppName, szAppBuff, sizeof(szAppBuff)/sizeof(szAppBuff[0])); pszAppName = UXTHEME_GetWindowProperty(hwnd, atSubAppName, szAppBuff, sizeof(szAppBuff)/sizeof(szAppBuff[0]));
@ -745,7 +742,10 @@ OpenThemeDataInternal(PTHEME_FILE ThemeFile, HWND hwnd, LPCWSTR pszClassList, DW
if(IsWindow(hwnd)) if(IsWindow(hwnd))
{ {
SetPropW(hwnd, (LPCWSTR)MAKEINTATOM(atWindowTheme), hTheme); if ((flags & OTD_NONCLIENT) == 0)
{
SetPropW(hwnd, (LPCWSTR)MAKEINTATOM(atWindowTheme), hTheme);
}
} }
else else
{ {

View file

@ -63,13 +63,21 @@ void ThemeDestroyWndData(HWND hWnd)
CloseThemeData(GetWindowTheme(hWnd)); CloseThemeData(GetWindowTheme(hWnd));
DeleteObject(pwndData->hTabBackgroundBrush); DeleteObject(pwndData->hTabBackgroundBrush);
pwndData->hTabBackgroundBrush = NULL;
} }
if (pwndData->hTabBackgroundBmp != NULL) if (pwndData->hTabBackgroundBmp != NULL)
{ {
DeleteObject(pwndData->hTabBackgroundBmp); DeleteObject(pwndData->hTabBackgroundBmp);
pwndData->hTabBackgroundBmp = NULL; }
if (pwndData->hthemeWindow)
{
CloseThemeData(pwndData->hthemeWindow);
}
if (pwndData->hthemeScrollbar)
{
CloseThemeData(pwndData->hthemeScrollbar);
} }
HeapFree(GetProcessHeap(), 0, pwndData); HeapFree(GetProcessHeap(), 0, pwndData);
@ -77,6 +85,46 @@ void ThemeDestroyWndData(HWND hWnd)
SetPropW( hWnd, (LPCWSTR)MAKEINTATOM(atWndContext), NULL); SetPropW( hWnd, (LPCWSTR)MAKEINTATOM(atWndContext), NULL);
} }
HTHEME GetNCCaptionTheme(HWND hWnd, DWORD style)
{
PWND_DATA pwndData;
/* We only get the theme for the window class if the window has a caption */
if((style & WS_CAPTION) != WS_CAPTION)
return NULL;
/* Get theme data for this window */
pwndData = ThemeGetWndData(hWnd);
if (pwndData == NULL)
return NULL;
/* If the theme data was not cached, open it now */
if (!pwndData->hthemeWindow)
pwndData->hthemeWindow = OpenThemeDataEx(hWnd, L"WINDOW", OTD_NONCLIENT);
return pwndData->hthemeWindow;
}
HTHEME GetNCScrollbarTheme(HWND hWnd, DWORD style)
{
PWND_DATA pwndData;
/* We only get the theme for the scrollbar class if the window has a scrollbar */
if((style & (WS_HSCROLL|WS_VSCROLL)) == 0)
return NULL;
/* Get theme data for this window */
pwndData = ThemeGetWndData(hWnd);
if (pwndData == NULL)
return NULL;
/* If the theme data was not cached, open it now */
if (!pwndData->hthemeScrollbar)
pwndData->hthemeScrollbar = OpenThemeDataEx(hWnd, L"SCROLLBAR", OTD_NONCLIENT);
return pwndData->hthemeScrollbar;
}
static BOOL CALLBACK ThemeCleanupChildWndContext (HWND hWnd, LPARAM msg) static BOOL CALLBACK ThemeCleanupChildWndContext (HWND hWnd, LPARAM msg)
{ {
ThemeDestroyWndData(hWnd); ThemeDestroyWndData(hWnd);
@ -130,9 +178,8 @@ void SetThemeRegion(HWND hWnd)
rcWindow.top = 0; rcWindow.top = 0;
rcWindow.left = 0; rcWindow.left = 0;
hTheme = MSSTYLES_OpenThemeClass(ActiveThemeFile, NULL, L"WINDOW"); hTheme = GetNCCaptionTheme(hWnd, wi.dwStyle);
GetThemeBackgroundRegion(hTheme, 0, iPart, FS_ACTIVE, &rcWindow, &hrgn); GetThemeBackgroundRegion(hTheme, 0, iPart, FS_ACTIVE, &rcWindow, &hrgn);
CloseThemeData(hTheme);
GetWindowRect(hWnd, &rcWindow); GetWindowRect(hWnd, &rcWindow);
rcWindow.right -= rcWindow.left; rcWindow.right -= rcWindow.left;
@ -260,6 +307,18 @@ ThemePreWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam, ULONG_PTR
DeleteObject(pwndData->hTabBackgroundBmp); DeleteObject(pwndData->hTabBackgroundBmp);
pwndData->hTabBackgroundBmp = NULL; pwndData->hTabBackgroundBmp = NULL;
} }
if (pwndData->hthemeWindow)
{
CloseThemeData(pwndData->hthemeWindow);
pwndData->hthemeWindow = NULL;
}
if (pwndData->hthemeScrollbar)
{
CloseThemeData(pwndData->hthemeScrollbar);
pwndData->hthemeScrollbar = NULL;
}
} }
case WM_NCCREATE: case WM_NCCREATE:
{ {
@ -306,8 +365,12 @@ HRESULT GetDiaogTextureBrush(HTHEME theme, HWND hwnd, HDC hdc, HBRUSH* result, B
HBITMAP hbmp; HBITMAP hbmp;
RECT dummy, bmpRect; RECT dummy, bmpRect;
BOOL hasImageAlpha; BOOL hasImageAlpha;
HRESULT hr;
hr = UXTHEME_LoadImage(theme, 0, TABP_BODY, 0, &dummy, FALSE, &hbmp, &bmpRect, &hasImageAlpha);
if (FAILED(hr))
return hr;
UXTHEME_LoadImage(theme, 0, TABP_BODY, 0, &dummy, FALSE, &hbmp, &bmpRect, &hasImageAlpha);
if (changeOrigin) if (changeOrigin)
{ {
/* Unfortunately SetBrushOrgEx doesn't work at all */ /* Unfortunately SetBrushOrgEx doesn't work at all */

View file

@ -136,6 +136,9 @@ enum SCROLL_HITTEST
/* The window context stores data for the window needed through the life of the window */ /* The window context stores data for the window needed through the life of the window */
typedef struct _WND_DATA typedef struct _WND_DATA
{ {
HTHEME hthemeWindow;
HTHEME hthemeScrollbar;
UINT lastHitTest; UINT lastHitTest;
BOOL HasAppDefinedRgn; BOOL HasAppDefinedRgn;
BOOL HasThemeRgn; BOOL HasThemeRgn;
@ -229,6 +232,8 @@ VOID NC_TrackScrollBar(HWND Wnd, WPARAM wParam, POINT Pt);
void ThemeInitDrawContext(PDRAW_CONTEXT pcontext, HWND hWnd, HRGN hRgn); void ThemeInitDrawContext(PDRAW_CONTEXT pcontext, HWND hWnd, HRGN hRgn);
void ThemeCleanupDrawContext(PDRAW_CONTEXT pcontext); void ThemeCleanupDrawContext(PDRAW_CONTEXT pcontext);
PWND_DATA ThemeGetWndData(HWND hWnd); PWND_DATA ThemeGetWndData(HWND hWnd);
HTHEME GetNCCaptionTheme(HWND hWnd, DWORD style);
HTHEME GetNCScrollbarTheme(HWND hWnd, DWORD style);
extern HINSTANCE hDllInst; extern HINSTANCE hDllInst;
extern ATOM atWindowTheme; extern ATOM atWindowTheme;