2 * Default dialog procedure
4 * Copyright 1993, 1996 Alexandre Julliard
10 #include "wine/winuser16.h"
16 /***********************************************************************
19 * Set the focus to a control of the dialog, selecting the text if
20 * the control is an edit dialog.
22 static void DEFDLG_SetFocus( HWND hwndDlg
, HWND hwndCtrl
)
24 HWND hwndPrev
= GetFocus();
26 if (IsChild( hwndDlg
, hwndPrev
))
28 if (SendMessage16( hwndPrev
, WM_GETDLGCODE
, 0, 0 ) & DLGC_HASSETSEL
)
29 SendMessage16( hwndPrev
, EM_SETSEL16
, TRUE
, MAKELONG( -1, 0 ) );
31 if (SendMessage16( hwndCtrl
, WM_GETDLGCODE
, 0, 0 ) & DLGC_HASSETSEL
)
32 SendMessage16( hwndCtrl
, EM_SETSEL16
, FALSE
, MAKELONG( 0, -1 ) );
37 /***********************************************************************
40 static BOOL
DEFDLG_SaveFocus( HWND hwnd
, DIALOGINFO
*infoPtr
)
42 HWND hwndFocus
= GetFocus();
44 if (!hwndFocus
|| !IsChild( hwnd
, hwndFocus
)) return FALSE
;
45 infoPtr
->hwndFocus
= hwndFocus
;
46 /* Remove default button */
51 /***********************************************************************
54 static BOOL
DEFDLG_RestoreFocus( HWND hwnd
, DIALOGINFO
*infoPtr
)
56 if (!infoPtr
->hwndFocus
|| IsIconic(hwnd
)) return FALSE
;
57 if (!IsWindow( infoPtr
->hwndFocus
)) return FALSE
;
59 /* Don't set the focus back to controls if EndDialog is already called.*/
60 if (!(infoPtr
->flags
& DF_END
))
61 DEFDLG_SetFocus( hwnd
, infoPtr
->hwndFocus
);
63 /* This used to set infoPtr->hwndFocus to NULL for no apparent reason,
64 sometimes losing focus when receiving WM_SETFOCUS messages. */
69 /***********************************************************************
70 * DEFDLG_FindDefButton
72 * Find the current default push-button.
74 static HWND
DEFDLG_FindDefButton( HWND hwndDlg
)
76 HWND hwndChild
= GetWindow( hwndDlg
, GW_CHILD
);
79 if (SendMessage16( hwndChild
, WM_GETDLGCODE
, 0, 0 ) & DLGC_DEFPUSHBUTTON
)
81 hwndChild
= GetWindow( hwndChild
, GW_HWNDNEXT
);
87 /***********************************************************************
90 * Set the new default button to be hwndNew.
92 static BOOL
DEFDLG_SetDefButton( HWND hwndDlg
, DIALOGINFO
*dlgInfo
,
96 !(SendMessage16(hwndNew
, WM_GETDLGCODE
, 0, 0 ) & DLGC_UNDEFPUSHBUTTON
))
97 return FALSE
; /* Destination is not a push button */
99 if (dlgInfo
->idResult
) /* There's already a default pushbutton */
101 HWND hwndOld
= GetDlgItem( hwndDlg
, dlgInfo
->idResult
);
102 if (SendMessageA( hwndOld
, WM_GETDLGCODE
, 0, 0) & DLGC_DEFPUSHBUTTON
)
103 SendMessageA( hwndOld
, BM_SETSTYLE
, BS_PUSHBUTTON
, TRUE
);
107 SendMessageA( hwndNew
, BM_SETSTYLE
, BS_DEFPUSHBUTTON
, TRUE
);
108 dlgInfo
->idResult
= GetDlgCtrlID( hwndNew
);
110 else dlgInfo
->idResult
= 0;
115 /***********************************************************************
118 * Implementation of DefDlgProc(). Only handle messages that need special
119 * handling for dialogs.
121 static LRESULT
DEFDLG_Proc( HWND hwnd
, UINT msg
, WPARAM wParam
,
122 LPARAM lParam
, DIALOGINFO
*dlgInfo
)
127 FillWindow16( hwnd
, hwnd
, (HDC16
)wParam
, (HBRUSH16
)CTLCOLOR_DLG
);
132 /* Free dialog heap (if created) */
133 if (dlgInfo
->hDialogHeap
)
135 GlobalUnlock16(dlgInfo
->hDialogHeap
);
136 GlobalFree16(dlgInfo
->hDialogHeap
);
137 dlgInfo
->hDialogHeap
= 0;
141 if (dlgInfo
->hUserFont
)
143 DeleteObject( dlgInfo
->hUserFont
);
144 dlgInfo
->hUserFont
= 0;
150 DestroyMenu( dlgInfo
->hMenu
);
154 /* Delete window procedure */
155 WINPROC_FreeProc( dlgInfo
->dlgProc
, WIN_PROC_WINDOW
);
156 dlgInfo
->dlgProc
= (HWINDOWPROC
)0;
157 dlgInfo
->flags
|= DF_END
; /* just in case */
159 /* Window clean-up */
160 return DefWindowProcA( hwnd
, msg
, wParam
, lParam
);
163 if (!wParam
) DEFDLG_SaveFocus( hwnd
, dlgInfo
);
164 return DefWindowProcA( hwnd
, msg
, wParam
, lParam
);
167 if (wParam
) DEFDLG_RestoreFocus( hwnd
, dlgInfo
);
168 else DEFDLG_SaveFocus( hwnd
, dlgInfo
);
172 DEFDLG_RestoreFocus( hwnd
, dlgInfo
);
176 if (dlgInfo
->flags
& DF_END
) return 1;
177 DEFDLG_SetDefButton( hwnd
, dlgInfo
,
178 wParam
? GetDlgItem( hwnd
, wParam
) : 0 );
184 if (dlgInfo
->flags
& DF_END
) return 0;
185 if (dlgInfo
->idResult
)
186 return MAKELONG( dlgInfo
->idResult
, DC_HASDEFID
);
187 if ((hwndDefId
= DEFDLG_FindDefButton( hwnd
)))
188 return MAKELONG( GetDlgCtrlID( hwndDefId
), DC_HASDEFID
);
194 HWND hwndDest
= (HWND
)wParam
;
196 hwndDest
= GetNextDlgTabItem(hwnd
, GetFocus(), wParam
);
197 if (hwndDest
) DEFDLG_SetFocus( hwnd
, hwndDest
);
198 DEFDLG_SetDefButton( hwnd
, dlgInfo
, hwndDest
);
202 case WM_ENTERMENULOOP
:
204 case WM_NCLBUTTONDOWN
:
206 HWND hwndFocus
= GetFocus();
209 WND
*wnd
= WIN_FindWndPtr( hwndFocus
);
213 /* always make combo box hide its listbox control */
215 if( WIDGETS_IsControl( wnd
, BIC32_COMBO
) )
216 SendMessageA( hwndFocus
, CB_SHOWDROPDOWN
,
218 else if( WIDGETS_IsControl( wnd
, BIC32_EDIT
) &&
219 WIDGETS_IsControl( wnd
->parent
,
221 SendMessageA( wnd
->parent
->hwndSelf
,
222 CB_SHOWDROPDOWN
, FALSE
, 0 );
224 WIN_ReleaseWndPtr(wnd
);
227 return DefWindowProcA( hwnd
, msg
, wParam
, lParam
);
230 return dlgInfo
->hUserFont
;
233 PostMessageA( hwnd
, WM_COMMAND
, IDCANCEL
,
234 (LPARAM
)GetDlgItem( hwnd
, IDCANCEL
) );
237 case WM_NOTIFYFORMAT
:
238 return DefWindowProcA( hwnd
, msg
, wParam
, lParam
);
243 /***********************************************************************
246 static LRESULT
DEFDLG_Epilog(DIALOGINFO
* dlgInfo
, UINT msg
, BOOL fResult
)
250 if ((msg
>= WM_CTLCOLORMSGBOX
&& msg
<= WM_CTLCOLORSTATIC
) ||
251 msg
== WM_CTLCOLOR
|| msg
== WM_COMPAREITEM
||
252 msg
== WM_VKEYTOITEM
|| msg
== WM_CHARTOITEM
||
253 msg
== WM_QUERYDRAGICON
|| msg
== WM_INITDIALOG
)
256 return dlgInfo
->msgResult
;
259 /***********************************************************************
260 * DefDlgProc16 (USER.308)
262 LRESULT WINAPI
DefDlgProc16( HWND16 hwnd
, UINT16 msg
, WPARAM16 wParam
,
265 DIALOGINFO
* dlgInfo
;
267 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
269 if (!wndPtr
) return 0;
270 dlgInfo
= (DIALOGINFO
*)&wndPtr
->wExtra
;
271 dlgInfo
->msgResult
= 0;
273 if (dlgInfo
->dlgProc
) { /* Call dialog procedure */
274 result
= CallWindowProc16( (WNDPROC16
)dlgInfo
->dlgProc
,
275 hwnd
, msg
, wParam
, lParam
);
276 /* 16 bit dlg procs only return BOOL16 */
277 if( WINPROC_GetProcType( dlgInfo
->dlgProc
) == WIN_PROC_16
)
278 result
= LOWORD(result
);
281 if (!result
&& IsWindow(hwnd
))
283 /* callback didn't process this message */
297 case WM_ENTERMENULOOP
:
299 case WM_NCLBUTTONDOWN
:
300 WIN_ReleaseWndPtr(wndPtr
);
301 return DEFDLG_Proc( (HWND
)hwnd
, msg
,
302 (WPARAM
)wParam
, lParam
, dlgInfo
);
310 WIN_ReleaseWndPtr(wndPtr
);
311 return DefWindowProc16( hwnd
, msg
, wParam
, lParam
);
314 WIN_ReleaseWndPtr(wndPtr
);
315 return DEFDLG_Epilog(dlgInfo
, msg
, result
);
319 /***********************************************************************
320 * DefDlgProc32A (USER32.120)
322 LRESULT WINAPI
DefDlgProcA( HWND hwnd
, UINT msg
,
323 WPARAM wParam
, LPARAM lParam
)
325 DIALOGINFO
* dlgInfo
;
327 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
329 if (!wndPtr
) return 0;
330 dlgInfo
= (DIALOGINFO
*)&wndPtr
->wExtra
;
331 dlgInfo
->msgResult
= 0;
333 if (dlgInfo
->dlgProc
) { /* Call dialog procedure */
334 result
= CallWindowProcA( (WNDPROC
)dlgInfo
->dlgProc
,
335 hwnd
, msg
, wParam
, lParam
);
336 /* 16 bit dlg procs only return BOOL16 */
337 if( WINPROC_GetProcType( dlgInfo
->dlgProc
) == WIN_PROC_16
)
338 result
= LOWORD(result
);
341 if (!result
&& IsWindow(hwnd
))
343 /* callback didn't process this message */
357 case WM_ENTERMENULOOP
:
359 case WM_NCLBUTTONDOWN
:
360 WIN_ReleaseWndPtr(wndPtr
);
361 return DEFDLG_Proc( (HWND
)hwnd
, msg
,
362 (WPARAM
)wParam
, lParam
, dlgInfo
);
370 WIN_ReleaseWndPtr(wndPtr
);
371 return DefWindowProcA( hwnd
, msg
, wParam
, lParam
);
374 WIN_ReleaseWndPtr(wndPtr
);
375 return DEFDLG_Epilog(dlgInfo
, msg
, result
);
379 /***********************************************************************
380 * DefDlgProc32W (USER32.121)
382 LRESULT WINAPI
DefDlgProcW( HWND hwnd
, UINT msg
, WPARAM wParam
,
385 DIALOGINFO
* dlgInfo
;
387 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
389 if (!wndPtr
) return 0;
390 dlgInfo
= (DIALOGINFO
*)&wndPtr
->wExtra
;
391 dlgInfo
->msgResult
= 0;
393 if (dlgInfo
->dlgProc
) { /* Call dialog procedure */
394 result
= CallWindowProcW( (WNDPROC
)dlgInfo
->dlgProc
,
395 hwnd
, msg
, wParam
, lParam
);
396 /* 16 bit dlg procs only return BOOL16 */
397 if( WINPROC_GetProcType( dlgInfo
->dlgProc
) == WIN_PROC_16
)
398 result
= LOWORD(result
);
401 if (!result
&& IsWindow(hwnd
))
403 /* callback didn't process this message */
417 case WM_ENTERMENULOOP
:
419 case WM_NCLBUTTONDOWN
:
420 WIN_ReleaseWndPtr(wndPtr
);
421 return DEFDLG_Proc( (HWND
)hwnd
, msg
,
422 (WPARAM
)wParam
, lParam
, dlgInfo
);
430 WIN_ReleaseWndPtr(wndPtr
);
431 return DefWindowProcW( hwnd
, msg
, wParam
, lParam
);
434 WIN_ReleaseWndPtr(wndPtr
);
435 return DEFDLG_Epilog(dlgInfo
, msg
, result
);