Determining the superclass for a window subclassed for theming doesn't

work - e.g. Delphi buttons have the classname "TButton" for which no
superclass will be found. Instead, use initial subclass window procs
that have the subclass hardcoded and store it for the "real" subclass
window proc.
This commit is contained in:
Frank Richter 2005-08-12 15:52:56 +00:00 committed by Alexandre Julliard
parent a202bacc58
commit b49c12a91e
1 changed files with 27 additions and 29 deletions

View File

@ -56,36 +56,10 @@ static ATOM atSubclassProp;
static LRESULT CALLBACK THEMING_SubclassProc (HWND wnd, UINT msg, static LRESULT CALLBACK THEMING_SubclassProc (HWND wnd, UINT msg,
WPARAM wParam, LPARAM lParam) WPARAM wParam, LPARAM lParam)
{ {
int subclass = (int)GetPropW (wnd, MAKEINTATOMW (atSubclassProp)) - 1; int subclass = (int)GetPropW (wnd, MAKEINTATOMW (atSubclassProp));
LRESULT result; LRESULT result;
ULONG_PTR refData; ULONG_PTR refData;
if (subclass == -1)
{
/* Means this is the first time this proc is called for this window.
* Determine the index of the subclass */
WCHAR className[32];
int l = 0, r = NUM_SUBCLASSES;
GetClassNameW (wnd, className, sizeof(className)/sizeof(WCHAR));
while (l < r)
{
int d, m = (l+r) / 2;
d = lstrcmpiW (className, subclasses[m].className);
if (d == 0)
{
subclass = m;
break;
}
if (d < 0)
r = m;
else
l = m + 1;
}
if (subclass == -1)
ERR("Couldn't find subclass info for %s!\n", debugstr_w (className));
SetPropW (wnd, MAKEINTATOMW (atSubclassProp), (HANDLE)(subclass + 1));
}
refData = (ULONG_PTR)GetPropW (wnd, MAKEINTATOMW (atRefDataProp)); refData = (ULONG_PTR)GetPropW (wnd, MAKEINTATOMW (atRefDataProp));
TRACE ("%d; (%p, %x, %x, %lx, %lx)", subclass, wnd, msg, wParam, lParam, TRACE ("%d; (%p, %x, %x, %lx, %lx)", subclass, wnd, msg, wParam, lParam,
@ -95,6 +69,23 @@ static LRESULT CALLBACK THEMING_SubclassProc (HWND wnd, UINT msg,
return result; return result;
} }
/* Generate a number of subclass window procs.
* With a single proc alone, we can't really reliably find out the superclass,
* hence, the first time the subclass is called, these "stubs" are used which
* just save the internal ID of the subclass.
*/
#define MAKE_SUBCLASS_STUB(N) \
static LRESULT CALLBACK subclass_stub ## N (HWND wnd, UINT msg, \
WPARAM wParam, LPARAM lParam) \
{ \
SetPropW (wnd, MAKEINTATOMW (atSubclassProp), (HANDLE)N); \
SetWindowLongPtrW (wnd, GWLP_WNDPROC, (LONG_PTR)THEMING_SubclassProc); \
return THEMING_SubclassProc (wnd, msg, wParam, lParam); \
}
const static WNDPROC subclassStubs[NUM_SUBCLASSES] = {
};
/*********************************************************************** /***********************************************************************
* THEMING_Initialize * THEMING_Initialize
* *
@ -120,7 +111,14 @@ void THEMING_Initialize (void)
class.style |= CS_GLOBALCLASS; class.style |= CS_GLOBALCLASS;
GetClassInfoExW (NULL, subclasses[i].className, &class); GetClassInfoExW (NULL, subclasses[i].className, &class);
originalProcs[i] = class.lpfnWndProc; originalProcs[i] = class.lpfnWndProc;
class.lpfnWndProc = THEMING_SubclassProc; class.lpfnWndProc = subclassStubs[i];
if (!class.lpfnWndProc)
{
ERR("Missing stub for class %s\n",
debugstr_w (subclasses[i].className));
continue;
}
if (!RegisterClassExW (&class)) if (!RegisterClassExW (&class))
{ {
@ -142,7 +140,7 @@ void THEMING_Initialize (void)
*/ */
LRESULT THEMING_CallOriginalClass (HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam) LRESULT THEMING_CallOriginalClass (HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam)
{ {
int subclass = (int)GetPropW (wnd, MAKEINTATOMW (atSubclassProp)) - 1; int subclass = (int)GetPropW (wnd, MAKEINTATOMW (atSubclassProp));
WNDPROC oldProc = originalProcs[subclass]; WNDPROC oldProc = originalProcs[subclass];
return CallWindowProcW (oldProc, wnd, msg, wParam, lParam); return CallWindowProcW (oldProc, wnd, msg, wParam, lParam);
} }