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 BOOL DEFDLG_SaveFocus( HWND hwnd, DIALOGINFO *infoPtr )
43 HWND hwndFocus = GetFocus();
45 if (!hwndFocus || !IsChild( hwnd, hwndFocus )) return FALSE;
46 infoPtr->hwndFocus = hwndFocus;
47 /* Remove default button */
52 /***********************************************************************
55 static BOOL DEFDLG_RestoreFocus( HWND hwnd, DIALOGINFO *infoPtr )
57 if (!infoPtr->hwndFocus || IsIconic(hwnd)) return FALSE;
58 if (!IsWindow( infoPtr->hwndFocus )) return FALSE;
60 /* Don't set the focus back to controls if EndDialog is already called.*/
61 if (!(infoPtr->flags & DF_END))
62 DEFDLG_SetFocus( hwnd, infoPtr->hwndFocus );
64 /* This used to set infoPtr->hwndFocus to NULL for no apparent reason,
65 sometimes losing focus when receiving WM_SETFOCUS messages. */
70 /***********************************************************************
71 * DEFDLG_FindDefButton
73 * Find the current default push-button.
75 static HWND DEFDLG_FindDefButton( HWND hwndDlg )
77 HWND hwndChild = GetWindow( hwndDlg, GW_CHILD );
80 if (SendMessageW( hwndChild, WM_GETDLGCODE, 0, 0 ) & DLGC_DEFPUSHBUTTON)
82 hwndChild = GetWindow( hwndChild, GW_HWNDNEXT );
88 /***********************************************************************
91 * Set the new default button to be hwndNew.
93 static BOOL DEFDLG_SetDefButton( HWND hwndDlg, DIALOGINFO *dlgInfo,
97 !(SendMessageW(hwndNew, WM_GETDLGCODE, 0, 0 ) & DLGC_UNDEFPUSHBUTTON))
98 return FALSE; /* Destination is not a push button */
100 if (dlgInfo->idResult) /* There's already a default pushbutton */
102 HWND hwndOld = GetDlgItem( hwndDlg, dlgInfo->idResult );
103 if (SendMessageA( hwndOld, WM_GETDLGCODE, 0, 0) & DLGC_DEFPUSHBUTTON)
104 SendMessageA( hwndOld, BM_SETSTYLE, BS_PUSHBUTTON, TRUE );
108 SendMessageA( hwndNew, BM_SETSTYLE, BS_DEFPUSHBUTTON, TRUE );
109 dlgInfo->idResult = GetDlgCtrlID( hwndNew );
111 else dlgInfo->idResult = 0;
116 /***********************************************************************
119 * Implementation of DefDlgProc(). Only handle messages that need special
120 * handling for dialogs.
122 static LRESULT DEFDLG_Proc( HWND hwnd, UINT msg, WPARAM wParam,
123 LPARAM lParam, DIALOGINFO *dlgInfo )
128 FillWindow16( hwnd, hwnd, (HDC16)wParam, (HBRUSH16)CTLCOLOR_DLG );
133 /* Free dialog heap (if created) */
134 if (dlgInfo->hDialogHeap)
136 GlobalUnlock16(dlgInfo->hDialogHeap);
137 GlobalFree16(dlgInfo->hDialogHeap);
138 dlgInfo->hDialogHeap = 0;
142 if (dlgInfo->hUserFont)
144 DeleteObject( dlgInfo->hUserFont );
145 dlgInfo->hUserFont = 0;
151 DestroyMenu( dlgInfo->hMenu );
155 /* Delete window procedure */
156 WINPROC_FreeProc( dlgInfo->dlgProc, WIN_PROC_WINDOW );
157 dlgInfo->dlgProc = (HWINDOWPROC)0;
158 dlgInfo->flags |= DF_END; /* just in case */
160 /* Window clean-up */
161 return DefWindowProcA( hwnd, msg, wParam, lParam );
164 if (!wParam) DEFDLG_SaveFocus( hwnd, dlgInfo );
165 return DefWindowProcA( hwnd, msg, wParam, lParam );
168 if (wParam) DEFDLG_RestoreFocus( hwnd, dlgInfo );
169 else DEFDLG_SaveFocus( hwnd, dlgInfo );
173 DEFDLG_RestoreFocus( hwnd, dlgInfo );
177 if (dlgInfo->flags & DF_END) return 1;
178 DEFDLG_SetDefButton( hwnd, dlgInfo,
179 wParam ? GetDlgItem( hwnd, wParam ) : 0 );
185 if (dlgInfo->flags & DF_END) return 0;
186 if (dlgInfo->idResult)
187 return MAKELONG( dlgInfo->idResult, DC_HASDEFID );
188 if ((hwndDefId = DEFDLG_FindDefButton( hwnd )))
189 return MAKELONG( GetDlgCtrlID( hwndDefId ), DC_HASDEFID);
195 HWND hwndDest = (HWND)wParam;
197 hwndDest = GetNextDlgTabItem(hwnd, GetFocus(), wParam);
198 if (hwndDest) DEFDLG_SetFocus( hwnd, hwndDest );
199 DEFDLG_SetDefButton( hwnd, dlgInfo, hwndDest );
203 case WM_ENTERMENULOOP:
205 case WM_NCLBUTTONDOWN:
207 HWND hwndFocus = GetFocus();
210 /* always make combo box hide its listbox control */
211 if (!SendMessageA( hwndFocus, CB_SHOWDROPDOWN, FALSE, 0 ))
212 SendMessageA( GetParent(hwndFocus), CB_SHOWDROPDOWN, FALSE, 0 );
215 return DefWindowProcA( hwnd, msg, wParam, lParam );
218 return dlgInfo->hUserFont;
221 PostMessageA( hwnd, WM_COMMAND, IDCANCEL,
222 (LPARAM)GetDlgItem( hwnd, IDCANCEL ) );
225 case WM_NOTIFYFORMAT:
226 return DefWindowProcA( hwnd, msg, wParam, lParam );
231 /***********************************************************************
234 static LRESULT DEFDLG_Epilog(DIALOGINFO* dlgInfo, UINT msg, BOOL fResult)
238 if ((msg >= WM_CTLCOLORMSGBOX && msg <= WM_CTLCOLORSTATIC) ||
239 msg == WM_CTLCOLOR || msg == WM_COMPAREITEM ||
240 msg == WM_VKEYTOITEM || msg == WM_CHARTOITEM ||
241 msg == WM_QUERYDRAGICON || msg == WM_INITDIALOG)
244 return dlgInfo->msgResult;
247 /***********************************************************************
248 * DefDlgProc (USER.308)
250 LRESULT WINAPI DefDlgProc16( HWND16 hwnd, UINT16 msg, WPARAM16 wParam,
253 DIALOGINFO * dlgInfo;
255 WND * wndPtr = WIN_FindWndPtr( hwnd );
257 if (!wndPtr) return 0;
258 dlgInfo = (DIALOGINFO *)&wndPtr->wExtra;
259 dlgInfo->msgResult = 0;
261 if (dlgInfo->dlgProc) { /* Call dialog procedure */
262 result = CallWindowProc16( (WNDPROC16)dlgInfo->dlgProc,
263 hwnd, msg, wParam, lParam );
264 /* 16 bit dlg procs only return BOOL16 */
265 if( WINPROC_GetProcType( dlgInfo->dlgProc ) == WIN_PROC_16 )
266 result = LOWORD(result);
269 if (!result && IsWindow(hwnd))
271 /* callback didn't process this message */
285 case WM_ENTERMENULOOP:
287 case WM_NCLBUTTONDOWN:
288 WIN_ReleaseWndPtr(wndPtr);
289 return DEFDLG_Proc( (HWND)hwnd, msg,
290 (WPARAM)wParam, lParam, dlgInfo );
298 WIN_ReleaseWndPtr(wndPtr);
299 return DefWindowProc16( hwnd, msg, wParam, lParam );
302 WIN_ReleaseWndPtr(wndPtr);
303 return DEFDLG_Epilog(dlgInfo, msg, result);
307 /***********************************************************************
308 * DefDlgProcA (USER32.@)
310 LRESULT WINAPI DefDlgProcA( HWND hwnd, UINT msg,
311 WPARAM wParam, LPARAM lParam )
313 DIALOGINFO * dlgInfo;
315 WND * wndPtr = WIN_FindWndPtr( hwnd );
317 if (!wndPtr) return 0;
318 dlgInfo = (DIALOGINFO *)&wndPtr->wExtra;
319 dlgInfo->msgResult = 0;
321 if (dlgInfo->dlgProc) { /* Call dialog procedure */
322 result = CallWindowProcA( (WNDPROC)dlgInfo->dlgProc,
323 hwnd, msg, wParam, lParam );
324 /* 16 bit dlg procs only return BOOL16 */
325 if( WINPROC_GetProcType( dlgInfo->dlgProc ) == WIN_PROC_16 )
326 result = LOWORD(result);
329 if (!result && IsWindow(hwnd))
331 /* callback didn't process this message */
345 case WM_ENTERMENULOOP:
347 case WM_NCLBUTTONDOWN:
348 WIN_ReleaseWndPtr(wndPtr);
349 return DEFDLG_Proc( (HWND)hwnd, msg,
350 (WPARAM)wParam, lParam, dlgInfo );
358 WIN_ReleaseWndPtr(wndPtr);
359 return DefWindowProcA( hwnd, msg, wParam, lParam );
362 WIN_ReleaseWndPtr(wndPtr);
363 return DEFDLG_Epilog(dlgInfo, msg, result);
367 /***********************************************************************
368 * DefDlgProcW (USER32.@)
370 LRESULT WINAPI DefDlgProcW( HWND hwnd, UINT msg, WPARAM wParam,
373 DIALOGINFO * dlgInfo;
375 WND * wndPtr = WIN_FindWndPtr( hwnd );
377 if (!wndPtr) return 0;
378 dlgInfo = (DIALOGINFO *)&wndPtr->wExtra;
379 dlgInfo->msgResult = 0;
381 if (dlgInfo->dlgProc) { /* Call dialog procedure */
382 result = CallWindowProcW( (WNDPROC)dlgInfo->dlgProc,
383 hwnd, msg, wParam, lParam );
384 /* 16 bit dlg procs only return BOOL16 */
385 if( WINPROC_GetProcType( dlgInfo->dlgProc ) == WIN_PROC_16 )
386 result = LOWORD(result);
389 if (!result && IsWindow(hwnd))
391 /* callback didn't process this message */
405 case WM_ENTERMENULOOP:
407 case WM_NCLBUTTONDOWN:
408 WIN_ReleaseWndPtr(wndPtr);
409 return DEFDLG_Proc( (HWND)hwnd, msg,
410 (WPARAM)wParam, lParam, dlgInfo );
418 WIN_ReleaseWndPtr(wndPtr);
419 return DefWindowProcW( hwnd, msg, wParam, lParam );
422 WIN_ReleaseWndPtr(wndPtr);
423 return DEFDLG_Epilog(dlgInfo, msg, result);