blob: a0970a867a64bb1039f7a32b6a88d42f2735080a [file] [log] [blame]
Alexandre Julliard0e607781993-11-03 19:23:37 +00001/*
2 * Default dialog procedure
3 *
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00004 * Copyright 1993, 1996 Alexandre Julliard
Alexandre Julliard234bc241994-12-10 13:02:28 +00005 *
Alexandre Julliard59730ae1996-03-24 16:20:51 +00006 */
Alexandre Julliard0e607781993-11-03 19:23:37 +00007
8#include "windows.h"
9#include "dialog.h"
10#include "win.h"
Alexandre Julliard1e9ac791996-06-06 18:38:27 +000011#include "winproc.h"
12
Alexandre Julliardaca05781994-10-17 18:12:41 +000013
Alexandre Julliardaca05781994-10-17 18:12:41 +000014/***********************************************************************
15 * DEFDLG_SetFocus
16 *
17 * Set the focus to a control of the dialog, selecting the text if
18 * the control is an edit dialog.
19 */
20static void DEFDLG_SetFocus( HWND hwndDlg, HWND hwndCtrl )
21{
Alexandre Julliard8bbf8181996-09-13 16:50:47 +000022 HWND32 hwndPrev = GetFocus32();
Alexandre Julliardaca05781994-10-17 18:12:41 +000023
24 if (IsChild( hwndDlg, hwndPrev ))
25 {
Alexandre Julliard2d93d001996-05-21 15:01:41 +000026 if (SendMessage16( hwndPrev, WM_GETDLGCODE, 0, 0 ) & DLGC_HASSETSEL)
27 SendMessage16( hwndPrev, EM_SETSEL, TRUE, MAKELONG( -1, 0 ) );
Alexandre Julliardaca05781994-10-17 18:12:41 +000028 }
Alexandre Julliard2d93d001996-05-21 15:01:41 +000029 if (SendMessage16( hwndCtrl, WM_GETDLGCODE, 0, 0 ) & DLGC_HASSETSEL)
30 SendMessage16( hwndCtrl, EM_SETSEL, FALSE, MAKELONG( 0, -1 ) );
Alexandre Julliard8bbf8181996-09-13 16:50:47 +000031 SetFocus32( hwndCtrl );
Alexandre Julliardaca05781994-10-17 18:12:41 +000032}
33
34
35/***********************************************************************
36 * DEFDLG_SaveFocus
37 */
38static BOOL DEFDLG_SaveFocus( HWND hwnd, DIALOGINFO *infoPtr )
39{
Alexandre Julliard8bbf8181996-09-13 16:50:47 +000040 HWND32 hwndFocus = GetFocus32();
Alexandre Julliardaca05781994-10-17 18:12:41 +000041
42 if (!hwndFocus || !IsChild( hwnd, hwndFocus )) return FALSE;
Alexandre Julliardaca05781994-10-17 18:12:41 +000043 infoPtr->hwndFocus = hwndFocus;
44 /* Remove default button */
45 return TRUE;
46}
47
48
49/***********************************************************************
50 * DEFDLG_RestoreFocus
51 */
52static BOOL DEFDLG_RestoreFocus( HWND hwnd, DIALOGINFO *infoPtr )
53{
54 if (!infoPtr->hwndFocus || IsIconic(hwnd)) return FALSE;
55 if (!IsWindow( infoPtr->hwndFocus )) return FALSE;
56 DEFDLG_SetFocus( hwnd, infoPtr->hwndFocus );
57 infoPtr->hwndFocus = 0;
58 return TRUE;
59}
60
61
62/***********************************************************************
63 * DEFDLG_FindDefButton
64 *
65 * Find the current default push-button.
66 */
67static HWND DEFDLG_FindDefButton( HWND hwndDlg )
68{
69 HWND hwndChild = GetWindow( hwndDlg, GW_CHILD );
70 while (hwndChild)
71 {
Alexandre Julliard2d93d001996-05-21 15:01:41 +000072 if (SendMessage16( hwndChild, WM_GETDLGCODE, 0, 0 ) & DLGC_DEFPUSHBUTTON)
Alexandre Julliardaca05781994-10-17 18:12:41 +000073 break;
74 hwndChild = GetWindow( hwndChild, GW_HWNDNEXT );
75 }
76 return hwndChild;
77}
78
79
80/***********************************************************************
81 * DEFDLG_SetDefButton
82 *
83 * Set the new default button to be hwndNew.
84 */
85static BOOL DEFDLG_SetDefButton( HWND hwndDlg, DIALOGINFO *dlgInfo,
86 HWND hwndNew )
87{
88 if (hwndNew &&
Alexandre Julliard2d93d001996-05-21 15:01:41 +000089 !(SendMessage16(hwndNew, WM_GETDLGCODE, 0, 0 ) & DLGC_UNDEFPUSHBUTTON))
Alexandre Julliardaca05781994-10-17 18:12:41 +000090 return FALSE; /* Destination is not a push button */
91
92 if (dlgInfo->msgResult) /* There's already a default pushbutton */
93 {
94 HWND hwndOld = GetDlgItem( hwndDlg, dlgInfo->msgResult );
Alexandre Julliard2d93d001996-05-21 15:01:41 +000095 if (SendMessage32A( hwndOld, WM_GETDLGCODE, 0, 0) & DLGC_DEFPUSHBUTTON)
96 SendMessage32A( hwndOld, BM_SETSTYLE32, BS_PUSHBUTTON, TRUE );
Alexandre Julliardaca05781994-10-17 18:12:41 +000097 }
98 if (hwndNew)
99 {
Alexandre Julliard2d93d001996-05-21 15:01:41 +0000100 SendMessage32A( hwndNew, BM_SETSTYLE32, BS_DEFPUSHBUTTON, TRUE );
Alexandre Julliardaca05781994-10-17 18:12:41 +0000101 dlgInfo->msgResult = GetDlgCtrlID( hwndNew );
102 }
103 else dlgInfo->msgResult = 0;
104 return TRUE;
105}
Alexandre Julliard0e607781993-11-03 19:23:37 +0000106
107
108/***********************************************************************
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000109 * DEFDLG_Proc
110 *
111 * Implementation of DefDlgProc(). Only handle messages that need special
112 * handling for dialogs.
Alexandre Julliard0e607781993-11-03 19:23:37 +0000113 */
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000114static LRESULT DEFDLG_Proc( HWND32 hwnd, UINT32 msg, WPARAM32 wParam,
115 LPARAM lParam, DIALOGINFO *dlgInfo )
Alexandre Julliard0e607781993-11-03 19:23:37 +0000116{
Alexandre Julliardf1aa3031996-08-05 17:42:43 +0000117 HWND hwndDefId;
118
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000119 switch(msg)
Alexandre Julliard0e607781993-11-03 19:23:37 +0000120 {
121 case WM_INITDIALOG:
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000122 return 0;
Alexandre Julliard0e607781993-11-03 19:23:37 +0000123
124 case WM_ERASEBKGND:
Alexandre Julliardbf9130a1996-10-13 17:45:47 +0000125 FillWindow( hwnd, hwnd, (HDC)wParam, (HBRUSH16)CTLCOLOR_DLG );
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000126 return 1;
Alexandre Julliard0e607781993-11-03 19:23:37 +0000127
128 case WM_NCDESTROY:
129
Alexandre Julliard3f2abfa1994-08-16 15:43:11 +0000130 /* Free dialog heap (if created) */
131 if (dlgInfo->hDialogHeap)
132 {
Alexandre Julliard1285c2f1996-05-06 16:06:24 +0000133 GlobalUnlock16(dlgInfo->hDialogHeap);
134 GlobalFree16(dlgInfo->hDialogHeap);
Alexandre Julliard3f2abfa1994-08-16 15:43:11 +0000135 dlgInfo->hDialogHeap = 0;
136 }
137
Alexandre Julliard0e607781993-11-03 19:23:37 +0000138 /* Delete font */
139 if (dlgInfo->hUserFont)
140 {
141 DeleteObject( dlgInfo->hUserFont );
142 dlgInfo->hUserFont = 0;
143 }
144
145 /* Delete menu */
146 if (dlgInfo->hMenu)
147 {
148 DestroyMenu( dlgInfo->hMenu );
149 dlgInfo->hMenu = 0;
150 }
151
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000152 /* Delete window procedure */
Alexandre Julliard3051b641996-07-05 17:14:13 +0000153 WINPROC_FreeProc( dlgInfo->dlgProc );
154 dlgInfo->dlgProc = (HWINDOWPROC)0;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000155
Alexandre Julliard0e607781993-11-03 19:23:37 +0000156 /* Window clean-up */
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000157 return DefWindowProc32A( hwnd, msg, wParam, lParam );
Alexandre Julliardaca05781994-10-17 18:12:41 +0000158
159 case WM_SHOWWINDOW:
160 if (!wParam) DEFDLG_SaveFocus( hwnd, dlgInfo );
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000161 return DefWindowProc32A( hwnd, msg, wParam, lParam );
Alexandre Julliardaca05781994-10-17 18:12:41 +0000162
163 case WM_ACTIVATE:
164 if (wParam) DEFDLG_RestoreFocus( hwnd, dlgInfo );
165 else DEFDLG_SaveFocus( hwnd, dlgInfo );
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000166 return 0;
Alexandre Julliardaca05781994-10-17 18:12:41 +0000167
168 case WM_SETFOCUS:
169 DEFDLG_RestoreFocus( hwnd, dlgInfo );
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000170 return 0;
Alexandre Julliardaca05781994-10-17 18:12:41 +0000171
172 case DM_SETDEFID:
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000173 if (dlgInfo->fEnd) return 1;
Alexandre Julliardaca05781994-10-17 18:12:41 +0000174 DEFDLG_SetDefButton( hwnd, dlgInfo,
175 wParam ? GetDlgItem( hwnd, wParam ) : 0 );
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000176 return 1;
Alexandre Julliardaca05781994-10-17 18:12:41 +0000177
178 case DM_GETDEFID:
Alexandre Julliardf1aa3031996-08-05 17:42:43 +0000179 if (dlgInfo->fEnd) return 0;
180 if (dlgInfo->msgResult)
181 return MAKELONG( dlgInfo->msgResult, DC_HASDEFID );
182 hwndDefId = DEFDLG_FindDefButton( hwnd );
183 if (hwndDefId)
184 return MAKELONG( GetDlgCtrlID( hwndDefId ), DC_HASDEFID);
185 return 0;
Alexandre Julliardaca05781994-10-17 18:12:41 +0000186
187 case WM_NEXTDLGCTL:
188 {
Alexandre Julliardaf0bae51995-10-03 17:06:08 +0000189 HWND hwndDest = (HWND)wParam;
Alexandre Julliardaca05781994-10-17 18:12:41 +0000190 if (!lParam)
Alexandre Julliardbf9130a1996-10-13 17:45:47 +0000191 hwndDest = GetNextDlgTabItem32(hwnd, GetFocus32(), wParam);
Alexandre Julliardaca05781994-10-17 18:12:41 +0000192 if (hwndDest) DEFDLG_SetFocus( hwnd, hwndDest );
193 DEFDLG_SetDefButton( hwnd, dlgInfo, hwndDest );
194 }
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000195 return 0;
Alexandre Julliardaca05781994-10-17 18:12:41 +0000196
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000197 case WM_CLOSE:
198 EndDialog( hwnd, TRUE );
199 DestroyWindow( hwnd );
200 return 0;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000201 }
202 return 0;
203}
204
205
206/***********************************************************************
207 * DefDlgProc16 (USER.308)
208 */
209LRESULT DefDlgProc16( HWND16 hwnd, UINT16 msg, WPARAM16 wParam, LPARAM lParam )
210{
211 DIALOGINFO * dlgInfo;
212 BOOL16 result = FALSE;
213 WND * wndPtr = WIN_FindWndPtr( hwnd );
214
215 if (!wndPtr) return 0;
216 dlgInfo = (DIALOGINFO *)&wndPtr->wExtra;
217
218 dlgInfo->msgResult = 0;
219 if (dlgInfo->dlgProc)
220 {
221 /* Call dialog procedure */
Alexandre Julliard3051b641996-07-05 17:14:13 +0000222 result = (BOOL16)CallWindowProc16( (WNDPROC16)dlgInfo->dlgProc,
223 hwnd, msg, wParam, lParam );
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000224
225 /* Check if window was destroyed by dialog procedure */
226 if (result || !IsWindow( hwnd )) return result;
227 }
228
229 switch(msg)
230 {
231 case WM_INITDIALOG:
232 case WM_ERASEBKGND:
233 case WM_NCDESTROY:
234 case WM_SHOWWINDOW:
235 case WM_ACTIVATE:
236 case WM_SETFOCUS:
237 case DM_SETDEFID:
238 case DM_GETDEFID:
239 case WM_NEXTDLGCTL:
240 case WM_CLOSE:
241 return DEFDLG_Proc( (HWND32)hwnd, msg, (WPARAM32)wParam,
242 lParam, dlgInfo );
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000243
Alexandre Julliard0e607781993-11-03 19:23:37 +0000244 default:
Alexandre Julliard2d93d001996-05-21 15:01:41 +0000245 return DefWindowProc16( hwnd, msg, wParam, lParam );
Alexandre Julliard0e607781993-11-03 19:23:37 +0000246 }
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000247}
248
249
250/***********************************************************************
251 * DefDlgProc32A (USER32.119)
252 */
253LRESULT DefDlgProc32A( HWND32 hwnd, UINT32 msg, WPARAM32 wParam, LPARAM lParam)
254{
255 DIALOGINFO * dlgInfo;
256 BOOL16 result = FALSE;
257 WND * wndPtr = WIN_FindWndPtr( hwnd );
258
259 if (!wndPtr) return 0;
260 dlgInfo = (DIALOGINFO *)&wndPtr->wExtra;
261
262 dlgInfo->msgResult = 0;
263 if (dlgInfo->dlgProc)
264 {
265 /* Call dialog procedure */
Alexandre Julliard3051b641996-07-05 17:14:13 +0000266 result = (BOOL16)CallWindowProc32A( (WNDPROC32)dlgInfo->dlgProc,
267 hwnd, msg, wParam, lParam );
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000268
269 /* Check if window was destroyed by dialog procedure */
270 if (result || !IsWindow( hwnd )) return result;
271 }
272
273 switch(msg)
274 {
275 case WM_INITDIALOG:
276 case WM_ERASEBKGND:
277 case WM_NCDESTROY:
278 case WM_SHOWWINDOW:
279 case WM_ACTIVATE:
280 case WM_SETFOCUS:
281 case DM_SETDEFID:
282 case DM_GETDEFID:
283 case WM_NEXTDLGCTL:
284 case WM_CLOSE:
285 return DEFDLG_Proc( hwnd, msg, wParam, lParam, dlgInfo );
286
287 default:
288 return DefWindowProc32A( hwnd, msg, wParam, lParam );
289 }
290}
291
292
293/***********************************************************************
294 * DefDlgProc32W (USER32.120)
295 */
296LRESULT DefDlgProc32W( HWND32 hwnd, UINT32 msg, WPARAM32 wParam, LPARAM lParam)
297{
298 DIALOGINFO * dlgInfo;
299 BOOL16 result = FALSE;
300 WND * wndPtr = WIN_FindWndPtr( hwnd );
301
302 if (!wndPtr) return 0;
303 dlgInfo = (DIALOGINFO *)&wndPtr->wExtra;
304
305 dlgInfo->msgResult = 0;
306 if (dlgInfo->dlgProc)
307 {
308 /* Call dialog procedure */
Alexandre Julliard3051b641996-07-05 17:14:13 +0000309 result = (BOOL16)CallWindowProc32W( (WNDPROC32)dlgInfo->dlgProc,
310 hwnd, msg, wParam, lParam );
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000311
312 /* Check if window was destroyed by dialog procedure */
313 if (result || !IsWindow( hwnd )) return result;
314 }
315
316 switch(msg)
317 {
318 case WM_INITDIALOG:
319 case WM_ERASEBKGND:
320 case WM_NCDESTROY:
321 case WM_SHOWWINDOW:
322 case WM_ACTIVATE:
323 case WM_SETFOCUS:
324 case DM_SETDEFID:
325 case DM_GETDEFID:
326 case WM_NEXTDLGCTL:
327 case WM_CLOSE:
328 return DEFDLG_Proc( hwnd, msg, wParam, lParam, dlgInfo );
329
330 default:
331 return DefWindowProc32W( hwnd, msg, wParam, lParam );
332 }
Alexandre Julliard0e607781993-11-03 19:23:37 +0000333}