Release 970112
[wine.git] / windows / defdlg.c
bloba4808e96b15e15aad6ff4a4bd84cc3d94c4674b9
1 /*
2 * Default dialog procedure
4 * Copyright 1993, 1996 Alexandre Julliard
6 */
8 #include "windows.h"
9 #include "dialog.h"
10 #include "win.h"
11 #include "winproc.h"
14 /***********************************************************************
15 * DEFDLG_SetFocus
17 * Set the focus to a control of the dialog, selecting the text if
18 * the control is an edit dialog.
20 static void DEFDLG_SetFocus( HWND32 hwndDlg, HWND32 hwndCtrl )
22 HWND32 hwndPrev = GetFocus32();
24 if (IsChild( hwndDlg, hwndPrev ))
26 if (SendMessage16( hwndPrev, WM_GETDLGCODE, 0, 0 ) & DLGC_HASSETSEL)
27 SendMessage16( hwndPrev, EM_SETSEL16, TRUE, MAKELONG( -1, 0 ) );
29 if (SendMessage16( hwndCtrl, WM_GETDLGCODE, 0, 0 ) & DLGC_HASSETSEL)
30 SendMessage16( hwndCtrl, EM_SETSEL16, FALSE, MAKELONG( 0, -1 ) );
31 SetFocus32( hwndCtrl );
35 /***********************************************************************
36 * DEFDLG_SaveFocus
38 static BOOL32 DEFDLG_SaveFocus( HWND32 hwnd, DIALOGINFO *infoPtr )
40 HWND32 hwndFocus = GetFocus32();
42 if (!hwndFocus || !IsChild( hwnd, hwndFocus )) return FALSE;
43 infoPtr->hwndFocus = hwndFocus;
44 /* Remove default button */
45 return TRUE;
49 /***********************************************************************
50 * DEFDLG_RestoreFocus
52 static BOOL32 DEFDLG_RestoreFocus( HWND32 hwnd, DIALOGINFO *infoPtr )
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;
62 /***********************************************************************
63 * DEFDLG_FindDefButton
65 * Find the current default push-button.
67 static HWND32 DEFDLG_FindDefButton( HWND32 hwndDlg )
69 HWND32 hwndChild = GetWindow( hwndDlg, GW_CHILD );
70 while (hwndChild)
72 if (SendMessage16( hwndChild, WM_GETDLGCODE, 0, 0 ) & DLGC_DEFPUSHBUTTON)
73 break;
74 hwndChild = GetWindow( hwndChild, GW_HWNDNEXT );
76 return hwndChild;
80 /***********************************************************************
81 * DEFDLG_SetDefButton
83 * Set the new default button to be hwndNew.
85 static BOOL32 DEFDLG_SetDefButton( HWND32 hwndDlg, DIALOGINFO *dlgInfo,
86 HWND32 hwndNew )
88 if (hwndNew &&
89 !(SendMessage16(hwndNew, WM_GETDLGCODE, 0, 0 ) & DLGC_UNDEFPUSHBUTTON))
90 return FALSE; /* Destination is not a push button */
92 if (dlgInfo->idResult) /* There's already a default pushbutton */
94 HWND32 hwndOld = GetDlgItem( hwndDlg, dlgInfo->idResult );
95 if (SendMessage32A( hwndOld, WM_GETDLGCODE, 0, 0) & DLGC_DEFPUSHBUTTON)
96 SendMessage32A( hwndOld, BM_SETSTYLE32, BS_PUSHBUTTON, TRUE );
98 if (hwndNew)
100 SendMessage32A( hwndNew, BM_SETSTYLE32, BS_DEFPUSHBUTTON, TRUE );
101 dlgInfo->idResult = GetDlgCtrlID( hwndNew );
103 else dlgInfo->idResult = 0;
104 return TRUE;
108 /***********************************************************************
109 * DEFDLG_Proc
111 * Implementation of DefDlgProc(). Only handle messages that need special
112 * handling for dialogs.
114 static LRESULT DEFDLG_Proc( HWND32 hwnd, UINT32 msg, WPARAM32 wParam,
115 LPARAM lParam, DIALOGINFO *dlgInfo )
117 HWND32 hwndDefId;
119 switch(msg)
121 case WM_ERASEBKGND:
122 FillWindow( hwnd, hwnd, (HDC16)wParam, (HBRUSH16)CTLCOLOR_DLG );
123 return 1;
125 case WM_NCDESTROY:
127 /* Free dialog heap (if created) */
128 if (dlgInfo->hDialogHeap)
130 GlobalUnlock16(dlgInfo->hDialogHeap);
131 GlobalFree16(dlgInfo->hDialogHeap);
132 dlgInfo->hDialogHeap = 0;
135 /* Delete font */
136 if (dlgInfo->hUserFont)
138 DeleteObject32( dlgInfo->hUserFont );
139 dlgInfo->hUserFont = 0;
142 /* Delete menu */
143 if (dlgInfo->hMenu)
145 DestroyMenu32( dlgInfo->hMenu );
146 dlgInfo->hMenu = 0;
149 /* Delete window procedure */
150 WINPROC_FreeProc( dlgInfo->dlgProc );
151 dlgInfo->dlgProc = (HWINDOWPROC)0;
152 dlgInfo->fEnd = TRUE; /* just in case */
154 /* Window clean-up */
155 return DefWindowProc32A( hwnd, msg, wParam, lParam );
157 case WM_SHOWWINDOW:
158 if (!wParam) DEFDLG_SaveFocus( hwnd, dlgInfo );
159 return DefWindowProc32A( hwnd, msg, wParam, lParam );
161 case WM_ACTIVATE:
162 if (wParam) DEFDLG_RestoreFocus( hwnd, dlgInfo );
163 else DEFDLG_SaveFocus( hwnd, dlgInfo );
164 return 0;
166 case WM_SETFOCUS:
167 DEFDLG_RestoreFocus( hwnd, dlgInfo );
168 return 0;
170 case DM_SETDEFID:
171 if (dlgInfo->fEnd) return 1;
172 DEFDLG_SetDefButton( hwnd, dlgInfo,
173 wParam ? GetDlgItem( hwnd, wParam ) : 0 );
174 return 1;
176 case DM_GETDEFID:
177 if (dlgInfo->fEnd) return 0;
178 if (dlgInfo->idResult)
179 return MAKELONG( dlgInfo->idResult, DC_HASDEFID );
180 hwndDefId = DEFDLG_FindDefButton( hwnd );
181 if (hwndDefId)
182 return MAKELONG( GetDlgCtrlID( hwndDefId ), DC_HASDEFID);
183 return 0;
185 case WM_NEXTDLGCTL:
187 HWND32 hwndDest = (HWND32)wParam;
188 if (!lParam)
189 hwndDest = GetNextDlgTabItem32(hwnd, GetFocus32(), wParam);
190 if (hwndDest) DEFDLG_SetFocus( hwnd, hwndDest );
191 DEFDLG_SetDefButton( hwnd, dlgInfo, hwndDest );
193 return 0;
195 case WM_GETFONT:
196 return dlgInfo->hUserFont;
198 case WM_CLOSE:
199 EndDialog( hwnd, TRUE );
200 DestroyWindow( hwnd );
201 return 0;
203 return 0;
206 /***********************************************************************
207 * DEFDLG_Signoff
209 static LRESULT DEFDLG_Signoff(DIALOGINFO* dlgInfo, UINT32 msg, BOOL16 fResult)
211 /* see SDK 3.1 */
213 if ((msg >= WM_CTLCOLORMSGBOX && msg <= WM_CTLCOLORSTATIC) ||
214 msg == WM_CTLCOLOR || msg == WM_COMPAREITEM ||
215 msg == WM_VKEYTOITEM || msg == WM_CHARTOITEM ||
216 msg == WM_QUERYDRAGICON || msg == WM_INITDIALOG)
217 return fResult;
219 return dlgInfo->msgResult;
222 /***********************************************************************
223 * DefDlgProc16 (USER.308)
225 LRESULT DefDlgProc16( HWND16 hwnd, UINT16 msg, WPARAM16 wParam, LPARAM lParam )
227 DIALOGINFO * dlgInfo;
228 BOOL16 result = FALSE;
229 WND * wndPtr = WIN_FindWndPtr( hwnd );
231 if (!wndPtr) return 0;
232 dlgInfo = (DIALOGINFO *)&wndPtr->wExtra;
233 dlgInfo->msgResult = 0;
235 if (dlgInfo->dlgProc) /* Call dialog procedure */
236 result = (BOOL16)CallWindowProc16( (WNDPROC16)dlgInfo->dlgProc,
237 hwnd, msg, wParam, lParam );
239 /* Check if window was destroyed by dialog procedure */
241 if( !result && IsWindow(hwnd))
243 /* callback didn't process this message */
245 switch(msg)
247 case WM_ERASEBKGND:
248 case WM_SHOWWINDOW:
249 case WM_ACTIVATE:
250 case WM_SETFOCUS:
251 case DM_SETDEFID:
252 case DM_GETDEFID:
253 case WM_NEXTDLGCTL:
254 case WM_GETFONT:
255 case WM_CLOSE:
256 case WM_NCDESTROY:
257 return DEFDLG_Proc( (HWND32)hwnd, msg,
258 (WPARAM32)wParam, lParam, dlgInfo );
259 case WM_INITDIALOG:
260 case WM_VKEYTOITEM:
261 case WM_COMPAREITEM:
262 case WM_CHARTOITEM:
263 break;
265 default:
266 return DefWindowProc16( hwnd, msg, wParam, lParam );
269 return DEFDLG_Signoff(dlgInfo, msg, result);
273 /***********************************************************************
274 * DefDlgProc32A (USER32.119)
276 LRESULT DefDlgProc32A( HWND32 hwnd, UINT32 msg, WPARAM32 wParam, LPARAM lParam)
278 DIALOGINFO * dlgInfo;
279 BOOL16 result = FALSE;
280 WND * wndPtr = WIN_FindWndPtr( hwnd );
282 if (!wndPtr) return 0;
283 dlgInfo = (DIALOGINFO *)&wndPtr->wExtra;
284 dlgInfo->msgResult = 0;
286 if (dlgInfo->dlgProc) /* Call dialog procedure */
287 result = (BOOL16)CallWindowProc32A( (WNDPROC32)dlgInfo->dlgProc,
288 hwnd, msg, wParam, lParam );
290 /* Check if window was destroyed by dialog procedure */
292 if( !result && IsWindow(hwnd))
294 /* callback didn't process this message */
296 switch(msg)
298 case WM_ERASEBKGND:
299 case WM_SHOWWINDOW:
300 case WM_ACTIVATE:
301 case WM_SETFOCUS:
302 case DM_SETDEFID:
303 case DM_GETDEFID:
304 case WM_NEXTDLGCTL:
305 case WM_GETFONT:
306 case WM_CLOSE:
307 case WM_NCDESTROY:
308 return DEFDLG_Proc( (HWND32)hwnd, msg,
309 (WPARAM32)wParam, lParam, dlgInfo );
310 case WM_INITDIALOG:
311 case WM_VKEYTOITEM:
312 case WM_COMPAREITEM:
313 case WM_CHARTOITEM:
314 break;
316 default:
317 return DefWindowProc32A( hwnd, msg, wParam, lParam );
320 return DEFDLG_Signoff(dlgInfo, msg, result);
324 /***********************************************************************
325 * DefDlgProc32W (USER32.120)
327 LRESULT DefDlgProc32W( HWND32 hwnd, UINT32 msg, WPARAM32 wParam, LPARAM lParam)
329 DIALOGINFO * dlgInfo;
330 BOOL16 result = FALSE;
331 WND * wndPtr = WIN_FindWndPtr( hwnd );
333 if (!wndPtr) return 0;
334 dlgInfo = (DIALOGINFO *)&wndPtr->wExtra;
335 dlgInfo->msgResult = 0;
337 if (dlgInfo->dlgProc) /* Call dialog procedure */
338 result = (BOOL16)CallWindowProc32W( (WNDPROC32)dlgInfo->dlgProc,
339 hwnd, msg, wParam, lParam );
341 /* Check if window was destroyed by dialog procedure */
343 if( !result && IsWindow(hwnd))
345 /* callback didn't process this message */
347 switch(msg)
349 case WM_ERASEBKGND:
350 case WM_SHOWWINDOW:
351 case WM_ACTIVATE:
352 case WM_SETFOCUS:
353 case DM_SETDEFID:
354 case DM_GETDEFID:
355 case WM_NEXTDLGCTL:
356 case WM_GETFONT:
357 case WM_CLOSE:
358 case WM_NCDESTROY:
359 return DEFDLG_Proc( (HWND32)hwnd, msg,
360 (WPARAM32)wParam, lParam, dlgInfo );
361 case WM_INITDIALOG:
362 case WM_VKEYTOITEM:
363 case WM_COMPAREITEM:
364 case WM_CHARTOITEM:
365 break;
367 default:
368 return DefWindowProc32W( hwnd, msg, wParam, lParam );
371 return DEFDLG_Signoff(dlgInfo, msg, result);