From: Giannis Adamopoulos Date: Fri, 19 May 2017 10:01:50 +0000 (+0000) Subject: [UXTHEME] Greatly reduce the number of times we open the theme data for the non clien... X-Git-Tag: ReactOS-0.4.6~674 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=94f9c1a7c1544e5975102c0ca587dcb1fefba1d5 [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 --- diff --git a/reactos/dll/win32/uxtheme/nonclient.c b/reactos/dll/win32/uxtheme/nonclient.c index b64ecd4b113..82309ad33b9 100644 --- a/reactos/dll/win32/uxtheme/nonclient.c +++ b/reactos/dll/win32/uxtheme/nonclient.c @@ -173,8 +173,8 @@ ThemeInitDrawContext(PDRAW_CONTEXT pcontext, GetWindowInfo(hWnd, &pcontext->wi); pcontext->hWnd = hWnd; pcontext->Active = IsWindowActive(hWnd, pcontext->wi.dwExStyle); - pcontext->theme = MSSTYLES_OpenThemeClass(ActiveThemeFile, NULL, L"WINDOW"); - pcontext->scrolltheme = MSSTYLES_OpenThemeClass(ActiveThemeFile, NULL, L"SCROLLBAR"); + pcontext->theme = GetNCCaptionTheme(hWnd, pcontext->wi.dwStyle); + pcontext->scrolltheme = GetNCScrollbarTheme(hWnd, pcontext->wi.dwStyle); pcontext->CaptionHeight = pcontext->wi.cyWindowBorders; 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); - CloseThemeData (pcontext->theme); - CloseThemeData (pcontext->scrolltheme); - if(pcontext->hRgn != NULL) { DeleteObject(pcontext->hRgn); @@ -1115,7 +1112,10 @@ HRESULT WINAPI DrawNCPreview(HDC hDC, /* Paint the window on the preview hDC */ rcCurrent = context.wi.rcWindow; ThemePaintWindow(&context, &rcCurrent, FALSE); + context.hDC = NULL; + CloseThemeData (context.theme); + CloseThemeData (context.scrolltheme); ThemeCleanupDrawContext(&context); /* Cleanup */ diff --git a/reactos/dll/win32/uxtheme/system.c b/reactos/dll/win32/uxtheme/system.c index 393778f3f2a..702f81b2fdf 100644 --- a/reactos/dll/win32/uxtheme/system.c +++ b/reactos/dll/win32/uxtheme/system.c @@ -724,9 +724,6 @@ OpenThemeDataInternal(PTHEME_FILE ThemeFile, HWND hwnd, LPCWSTR pszClassList, DW return NULL; } - if(flags) - FIXME("unhandled flags: %x\n", flags); - if (ThemeFile) { 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)) { - SetPropW(hwnd, (LPCWSTR)MAKEINTATOM(atWindowTheme), hTheme); + if ((flags & OTD_NONCLIENT) == 0) + { + SetPropW(hwnd, (LPCWSTR)MAKEINTATOM(atWindowTheme), hTheme); + } } else { diff --git a/reactos/dll/win32/uxtheme/themehooks.c b/reactos/dll/win32/uxtheme/themehooks.c index 65606485d31..a7b446941a1 100644 --- a/reactos/dll/win32/uxtheme/themehooks.c +++ b/reactos/dll/win32/uxtheme/themehooks.c @@ -63,13 +63,21 @@ void ThemeDestroyWndData(HWND hWnd) CloseThemeData(GetWindowTheme(hWnd)); DeleteObject(pwndData->hTabBackgroundBrush); - pwndData->hTabBackgroundBrush = NULL; } if (pwndData->hTabBackgroundBmp != NULL) { DeleteObject(pwndData->hTabBackgroundBmp); - pwndData->hTabBackgroundBmp = NULL; + } + + if (pwndData->hthemeWindow) + { + CloseThemeData(pwndData->hthemeWindow); + } + + if (pwndData->hthemeScrollbar) + { + CloseThemeData(pwndData->hthemeScrollbar); } HeapFree(GetProcessHeap(), 0, pwndData); @@ -77,6 +85,46 @@ void ThemeDestroyWndData(HWND hWnd) 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) { ThemeDestroyWndData(hWnd); @@ -130,9 +178,8 @@ void SetThemeRegion(HWND hWnd) rcWindow.top = 0; rcWindow.left = 0; - hTheme = MSSTYLES_OpenThemeClass(ActiveThemeFile, NULL, L"WINDOW"); + hTheme = GetNCCaptionTheme(hWnd, wi.dwStyle); GetThemeBackgroundRegion(hTheme, 0, iPart, FS_ACTIVE, &rcWindow, &hrgn); - CloseThemeData(hTheme); GetWindowRect(hWnd, &rcWindow); rcWindow.right -= rcWindow.left; @@ -260,6 +307,18 @@ ThemePreWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam, ULONG_PTR DeleteObject(pwndData->hTabBackgroundBmp); pwndData->hTabBackgroundBmp = NULL; } + + if (pwndData->hthemeWindow) + { + CloseThemeData(pwndData->hthemeWindow); + pwndData->hthemeWindow = NULL; + } + + if (pwndData->hthemeScrollbar) + { + CloseThemeData(pwndData->hthemeScrollbar); + pwndData->hthemeScrollbar = NULL; + } } case WM_NCCREATE: { @@ -306,8 +365,12 @@ HRESULT GetDiaogTextureBrush(HTHEME theme, HWND hwnd, HDC hdc, HBRUSH* result, B HBITMAP hbmp; RECT dummy, bmpRect; 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) { /* Unfortunately SetBrushOrgEx doesn't work at all */ diff --git a/reactos/dll/win32/uxtheme/uxthemep.h b/reactos/dll/win32/uxtheme/uxthemep.h index 08a57cb87fc..97b336357c6 100644 --- a/reactos/dll/win32/uxtheme/uxthemep.h +++ b/reactos/dll/win32/uxtheme/uxthemep.h @@ -136,6 +136,9 @@ enum SCROLL_HITTEST /* The window context stores data for the window needed through the life of the window */ typedef struct _WND_DATA { + HTHEME hthemeWindow; + HTHEME hthemeScrollbar; + UINT lastHitTest; BOOL HasAppDefinedRgn; 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 ThemeCleanupDrawContext(PDRAW_CONTEXT pcontext); PWND_DATA ThemeGetWndData(HWND hWnd); +HTHEME GetNCCaptionTheme(HWND hWnd, DWORD style); +HTHEME GetNCScrollbarTheme(HWND hWnd, DWORD style); extern HINSTANCE hDllInst; extern ATOM atWindowTheme;