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
);