2 * Default dialog procedure
4 * Copyright 1993, 1996 Alexandre Julliard
11 #include "wine/winuser16.h"
17 /***********************************************************************
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 );
38 /***********************************************************************
41 static void DEFDLG_SaveFocus( HWND hwnd )
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 /***********************************************************************
59 static void DEFDLG_RestoreFocus( HWND hwnd )
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 );
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 );
93 if (SendMessageW( hwndChild, WM_GETDLGCODE, 0, 0 ) & DLGC_DEFPUSHBUTTON)
95 hwndChild = GetWindow( hwndChild, GW_HWNDNEXT );
101 /***********************************************************************
102 * DEFDLG_SetDefButton
104 * Set the new default button to be hwndNew.
106 static BOOL DEFDLG_SetDefButton( HWND hwndDlg, DIALOGINFO *dlgInfo,
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 );
121 SendMessageA( hwndNew, BM_SETSTYLE, BS_DEFPUSHBUTTON, TRUE );
122 dlgInfo->idResult = GetDlgCtrlID( hwndNew );
124 else dlgInfo->idResult = 0;
129 /***********************************************************************
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 )
141 FillWindow16( hwnd, hwnd, (HDC16)wParam, (HBRUSH16)CTLCOLOR_DLG );
146 /* Free dialog heap (if created) */
147 if (dlgInfo->hDialogHeap)
149 GlobalUnlock16(dlgInfo->hDialogHeap);
150 GlobalFree16(dlgInfo->hDialogHeap);
151 dlgInfo->hDialogHeap = 0;
155 if (dlgInfo->hUserFont)
157 DeleteObject( dlgInfo->hUserFont );
158 dlgInfo->hUserFont = 0;
164 DestroyMenu( dlgInfo->hMenu );
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 );
177 if (!wParam) DEFDLG_SaveFocus( hwnd );
178 return DefWindowProcA( hwnd, msg, wParam, lParam );
181 if (wParam) DEFDLG_RestoreFocus( hwnd );
182 else DEFDLG_SaveFocus( hwnd );
186 DEFDLG_RestoreFocus( hwnd );
190 if (dlgInfo->flags & DF_END) return 1;
191 DEFDLG_SetDefButton( hwnd, dlgInfo,
192 wParam ? GetDlgItem( hwnd, wParam ) : 0 );
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);
208 HWND hwndDest = (HWND)wParam;
210 hwndDest = GetNextDlgTabItem(hwnd, GetFocus(), wParam);
211 if (hwndDest) DEFDLG_SetFocus( hwnd, hwndDest );
212 DEFDLG_SetDefButton( hwnd, dlgInfo, hwndDest );
216 case WM_ENTERMENULOOP:
218 case WM_NCLBUTTONDOWN:
220 HWND hwndFocus = GetFocus();
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 );
231 return dlgInfo->hUserFont;
234 PostMessageA( hwnd, WM_COMMAND, IDCANCEL,
235 (LPARAM)GetDlgItem( hwnd, IDCANCEL ) );
238 case WM_NOTIFYFORMAT:
239 return DefWindowProcA( hwnd, msg, wParam, lParam );
244 /***********************************************************************
247 static LRESULT DEFDLG_Epilog(HWND hwnd, UINT msg, BOOL fResult)
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)
257 return GetWindowLongA( hwnd, DWL_MSGRESULT );
260 /***********************************************************************
261 * DefDlgProc (USER.308)
263 LRESULT WINAPI DefDlgProc16( HWND16 hwnd, UINT16 msg, WPARAM16 wParam,
266 DIALOGINFO * dlgInfo;
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);
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 */
302 case WM_ENTERMENULOOP:
304 case WM_NCLBUTTONDOWN:
305 return DEFDLG_Proc( (HWND)hwnd, msg,
306 (WPARAM)wParam, lParam, dlgInfo );
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;
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);
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 */
363 case WM_ENTERMENULOOP:
365 case WM_NCLBUTTONDOWN:
366 return DEFDLG_Proc( hwnd, msg, wParam, lParam, dlgInfo );
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,
387 DIALOGINFO * dlgInfo;
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);
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 */
423 case WM_ENTERMENULOOP:
425 case WM_NCLBUTTONDOWN:
426 return DEFDLG_Proc( hwnd, msg, wParam, lParam, dlgInfo );
434 return DefWindowProcW( hwnd, msg, wParam, lParam );
437 return DEFDLG_Epilog(hwnd, msg, result);