The [windows] section is in win.ini not in ~/.wine/config.
[wine.git] / windows / defdlg.c
blobfccd1405eb7349046d5099998a7b42ae426482ee
1 /*
2 * Default dialog procedure
4 * Copyright 1993, 1996 Alexandre Julliard
6 */
8 #include "windef.h"
9 #include "winbase.h"
10 #include "wingdi.h"
11 #include "wine/winuser16.h"
12 #include "controls.h"
13 #include "win.h"
14 #include "winproc.h"
17 /***********************************************************************
18 * DEFDLG_SetFocus
20 * Set the focus to a control of the dialog, selecting the text if
21 * the control is an edit dialog.
23 static void DEFDLG_SetFocus( HWND hwndDlg, HWND hwndCtrl )
25 HWND hwndPrev = GetFocus();
27 if (IsChild( hwndDlg, hwndPrev ))
29 if (SendMessageW( hwndPrev, WM_GETDLGCODE, 0, 0 ) & DLGC_HASSETSEL)
30 SendMessageW( hwndPrev, EM_SETSEL, -1, 0 );
32 if (SendMessageW( hwndCtrl, WM_GETDLGCODE, 0, 0 ) & DLGC_HASSETSEL)
33 SendMessageW( hwndCtrl, EM_SETSEL, 0, -1 );
34 SetFocus( hwndCtrl );
38 /***********************************************************************
39 * DEFDLG_SaveFocus
41 static void DEFDLG_SaveFocus( HWND hwnd )
43 DIALOGINFO *infoPtr;
44 WND *wndPtr;
45 HWND hwndFocus = GetFocus();
47 if (!hwndFocus || !IsChild( hwnd, hwndFocus )) return;
48 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return;
49 infoPtr = (DIALOGINFO *)&wndPtr->wExtra;
50 infoPtr->hwndFocus = hwndFocus;
51 WIN_ReleaseWndPtr( wndPtr );
52 /* Remove default button */
56 /***********************************************************************
57 * DEFDLG_RestoreFocus
59 static void DEFDLG_RestoreFocus( HWND hwnd )
61 DIALOGINFO *infoPtr;
62 WND *wndPtr;
64 if (IsIconic( hwnd )) return;
65 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return;
66 infoPtr = (DIALOGINFO *)&wndPtr->wExtra;
67 if (IsWindow( infoPtr->hwndFocus ))
69 /* Don't set the focus back to controls if EndDialog is already called.*/
70 if (!(infoPtr->flags & DF_END))
72 WIN_ReleaseWndPtr( wndPtr );
73 DEFDLG_SetFocus( hwnd, infoPtr->hwndFocus );
74 return;
76 /* This used to set infoPtr->hwndFocus to NULL for no apparent reason,
77 sometimes losing focus when receiving WM_SETFOCUS messages. */
79 WIN_ReleaseWndPtr( wndPtr );
83 /***********************************************************************
84 * DEFDLG_FindDefButton
86 * Find the current default push-button.
88 static HWND DEFDLG_FindDefButton( HWND hwndDlg )
90 HWND hwndChild = GetWindow( hwndDlg, GW_CHILD );
91 while (hwndChild)
93 if (SendMessageW( hwndChild, WM_GETDLGCODE, 0, 0 ) & DLGC_DEFPUSHBUTTON)
94 break;
95 hwndChild = GetWindow( hwndChild, GW_HWNDNEXT );
97 return hwndChild;
101 /***********************************************************************
102 * DEFDLG_SetDefButton
104 * Set the new default button to be hwndNew.
106 static BOOL DEFDLG_SetDefButton( HWND hwndDlg, DIALOGINFO *dlgInfo,
107 HWND hwndNew )
109 if (hwndNew &&
110 !(SendMessageW(hwndNew, WM_GETDLGCODE, 0, 0 ) & DLGC_UNDEFPUSHBUTTON))
111 return FALSE; /* Destination is not a push button */
113 if (dlgInfo->idResult) /* There's already a default pushbutton */
115 HWND hwndOld = GetDlgItem( hwndDlg, dlgInfo->idResult );
116 if (SendMessageA( hwndOld, WM_GETDLGCODE, 0, 0) & DLGC_DEFPUSHBUTTON)
117 SendMessageA( hwndOld, BM_SETSTYLE, BS_PUSHBUTTON, TRUE );
119 if (hwndNew)
121 SendMessageA( hwndNew, BM_SETSTYLE, BS_DEFPUSHBUTTON, TRUE );
122 dlgInfo->idResult = GetDlgCtrlID( hwndNew );
124 else dlgInfo->idResult = 0;
125 return TRUE;
129 /***********************************************************************
130 * DEFDLG_Proc
132 * Implementation of DefDlgProc(). Only handle messages that need special
133 * handling for dialogs.
135 static LRESULT DEFDLG_Proc( HWND hwnd, UINT msg, WPARAM wParam,
136 LPARAM lParam, DIALOGINFO *dlgInfo )
138 switch(msg)
140 case WM_ERASEBKGND:
141 FillWindow16( hwnd, hwnd, (HDC16)wParam, (HBRUSH16)CTLCOLOR_DLG );
142 return 1;
144 case WM_NCDESTROY:
146 /* Free dialog heap (if created) */
147 if (dlgInfo->hDialogHeap)
149 GlobalUnlock16(dlgInfo->hDialogHeap);
150 GlobalFree16(dlgInfo->hDialogHeap);
151 dlgInfo->hDialogHeap = 0;
154 /* Delete font */
155 if (dlgInfo->hUserFont)
157 DeleteObject( dlgInfo->hUserFont );
158 dlgInfo->hUserFont = 0;
161 /* Delete menu */
162 if (dlgInfo->hMenu)
164 DestroyMenu( dlgInfo->hMenu );
165 dlgInfo->hMenu = 0;
168 /* Delete window procedure */
169 WINPROC_FreeProc( dlgInfo->dlgProc, WIN_PROC_WINDOW );
170 dlgInfo->dlgProc = (HWINDOWPROC)0;
171 dlgInfo->flags |= DF_END; /* just in case */
173 /* Window clean-up */
174 return DefWindowProcA( hwnd, msg, wParam, lParam );
176 case WM_SHOWWINDOW:
177 if (!wParam) DEFDLG_SaveFocus( hwnd );
178 return DefWindowProcA( hwnd, msg, wParam, lParam );
180 case WM_ACTIVATE:
181 if (wParam) DEFDLG_RestoreFocus( hwnd );
182 else DEFDLG_SaveFocus( hwnd );
183 return 0;
185 case WM_SETFOCUS:
186 DEFDLG_RestoreFocus( hwnd );
187 return 0;
189 case DM_SETDEFID:
190 if (dlgInfo->flags & DF_END) return 1;
191 DEFDLG_SetDefButton( hwnd, dlgInfo,
192 wParam ? GetDlgItem( hwnd, wParam ) : 0 );
193 return 1;
195 case DM_GETDEFID:
197 HWND hwndDefId;
198 if (dlgInfo->flags & DF_END) return 0;
199 if (dlgInfo->idResult)
200 return MAKELONG( dlgInfo->idResult, DC_HASDEFID );
201 if ((hwndDefId = DEFDLG_FindDefButton( hwnd )))
202 return MAKELONG( GetDlgCtrlID( hwndDefId ), DC_HASDEFID);
204 return 0;
206 case WM_NEXTDLGCTL:
208 HWND hwndDest = (HWND)wParam;
209 if (!lParam)
210 hwndDest = GetNextDlgTabItem(hwnd, GetFocus(), wParam);
211 if (hwndDest) DEFDLG_SetFocus( hwnd, hwndDest );
212 DEFDLG_SetDefButton( hwnd, dlgInfo, hwndDest );
214 return 0;
216 case WM_ENTERMENULOOP:
217 case WM_LBUTTONDOWN:
218 case WM_NCLBUTTONDOWN:
220 HWND hwndFocus = GetFocus();
221 if (hwndFocus)
223 /* always make combo box hide its listbox control */
224 if (!SendMessageA( hwndFocus, CB_SHOWDROPDOWN, FALSE, 0 ))
225 SendMessageA( GetParent(hwndFocus), CB_SHOWDROPDOWN, FALSE, 0 );
228 return DefWindowProcA( hwnd, msg, wParam, lParam );
230 case WM_GETFONT:
231 return dlgInfo->hUserFont;
233 case WM_CLOSE:
234 PostMessageA( hwnd, WM_COMMAND, IDCANCEL,
235 (LPARAM)GetDlgItem( hwnd, IDCANCEL ) );
236 return 0;
238 case WM_NOTIFYFORMAT:
239 return DefWindowProcA( hwnd, msg, wParam, lParam );
241 return 0;
244 /***********************************************************************
245 * DEFDLG_Epilog
247 static LRESULT DEFDLG_Epilog(HWND hwnd, UINT msg, BOOL fResult)
249 /* see SDK 3.1 */
251 if ((msg >= WM_CTLCOLORMSGBOX && msg <= WM_CTLCOLORSTATIC) ||
252 msg == WM_CTLCOLOR || msg == WM_COMPAREITEM ||
253 msg == WM_VKEYTOITEM || msg == WM_CHARTOITEM ||
254 msg == WM_QUERYDRAGICON || msg == WM_INITDIALOG)
255 return fResult;
257 return GetWindowLongA( hwnd, DWL_MSGRESULT );
260 /***********************************************************************
261 * DefDlgProc (USER.308)
263 LRESULT WINAPI DefDlgProc16( HWND16 hwnd, UINT16 msg, WPARAM16 wParam,
264 LPARAM lParam )
266 DIALOGINFO * dlgInfo;
267 WNDPROC16 dlgproc;
268 BOOL result = FALSE;
269 WND * wndPtr = WIN_FindWndPtr( hwnd );
271 if (!wndPtr) return 0;
272 dlgInfo = (DIALOGINFO *)&wndPtr->wExtra;
273 dlgInfo->msgResult = 0;
274 dlgproc = (WNDPROC16)dlgInfo->dlgProc;
275 WIN_ReleaseWndPtr(wndPtr);
277 if (dlgproc)
279 /* Call dialog procedure */
280 result = CallWindowProc16( dlgproc, hwnd, msg, wParam, lParam );
281 /* 16 bit dlg procs only return BOOL16 */
282 if( WINPROC_GetProcType( dlgproc ) == WIN_PROC_16 )
283 result = LOWORD(result);
286 if (!result && IsWindow(hwnd))
288 /* callback didn't process this message */
290 switch(msg)
292 case WM_ERASEBKGND:
293 case WM_SHOWWINDOW:
294 case WM_ACTIVATE:
295 case WM_SETFOCUS:
296 case DM_SETDEFID:
297 case DM_GETDEFID:
298 case WM_NEXTDLGCTL:
299 case WM_GETFONT:
300 case WM_CLOSE:
301 case WM_NCDESTROY:
302 case WM_ENTERMENULOOP:
303 case WM_LBUTTONDOWN:
304 case WM_NCLBUTTONDOWN:
305 return DEFDLG_Proc( (HWND)hwnd, msg,
306 (WPARAM)wParam, lParam, dlgInfo );
307 case WM_INITDIALOG:
308 case WM_VKEYTOITEM:
309 case WM_COMPAREITEM:
310 case WM_CHARTOITEM:
311 break;
313 default:
314 return DefWindowProc16( hwnd, msg, wParam, lParam );
317 return DEFDLG_Epilog(hwnd, msg, result);
321 /***********************************************************************
322 * DefDlgProcA (USER32.@)
324 LRESULT WINAPI DefDlgProcA( HWND hwnd, UINT msg,
325 WPARAM wParam, LPARAM lParam )
327 DIALOGINFO * dlgInfo;
328 WNDPROC dlgproc;
329 BOOL result = FALSE;
330 WND * wndPtr = WIN_FindWndPtr( hwnd );
332 if (!wndPtr) return 0;
333 dlgInfo = (DIALOGINFO *)&wndPtr->wExtra;
334 dlgInfo->msgResult = 0;
335 dlgproc = dlgInfo->dlgProc;
336 WIN_ReleaseWndPtr(wndPtr);
338 if (dlgproc)
340 /* Call dialog procedure */
341 result = CallWindowProcA( dlgproc, hwnd, msg, wParam, lParam );
342 /* 16 bit dlg procs only return BOOL16 */
343 if( WINPROC_GetProcType( dlgproc ) == WIN_PROC_16 )
344 result = LOWORD(result);
347 if (!result && IsWindow(hwnd))
349 /* callback didn't process this message */
351 switch(msg)
353 case WM_ERASEBKGND:
354 case WM_SHOWWINDOW:
355 case WM_ACTIVATE:
356 case WM_SETFOCUS:
357 case DM_SETDEFID:
358 case DM_GETDEFID:
359 case WM_NEXTDLGCTL:
360 case WM_GETFONT:
361 case WM_CLOSE:
362 case WM_NCDESTROY:
363 case WM_ENTERMENULOOP:
364 case WM_LBUTTONDOWN:
365 case WM_NCLBUTTONDOWN:
366 return DEFDLG_Proc( hwnd, msg, wParam, lParam, dlgInfo );
367 case WM_INITDIALOG:
368 case WM_VKEYTOITEM:
369 case WM_COMPAREITEM:
370 case WM_CHARTOITEM:
371 break;
373 default:
374 return DefWindowProcA( hwnd, msg, wParam, lParam );
377 return DEFDLG_Epilog(hwnd, msg, result);
381 /***********************************************************************
382 * DefDlgProcW (USER32.@)
384 LRESULT WINAPI DefDlgProcW( HWND hwnd, UINT msg, WPARAM wParam,
385 LPARAM lParam )
387 DIALOGINFO * dlgInfo;
388 BOOL result = FALSE;
389 WNDPROC dlgproc;
390 WND * wndPtr = WIN_FindWndPtr( hwnd );
392 if (!wndPtr) return 0;
393 dlgInfo = (DIALOGINFO *)&wndPtr->wExtra;
394 dlgInfo->msgResult = 0;
395 dlgproc = dlgInfo->dlgProc;
396 WIN_ReleaseWndPtr(wndPtr);
398 if (dlgproc)
400 /* Call dialog procedure */
401 result = CallWindowProcW( dlgproc, hwnd, msg, wParam, lParam );
402 /* 16 bit dlg procs only return BOOL16 */
403 if( WINPROC_GetProcType( dlgproc ) == WIN_PROC_16 )
404 result = LOWORD(result);
407 if (!result && IsWindow(hwnd))
409 /* callback didn't process this message */
411 switch(msg)
413 case WM_ERASEBKGND:
414 case WM_SHOWWINDOW:
415 case WM_ACTIVATE:
416 case WM_SETFOCUS:
417 case DM_SETDEFID:
418 case DM_GETDEFID:
419 case WM_NEXTDLGCTL:
420 case WM_GETFONT:
421 case WM_CLOSE:
422 case WM_NCDESTROY:
423 case WM_ENTERMENULOOP:
424 case WM_LBUTTONDOWN:
425 case WM_NCLBUTTONDOWN:
426 return DEFDLG_Proc( hwnd, msg, wParam, lParam, dlgInfo );
427 case WM_INITDIALOG:
428 case WM_VKEYTOITEM:
429 case WM_COMPAREITEM:
430 case WM_CHARTOITEM:
431 break;
433 default:
434 return DefWindowProcW( hwnd, msg, wParam, lParam );
437 return DEFDLG_Epilog(hwnd, msg, result);