[UXTHEME] -Implement the tab background texture. NOTE: A hack was used to go around...
authorGiannis Adamopoulos <gadamopoulos@reactos.org>
Wed, 26 Apr 2017 09:28:35 +0000 (09:28 +0000)
committerGiannis Adamopoulos <gadamopoulos@reactos.org>
Wed, 26 Apr 2017 09:28:35 +0000 (09:28 +0000)
svn path=/trunk/; revision=74407

reactos/dll/win32/uxtheme/draw.c
reactos/dll/win32/uxtheme/themehooks.c
reactos/dll/win32/uxtheme/uxthemep.h

index 6bcf0b0..4db6a9c 100644 (file)
@@ -61,7 +61,7 @@ BOOL WINAPI IsThemeDialogTextureEnabled(HWND hwnd)
     dwDialogTextureFlags = HandleToUlong( GetPropW( hwnd, (LPCWSTR)MAKEINTATOM(atDialogThemeEnabled) ));
     if (dwDialogTextureFlags == 0) 
         /* Means EnableThemeDialogTexture wasn't called for this dialog */
-        return TRUE;
+        return FALSE;
 
     return (dwDialogTextureFlags & ETDT_ENABLE) && !(dwDialogTextureFlags & ETDT_DISABLE);
 }
@@ -224,7 +224,7 @@ static PTHEME_PROPERTY UXTHEME_SelectImage(HTHEME hTheme, HDC hdc, int iPartId,
  *
  * Load image for part/state
  */
-static HRESULT UXTHEME_LoadImage(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pRect, BOOL glyph,
+HRESULT UXTHEME_LoadImage(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pRect, BOOL glyph,
                           HBITMAP *hBmp, RECT *bmpRect, BOOL* hasImageAlpha)
 {
     int imagelayout = IL_HORIZONTAL;
index a327f18..5102f41 100644 (file)
@@ -11,6 +11,7 @@
 USERAPIHOOK user32ApiHook;
 BYTE gabDWPmessages[UAHOWP_MAX_SIZE];
 BYTE gabMSGPmessages[UAHOWP_MAX_SIZE];
+BYTE gabDLGPmessages[UAHOWP_MAX_SIZE];
 BOOL gbThemeHooksActive = FALSE;
 
 PWND_CONTEXT ThemeGetWndContext(HWND hWnd)
@@ -56,7 +57,19 @@ void ThemeDestroyWndContext(HWND hWnd)
     {
         user32ApiHook.SetWindowRgn(hWnd, 0, TRUE);
     }
-    
+
+    if (pContext->hTabBackgroundBrush != NULL)
+    {
+        DeleteObject(pContext->hTabBackgroundBrush);
+        pContext->hTabBackgroundBrush = NULL;
+    }
+
+    if (pContext->hTabBackgroundBmp != NULL)
+    {
+        DeleteObject(pContext->hTabBackgroundBmp);
+        pContext->hTabBackgroundBmp = NULL;
+    }
+
     HeapFree(GetProcessHeap(), 0, pContext);
 
     SetPropW( hWnd, (LPCWSTR)MAKEINTATOM(atWndContext), NULL);
@@ -225,8 +238,27 @@ ThemePreWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam, ULONG_PTR
     switch(Msg)
     {
         case WM_THEMECHANGED:
+        {
+            PWND_CONTEXT pcontext = ThemeGetWndContext(hWnd);
+
             if (GetAncestor(hWnd, GA_PARENT) == GetDesktopWindow())
                 UXTHEME_LoadTheme(TRUE);
+
+            if (pcontext == NULL)
+                return 0;
+
+            if (pcontext->hTabBackgroundBrush != NULL)
+            {
+                DeleteObject(pcontext->hTabBackgroundBrush);
+                pcontext->hTabBackgroundBrush = NULL;
+            }
+
+            if (pcontext->hTabBackgroundBmp != NULL)
+            {
+                DeleteObject(pcontext->hTabBackgroundBmp);
+                pcontext->hTabBackgroundBmp = NULL;
+            }
+        }
         case WM_NCCREATE:
         {
             PWND_CONTEXT pcontext = ThemeGetWndContext(hWnd);
@@ -259,6 +291,126 @@ ThemePostWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam, ULONG_PTR
     return 0;
 }
 
+HRESULT GetDiaogTextureBrush(HTHEME theme, HWND hwnd, HDC hdc, HBRUSH* result, BOOL changeOrigin)
+{
+    PWND_CONTEXT pcontext;
+
+    pcontext = ThemeGetWndContext(hwnd);
+    if (pcontext == NULL)
+        return E_FAIL;
+
+    if (pcontext->hTabBackgroundBrush == NULL)
+    {
+        HBITMAP hbmp;
+        RECT dummy, bmpRect;
+        BOOL hasImageAlpha;
+        //HTHEME theme = GetWindowTheme(hwnd);
+        theme = MSSTYLES_OpenThemeClass(ActiveThemeFile, NULL, L"TAB");
+        if (!theme)
+            return E_FAIL;
+
+        UXTHEME_LoadImage(theme, 0, TABP_BODY, 0, &dummy, FALSE, &hbmp, &bmpRect, &hasImageAlpha);
+        if (changeOrigin)
+        {
+            /* Unfortunately SetBrushOrgEx doesn't work at all */
+            RECT rcWindow, rcParent;
+            POINT pt;
+            HDC hdcPattern, hdcHackPattern;
+            HBITMAP hbmpOld1, hbmpold2, hbmpHack;
+
+            GetWindowRect(hwnd, &rcWindow);
+            GetWindowRect(GetParent(hwnd), &rcParent);
+            pt.x = rcWindow.left - rcParent.left;
+            pt.y = rcWindow.top - rcParent.top;
+
+            hdcPattern = CreateCompatibleDC(hdc);
+            hbmpOld1 = (HBITMAP)SelectObject(hdcPattern, hbmp);
+
+            hdcHackPattern = CreateCompatibleDC(hdc);
+            hbmpHack = CreateCompatibleBitmap(hdc, bmpRect.right, bmpRect.bottom);
+            hbmpold2 = (HBITMAP)SelectObject(hdcHackPattern, hbmpHack);
+
+            BitBlt(hdcHackPattern, 0, 0, bmpRect.right, bmpRect.bottom - pt.y, hdcPattern, 0, pt.y, SRCCOPY);
+            BitBlt(hdcHackPattern, 0, bmpRect.bottom - pt.y, bmpRect.right, pt.y, hdcPattern, 0, 0, SRCCOPY);
+
+            hbmpold2 = (HBITMAP)SelectObject(hdcHackPattern, hbmpold2);
+            hbmpOld1 = (HBITMAP)SelectObject(hdcPattern, hbmpOld1);
+
+            DeleteDC(hdcPattern);
+            DeleteDC(hdcHackPattern);
+
+            /* Keep the handle of the bitmap we created so that it can be used later */
+            pcontext->hTabBackgroundBmp = hbmpHack;
+            hbmp = hbmpHack;
+        }
+
+        /* hbmp is cached so there is no need to free it */
+        pcontext->hTabBackgroundBrush = CreatePatternBrush(hbmp);
+    }
+
+    if (!pcontext->hTabBackgroundBrush)
+        return E_FAIL;
+
+    *result = pcontext->hTabBackgroundBrush;
+    return S_OK;
+}
+
+void HackFillStaticBg(HWND hwnd, HDC hdc, HBRUSH* result)
+{
+    RECT rcStatic;
+
+    GetClientRect(hwnd, &rcStatic);
+    FillRect(hdc, &rcStatic, *result);
+
+    SetBkMode (hdc, TRANSPARENT);
+    *result = GetStockObject (NULL_BRUSH);
+}
+
+static LRESULT CALLBACK
+ThemeDlgPreWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam, ULONG_PTR ret,PDWORD unknown)
+{
+    return 0;
+}
+
+static LRESULT CALLBACK
+ThemeDlgPostWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam, ULONG_PTR ret,PDWORD unknown)
+{
+    switch(Msg)
+    {
+        case WM_CTLCOLORDLG:
+        case WM_CTLCOLORBTN:
+        case WM_CTLCOLORSTATIC:
+        {
+            HWND hwndTarget = (HWND)lParam;
+            HDC hdc = (HDC)wParam;
+            HBRUSH* phbrush = (HBRUSH*)ret;
+            HTHEME theme = GetWindowTheme ( hWnd );
+
+            if (!IsAppThemed())
+                break;
+
+            if (!IsThemeDialogTextureEnabled (hWnd))
+                break;
+
+            GetDiaogTextureBrush(theme, hwndTarget, hdc, phbrush, Msg != WM_CTLCOLORDLG);
+
+#if 1 
+            {
+                WCHAR controlClass[32];
+                GetClassNameW (hwndTarget, controlClass, sizeof(controlClass) / sizeof(controlClass[0]));
+
+                /* This is a hack for the static class. Windows have a v6 static class just for this. */
+                if (lstrcmpiW (controlClass, WC_STATICW) == 0)
+                    HackFillStaticBg(hwndTarget, hdc, phbrush);
+            }
+#endif
+            break;
+        }
+    }
+
+    return 0;
+}
+
 int WINAPI ThemeSetWindowRgn(HWND hWnd, HRGN hRgn, BOOL bRedraw)
 {
     PWND_CONTEXT pcontext = ThemeGetWndContext(hWnd);
@@ -333,8 +485,8 @@ ThemeInitApiHook(UAPIHK State, PUSERAPIHOOK puah)
     puah->DefWindowProcW = ThemeDefWindowProcW;
     puah->PreWndProc = ThemePreWindowProc;
     puah->PostWndProc = ThemePostWindowProc;
-    puah->PreDefDlgProc = ThemePreWindowProc;
-    puah->PostDefDlgProc = ThemePostWindowProc;
+    puah->PreDefDlgProc = ThemeDlgPreWindowProc;
+    puah->PostDefDlgProc = ThemeDlgPostWindowProc;
     puah->DefWndProcArray.MsgBitArray  = gabDWPmessages;
     puah->DefWndProcArray.Size = UAHOWP_MAX_SIZE;
     puah->WndProcArray.MsgBitArray = gabMSGPmessages;
@@ -380,6 +532,16 @@ ThemeInitApiHook(UAPIHK State, PUSERAPIHOOK puah)
     UAH_HOOK_MESSAGE(puah->WndProcArray, WM_THEMECHANGED);
     UAH_HOOK_MESSAGE(puah->WndProcArray, WM_UAHINIT);
 
+    puah->DlgProcArray.MsgBitArray = gabDLGPmessages;
+    puah->DlgProcArray.Size = UAHOWP_MAX_SIZE;
+
+    UAH_HOOK_MESSAGE(puah->DlgProcArray, WM_INITDIALOG);
+    UAH_HOOK_MESSAGE(puah->DlgProcArray, WM_CTLCOLORMSGBOX);
+    UAH_HOOK_MESSAGE(puah->DlgProcArray, WM_CTLCOLORBTN);
+    UAH_HOOK_MESSAGE(puah->DlgProcArray, WM_CTLCOLORDLG);
+    UAH_HOOK_MESSAGE(puah->DlgProcArray, WM_CTLCOLORSTATIC);
+    UAH_HOOK_MESSAGE(puah->DlgProcArray, WM_PRINTCLIENT);
+
     UXTHEME_LoadTheme(TRUE);
 
     return TRUE;
index ceb9b12..acdca1e 100644 (file)
@@ -85,6 +85,9 @@ typedef struct _THEME_FILE {
 
 typedef struct _UXINI_FILE *PUXINI_FILE;
 
+HRESULT UXTHEME_LoadImage(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pRect, BOOL glyph,
+                          HBITMAP *hBmp, RECT *bmpRect, BOOL* hasImageAlpha);
+
 BOOL MSSTYLES_LookupProperty(LPCWSTR pszPropertyName, int *dwPrimitive, int *dwId);
 BOOL MSSTYLES_LookupEnum(LPCWSTR pszValueName, int dwEnum, int *dwValue);
 BOOL MSSTYLES_LookupPartState(LPCWSTR pszClass, LPCWSTR pszPart, LPCWSTR pszState, int *iPartId, int *iStateId);
@@ -137,6 +140,8 @@ typedef struct _WND_CONTEXT
     BOOL HasThemeRgn;
     BOOL UpdatingRgn;
     BOOL DirtyThemeRegion;
+    HBRUSH hTabBackgroundBrush;
+    HBITMAP hTabBackgroundBmp;
 
     BOOL SCROLL_trackVertical;
     enum SCROLL_HITTEST SCROLL_trackHitTest;