windows-vs2005b2-20050706
[openafs.git] / src / WINNT / afsapplib / al_pump.cpp
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
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
8  */
9
10 extern "C" {
11 #include <afs/param.h>
12 #include <afs/stds.h>
13 }
14
15 #include <WINNT/afsapplib.h>
16
17
18 /*
19  * DEFINITIONS ________________________________________________________________
20  *
21  */
22
23 #define cREALLOC_MODELESS 16
24 #define cREALLOC_WINDOWDATA_FIELDS 4
25 #define cREALLOC_WINDOWDATA_WINDOWS 16
26 #define cREALLOC_WINDOWDATA_DATA 8
27
28 #define GWD_IS_MODELESS  TEXT("afsapplib/al_pump.cpp - is window modeless?")
29
30
31 /*
32  * VARIABLES __________________________________________________________________
33  *
34  */
35
36          // Modeless-dialog support
37          //
38 static HWND  *aModeless = NULL;
39 static size_t cModeless = 0;
40 static LPCRITICAL_SECTION pcsPump = NULL;
41
42 static void (*g_fnPump)(MSG *lpm) = NULL;
43
44          // Window-data support
45          //
46 static struct
47    {
48    TCHAR szField[ cchNAME ];
49    } *aFields = NULL;
50 static size_t cFields = 0;
51
52 static struct
53    {
54    HWND hWnd;
55    DWORD *adwData;
56    size_t cdwData;
57    } *aWindows = NULL;
58 static size_t cWindows = 0;
59 static LPCRITICAL_SECTION pcsData = NULL;
60
61
62 /*
63  * DIALOG ROUTINES ____________________________________________________________
64  *
65  */
66
67 BOOL CALLBACK Modeless_HookProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp)
68 {
69    PVOID oldProc = Subclass_FindNextHook (hDlg, Modeless_HookProc);
70
71    if (msg == WM_DESTROY)
72       {
73       EnterCriticalSection (pcsPump);
74       for (size_t ii = 0; ii < cModeless; ++ii)
75          {
76          if (aModeless[ ii ] == hDlg)
77             aModeless[ ii ] = 0;
78          }
79       LeaveCriticalSection (pcsPump);
80       Subclass_RemoveHook (hDlg, Modeless_HookProc);
81       }
82
83    if (oldProc)
84       return CallWindowProc ((WNDPROC)oldProc, hDlg, msg, wp, lp);
85    else
86       return DefWindowProc (hDlg, msg, wp, lp);
87 }
88
89
90 BOOL AfsAppLib_IsModelessDialogMessage (MSG *lpm)
91 {
92    BOOL rc = FALSE;
93
94    if (pcsPump)
95       {
96       EnterCriticalSection (pcsPump);
97
98       for (size_t ii = 0; (!rc) && (ii < cModeless); ++ii)
99          {
100          if (aModeless[ ii ] != 0)
101             {
102             if (IsPropSheet (aModeless[ ii ]))
103                {
104                if (!PropSheet_GetCurrentPageHwnd(aModeless[ ii ]))
105                   DestroyWindow (aModeless[ ii ]);
106                if (PropSheet_IsDialogMessage(aModeless[ ii ], lpm))
107                   rc = TRUE;
108                }
109             else
110                {
111                if (IsDialogMessage (aModeless[ ii ], lpm))
112                   rc = TRUE;
113                }
114             }
115          }
116
117       LeaveCriticalSection (pcsPump);
118       }
119
120    return rc;
121 }
122
123
124 void AfsAppLib_RegisterModelessDialog (HWND hDlg)
125 {
126    if (pcsPump == NULL)
127       {
128       pcsPump = New (CRITICAL_SECTION);
129       InitializeCriticalSection (pcsPump);
130       }
131
132    EnterCriticalSection (pcsPump);
133
134    size_t ii;
135    for (ii = 0; ii < cModeless; ++ii)
136       {
137       if (aModeless[ ii ] == hDlg)
138          break;
139       }
140    if (ii == cModeless)
141       {
142       for (ii = 0; ii < cModeless; ++ii)
143          {
144          if (aModeless[ ii ] == 0)
145             break;
146          }
147       if (ii == cModeless)
148          {
149          (void)REALLOC (aModeless, cModeless, 1+ii, cREALLOC_MODELESS);
150          }
151       if (ii < cModeless)
152          {
153          aModeless[ ii ] = hDlg;
154          Subclass_AddHook (hDlg, Modeless_HookProc);
155          }
156       }
157
158    LeaveCriticalSection (pcsPump);
159 }
160
161
162 void AfsAppLib_SetPumpRoutine (void (*fnPump)(MSG *lpm))
163 {
164    g_fnPump = fnPump;
165 }
166
167
168 void AfsAppLib_MainPump (void)
169 {
170    MSG msg;
171
172    while (GetMessage (&msg, NULL, 0, 0))
173       {
174       if (AfsAppLib_IsModelessDialogMessage (&msg))
175          continue;
176
177       if (g_fnPump)
178          (*g_fnPump)(&msg);
179       else
180          {
181          TranslateMessage (&msg);
182          DispatchMessage (&msg);
183          }
184       }
185 }
186
187
188 /*
189  * WINDOW-DATA ________________________________________________________________
190  *
191  */
192
193 BOOL CALLBACK WindowData_HookProc (HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
194 {
195    PVOID oldProc = Subclass_FindNextHook (hWnd, WindowData_HookProc);
196
197    if (msg == WM_DESTROY)
198       {
199       EnterCriticalSection (pcsData);
200       for (size_t ii = 0; ii < cWindows; ++ii)
201          {
202          if (aWindows[ ii ].hWnd == hWnd)
203             {
204             if (aWindows[ ii ].adwData)
205                Free (aWindows[ ii ].adwData);
206             memset (&aWindows[ii], 0x00, sizeof(aWindows[ii]));
207             }
208          }
209       LeaveCriticalSection (pcsData);
210       Subclass_RemoveHook (hWnd, WindowData_HookProc);
211       }
212
213    if (oldProc)
214       return CallWindowProc ((WNDPROC)oldProc, hWnd, msg, wp, lp);
215    else
216       return DefWindowProc (hWnd, msg, wp, lp);
217 }
218
219
220 size_t GetWindowDataField (LPTSTR pszField)
221 {
222    size_t rc = (size_t)-1;
223
224    if (pcsData == NULL)
225       {
226       pcsData = New (CRITICAL_SECTION);
227       InitializeCriticalSection (pcsData);
228       }
229    EnterCriticalSection (pcsData);
230
231    size_t ii;
232    for (ii = 0; ii < cFields; ++ii)
233       {
234       if (!lstrcmpi (aFields[ ii ].szField, pszField))
235          break;
236       }
237    if (ii == cFields)
238       {
239       for (ii = 0; ii < cFields; ++ii)
240          {
241          if (aFields[ ii ].szField[0] == TEXT('\0'))
242             break;
243          }
244       if (ii == cFields)
245          {
246          (void)REALLOC (aFields, cFields, 1+ii, cREALLOC_WINDOWDATA_FIELDS);
247          }
248       if (ii < cFields)
249          {
250          lstrcpy (aFields[ ii ].szField, pszField);
251          }
252       }
253    if (ii < cFields)
254       {
255       rc = ii;
256       }
257
258    LeaveCriticalSection (pcsData);
259    return rc;
260 }
261
262
263 DWORD GetWindowData (HWND hWnd, LPTSTR pszField)
264 {
265    DWORD rc = 0;
266
267    if (pcsData == NULL)
268       {
269       pcsData = New (CRITICAL_SECTION);
270       InitializeCriticalSection (pcsData);
271       }
272    EnterCriticalSection (pcsData);
273
274    size_t iField;
275    if ((iField = GetWindowDataField (pszField)) != (size_t)-1)
276       {
277       for (size_t ii = 0; ii < cWindows; ++ii)
278          {
279          if (aWindows[ ii ].hWnd == hWnd)
280             {
281             if (iField < aWindows[ ii ].cdwData)
282                rc = aWindows[ ii ].adwData[ iField ];
283             break;
284             }
285          }
286       }
287
288    LeaveCriticalSection (pcsData);
289    return rc;
290 }
291
292
293 DWORD SetWindowData (HWND hWnd, LPTSTR pszField, DWORD dwNewData)
294 {
295    DWORD rc = 0;
296
297    if (pcsData == NULL)
298       {
299       pcsData = New (CRITICAL_SECTION);
300       InitializeCriticalSection (pcsData);
301       }
302    EnterCriticalSection (pcsData);
303
304    size_t iField;
305    if ((iField = GetWindowDataField (pszField)) != (size_t)-1)
306       {
307       size_t ii;
308       for (ii = 0; ii < cWindows; ++ii)
309          {
310          if (aWindows[ ii ].hWnd == hWnd)
311             {
312             if (iField < aWindows[ ii ].cdwData)
313                rc = aWindows[ ii ].adwData[ iField ];
314             break;
315             }
316          }
317       if (ii == cWindows)
318          {
319          for (ii = 0; ii < cWindows; ++ii)
320             {
321             if (aWindows[ ii ].hWnd == 0)
322                break;
323             }
324          if (ii == cWindows)
325             {
326             (void)REALLOC (aWindows, cWindows, 1+ii, cREALLOC_WINDOWDATA_WINDOWS);
327             }
328          }
329       if (ii < cWindows)
330          {
331          if (aWindows[ ii ].hWnd == 0)
332             {
333             aWindows[ ii ].hWnd = hWnd;
334             Subclass_AddHook (hWnd, WindowData_HookProc);
335             }
336          if ((dwNewData) && (iField >= aWindows[ ii ].cdwData))
337             {
338             (void)REALLOC (aWindows[ ii ].adwData, aWindows[ ii ].cdwData, 1+iField, cREALLOC_WINDOWDATA_DATA);
339             }
340          if (iField < aWindows[ ii ].cdwData)
341             {
342             aWindows[ ii ].adwData[ iField ] = dwNewData;
343             }
344          }
345       }
346
347    LeaveCriticalSection (pcsData);
348    return rc;
349 }
350