2 * Default dialog procedure
4 * Copyright 1993, 1996 Alexandre Julliard
8 #include "wine/winuser16.h"
14 /***********************************************************************
17 * Set the focus to a control of the dialog, selecting the text if
18 * the control is an edit dialog.
20 static void DEFDLG_SetFocus( HWND hwndDlg
, HWND hwndCtrl
)
22 HWND hwndPrev
= GetFocus();
24 if (IsChild( hwndDlg
, hwndPrev
))
26 if (SendMessage16( hwndPrev
, WM_GETDLGCODE
, 0, 0 ) & DLGC_HASSETSEL
)
27 SendMessage16( hwndPrev
, EM_SETSEL16
, TRUE
, MAKELONG( -1, 0 ) );
29 if (SendMessage16( hwndCtrl
, WM_GETDLGCODE
, 0, 0 ) & DLGC_HASSETSEL
)
30 SendMessage16( hwndCtrl
, EM_SETSEL16
, FALSE
, MAKELONG( 0, -1 ) );
35 /***********************************************************************
38 static BOOL
DEFDLG_SaveFocus( HWND hwnd
, DIALOGINFO
*infoPtr
)
40 HWND hwndFocus
= GetFocus();
42 if (!hwndFocus
|| !IsChild( hwnd
, hwndFocus
)) return FALSE
;
43 infoPtr
->hwndFocus
= hwndFocus
;
44 /* Remove default button */
49 /***********************************************************************
52 static BOOL
DEFDLG_RestoreFocus( HWND hwnd
, DIALOGINFO
*infoPtr
)
54 if (!infoPtr
->hwndFocus
|| IsIconic(hwnd
)) return FALSE
;
55 if (!IsWindow( infoPtr
->hwndFocus
)) return FALSE
;
57 /* Don't set the focus back to controls if EndDialog is already called.*/
58 if (!(infoPtr
->flags
& DF_END
))
59 DEFDLG_SetFocus( hwnd
, infoPtr
->hwndFocus
);
61 /* This used to set infoPtr->hwndFocus to NULL for no apparent reason,
62 sometimes losing focus when receiving WM_SETFOCUS messages. */
67 /***********************************************************************
68 * DEFDLG_FindDefButton
70 * Find the current default push-button.
72 static HWND
DEFDLG_FindDefButton( HWND hwndDlg
)
74 HWND hwndChild
= GetWindow( hwndDlg
, GW_CHILD
);
77 if (SendMessage16( hwndChild
, WM_GETDLGCODE
, 0, 0 ) & DLGC_DEFPUSHBUTTON
)
79 hwndChild
= GetWindow( hwndChild
, GW_HWNDNEXT
);
85 /***********************************************************************
88 * Set the new default button to be hwndNew.
90 static BOOL
DEFDLG_SetDefButton( HWND hwndDlg
, DIALOGINFO
*dlgInfo
,
94 !(SendMessage16(hwndNew
, WM_GETDLGCODE
, 0, 0 ) & DLGC_UNDEFPUSHBUTTON
))
95 return FALSE
; /* Destination is not a push button */
97 if (dlgInfo
->idResult
) /* There's already a default pushbutton */
99 HWND hwndOld
= GetDlgItem( hwndDlg
, dlgInfo
->idResult
);
100 if (SendMessageA( hwndOld
, WM_GETDLGCODE
, 0, 0) & DLGC_DEFPUSHBUTTON
)
101 SendMessageA( hwndOld
, BM_SETSTYLE
, BS_PUSHBUTTON
, TRUE
);
105 SendMessageA( hwndNew
, BM_SETSTYLE
, BS_DEFPUSHBUTTON
, TRUE
);
106 dlgInfo
->idResult
= GetDlgCtrlID( hwndNew
);
108 else dlgInfo
->idResult
= 0;
113 /***********************************************************************
116 * Implementation of DefDlgProc(). Only handle messages that need special
117 * handling for dialogs.
119 static LRESULT
DEFDLG_Proc( HWND hwnd
, UINT msg
, WPARAM wParam
,
120 LPARAM lParam
, DIALOGINFO
*dlgInfo
)
125 FillWindow16( hwnd
, hwnd
, (HDC16
)wParam
, (HBRUSH16
)CTLCOLOR_DLG
);
130 /* Free dialog heap (if created) */
131 if (dlgInfo
->hDialogHeap
)
133 GlobalUnlock16(dlgInfo
->hDialogHeap
);
134 GlobalFree16(dlgInfo
->hDialogHeap
);
135 dlgInfo
->hDialogHeap
= 0;
139 if (dlgInfo
->hUserFont
)
141 DeleteObject( dlgInfo
->hUserFont
);
142 dlgInfo
->hUserFont
= 0;
148 DestroyMenu( dlgInfo
->hMenu
);
152 /* Delete window procedure */
153 WINPROC_FreeProc( dlgInfo
->dlgProc
, WIN_PROC_WINDOW
);
154 dlgInfo
->dlgProc
= (HWINDOWPROC
)0;
155 dlgInfo
->flags
|= DF_END
; /* just in case */
157 /* Window clean-up */
158 return DefWindowProcA( hwnd
, msg
, wParam
, lParam
);
161 if (!wParam
) DEFDLG_SaveFocus( hwnd
, dlgInfo
);
162 return DefWindowProcA( hwnd
, msg
, wParam
, lParam
);
165 if (wParam
) DEFDLG_RestoreFocus( hwnd
, dlgInfo
);
166 else DEFDLG_SaveFocus( hwnd
, dlgInfo
);
170 DEFDLG_RestoreFocus( hwnd
, dlgInfo
);
174 if (dlgInfo
->flags
& DF_END
) return 1;
175 DEFDLG_SetDefButton( hwnd
, dlgInfo
,
176 wParam
? GetDlgItem( hwnd
, wParam
) : 0 );
182 if (dlgInfo
->flags
& DF_END
) return 0;
183 if (dlgInfo
->idResult
)
184 return MAKELONG( dlgInfo
->idResult
, DC_HASDEFID
);
185 if ((hwndDefId
= DEFDLG_FindDefButton( hwnd
)))
186 return MAKELONG( GetDlgCtrlID( hwndDefId
), DC_HASDEFID
);
192 HWND hwndDest
= (HWND
)wParam
;
194 hwndDest
= GetNextDlgTabItem(hwnd
, GetFocus(), wParam
);
195 if (hwndDest
) DEFDLG_SetFocus( hwnd
, hwndDest
);
196 DEFDLG_SetDefButton( hwnd
, dlgInfo
, hwndDest
);
200 case WM_ENTERMENULOOP
:
202 case WM_NCLBUTTONDOWN
:
204 HWND hwndFocus
= GetFocus();
207 WND
*wnd
= WIN_FindWndPtr( hwndFocus
);
211 /* always make combo box hide its listbox control */
213 if( WIDGETS_IsControl( wnd
, BIC32_COMBO
) )
214 SendMessageA( hwndFocus
, CB_SHOWDROPDOWN
,
216 else if( WIDGETS_IsControl( wnd
, BIC32_EDIT
) &&
217 WIDGETS_IsControl( wnd
->parent
,
219 SendMessageA( wnd
->parent
->hwndSelf
,
220 CB_SHOWDROPDOWN
, FALSE
, 0 );
222 WIN_ReleaseWndPtr(wnd
);
225 return DefWindowProcA( hwnd
, msg
, wParam
, lParam
);
228 return dlgInfo
->hUserFont
;
231 PostMessageA( hwnd
, WM_COMMAND
, IDCANCEL
,
232 (LPARAM
)GetDlgItem( hwnd
, IDCANCEL
) );
235 case WM_NOTIFYFORMAT
:
236 return DefWindowProcA( hwnd
, msg
, wParam
, lParam
);
241 /***********************************************************************
244 static LRESULT
DEFDLG_Epilog(DIALOGINFO
* dlgInfo
, UINT msg
, BOOL fResult
)
248 if ((msg
>= WM_CTLCOLORMSGBOX
&& msg
<= WM_CTLCOLORSTATIC
) ||
249 msg
== WM_CTLCOLOR
|| msg
== WM_COMPAREITEM
||
250 msg
== WM_VKEYTOITEM
|| msg
== WM_CHARTOITEM
||
251 msg
== WM_QUERYDRAGICON
|| msg
== WM_INITDIALOG
)
254 return dlgInfo
->msgResult
;
257 /***********************************************************************
258 * DefDlgProc16 (USER.308)
260 LRESULT WINAPI
DefDlgProc16( HWND16 hwnd
, UINT16 msg
, WPARAM16 wParam
,
263 DIALOGINFO
* dlgInfo
;
265 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
267 if (!wndPtr
) return 0;
268 dlgInfo
= (DIALOGINFO
*)&wndPtr
->wExtra
;
269 dlgInfo
->msgResult
= 0;
271 if (dlgInfo
->dlgProc
) { /* Call dialog procedure */
272 result
= CallWindowProc16( (WNDPROC16
)dlgInfo
->dlgProc
,
273 hwnd
, msg
, wParam
, lParam
);
274 /* 16 bit dlg procs only return BOOL16 */
275 if( WINPROC_GetProcType( dlgInfo
->dlgProc
) == WIN_PROC_16
)
276 result
= LOWORD(result
);
279 if (!result
&& IsWindow(hwnd
))
281 /* callback didn't process this message */
295 case WM_ENTERMENULOOP
:
297 case WM_NCLBUTTONDOWN
:
298 WIN_ReleaseWndPtr(wndPtr
);
299 return DEFDLG_Proc( (HWND
)hwnd
, msg
,
300 (WPARAM
)wParam
, lParam
, dlgInfo
);
308 WIN_ReleaseWndPtr(wndPtr
);
309 return DefWindowProc16( hwnd
, msg
, wParam
, lParam
);
312 WIN_ReleaseWndPtr(wndPtr
);
313 return DEFDLG_Epilog(dlgInfo
, msg
, result
);
317 /***********************************************************************
318 * DefDlgProc32A (USER32.120)
320 LRESULT WINAPI
DefDlgProcA( HWND hwnd
, UINT msg
,
321 WPARAM wParam
, LPARAM lParam
)
323 DIALOGINFO
* dlgInfo
;
325 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
327 if (!wndPtr
) return 0;
328 dlgInfo
= (DIALOGINFO
*)&wndPtr
->wExtra
;
329 dlgInfo
->msgResult
= 0;
331 if (dlgInfo
->dlgProc
) { /* Call dialog procedure */
332 result
= CallWindowProcA( (WNDPROC
)dlgInfo
->dlgProc
,
333 hwnd
, msg
, wParam
, lParam
);
334 /* 16 bit dlg procs only return BOOL16 */
335 if( WINPROC_GetProcType( dlgInfo
->dlgProc
) == WIN_PROC_16
)
336 result
= LOWORD(result
);
339 if (!result
&& IsWindow(hwnd
))
341 /* callback didn't process this message */
355 case WM_ENTERMENULOOP
:
357 case WM_NCLBUTTONDOWN
:
358 WIN_ReleaseWndPtr(wndPtr
);
359 return DEFDLG_Proc( (HWND
)hwnd
, msg
,
360 (WPARAM
)wParam
, lParam
, dlgInfo
);
368 WIN_ReleaseWndPtr(wndPtr
);
369 return DefWindowProcA( hwnd
, msg
, wParam
, lParam
);
372 WIN_ReleaseWndPtr(wndPtr
);
373 return DEFDLG_Epilog(dlgInfo
, msg
, result
);
377 /***********************************************************************
378 * DefDlgProc32W (USER32.121)
380 LRESULT WINAPI
DefDlgProcW( HWND hwnd
, UINT msg
, WPARAM wParam
,
383 DIALOGINFO
* dlgInfo
;
385 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
387 if (!wndPtr
) return 0;
388 dlgInfo
= (DIALOGINFO
*)&wndPtr
->wExtra
;
389 dlgInfo
->msgResult
= 0;
391 if (dlgInfo
->dlgProc
) { /* Call dialog procedure */
392 result
= CallWindowProcW( (WNDPROC
)dlgInfo
->dlgProc
,
393 hwnd
, msg
, wParam
, lParam
);
394 /* 16 bit dlg procs only return BOOL16 */
395 if( WINPROC_GetProcType( dlgInfo
->dlgProc
) == WIN_PROC_16
)
396 result
= LOWORD(result
);
399 if (!result
&& IsWindow(hwnd
))
401 /* callback didn't process this message */
415 case WM_ENTERMENULOOP
:
417 case WM_NCLBUTTONDOWN
:
418 WIN_ReleaseWndPtr(wndPtr
);
419 return DEFDLG_Proc( (HWND
)hwnd
, msg
,
420 (WPARAM
)wParam
, lParam
, dlgInfo
);
428 WIN_ReleaseWndPtr(wndPtr
);
429 return DefWindowProcW( hwnd
, msg
, wParam
, lParam
);
432 WIN_ReleaseWndPtr(wndPtr
);
433 return DEFDLG_Epilog(dlgInfo
, msg
, result
);