2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
11 #include <afs/param.h>
16 #include <WINNT/subclass.h>
20 * PROTOTYPES _________________________________________________________________
24 LONG CALLBACK Subclass_WndProc (HWND hTarget, UINT msg, WPARAM wp, LPARAM lp);
28 * MISCELLANEOUS ______________________________________________________________
33 #define REALLOC(_a,_c,_r,_i) SubclassReallocFunction ((LPVOID*)&_a,sizeof(*_a),&_c,_r,_i)
34 BOOL SubclassReallocFunction (LPVOID *ppTarget, size_t cbElement, size_t *pcTarget, size_t cReq, size_t cInc)
39 if (cReq <= *pcTarget)
42 if ((cNew = cInc * ((cReq + cInc-1) / cInc)) <= 0)
45 if ((pNew = (LPVOID)GlobalAlloc (GMEM_FIXED, cbElement * cNew)) == NULL)
47 memset (pNew, 0x00, cbElement * cNew);
51 memcpy (pNew, *ppTarget, cbElement * (*pcTarget));
52 GlobalFree ((HGLOBAL)*ppTarget);
63 * VARIABLES __________________________________________________________________
69 HWND hTarget; // window being subclassed
70 PVOID procOrig; // original pre-SubclassProc proc
78 size_t nHooks; // number of entries in aHooks
79 size_t nHooksActive; // number of hooks in use
82 SubclassWindow *aTargets = NULL;
85 #define cREALLOC_SUBCLASS_TARGETS 8
86 #define cREALLOC_SUBCLASS_HOOKS 4
90 * ROUTINES ___________________________________________________________________
94 BOOL Subclass_AddHook (HWND hTarget, PVOID wndProc)
96 for (size_t iTarget = 0; iTarget < nTargets; ++iTarget)
98 if (aTargets[ iTarget ].hTarget == hTarget)
101 if (iTarget >= nTargets)
103 for (iTarget = 0; iTarget < nTargets; ++iTarget)
105 if (aTargets[ iTarget ].hTarget == NULL)
109 if (iTarget >= nTargets)
111 if (!REALLOC (aTargets, nTargets, 1+iTarget, cREALLOC_SUBCLASS_TARGETS))
115 aTargets[ iTarget ].hTarget = hTarget;
118 for (size_t iHook = 0; iHook < aTargets[iTarget].nHooks; ++iHook)
120 if (aTargets[ iTarget ].aHooks[ iHook ].wndProc == wndProc)
123 if (iHook >= aTargets[ iTarget ].nHooks)
125 for (iHook = 0; iHook < aTargets[iTarget].nHooks; ++iHook)
127 if (aTargets[ iTarget ].aHooks[ iHook ].wndProc == NULL)
131 if (iHook >= aTargets[ iTarget ].nHooks)
133 if (!REALLOC (aTargets[ iTarget ].aHooks, aTargets[ iTarget ].nHooks, 1+iHook, cREALLOC_SUBCLASS_HOOKS))
137 aTargets[ iTarget ].aHooks[ iHook ].wndProc = wndProc;
138 aTargets[ iTarget ].aHooks[ iHook ].nReq ++;
139 aTargets[ iTarget ].nHooksActive ++;
141 if (aTargets[ iTarget ].nHooksActive == 1)
143 aTargets[ iTarget ].procOrig = (PVOID)GetWindowLong (hTarget, GWL_WNDPROC);
144 SetWindowLong (hTarget, GWL_WNDPROC, (LONG)Subclass_WndProc);
151 void Subclass_RemoveHook (HWND hTarget, PVOID wndProc)
153 for (size_t iTarget = 0; iTarget < nTargets; ++iTarget)
155 if (aTargets[ iTarget ].hTarget == hTarget)
158 if (iTarget < nTargets)
160 for (size_t iHook = 0; iHook < aTargets[iTarget].nHooks; ++iHook)
162 if (aTargets[ iTarget ].aHooks[ iHook ].wndProc == wndProc)
165 if (iHook < aTargets[ iTarget ].nHooks)
167 aTargets[ iTarget ].aHooks[ iHook ].nReq --;
168 if (aTargets[ iTarget ].aHooks[ iHook ].nReq == 0)
170 memset (&aTargets[ iTarget ].aHooks[ iHook ], 0x00, sizeof(aTargets[ iTarget ].aHooks[ iHook ]));
174 aTargets[ iTarget ].nHooksActive --;
175 if (aTargets[ iTarget ].nHooksActive == 0)
177 SetWindowLong (aTargets[ iTarget ].hTarget, GWL_WNDPROC, (LONG)aTargets[ iTarget ].procOrig);
178 memset (&aTargets[ iTarget ], 0x00, sizeof(aTargets[ iTarget ]));
184 PVOID Subclass_FindNextHook (HWND hTarget, PVOID wndProc)
186 for (size_t iTarget = 0; iTarget < nTargets; ++iTarget)
188 if (aTargets[ iTarget ].hTarget == hTarget)
191 if (iTarget >= nTargets)
194 for (size_t iHook = 0; iHook < aTargets[iTarget].nHooks; ++iHook)
196 if (aTargets[ iTarget ].aHooks[ iHook ].wndProc == wndProc)
199 if (iHook >= aTargets[ iTarget ].nHooks)
200 return aTargets[ iTarget ].procOrig;
202 for (++iHook; iHook < aTargets[iTarget].nHooks; ++iHook)
204 if (aTargets[ iTarget ].aHooks[ iHook ].wndProc != NULL)
205 return aTargets[ iTarget ].aHooks[ iHook ].wndProc;
208 return aTargets[ iTarget ].procOrig;
212 LONG CALLBACK Subclass_WndProc (HWND hTarget, UINT msg, WPARAM wp, LPARAM lp)
214 for (size_t iTarget = 0; iTarget < nTargets; ++iTarget)
216 if (aTargets[ iTarget ].hTarget == hTarget)
219 if (iTarget >= nTargets)
220 return DefWindowProc (hTarget, msg, wp, lp);
222 for (size_t iHook = 0; iHook < aTargets[iTarget].nHooks; ++iHook)
224 if (aTargets[ iTarget ].aHooks[ iHook ].wndProc != NULL)
228 if (iHook >= aTargets[iTarget].nHooks)
229 return CallWindowProc ((WNDPROC)aTargets[ iTarget ].procOrig, hTarget, msg, wp, lp);
231 return CallWindowProc ((WNDPROC)aTargets[ iTarget ].aHooks[ iHook ].wndProc, hTarget, msg, wp, lp);