- Let the subclassing stack grow the opposite way to make the code
more transparent. - Remove SubclassWndProc and move its logic to DefSubclassProc.
This commit is contained in:
parent
56b5164686
commit
c8aba95f50
@ -154,7 +154,7 @@ typedef struct
|
|||||||
} SubclassProcs[31];
|
} SubclassProcs[31];
|
||||||
int stackpos;
|
int stackpos;
|
||||||
int stacknum;
|
int stacknum;
|
||||||
int stacknew;
|
int wndprocrecursion;
|
||||||
WNDPROC origproc;
|
WNDPROC origproc;
|
||||||
} SUBCLASS_INFO, *LPSUBCLASS_INFO;
|
} SUBCLASS_INFO, *LPSUBCLASS_INFO;
|
||||||
|
|
||||||
|
@ -114,7 +114,6 @@ extern void TREEVIEW_Unregister(void);
|
|||||||
extern void UPDOWN_Register(void);
|
extern void UPDOWN_Register(void);
|
||||||
extern void UPDOWN_Unregister(void);
|
extern void UPDOWN_Unregister(void);
|
||||||
|
|
||||||
static LRESULT WINAPI SubclassWndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
|
||||||
|
|
||||||
LPSTR COMCTL32_aSubclass = NULL;
|
LPSTR COMCTL32_aSubclass = NULL;
|
||||||
HMODULE COMCTL32_hModule = 0;
|
HMODULE COMCTL32_hModule = 0;
|
||||||
@ -1085,7 +1084,7 @@ BOOL WINAPI SetWindowSubclass (HWND hWnd, SUBCLASSPROC pfnSubclass,
|
|||||||
UINT_PTR uIDSubclass, DWORD_PTR dwRef)
|
UINT_PTR uIDSubclass, DWORD_PTR dwRef)
|
||||||
{
|
{
|
||||||
LPSUBCLASS_INFO stack;
|
LPSUBCLASS_INFO stack;
|
||||||
int newnum, n;
|
int n;
|
||||||
|
|
||||||
TRACE ("(%p, %p, %x, %lx)\n", hWnd, pfnSubclass, uIDSubclass, dwRef);
|
TRACE ("(%p, %p, %x, %lx)\n", hWnd, pfnSubclass, uIDSubclass, dwRef);
|
||||||
|
|
||||||
@ -1109,10 +1108,10 @@ BOOL WINAPI SetWindowSubclass (HWND hWnd, SUBCLASSPROC pfnSubclass,
|
|||||||
/* set window procedure to our own and save the current one */
|
/* set window procedure to our own and save the current one */
|
||||||
if (IsWindowUnicode (hWnd))
|
if (IsWindowUnicode (hWnd))
|
||||||
stack->origproc = (WNDPROC)SetWindowLongW (hWnd, GWL_WNDPROC,
|
stack->origproc = (WNDPROC)SetWindowLongW (hWnd, GWL_WNDPROC,
|
||||||
(LONG)SubclassWndProc);
|
(LONG)DefSubclassProc);
|
||||||
else
|
else
|
||||||
stack->origproc = (WNDPROC)SetWindowLongA (hWnd, GWL_WNDPROC,
|
stack->origproc = (WNDPROC)SetWindowLongA (hWnd, GWL_WNDPROC,
|
||||||
(LONG)SubclassWndProc);
|
(LONG)DefSubclassProc);
|
||||||
} else {
|
} else {
|
||||||
WNDPROC current;
|
WNDPROC current;
|
||||||
if (IsWindowUnicode (hWnd))
|
if (IsWindowUnicode (hWnd))
|
||||||
@ -1120,7 +1119,7 @@ BOOL WINAPI SetWindowSubclass (HWND hWnd, SUBCLASSPROC pfnSubclass,
|
|||||||
else
|
else
|
||||||
current = (WNDPROC)GetWindowLongA (hWnd, GWL_WNDPROC);
|
current = (WNDPROC)GetWindowLongA (hWnd, GWL_WNDPROC);
|
||||||
|
|
||||||
if (current != SubclassWndProc) {
|
if (current != DefSubclassProc) {
|
||||||
ERR ("Application has subclassed with our procedure, then manually, then with us again. The current implementation can't handle this.\n");
|
ERR ("Application has subclassed with our procedure, then manually, then with us again. The current implementation can't handle this.\n");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@ -1128,32 +1127,28 @@ BOOL WINAPI SetWindowSubclass (HWND hWnd, SUBCLASSPROC pfnSubclass,
|
|||||||
|
|
||||||
/* Check to see if we have called this function with the same uIDSubClass
|
/* Check to see if we have called this function with the same uIDSubClass
|
||||||
* and pfnSubclass */
|
* and pfnSubclass */
|
||||||
for (n = 0; n <= stack->stacknum + stack->stacknew - 1; n++)
|
for (n = 0; n < stack->stacknum; n++)
|
||||||
if ((stack->SubclassProcs[n].id == uIDSubclass) &&
|
if ((stack->SubclassProcs[n].id == uIDSubclass) &&
|
||||||
(stack->SubclassProcs[n].subproc == pfnSubclass)) {
|
(stack->SubclassProcs[n].subproc == pfnSubclass)) {
|
||||||
stack->SubclassProcs[n].ref = dwRef;
|
stack->SubclassProcs[n].ref = dwRef;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((stack->stacknum + stack->stacknew) >= 32) {
|
if (stack->stacknum >= 32) {
|
||||||
ERR ("We have a Subclass stack overflow, please increment size\n");
|
ERR ("We have a Subclass stack overflow, please increment size\n");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* we can't simply increment both stackpos and stacknum because there might
|
memmove (&stack->SubclassProcs[1], &stack->SubclassProcs[0],
|
||||||
* be a window procedure running lower in the stack, we can only get them
|
sizeof(stack->SubclassProcs[0]) * stack->stacknum);
|
||||||
* up to date once the last window procedure has run */
|
|
||||||
if (stack->stacknum == stack->stackpos) {
|
|
||||||
stack->stacknum++;
|
stack->stacknum++;
|
||||||
|
if (stack->wndprocrecursion)
|
||||||
stack->stackpos++;
|
stack->stackpos++;
|
||||||
} else
|
|
||||||
stack->stacknew++;
|
|
||||||
|
|
||||||
newnum = stack->stacknew + stack->stacknum - 1;
|
stack->SubclassProcs[0].subproc = pfnSubclass;
|
||||||
|
stack->SubclassProcs[0].ref = dwRef;
|
||||||
stack->SubclassProcs[newnum].subproc = pfnSubclass;
|
stack->SubclassProcs[0].id = uIDSubclass;
|
||||||
stack->SubclassProcs[newnum].ref = dwRef;
|
|
||||||
stack->SubclassProcs[newnum].id = uIDSubclass;
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@ -1188,7 +1183,7 @@ BOOL WINAPI GetWindowSubclass (HWND hWnd, SUBCLASSPROC pfnSubclass,
|
|||||||
if (!stack)
|
if (!stack)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
for (n = 0; n <= stack->stacknum + stack->stacknew - 1; n++)
|
for (n = 0; n < stack->stacknum; n++)
|
||||||
if ((stack->SubclassProcs[n].id == uID) &&
|
if ((stack->SubclassProcs[n].id == uID) &&
|
||||||
(stack->SubclassProcs[n].subproc == pfnSubclass)) {
|
(stack->SubclassProcs[n].subproc == pfnSubclass)) {
|
||||||
*pdwRef = stack->SubclassProcs[n].ref;
|
*pdwRef = stack->SubclassProcs[n].ref;
|
||||||
@ -1226,7 +1221,8 @@ BOOL WINAPI RemoveWindowSubclass(HWND hWnd, SUBCLASSPROC pfnSubclass, UINT_PTR u
|
|||||||
if (!stack)
|
if (!stack)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if ((stack->stacknum == 1) && (stack->stackpos == 1) && !stack->stacknew) {
|
if ((stack->stacknum == 1) && (stack->stackpos == 1) &&
|
||||||
|
!stack->wndprocrecursion) {
|
||||||
TRACE("Last Subclass removed, cleaning up\n");
|
TRACE("Last Subclass removed, cleaning up\n");
|
||||||
/* clean up our heap and reset the origional window procedure */
|
/* clean up our heap and reset the origional window procedure */
|
||||||
if (IsWindowUnicode (hWnd))
|
if (IsWindowUnicode (hWnd))
|
||||||
@ -1238,24 +1234,21 @@ BOOL WINAPI RemoveWindowSubclass(HWND hWnd, SUBCLASSPROC pfnSubclass, UINT_PTR u
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (n = stack->stacknum + stack->stacknew - 1; n >= 0; n--)
|
for (n = stack->stacknum - 1; n >= 0; n--)
|
||||||
if ((stack->SubclassProcs[n].id == uID) &&
|
if ((stack->SubclassProcs[n].id == uID) &&
|
||||||
(stack->SubclassProcs[n].subproc == pfnSubclass)) {
|
(stack->SubclassProcs[n].subproc == pfnSubclass)) {
|
||||||
if (n != (stack->stacknum + stack->stacknew))
|
if (n != stack->stacknum)
|
||||||
/* Fill the hole in the stack */
|
/* Fill the hole in the stack */
|
||||||
memmove (&stack->SubclassProcs[n], &stack->SubclassProcs[n + 1],
|
memmove (&stack->SubclassProcs[n], &stack->SubclassProcs[n + 1],
|
||||||
sizeof(stack->SubclassProcs[0]) * (stack->stacknew + stack->stacknum - n));
|
sizeof(stack->SubclassProcs[0]) * (stack->stacknum - n));
|
||||||
stack->SubclassProcs[n].subproc = NULL;
|
stack->SubclassProcs[n].subproc = NULL;
|
||||||
stack->SubclassProcs[n].ref = 0;
|
stack->SubclassProcs[n].ref = 0;
|
||||||
stack->SubclassProcs[n].id = 0;
|
stack->SubclassProcs[n].id = 0;
|
||||||
|
|
||||||
/* If we are currently running a window procedure we have to manipulate
|
|
||||||
* the stack position pointers so that we don't corrupt the stack */
|
|
||||||
if ((n < stack->stackpos) || (stack->stackpos == stack->stacknum)) {
|
|
||||||
stack->stacknum--;
|
stack->stacknum--;
|
||||||
|
if (n < stack->stackpos && stack->wndprocrecursion)
|
||||||
stack->stackpos--;
|
stack->stackpos--;
|
||||||
} else if (n >= stack->stackpos)
|
|
||||||
stack->stacknew--;
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1263,33 +1256,6 @@ BOOL WINAPI RemoveWindowSubclass(HWND hWnd, SUBCLASSPROC pfnSubclass, UINT_PTR u
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* SubclassWndProc (internal)
|
|
||||||
*
|
|
||||||
* Window procedure for all subclassed windows.
|
|
||||||
* Saves the current subclassing stack position to support nested messages
|
|
||||||
*/
|
|
||||||
|
|
||||||
static LRESULT WINAPI SubclassWndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
||||||
{
|
|
||||||
LPSUBCLASS_INFO stack;
|
|
||||||
int stackpos;
|
|
||||||
LRESULT ret;
|
|
||||||
|
|
||||||
/* retrieve our little stack from the Properties */
|
|
||||||
stack = (LPSUBCLASS_INFO)GetPropA (hWnd, COMCTL32_aSubclass);
|
|
||||||
if (!stack) {
|
|
||||||
ERR ("Our sub classing stack got erased for %p!! Nothing we can do\n", hWnd);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
stackpos = stack->stackpos;
|
|
||||||
stack->stackpos = stack->stacknum;
|
|
||||||
ret = DefSubclassProc(hWnd,uMsg,wParam,lParam);
|
|
||||||
stack->stackpos = stackpos;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* DefSubclassProc [COMCTL32.413]
|
* DefSubclassProc [COMCTL32.413]
|
||||||
*
|
*
|
||||||
@ -1309,7 +1275,6 @@ static LRESULT WINAPI SubclassWndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPAR
|
|||||||
LRESULT WINAPI DefSubclassProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
LRESULT WINAPI DefSubclassProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
LPSUBCLASS_INFO stack;
|
LPSUBCLASS_INFO stack;
|
||||||
int stackpos;
|
|
||||||
LRESULT ret;
|
LRESULT ret;
|
||||||
|
|
||||||
/* retrieve our little stack from the Properties */
|
/* retrieve our little stack from the Properties */
|
||||||
@ -1319,24 +1284,27 @@ LRESULT WINAPI DefSubclassProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we are at pos 0 then we have to call the origional window procedure */
|
stack->wndprocrecursion++;
|
||||||
if (stack->stackpos == 0) {
|
|
||||||
|
/* If we are at the end of stack then we have to call the original
|
||||||
|
* window procedure */
|
||||||
|
if (stack->stackpos == stack->stacknum) {
|
||||||
if (IsWindowUnicode (hWnd))
|
if (IsWindowUnicode (hWnd))
|
||||||
return CallWindowProcW (stack->origproc, hWnd, uMsg, wParam, lParam);
|
ret = CallWindowProcW (stack->origproc, hWnd, uMsg, wParam, lParam);
|
||||||
else
|
else
|
||||||
return CallWindowProcA (stack->origproc, hWnd, uMsg, wParam, lParam);
|
ret = CallWindowProcA (stack->origproc, hWnd, uMsg, wParam, lParam);
|
||||||
|
} else {
|
||||||
|
stack->stackpos++;
|
||||||
|
/* call the Subclass procedure from the stack */
|
||||||
|
ret = stack->SubclassProcs[stack->stackpos - 1].subproc (hWnd, uMsg, wParam, lParam,
|
||||||
|
stack->SubclassProcs[stack->stackpos - 1].id, stack->SubclassProcs[stack->stackpos - 1].ref);
|
||||||
|
stack->stackpos--;
|
||||||
}
|
}
|
||||||
|
|
||||||
stackpos = --stack->stackpos;
|
/* We finished the recursion, so let's reinitalize the stack position to
|
||||||
/* call the Subclass procedure from the stack */
|
* beginning */
|
||||||
ret = stack->SubclassProcs[stackpos].subproc (hWnd, uMsg, wParam, lParam,
|
if ((--stack->wndprocrecursion) == 0) {
|
||||||
stack->SubclassProcs[stackpos].id, stack->SubclassProcs[stackpos].ref);
|
stack->stackpos = 0;
|
||||||
stack->stackpos++;
|
|
||||||
|
|
||||||
if ((stack->stackpos == stack->stacknum) && stack->stacknew) {
|
|
||||||
stack->stacknum += stack->stacknew;
|
|
||||||
stack->stackpos += stack->stacknew;
|
|
||||||
stack->stacknew = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we removed the last entry in our stack while a window procedure was
|
/* If we removed the last entry in our stack while a window procedure was
|
||||||
|
Loading…
x
Reference in New Issue
Block a user