Author: gadamopoulos
Date: Mon Aug 15 10:22:23 2011
New Revision: 53262
URL:
http://svn.reactos.org/svn/reactos?rev=53262&view=rev
Log:
[uxtheme]
- Properly disable themes when theme hooks are removed
- Add WND_CONTEXT a per window struct that will hold several theme specific information.
For now it contains only theme region related info. It will be stored as a window
property
- Implement destroying WND_CONTEXT for every window when theme hooks are removed or when
the window is destroyed
- Hook the messages that are sent to dialogs, like they are hooked for normal windows
- Hook SetWindowRgn call from user32. When an application calls it, uxtheme will stop
setting window region on its own region
- Implement setting a custom window region for windows after receiving WM_WINDOWPOSCHANGED
message using GetThemeBackgroundRegion
Modified:
branches/GSoC_2011/ThemesSupport/dll/win32/uxtheme/ncthm.h
branches/GSoC_2011/ThemesSupport/dll/win32/uxtheme/system.c
branches/GSoC_2011/ThemesSupport/dll/win32/uxtheme/themehooks.c
branches/GSoC_2011/ThemesSupport/dll/win32/uxtheme/uxthemedll.h
Modified: branches/GSoC_2011/ThemesSupport/dll/win32/uxtheme/ncthm.h
URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2011/ThemesSupport/dll/win…
==============================================================================
--- branches/GSoC_2011/ThemesSupport/dll/win32/uxtheme/ncthm.h [iso-8859-1] (original)
+++ branches/GSoC_2011/ThemesSupport/dll/win32/uxtheme/ncthm.h [iso-8859-1] Mon Aug 15
10:22:23 2011
@@ -1,3 +1,10 @@
+
+typedef struct _WND_CONTEXT
+{
+ BOOL HasAppDefinedRgn;
+ BOOL HasThemeRgn;
+ BOOL UpdatingRgn;
+} WND_CONTEXT, *PWND_CONTEXT;
typedef struct _DRAW_CONTEXT
{
@@ -91,5 +98,9 @@
void
ThemeCleanupDrawContext(PDRAW_CONTEXT pcontext);
+PWND_CONTEXT
+ThemeGetWndContext(HWND hWnd);
extern ATOM atWindowTheme;
+extern ATOM atWndContrext;
+
Modified: branches/GSoC_2011/ThemesSupport/dll/win32/uxtheme/system.c
URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2011/ThemesSupport/dll/win…
==============================================================================
--- branches/GSoC_2011/ThemesSupport/dll/win32/uxtheme/system.c [iso-8859-1] (original)
+++ branches/GSoC_2011/ThemesSupport/dll/win32/uxtheme/system.c [iso-8859-1] Mon Aug 15
10:22:23 2011
@@ -34,6 +34,7 @@
#include "uxthemedll.h"
#include "msstyles.h"
+#include "ncthm.h"
#include "wine/debug.h"
@@ -64,6 +65,7 @@
ATOM atWindowTheme;
static ATOM atSubAppName;
static ATOM atSubIdList;
+ATOM atWndContrext;
static BOOL bThemeActive = FALSE;
static WCHAR szCurrentTheme[MAX_PATH];
@@ -148,7 +150,7 @@
*
* Set the current active theme from the registry
*/
-void UXTHEME_LoadTheme(void)
+void UXTHEME_LoadTheme(BOOL bLoad)
{
HKEY hKey;
DWORD buffsize;
@@ -156,29 +158,36 @@
WCHAR tmp[10];
PTHEME_FILE pt;
- /* Get current theme configuration */
- if(!RegOpenKeyW(HKEY_CURRENT_USER, szThemeManager, &hKey)) {
- TRACE("Loading theme config\n");
- buffsize = sizeof(tmp)/sizeof(tmp[0]);
- if(!RegQueryValueExW(hKey, szThemeActive, NULL, NULL, (LPBYTE)tmp,
&buffsize)) {
- bThemeActive = (tmp[0] != '0');
+ if(bLoad == TRUE)
+ {
+ /* Get current theme configuration */
+ if(!RegOpenKeyW(HKEY_CURRENT_USER, szThemeManager, &hKey)) {
+ TRACE("Loading theme config\n");
+ buffsize = sizeof(tmp)/sizeof(tmp[0]);
+ if(!RegQueryValueExW(hKey, szThemeActive, NULL, NULL, (LPBYTE)tmp,
&buffsize)) {
+ bThemeActive = (tmp[0] != '0');
+ }
+ else {
+ bThemeActive = FALSE;
+ TRACE("Failed to get ThemeActive: %d\n", GetLastError());
+ }
+ buffsize = sizeof(szCurrentColor)/sizeof(szCurrentColor[0]);
+ if(RegQueryValueExW(hKey, szColorName, NULL, NULL, (LPBYTE)szCurrentColor,
&buffsize))
+ szCurrentColor[0] = '\0';
+ buffsize = sizeof(szCurrentSize)/sizeof(szCurrentSize[0]);
+ if(RegQueryValueExW(hKey, szSizeName, NULL, NULL, (LPBYTE)szCurrentSize,
&buffsize))
+ szCurrentSize[0] = '\0';
+ if (query_reg_path (hKey, szDllName, szCurrentTheme))
+ szCurrentTheme[0] = '\0';
+ RegCloseKey(hKey);
}
- else {
- bThemeActive = FALSE;
- TRACE("Failed to get ThemeActive: %d\n", GetLastError());
- }
- buffsize = sizeof(szCurrentColor)/sizeof(szCurrentColor[0]);
- if(RegQueryValueExW(hKey, szColorName, NULL, NULL, (LPBYTE)szCurrentColor,
&buffsize))
- szCurrentColor[0] = '\0';
- buffsize = sizeof(szCurrentSize)/sizeof(szCurrentSize[0]);
- if(RegQueryValueExW(hKey, szSizeName, NULL, NULL, (LPBYTE)szCurrentSize,
&buffsize))
- szCurrentSize[0] = '\0';
- if (query_reg_path (hKey, szDllName, szCurrentTheme))
- szCurrentTheme[0] = '\0';
- RegCloseKey(hKey);
+ else
+ TRACE("Failed to open theme registry key\n");
}
else
- TRACE("Failed to open theme registry key\n");
+ {
+ bThemeActive = FALSE;
+ }
if(bThemeActive) {
/* Make sure the theme requested is actually valid */
@@ -542,6 +551,7 @@
atSubAppName = GlobalAddAtomW(szSubAppName);
atSubIdList = GlobalAddAtomW(szSubIdList);
atDialogThemeEnabled = GlobalAddAtomW(szDialogThemeEnabled);
+ atWndContrext = GlobalAddAtomW(L"ux_WndContext");
}
/***********************************************************************
Modified: branches/GSoC_2011/ThemesSupport/dll/win32/uxtheme/themehooks.c
URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2011/ThemesSupport/dll/win…
==============================================================================
--- branches/GSoC_2011/ThemesSupport/dll/win32/uxtheme/themehooks.c [iso-8859-1]
(original)
+++ branches/GSoC_2011/ThemesSupport/dll/win32/uxtheme/themehooks.c [iso-8859-1] Mon Aug
15 10:22:23 2011
@@ -12,6 +12,9 @@
#include "vfwmsgs.h"
#include "uxtheme.h"
#include "uxthemedll.h"
+#include "ncthm.h"
+#include "tmschema.h"
+
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(uxtheme);
@@ -25,6 +28,163 @@
USERAPIHOOK user32ApiHook;
BYTE gabDWPmessages[UAHOWP_MAX_SIZE];
BYTE gabMSGPmessages[UAHOWP_MAX_SIZE];
+
+
+PWND_CONTEXT ThemeGetWndContext(HWND hWnd)
+{
+ PWND_CONTEXT pcontext;
+
+ pcontext = (PWND_CONTEXT)GetPropW(hWnd, (LPCWSTR)MAKEINTATOM(atWndContrext));
+ if(pcontext == NULL)
+ {
+ pcontext = HeapAlloc(GetProcessHeap(),
+ HEAP_ZERO_MEMORY,
+ sizeof(WND_CONTEXT));
+ if(pcontext == NULL)
+ {
+ return NULL;
+ }
+
+ SetPropW( hWnd, (LPCWSTR)MAKEINTATOM(atWndContrext), pcontext);
+ }
+
+ return pcontext;
+}
+
+void ThemeDetroyWndContext(HWND hWnd)
+{
+ PWND_CONTEXT pContext;
+ DWORD ProcessId;
+
+ /*Do not destroy WND_CONTEXT of a window that belong to another process */
+ GetWindowThreadProcessId(hWnd, &ProcessId);
+ if(ProcessId != GetCurrentProcessId())
+ {
+ return;
+ }
+
+ pContext = (PWND_CONTEXT)GetPropW(hWnd, (LPCWSTR)MAKEINTATOM(atWndContrext));
+ if(pContext == NULL)
+ {
+ return;
+ }
+
+ if(pContext->HasThemeRgn)
+ {
+ user32ApiHook.SetWindowRgn(hWnd, 0, TRUE);
+ }
+
+ HeapFree(GetProcessHeap(), 0, pContext);
+
+ SetPropW( hWnd, (LPCWSTR)MAKEINTATOM(atWndContrext), NULL);
+}
+
+static BOOL CALLBACK ThemeCleanupChildWndContext (HWND hWnd, LPARAM msg)
+{
+ ThemeDetroyWndContext(hWnd);
+ return TRUE;
+}
+
+static BOOL CALLBACK ThemeCleanupWndContext(HWND hWnd, LPARAM msg)
+{
+ if (hWnd == NULL)
+ {
+ EnumWindows (ThemeCleanupWndContext, 0);
+ }
+ else
+ {
+ ThemeDetroyWndContext(hWnd);
+ EnumChildWindows (hWnd, ThemeCleanupChildWndContext, 0);
+ }
+
+ return TRUE;
+}
+
+void SetThemeRegion(HWND hWnd, PWND_CONTEXT pcontext)
+{
+ HTHEME hTheme;
+ RECT rcWindow;
+ HRGN hrgn, hrgn1;
+ int CaptionHeight, iPart;
+ WINDOWINFO wi;
+
+ if(!IsAppThemed())
+ {
+ if(pcontext->HasThemeRgn)
+ {
+ pcontext->HasThemeRgn = FALSE;
+ user32ApiHook.SetWindowRgn(hWnd, 0, TRUE);
+ }
+ return;
+ }
+
+ wi.cbSize = sizeof(wi);
+
+ GetWindowInfo(hWnd, &wi);
+
+ if((wi.dwStyle & WS_CAPTION)!=WS_CAPTION)
+ {
+ return;
+ }
+
+ /* Get the caption part id */
+ if (wi.dwExStyle & WS_EX_TOOLWINDOW)
+ iPart = WP_SMALLCAPTION;
+ else if (wi.dwStyle & WS_MAXIMIZE)
+ iPart = WP_MAXCAPTION;
+ else
+ iPart = WP_CAPTION;
+
+ pcontext->HasThemeRgn = TRUE;
+
+ CaptionHeight = wi.cyWindowBorders;
+ CaptionHeight += GetSystemMetrics(wi.dwExStyle & WS_EX_TOOLWINDOW ?
SM_CYSMCAPTION : SM_CYCAPTION );
+
+ GetWindowRect(hWnd, &rcWindow);
+ rcWindow.right -= rcWindow.left;
+ rcWindow.bottom = CaptionHeight;
+ rcWindow.top = 0;
+ rcWindow.left = 0;
+
+ hTheme = OpenThemeData (hWnd, L"WINDOW");
+
+ GetThemeBackgroundRegion(hTheme, 0, iPart, FS_ACTIVE, &rcWindow, &hrgn);
+
+ CloseThemeData(hTheme);
+
+ GetWindowRect(hWnd, &rcWindow);
+ rcWindow.right -= rcWindow.left;
+ rcWindow.bottom -= rcWindow.top;
+ rcWindow.top = CaptionHeight;
+ rcWindow.left = 0;
+ hrgn1 = CreateRectRgnIndirect(&rcWindow);
+
+ CombineRgn(hrgn, hrgn, hrgn1, RGN_OR );
+
+ DeleteObject(hrgn1);
+
+ user32ApiHook.SetWindowRgn(hWnd, hrgn, TRUE);
+}
+
+int OnPostWinPosChanged(HWND hWnd)
+{
+ PWND_CONTEXT pcontext = ThemeGetWndContext(hWnd);
+
+ if(pcontext &&
+ pcontext->HasAppDefinedRgn == FALSE &&
+ pcontext->UpdatingRgn == FALSE)
+ {
+ pcontext->UpdatingRgn = TRUE;
+ SetThemeRegion(hWnd, pcontext);
+ pcontext = ThemeGetWndContext(hWnd);
+ pcontext->UpdatingRgn = FALSE;
+ }
+ return 0;
+}
+
+/**********************************************************************
+ * Hook Functions
+ */
static LRESULT CALLBACK
ThemeDefWindowProcW(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
@@ -75,12 +235,50 @@
return 0;
}
+
+static LRESULT CALLBACK
+ThemePostWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam, ULONG_PTR
ret,PDWORD unknown)
+{
+ switch(Msg)
+ {
+ case WM_WINDOWPOSCHANGED:
+ {
+ return OnPostWinPosChanged(hWnd);
+ }
+ case WM_DESTROY:
+ {
+ ThemeDetroyWndContext(hWnd);
+ return 0;
+ }
+ }
+
+ return 0;
+}
+
+int WINAPI ThemeSetWindowRgn(HWND hWnd, HRGN hRgn, BOOL bRedraw)
+{
+ PWND_CONTEXT pcontext = ThemeGetWndContext(hWnd);
+ if(pcontext)
+ {
+ pcontext->HasAppDefinedRgn = TRUE;
+ pcontext->HasThemeRgn = FALSE;
+ }
+
+ return user32ApiHook.SetWindowRgn(hWnd, hRgn, bRedraw);
+}
+
+/**********************************************************************
+ * Exports
+ */
+
BOOL CALLBACK
ThemeInitApiHook(UAPIHK State, PUSERAPIHOOK puah)
{
/* Sanity checks for the caller */
if (!puah || State != uahLoadInit)
{
+ UXTHEME_LoadTheme(FALSE);
+ ThemeCleanupWndContext(NULL, 0);
return TRUE;
}
@@ -90,10 +288,17 @@
puah->DefWindowProcA = ThemeDefWindowProcA;
puah->DefWindowProcW = ThemeDefWindowProcW;
puah->PreWndProc = ThemePreWindowProc;
+ puah->PostWndProc = ThemePostWindowProc;
+ puah->PreDefDlgProc = ThemePreWindowProc;
+ puah->PostDefDlgProc = ThemePostWindowProc;
puah->DefWndProcArray.MsgBitArray = gabDWPmessages;
puah->DefWndProcArray.Size = UAHOWP_MAX_SIZE;
puah->WndProcArray.MsgBitArray = gabMSGPmessages;
puah->WndProcArray.Size = UAHOWP_MAX_SIZE;
+ puah->DlgProcArray.MsgBitArray = gabMSGPmessages;
+ puah->DlgProcArray.Size = UAHOWP_MAX_SIZE;
+
+ puah->SetWindowRgn = ThemeSetWindowRgn;
UAH_HOOK_MESSAGE(puah->DefWndProcArray, WM_NCPAINT);
UAH_HOOK_MESSAGE(puah->DefWndProcArray, WM_NCACTIVATE);
@@ -130,7 +335,7 @@
UAH_HOOK_MESSAGE(puah->WndProcArray, WM_THEMECHANGED);
UAH_HOOK_MESSAGE(puah->WndProcArray, WM_UAHINIT);
- UXTHEME_LoadTheme();
+ UXTHEME_LoadTheme(TRUE);
return TRUE;
}
@@ -187,8 +392,7 @@
ret = UnregisterUserApiHook();
- if(IsThemeActive())
- UXTHEME_broadcast_msg (NULL, WM_THEMECHANGED);
+ UXTHEME_broadcast_msg (NULL, WM_THEMECHANGED);
return ret;
}
Modified: branches/GSoC_2011/ThemesSupport/dll/win32/uxtheme/uxthemedll.h
URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2011/ThemesSupport/dll/win…
==============================================================================
--- branches/GSoC_2011/ThemesSupport/dll/win32/uxtheme/uxthemedll.h [iso-8859-1]
(original)
+++ branches/GSoC_2011/ThemesSupport/dll/win32/uxtheme/uxthemedll.h [iso-8859-1] Mon Aug
15 10:22:23 2011
@@ -95,7 +95,7 @@
ParseThemeIniFileProc callback, LPVOID lpData);
extern void UXTHEME_InitSystem(HINSTANCE hInst);
-extern void UXTHEME_LoadTheme(void);
+extern void UXTHEME_LoadTheme(BOOL bLoad);
extern BOOL CALLBACK UXTHEME_broadcast_msg (HWND hWnd, LPARAM msg);
/* No alpha blending */