mirror of
https://github.com/reactos/reactos.git
synced 2025-08-04 04:36:40 +00:00
[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 svn path=/branches/GSoC_2011/ThemesSupport/; revision=53262
This commit is contained in:
parent
5ceabc031a
commit
10bed5b061
4 changed files with 250 additions and 25 deletions
|
@ -1,4 +1,11 @@
|
||||||
|
|
||||||
|
typedef struct _WND_CONTEXT
|
||||||
|
{
|
||||||
|
BOOL HasAppDefinedRgn;
|
||||||
|
BOOL HasThemeRgn;
|
||||||
|
BOOL UpdatingRgn;
|
||||||
|
} WND_CONTEXT, *PWND_CONTEXT;
|
||||||
|
|
||||||
typedef struct _DRAW_CONTEXT
|
typedef struct _DRAW_CONTEXT
|
||||||
{
|
{
|
||||||
HWND hWnd;
|
HWND hWnd;
|
||||||
|
@ -91,5 +98,9 @@ ThemeInitDrawContext(PDRAW_CONTEXT pcontext,
|
||||||
void
|
void
|
||||||
ThemeCleanupDrawContext(PDRAW_CONTEXT pcontext);
|
ThemeCleanupDrawContext(PDRAW_CONTEXT pcontext);
|
||||||
|
|
||||||
|
PWND_CONTEXT
|
||||||
|
ThemeGetWndContext(HWND hWnd);
|
||||||
|
|
||||||
extern ATOM atWindowTheme;
|
extern ATOM atWindowTheme;
|
||||||
|
extern ATOM atWndContrext;
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
|
|
||||||
#include "uxthemedll.h"
|
#include "uxthemedll.h"
|
||||||
#include "msstyles.h"
|
#include "msstyles.h"
|
||||||
|
#include "ncthm.h"
|
||||||
|
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
|
|
||||||
|
@ -64,6 +65,7 @@ static DWORD dwThemeAppProperties = STAP_ALLOW_NONCLIENT | STAP_ALLOW_CONTROLS;
|
||||||
ATOM atWindowTheme;
|
ATOM atWindowTheme;
|
||||||
static ATOM atSubAppName;
|
static ATOM atSubAppName;
|
||||||
static ATOM atSubIdList;
|
static ATOM atSubIdList;
|
||||||
|
ATOM atWndContrext;
|
||||||
|
|
||||||
static BOOL bThemeActive = FALSE;
|
static BOOL bThemeActive = FALSE;
|
||||||
static WCHAR szCurrentTheme[MAX_PATH];
|
static WCHAR szCurrentTheme[MAX_PATH];
|
||||||
|
@ -148,7 +150,7 @@ static DWORD query_reg_path (HKEY hKey, LPCWSTR lpszValue,
|
||||||
*
|
*
|
||||||
* Set the current active theme from the registry
|
* Set the current active theme from the registry
|
||||||
*/
|
*/
|
||||||
void UXTHEME_LoadTheme(void)
|
void UXTHEME_LoadTheme(BOOL bLoad)
|
||||||
{
|
{
|
||||||
HKEY hKey;
|
HKEY hKey;
|
||||||
DWORD buffsize;
|
DWORD buffsize;
|
||||||
|
@ -156,6 +158,8 @@ void UXTHEME_LoadTheme(void)
|
||||||
WCHAR tmp[10];
|
WCHAR tmp[10];
|
||||||
PTHEME_FILE pt;
|
PTHEME_FILE pt;
|
||||||
|
|
||||||
|
if(bLoad == TRUE)
|
||||||
|
{
|
||||||
/* Get current theme configuration */
|
/* Get current theme configuration */
|
||||||
if(!RegOpenKeyW(HKEY_CURRENT_USER, szThemeManager, &hKey)) {
|
if(!RegOpenKeyW(HKEY_CURRENT_USER, szThemeManager, &hKey)) {
|
||||||
TRACE("Loading theme config\n");
|
TRACE("Loading theme config\n");
|
||||||
|
@ -179,6 +183,11 @@ void UXTHEME_LoadTheme(void)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
TRACE("Failed to open theme registry key\n");
|
TRACE("Failed to open theme registry key\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bThemeActive = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
if(bThemeActive) {
|
if(bThemeActive) {
|
||||||
/* Make sure the theme requested is actually valid */
|
/* Make sure the theme requested is actually valid */
|
||||||
|
@ -542,6 +551,7 @@ void UXTHEME_InitSystem(HINSTANCE hInst)
|
||||||
atSubAppName = GlobalAddAtomW(szSubAppName);
|
atSubAppName = GlobalAddAtomW(szSubAppName);
|
||||||
atSubIdList = GlobalAddAtomW(szSubIdList);
|
atSubIdList = GlobalAddAtomW(szSubIdList);
|
||||||
atDialogThemeEnabled = GlobalAddAtomW(szDialogThemeEnabled);
|
atDialogThemeEnabled = GlobalAddAtomW(szDialogThemeEnabled);
|
||||||
|
atWndContrext = GlobalAddAtomW(L"ux_WndContext");
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
|
|
@ -12,6 +12,9 @@
|
||||||
#include "vfwmsgs.h"
|
#include "vfwmsgs.h"
|
||||||
#include "uxtheme.h"
|
#include "uxtheme.h"
|
||||||
#include "uxthemedll.h"
|
#include "uxthemedll.h"
|
||||||
|
#include "ncthm.h"
|
||||||
|
#include "tmschema.h"
|
||||||
|
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(uxtheme);
|
WINE_DEFAULT_DEBUG_CHANNEL(uxtheme);
|
||||||
|
@ -26,6 +29,163 @@ USERAPIHOOK user32ApiHook;
|
||||||
BYTE gabDWPmessages[UAHOWP_MAX_SIZE];
|
BYTE gabDWPmessages[UAHOWP_MAX_SIZE];
|
||||||
BYTE gabMSGPmessages[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
|
static LRESULT CALLBACK
|
||||||
ThemeDefWindowProcW(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
|
ThemeDefWindowProcW(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
|
@ -75,12 +235,50 @@ ThemePreWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam, ULONG_PTR
|
||||||
return 0;
|
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
|
BOOL CALLBACK
|
||||||
ThemeInitApiHook(UAPIHK State, PUSERAPIHOOK puah)
|
ThemeInitApiHook(UAPIHK State, PUSERAPIHOOK puah)
|
||||||
{
|
{
|
||||||
/* Sanity checks for the caller */
|
/* Sanity checks for the caller */
|
||||||
if (!puah || State != uahLoadInit)
|
if (!puah || State != uahLoadInit)
|
||||||
{
|
{
|
||||||
|
UXTHEME_LoadTheme(FALSE);
|
||||||
|
ThemeCleanupWndContext(NULL, 0);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,10 +288,17 @@ ThemeInitApiHook(UAPIHK State, PUSERAPIHOOK puah)
|
||||||
puah->DefWindowProcA = ThemeDefWindowProcA;
|
puah->DefWindowProcA = ThemeDefWindowProcA;
|
||||||
puah->DefWindowProcW = ThemeDefWindowProcW;
|
puah->DefWindowProcW = ThemeDefWindowProcW;
|
||||||
puah->PreWndProc = ThemePreWindowProc;
|
puah->PreWndProc = ThemePreWindowProc;
|
||||||
|
puah->PostWndProc = ThemePostWindowProc;
|
||||||
|
puah->PreDefDlgProc = ThemePreWindowProc;
|
||||||
|
puah->PostDefDlgProc = ThemePostWindowProc;
|
||||||
puah->DefWndProcArray.MsgBitArray = gabDWPmessages;
|
puah->DefWndProcArray.MsgBitArray = gabDWPmessages;
|
||||||
puah->DefWndProcArray.Size = UAHOWP_MAX_SIZE;
|
puah->DefWndProcArray.Size = UAHOWP_MAX_SIZE;
|
||||||
puah->WndProcArray.MsgBitArray = gabMSGPmessages;
|
puah->WndProcArray.MsgBitArray = gabMSGPmessages;
|
||||||
puah->WndProcArray.Size = UAHOWP_MAX_SIZE;
|
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_NCPAINT);
|
||||||
UAH_HOOK_MESSAGE(puah->DefWndProcArray, WM_NCACTIVATE);
|
UAH_HOOK_MESSAGE(puah->DefWndProcArray, WM_NCACTIVATE);
|
||||||
|
@ -130,7 +335,7 @@ ThemeInitApiHook(UAPIHK State, PUSERAPIHOOK puah)
|
||||||
UAH_HOOK_MESSAGE(puah->WndProcArray, WM_THEMECHANGED);
|
UAH_HOOK_MESSAGE(puah->WndProcArray, WM_THEMECHANGED);
|
||||||
UAH_HOOK_MESSAGE(puah->WndProcArray, WM_UAHINIT);
|
UAH_HOOK_MESSAGE(puah->WndProcArray, WM_UAHINIT);
|
||||||
|
|
||||||
UXTHEME_LoadTheme();
|
UXTHEME_LoadTheme(TRUE);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -187,7 +392,6 @@ ThemeHooksRemove()
|
||||||
|
|
||||||
ret = UnregisterUserApiHook();
|
ret = UnregisterUserApiHook();
|
||||||
|
|
||||||
if(IsThemeActive())
|
|
||||||
UXTHEME_broadcast_msg (NULL, WM_THEMECHANGED);
|
UXTHEME_broadcast_msg (NULL, WM_THEMECHANGED);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -95,7 +95,7 @@ HRESULT WINAPI ParseThemeIniFile(LPCWSTR pszIniFileName, LPWSTR pszUnknown,
|
||||||
ParseThemeIniFileProc callback, LPVOID lpData);
|
ParseThemeIniFileProc callback, LPVOID lpData);
|
||||||
|
|
||||||
extern void UXTHEME_InitSystem(HINSTANCE hInst);
|
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);
|
extern BOOL CALLBACK UXTHEME_broadcast_msg (HWND hWnd, LPARAM msg);
|
||||||
|
|
||||||
/* No alpha blending */
|
/* No alpha blending */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue