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 (SendMessage16( hwndPrev
, WM_GETDLGCODE
, 0, 0 ) & DLGC_HASSETSEL
)
30 SendMessage16( hwndPrev
, EM_SETSEL16
, TRUE
, MAKELONG( -1, 0 ) );
32 if (SendMessage16( hwndCtrl
, WM_GETDLGCODE
, 0, 0 ) & DLGC_HASSETSEL
)
33 SendMessage16( hwndCtrl
, EM_SETSEL16
, FALSE
, MAKELONG( 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 (SendMessage16( 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 !(SendMessage16(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 WND
*wnd
= WIN_FindWndPtr( hwndFocus
);
214 /* always make combo box hide its listbox control */
216 if( WIDGETS_IsControl( wnd
, BIC32_COMBO
) )
217 SendMessageA( hwndFocus
, CB_SHOWDROPDOWN
,
219 else if( WIDGETS_IsControl( wnd
, BIC32_EDIT
) &&
220 WIDGETS_IsControl( wnd
->parent
,
222 SendMessageA( wnd
->parent
->hwndSelf
,
223 CB_SHOWDROPDOWN
, FALSE
, 0 );
225 WIN_ReleaseWndPtr(wnd
);
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(DIALOGINFO
* dlgInfo
, 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 dlgInfo
->msgResult
;
260 /***********************************************************************
261 * DefDlgProc16 (USER.308)
263 LRESULT WINAPI
DefDlgProc16( HWND16 hwnd
, UINT16 msg
, WPARAM16 wParam
,
266 DIALOGINFO
* dlgInfo
;
268 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
270 if (!wndPtr
) return 0;
271 dlgInfo
= (DIALOGINFO
*)&wndPtr
->wExtra
;
272 dlgInfo
->msgResult
= 0;
274 if (dlgInfo
->dlgProc
) { /* Call dialog procedure */
275 result
= CallWindowProc16( (WNDPROC16
)dlgInfo
->dlgProc
,
276 hwnd
, msg
, wParam
, lParam
);
277 /* 16 bit dlg procs only return BOOL16 */
278 if( WINPROC_GetProcType( dlgInfo
->dlgProc
) == WIN_PROC_16
)
279 result
= LOWORD(result
);
282 if (!result
&& IsWindow(hwnd
))
284 /* callback didn't process this message */
298 case WM_ENTERMENULOOP
:
300 case WM_NCLBUTTONDOWN
:
301 WIN_ReleaseWndPtr(wndPtr
);
302 return DEFDLG_Proc( (HWND
)hwnd
, msg
,
303 (WPARAM
)wParam
, lParam
, dlgInfo
);
311 WIN_ReleaseWndPtr(wndPtr
);
312 return DefWindowProc16( hwnd
, msg
, wParam
, lParam
);
315 WIN_ReleaseWndPtr(wndPtr
);
316 return DEFDLG_Epilog(dlgInfo
, msg
, result
);
320 /***********************************************************************
321 * DefDlgProcA (USER32.120)
323 LRESULT WINAPI
DefDlgProcA( HWND hwnd
, UINT msg
,
324 WPARAM wParam
, LPARAM lParam
)
326 DIALOGINFO
* dlgInfo
;
328 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
330 if (!wndPtr
) return 0;
331 dlgInfo
= (DIALOGINFO
*)&wndPtr
->wExtra
;
332 dlgInfo
->msgResult
= 0;
334 if (dlgInfo
->dlgProc
) { /* Call dialog procedure */
335 result
= CallWindowProcA( (WNDPROC
)dlgInfo
->dlgProc
,
336 hwnd
, msg
, wParam
, lParam
);
337 /* 16 bit dlg procs only return BOOL16 */
338 if( WINPROC_GetProcType( dlgInfo
->dlgProc
) == WIN_PROC_16
)
339 result
= LOWORD(result
);
342 if (!result
&& IsWindow(hwnd
))
344 /* callback didn't process this message */
358 case WM_ENTERMENULOOP
:
360 case WM_NCLBUTTONDOWN
:
361 WIN_ReleaseWndPtr(wndPtr
);
362 return DEFDLG_Proc( (HWND
)hwnd
, msg
,
363 (WPARAM
)wParam
, lParam
, dlgInfo
);
371 WIN_ReleaseWndPtr(wndPtr
);
372 return DefWindowProcA( hwnd
, msg
, wParam
, lParam
);
375 WIN_ReleaseWndPtr(wndPtr
);
376 return DEFDLG_Epilog(dlgInfo
, msg
, result
);
380 /***********************************************************************
381 * DefDlgProcW (USER32.121)
383 LRESULT WINAPI
DefDlgProcW( HWND hwnd
, UINT msg
, WPARAM wParam
,
386 DIALOGINFO
* dlgInfo
;
388 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
390 if (!wndPtr
) return 0;
391 dlgInfo
= (DIALOGINFO
*)&wndPtr
->wExtra
;
392 dlgInfo
->msgResult
= 0;
394 if (dlgInfo
->dlgProc
) { /* Call dialog procedure */
395 result
= CallWindowProcW( (WNDPROC
)dlgInfo
->dlgProc
,
396 hwnd
, msg
, wParam
, lParam
);
397 /* 16 bit dlg procs only return BOOL16 */
398 if( WINPROC_GetProcType( dlgInfo
->dlgProc
) == WIN_PROC_16
)
399 result
= LOWORD(result
);
402 if (!result
&& IsWindow(hwnd
))
404 /* callback didn't process this message */
418 case WM_ENTERMENULOOP
:
420 case WM_NCLBUTTONDOWN
:
421 WIN_ReleaseWndPtr(wndPtr
);
422 return DEFDLG_Proc( (HWND
)hwnd
, msg
,
423 (WPARAM
)wParam
, lParam
, dlgInfo
);
431 WIN_ReleaseWndPtr(wndPtr
);
432 return DefWindowProcW( hwnd
, msg
, wParam
, lParam
);
435 WIN_ReleaseWndPtr(wndPtr
);
436 return DEFDLG_Epilog(dlgInfo
, msg
, result
);