[UXTHEME] Greatly reduce the number of times we open the theme data for the non clien...
authorGiannis Adamopoulos <gadamopoulos@reactos.org>
Fri, 19 May 2017 10:01:50 +0000 (10:01 +0000)
committerGiannis Adamopoulos <gadamopoulos@reactos.org>
Fri, 19 May 2017 10:01:50 +0000 (10:01 +0000)
- 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

reactos/dll/win32/uxtheme/nonclient.c
reactos/dll/win32/uxtheme/system.c
reactos/dll/win32/uxtheme/themehooks.c
reactos/dll/win32/uxtheme/uxthemep.h

index b64ecd4..82309ad 100644 (file)
@@ -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 */
index 393778f..702f81b 100644 (file)
@@ -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
     {
index 6560648..a7b4469 100644 (file)
@@ -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 */
index 08a57cb..97b3363 100644 (file)
@@ -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;