2005-09-05 20:25:16 +00:00
|
|
|
/*
|
|
|
|
* Theming - Initialization
|
|
|
|
*
|
|
|
|
* Copyright (c) 2005 by Frank Richter
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library; if not, write to the Free Software
|
2006-07-04 19:27:14 +00:00
|
|
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
2005-09-05 20:25:16 +00:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2018-04-04 13:39:21 +00:00
|
|
|
#include <stdarg.h>
|
|
|
|
|
|
|
|
#include "windef.h"
|
|
|
|
#include "winbase.h"
|
|
|
|
#include "wingdi.h"
|
|
|
|
#include "winuser.h"
|
2005-09-05 20:25:16 +00:00
|
|
|
#include "comctl32.h"
|
2018-04-04 13:39:21 +00:00
|
|
|
#include "uxtheme.h"
|
|
|
|
#include "wine/debug.h"
|
2005-09-05 20:25:16 +00:00
|
|
|
|
|
|
|
WINE_DEFAULT_DEBUG_CHANNEL(theming);
|
|
|
|
|
|
|
|
typedef LRESULT (CALLBACK* THEMING_SUBCLASSPROC)(HWND, UINT, WPARAM, LPARAM,
|
|
|
|
ULONG_PTR);
|
|
|
|
|
2017-06-04 12:53:17 +00:00
|
|
|
#ifndef __REACTOS__ /* r73803 */
|
|
|
|
extern LRESULT CALLBACK THEMING_DialogSubclassProc (HWND, UINT, WPARAM, LPARAM,
|
|
|
|
ULONG_PTR) DECLSPEC_HIDDEN;
|
|
|
|
#endif
|
2015-03-19 12:07:32 +00:00
|
|
|
extern LRESULT CALLBACK THEMING_ScrollbarSubclassProc (HWND, UINT, WPARAM, LPARAM,
|
|
|
|
ULONG_PTR) DECLSPEC_HIDDEN;
|
2005-09-05 20:25:16 +00:00
|
|
|
|
2017-12-07 23:06:13 +00:00
|
|
|
#ifndef __REACTOS__
|
2005-09-05 20:25:16 +00:00
|
|
|
static const WCHAR dialogClass[] = {'#','3','2','7','7','0',0};
|
2017-12-07 23:06:13 +00:00
|
|
|
#endif
|
2005-09-05 20:25:16 +00:00
|
|
|
|
|
|
|
static const struct ThemingSubclass
|
|
|
|
{
|
|
|
|
const WCHAR* className;
|
|
|
|
THEMING_SUBCLASSPROC subclassProc;
|
|
|
|
} subclasses[] = {
|
|
|
|
/* Note: list must be sorted by class name */
|
2017-06-04 12:53:17 +00:00
|
|
|
#ifndef __REACTOS__ /* r73803 & r73871 */
|
|
|
|
{dialogClass, THEMING_DialogSubclassProc},
|
|
|
|
#endif
|
2015-03-19 12:07:32 +00:00
|
|
|
{WC_SCROLLBARW, THEMING_ScrollbarSubclassProc}
|
2005-09-05 20:25:16 +00:00
|
|
|
};
|
|
|
|
|
2018-04-04 13:39:21 +00:00
|
|
|
#define NUM_SUBCLASSES (ARRAY_SIZE(subclasses))
|
2005-09-05 20:25:16 +00:00
|
|
|
|
|
|
|
static WNDPROC originalProcs[NUM_SUBCLASSES];
|
|
|
|
static ATOM atRefDataProp;
|
|
|
|
static ATOM atSubclassProp;
|
|
|
|
|
|
|
|
/* Generate a number of subclass window procs.
|
|
|
|
* With a single proc alone, we can't really reliably find out the superclass,
|
|
|
|
* so have one for each subclass. The subclass number is also stored in a prop
|
2007-12-01 18:28:50 +00:00
|
|
|
* since it's needed by THEMING_CallOriginalClass(). Then, the subclass
|
2005-09-05 20:25:16 +00:00
|
|
|
* proc and ref data are fetched and the proc called.
|
|
|
|
*/
|
|
|
|
#define MAKE_SUBCLASS_PROC(N) \
|
|
|
|
static LRESULT CALLBACK subclass_proc ## N (HWND wnd, UINT msg, \
|
|
|
|
WPARAM wParam, LPARAM lParam) \
|
|
|
|
{ \
|
|
|
|
LRESULT result; \
|
|
|
|
ULONG_PTR refData; \
|
2006-11-23 15:49:53 +00:00
|
|
|
SetPropW (wnd, (LPCWSTR)MAKEINTATOM(atSubclassProp), (HANDLE)N); \
|
|
|
|
refData = (ULONG_PTR)GetPropW (wnd, (LPCWSTR)MAKEINTATOM(atRefDataProp)); \
|
2007-07-27 09:21:42 +00:00
|
|
|
TRACE ("%d; (%p, %x, %lx, %lx, %lx)\n", N, wnd, msg, wParam, lParam, \
|
2005-09-05 20:25:16 +00:00
|
|
|
refData); \
|
|
|
|
result = subclasses[N].subclassProc (wnd, msg, wParam, lParam, refData);\
|
|
|
|
TRACE ("result = %lx\n", result); \
|
|
|
|
return result; \
|
|
|
|
}
|
|
|
|
|
|
|
|
MAKE_SUBCLASS_PROC(0)
|
2018-04-04 13:39:21 +00:00
|
|
|
#ifndef __REACTOS__
|
2005-09-05 20:25:16 +00:00
|
|
|
MAKE_SUBCLASS_PROC(1)
|
2017-06-04 12:53:17 +00:00
|
|
|
#endif
|
2005-09-05 20:25:16 +00:00
|
|
|
|
2005-10-27 19:01:29 +00:00
|
|
|
static const WNDPROC subclassProcs[NUM_SUBCLASSES] = {
|
2005-09-05 20:25:16 +00:00
|
|
|
subclass_proc0,
|
2018-04-04 13:39:21 +00:00
|
|
|
#ifndef __REACTOS__
|
2005-09-05 20:25:16 +00:00
|
|
|
subclass_proc1,
|
2017-06-04 12:53:17 +00:00
|
|
|
#endif
|
2005-09-05 20:25:16 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* THEMING_Initialize
|
|
|
|
*
|
|
|
|
* Register classes for standard controls that will shadow the system
|
|
|
|
* classes.
|
|
|
|
*/
|
2017-06-04 12:53:17 +00:00
|
|
|
#ifdef __REACTOS__ /* r73803 */
|
|
|
|
void THEMING_Initialize(HANDLE hActCtx5, HANDLE hActCtx6)
|
|
|
|
#else
|
|
|
|
void THEMING_Initialize (void)
|
|
|
|
#endif
|
2005-09-05 20:25:16 +00:00
|
|
|
{
|
2009-01-17 16:43:06 +00:00
|
|
|
unsigned int i;
|
2007-12-01 18:28:50 +00:00
|
|
|
static const WCHAR subclassPropName[] =
|
2005-09-05 20:25:16 +00:00
|
|
|
{ 'C','C','3','2','T','h','e','m','i','n','g','S','u','b','C','l',0 };
|
2007-12-01 18:28:50 +00:00
|
|
|
static const WCHAR refDataPropName[] =
|
2005-09-05 20:25:16 +00:00
|
|
|
{ 'C','C','3','2','T','h','e','m','i','n','g','D','a','t','a',0 };
|
2017-06-04 12:53:17 +00:00
|
|
|
#ifdef __REACTOS__ /* r73803 */
|
2017-02-17 10:04:24 +00:00
|
|
|
ULONG_PTR ulCookie;
|
|
|
|
BOOL ret, bActivated;
|
2017-06-04 12:53:17 +00:00
|
|
|
#else
|
|
|
|
if (!IsThemeActive()) return;
|
|
|
|
#endif
|
2011-09-26 19:36:01 +00:00
|
|
|
|
2005-09-05 20:25:16 +00:00
|
|
|
atSubclassProp = GlobalAddAtomW (subclassPropName);
|
|
|
|
atRefDataProp = GlobalAddAtomW (refDataPropName);
|
|
|
|
|
|
|
|
for (i = 0; i < NUM_SUBCLASSES; i++)
|
|
|
|
{
|
|
|
|
WNDCLASSEXW class;
|
|
|
|
|
|
|
|
class.cbSize = sizeof(class);
|
2017-02-17 10:04:24 +00:00
|
|
|
|
2017-06-04 12:53:17 +00:00
|
|
|
#ifdef __REACTOS__ /* r73803 */
|
2017-02-17 10:04:24 +00:00
|
|
|
bActivated = ActivateActCtx(hActCtx5, &ulCookie);
|
|
|
|
ret = GetClassInfoExW (NULL, subclasses[i].className, &class);
|
|
|
|
if (bActivated)
|
|
|
|
DeactivateActCtx(0, ulCookie);
|
|
|
|
|
|
|
|
if (!ret)
|
2017-06-04 12:53:17 +00:00
|
|
|
#else
|
|
|
|
if (!GetClassInfoExW (NULL, subclasses[i].className, &class))
|
|
|
|
#endif
|
2012-02-13 16:34:02 +00:00
|
|
|
{
|
|
|
|
ERR("Could not retrieve information for class %s\n",
|
|
|
|
debugstr_w (subclasses[i].className));
|
|
|
|
continue;
|
|
|
|
}
|
2005-09-05 20:25:16 +00:00
|
|
|
originalProcs[i] = class.lpfnWndProc;
|
|
|
|
class.lpfnWndProc = subclassProcs[i];
|
2017-06-04 12:53:17 +00:00
|
|
|
#ifdef __REACTOS__ /* r73803 */
|
2017-02-17 10:04:24 +00:00
|
|
|
class.style |= CS_GLOBALCLASS;
|
|
|
|
class.hInstance = COMCTL32_hModule;
|
2017-06-04 12:53:17 +00:00
|
|
|
#endif
|
|
|
|
|
2005-09-05 20:25:16 +00:00
|
|
|
if (!class.lpfnWndProc)
|
|
|
|
{
|
2007-12-01 18:28:50 +00:00
|
|
|
ERR("Missing proc for class %s\n",
|
2005-09-05 20:25:16 +00:00
|
|
|
debugstr_w (subclasses[i].className));
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2017-06-04 12:53:17 +00:00
|
|
|
#ifdef __REACTOS__ /* r73803 */
|
2017-02-17 10:04:24 +00:00
|
|
|
bActivated = ActivateActCtx(hActCtx6, &ulCookie);
|
2017-06-04 12:53:17 +00:00
|
|
|
#endif
|
2005-09-05 20:25:16 +00:00
|
|
|
if (!RegisterClassExW (&class))
|
|
|
|
{
|
2017-06-04 12:53:17 +00:00
|
|
|
#ifdef __REACTOS__ /* r73803 */
|
2017-02-17 10:04:24 +00:00
|
|
|
WARN("Could not re-register class %s: %x\n",
|
2017-06-04 12:53:17 +00:00
|
|
|
#else
|
|
|
|
ERR("Could not re-register class %s: %x\n",
|
|
|
|
#endif
|
2005-09-05 20:25:16 +00:00
|
|
|
debugstr_w (subclasses[i].className), GetLastError ());
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2007-12-01 18:28:50 +00:00
|
|
|
TRACE("Re-registered class %s\n",
|
2005-09-05 20:25:16 +00:00
|
|
|
debugstr_w (subclasses[i].className));
|
|
|
|
}
|
2017-02-17 10:04:24 +00:00
|
|
|
|
2017-06-04 12:53:17 +00:00
|
|
|
#ifdef __REACTOS__ /* r73803 */
|
2017-02-17 10:04:24 +00:00
|
|
|
if (bActivated)
|
|
|
|
DeactivateActCtx(0, ulCookie);
|
2017-06-04 12:53:17 +00:00
|
|
|
#endif
|
2005-09-05 20:25:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Sync to Wine-20050930:
Michael Jung <mjung@iss.tu-darmstadt.de>
- Fixed inconsistency in LISTVIEW_DUMP macro.
Robert Shearman <rob@codeweavers.com>
- Add support for navigating a toolbar with the arrow keys.
- Fix WrapToolbar in the case of no parent window.
- Use the newly added NMTBINITCUSTOMIZE for sending the
TBN_INITCUSTOMIZE so that it is safe on 64-bit platforms.
Aric Stewart <aric@codeweavers.com>
- Reading the MRUlist using the W functions we need to divide the size
by sizeof(WCHAR) to get the count of characters.
Alexandre Julliard <julliard@winehq.org>
- Specify 64-bit integers as double instead of long long in spec files
so that we get the correct number of arguments.
- We are no longer generating .dbg.c files.
Milko Krachounov <milko@3mhz.net>
- Bulgarian resources for mpr, msi, user, commdlg, oleaut32, shdocvw,
shell32, comctl32, msrle32, mshtml, winspool, wineps, serialui,
setupapi, wininet, regedit, uninstaller, notepad, winecfg and
winhelp.
Dmitry Timoshkov <dmitry@codeweavers.com>
- Call SetDIBits with a proper DC in order to set bitmap bits.
Mike McCormack <mike@codeweavers.com>
- Fix if's that are followed by semicolons.
Alexander N. Sørnes <alex@thehandofagony.com>
- Added Norwegian translation of comctl32 and shell32.
Marcus Meissner <marcus@jet.franken.de>
- The last argument to MultiByteToWideChar is wide character count and
not the buffer size in bytes. Fixed all places where it was wrong.
Frank Richter <frank.richter@gmail.com>
- Unregister theming subclasses at comctl32 shutdown; should fix
reported re-registration errors.
Jason Edmeades <us@edmeades.me.uk>
- Fix some off by one calculations in the comboboxex functions, and
handle an out of range positive index the same as windows + unit test
case.
svn path=/trunk/; revision=18329
2005-10-08 13:20:03 +00:00
|
|
|
/***********************************************************************
|
|
|
|
* THEMING_Uninitialize
|
|
|
|
*
|
|
|
|
* Unregister shadow classes for standard controls.
|
|
|
|
*/
|
|
|
|
void THEMING_Uninitialize (void)
|
|
|
|
{
|
2009-01-17 16:43:06 +00:00
|
|
|
unsigned int i;
|
2005-10-27 19:01:29 +00:00
|
|
|
|
|
|
|
if (!atSubclassProp) return; /* not initialized */
|
|
|
|
|
Sync to Wine-20050930:
Michael Jung <mjung@iss.tu-darmstadt.de>
- Fixed inconsistency in LISTVIEW_DUMP macro.
Robert Shearman <rob@codeweavers.com>
- Add support for navigating a toolbar with the arrow keys.
- Fix WrapToolbar in the case of no parent window.
- Use the newly added NMTBINITCUSTOMIZE for sending the
TBN_INITCUSTOMIZE so that it is safe on 64-bit platforms.
Aric Stewart <aric@codeweavers.com>
- Reading the MRUlist using the W functions we need to divide the size
by sizeof(WCHAR) to get the count of characters.
Alexandre Julliard <julliard@winehq.org>
- Specify 64-bit integers as double instead of long long in spec files
so that we get the correct number of arguments.
- We are no longer generating .dbg.c files.
Milko Krachounov <milko@3mhz.net>
- Bulgarian resources for mpr, msi, user, commdlg, oleaut32, shdocvw,
shell32, comctl32, msrle32, mshtml, winspool, wineps, serialui,
setupapi, wininet, regedit, uninstaller, notepad, winecfg and
winhelp.
Dmitry Timoshkov <dmitry@codeweavers.com>
- Call SetDIBits with a proper DC in order to set bitmap bits.
Mike McCormack <mike@codeweavers.com>
- Fix if's that are followed by semicolons.
Alexander N. Sørnes <alex@thehandofagony.com>
- Added Norwegian translation of comctl32 and shell32.
Marcus Meissner <marcus@jet.franken.de>
- The last argument to MultiByteToWideChar is wide character count and
not the buffer size in bytes. Fixed all places where it was wrong.
Frank Richter <frank.richter@gmail.com>
- Unregister theming subclasses at comctl32 shutdown; should fix
reported re-registration errors.
Jason Edmeades <us@edmeades.me.uk>
- Fix some off by one calculations in the comboboxex functions, and
handle an out of range positive index the same as windows + unit test
case.
svn path=/trunk/; revision=18329
2005-10-08 13:20:03 +00:00
|
|
|
for (i = 0; i < NUM_SUBCLASSES; i++)
|
|
|
|
{
|
|
|
|
UnregisterClassW (subclasses[i].className, NULL);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-09-05 20:25:16 +00:00
|
|
|
/***********************************************************************
|
|
|
|
* THEMING_CallOriginalClass
|
|
|
|
*
|
|
|
|
* Determines the original window proc and calls it.
|
|
|
|
*/
|
|
|
|
LRESULT THEMING_CallOriginalClass (HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
|
|
{
|
2006-11-23 15:49:53 +00:00
|
|
|
INT_PTR subclass = (INT_PTR)GetPropW (wnd, (LPCWSTR)MAKEINTATOM(atSubclassProp));
|
2005-09-05 20:25:16 +00:00
|
|
|
WNDPROC oldProc = originalProcs[subclass];
|
|
|
|
return CallWindowProcW (oldProc, wnd, msg, wParam, lParam);
|
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* THEMING_SetSubclassData
|
|
|
|
*
|
|
|
|
* Update the "refData" value of the subclassed window.
|
|
|
|
*/
|
|
|
|
void THEMING_SetSubclassData (HWND wnd, ULONG_PTR refData)
|
|
|
|
{
|
2006-11-23 15:49:53 +00:00
|
|
|
SetPropW (wnd, (LPCWSTR)MAKEINTATOM(atRefDataProp), (HANDLE)refData);
|
2005-09-05 20:25:16 +00:00
|
|
|
}
|