2 * Default dialog procedure
4 * Copyright 1993, 1996 Alexandre Julliard
11 #include "wine/winuser16.h"
17 /***********************************************************************
20 static WNDPROC
DEFDLG_GetDlgProc( HWND hwnd
)
23 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
26 ret
= *(WNDPROC
*)((char *)wndPtr
->wExtra
+ DWL_DLGPROC
);
27 WIN_ReleaseWndPtr(wndPtr
);
32 /***********************************************************************
35 * Set the focus to a control of the dialog, selecting the text if
36 * the control is an edit dialog.
38 static void DEFDLG_SetFocus( HWND hwndDlg
, HWND hwndCtrl
)
40 HWND hwndPrev
= GetFocus();
42 if (IsChild( hwndDlg
, hwndPrev
))
44 if (SendMessageW( hwndPrev
, WM_GETDLGCODE
, 0, 0 ) & DLGC_HASSETSEL
)
45 SendMessageW( hwndPrev
, EM_SETSEL
, -1, 0 );
47 if (SendMessageW( hwndCtrl
, WM_GETDLGCODE
, 0, 0 ) & DLGC_HASSETSEL
)
48 SendMessageW( hwndCtrl
, EM_SETSEL
, 0, -1 );
53 /***********************************************************************
56 static void DEFDLG_SaveFocus( HWND hwnd
)
59 HWND hwndFocus
= GetFocus();
61 if (!hwndFocus
|| !IsChild( hwnd
, hwndFocus
)) return;
62 if (!(infoPtr
= DIALOG_get_info( hwnd
))) return;
63 infoPtr
->hwndFocus
= hwndFocus
;
64 /* Remove default button */
68 /***********************************************************************
71 static void DEFDLG_RestoreFocus( HWND hwnd
)
75 if (IsIconic( hwnd
)) return;
76 if (!(infoPtr
= DIALOG_get_info( hwnd
))) return;
77 if (!IsWindow( infoPtr
->hwndFocus
)) return;
78 /* Don't set the focus back to controls if EndDialog is already called.*/
79 if (!(infoPtr
->flags
& DF_END
))
81 DEFDLG_SetFocus( hwnd
, infoPtr
->hwndFocus
);
84 /* This used to set infoPtr->hwndFocus to NULL for no apparent reason,
85 sometimes losing focus when receiving WM_SETFOCUS messages. */
89 /***********************************************************************
90 * DEFDLG_FindDefButton
92 * Find the current default push-button.
94 static HWND
DEFDLG_FindDefButton( HWND hwndDlg
)
96 HWND hwndChild
= GetWindow( hwndDlg
, GW_CHILD
);
99 if (SendMessageW( hwndChild
, WM_GETDLGCODE
, 0, 0 ) & DLGC_DEFPUSHBUTTON
)
101 hwndChild
= GetWindow( hwndChild
, GW_HWNDNEXT
);
107 /***********************************************************************
108 * DEFDLG_SetDefButton
110 * Set the new default button to be hwndNew.
112 static BOOL
DEFDLG_SetDefButton( HWND hwndDlg
, DIALOGINFO
*dlgInfo
,
116 !(SendMessageW(hwndNew
, WM_GETDLGCODE
, 0, 0 ) & DLGC_UNDEFPUSHBUTTON
))
117 return FALSE
; /* Destination is not a push button */
119 if (dlgInfo
->idResult
) /* There's already a default pushbutton */
121 HWND hwndOld
= GetDlgItem( hwndDlg
, dlgInfo
->idResult
);
122 if (SendMessageA( hwndOld
, WM_GETDLGCODE
, 0, 0) & DLGC_DEFPUSHBUTTON
)
123 SendMessageA( hwndOld
, BM_SETSTYLE
, BS_PUSHBUTTON
, TRUE
);
127 SendMessageA( hwndNew
, BM_SETSTYLE
, BS_DEFPUSHBUTTON
, TRUE
);
128 dlgInfo
->idResult
= GetDlgCtrlID( hwndNew
);
130 else dlgInfo
->idResult
= 0;
135 /***********************************************************************
138 * Implementation of DefDlgProc(). Only handle messages that need special
139 * handling for dialogs.
141 static LRESULT
DEFDLG_Proc( HWND hwnd
, UINT msg
, WPARAM wParam
,
142 LPARAM lParam
, DIALOGINFO
*dlgInfo
)
148 HBRUSH brush
= SendMessageW( hwnd
, WM_CTLCOLORDLG
, wParam
, (LPARAM
)hwnd
);
149 if (!brush
) brush
= DefWindowProcW( hwnd
, WM_CTLCOLORDLG
, wParam
, (LPARAM
)hwnd
);
153 HDC hdc
= (HDC
)wParam
;
154 GetClientRect( hwnd
, &rect
);
155 DPtoLP( hdc
, (LPPOINT
)&rect
, 2 );
156 FillRect( hdc
, &rect
, brush
);
161 if ((dlgInfo
= (DIALOGINFO
*)SetWindowLongW( hwnd
, DWL_WINE_DIALOGINFO
, 0 )))
163 /* Free dialog heap (if created) */
164 if (dlgInfo
->hDialogHeap
)
166 GlobalUnlock16(dlgInfo
->hDialogHeap
);
167 GlobalFree16(dlgInfo
->hDialogHeap
);
169 if (dlgInfo
->hUserFont
) DeleteObject( dlgInfo
->hUserFont
);
170 if (dlgInfo
->hMenu
) DestroyMenu( dlgInfo
->hMenu
);
171 WINPROC_FreeProc( DEFDLG_GetDlgProc( hwnd
), WIN_PROC_WINDOW
);
172 HeapFree( GetProcessHeap(), 0, dlgInfo
);
174 /* Window clean-up */
175 return DefWindowProcA( hwnd
, msg
, wParam
, lParam
);
178 if (!wParam
) DEFDLG_SaveFocus( hwnd
);
179 return DefWindowProcA( hwnd
, msg
, wParam
, lParam
);
182 if (wParam
) DEFDLG_RestoreFocus( hwnd
);
183 else DEFDLG_SaveFocus( hwnd
);
187 DEFDLG_RestoreFocus( hwnd
);
191 if (dlgInfo
->flags
& DF_END
) return 1;
192 DEFDLG_SetDefButton( hwnd
, dlgInfo
,
193 wParam
? GetDlgItem( hwnd
, wParam
) : 0 );
199 if (dlgInfo
->flags
& DF_END
) return 0;
200 if (dlgInfo
->idResult
)
201 return MAKELONG( dlgInfo
->idResult
, DC_HASDEFID
);
202 if ((hwndDefId
= DEFDLG_FindDefButton( hwnd
)))
203 return MAKELONG( GetDlgCtrlID( hwndDefId
), DC_HASDEFID
);
209 HWND hwndDest
= (HWND
)wParam
;
211 hwndDest
= GetNextDlgTabItem(hwnd
, GetFocus(), wParam
);
212 if (hwndDest
) DEFDLG_SetFocus( hwnd
, hwndDest
);
213 DEFDLG_SetDefButton( hwnd
, dlgInfo
, hwndDest
);
217 case WM_ENTERMENULOOP
:
219 case WM_NCLBUTTONDOWN
:
221 HWND hwndFocus
= GetFocus();
224 /* always make combo box hide its listbox control */
225 if (!SendMessageA( hwndFocus
, CB_SHOWDROPDOWN
, FALSE
, 0 ))
226 SendMessageA( GetParent(hwndFocus
), CB_SHOWDROPDOWN
, FALSE
, 0 );
229 return DefWindowProcA( hwnd
, msg
, wParam
, lParam
);
232 return dlgInfo
->hUserFont
;
235 PostMessageA( hwnd
, WM_COMMAND
, IDCANCEL
,
236 (LPARAM
)GetDlgItem( hwnd
, IDCANCEL
) );
239 case WM_NOTIFYFORMAT
:
240 return DefWindowProcA( hwnd
, msg
, wParam
, lParam
);
245 /***********************************************************************
248 static LRESULT
DEFDLG_Epilog(HWND hwnd
, UINT msg
, BOOL fResult
)
252 if ((msg
>= WM_CTLCOLORMSGBOX
&& msg
<= WM_CTLCOLORSTATIC
) ||
253 msg
== WM_CTLCOLOR
|| msg
== WM_COMPAREITEM
||
254 msg
== WM_VKEYTOITEM
|| msg
== WM_CHARTOITEM
||
255 msg
== WM_QUERYDRAGICON
|| msg
== WM_INITDIALOG
)
258 return GetWindowLongA( hwnd
, DWL_MSGRESULT
);
261 /***********************************************************************
262 * DefDlgProc (USER.308)
264 LRESULT WINAPI
DefDlgProc16( HWND16 hwnd
, UINT16 msg
, WPARAM16 wParam
,
268 HWND hwnd32
= WIN_Handle32( hwnd
);
271 SetWindowLongW( hwnd32
, DWL_MSGRESULT
, 0 );
273 if ((dlgproc
= (WNDPROC16
)DEFDLG_GetDlgProc( hwnd32
)))
275 /* Call dialog procedure */
276 result
= CallWindowProc16( dlgproc
, hwnd
, msg
, wParam
, lParam
);
277 /* 16 bit dlg procs only return BOOL16 */
278 if( WINPROC_GetProcType( dlgproc
) == WIN_PROC_16
)
279 result
= LOWORD(result
);
282 if (!result
&& IsWindow(hwnd32
))
284 /* callback didn't process this message */
298 case WM_ENTERMENULOOP
:
300 case WM_NCLBUTTONDOWN
:
301 return DEFDLG_Proc( hwnd32
, msg
, (WPARAM
)wParam
, lParam
, DIALOG_get_info(hwnd32
) );
309 return DefWindowProc16( hwnd
, msg
, wParam
, lParam
);
312 return DEFDLG_Epilog( hwnd32
, msg
, result
);
316 /***********************************************************************
317 * DefDlgProcA (USER32.@)
319 LRESULT WINAPI
DefDlgProcA( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
324 SetWindowLongW( hwnd
, DWL_MSGRESULT
, 0 );
326 if ((dlgproc
= DEFDLG_GetDlgProc( hwnd
)))
328 /* Call dialog procedure */
329 result
= CallWindowProcA( dlgproc
, hwnd
, msg
, wParam
, lParam
);
330 /* 16 bit dlg procs only return BOOL16 */
331 if( WINPROC_GetProcType( dlgproc
) == WIN_PROC_16
)
332 result
= LOWORD(result
);
335 if (!result
&& IsWindow(hwnd
))
337 /* callback didn't process this message */
351 case WM_ENTERMENULOOP
:
353 case WM_NCLBUTTONDOWN
:
354 return DEFDLG_Proc( hwnd
, msg
, wParam
, lParam
, DIALOG_get_info(hwnd
) );
362 return DefWindowProcA( hwnd
, msg
, wParam
, lParam
);
365 return DEFDLG_Epilog(hwnd
, msg
, result
);
369 /***********************************************************************
370 * DefDlgProcW (USER32.@)
372 LRESULT WINAPI
DefDlgProcW( HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
377 SetWindowLongW( hwnd
, DWL_MSGRESULT
, 0 );
379 if ((dlgproc
= DEFDLG_GetDlgProc( hwnd
)))
381 /* Call dialog procedure */
382 result
= CallWindowProcW( dlgproc
, hwnd
, msg
, wParam
, lParam
);
383 /* 16 bit dlg procs only return BOOL16 */
384 if( WINPROC_GetProcType( dlgproc
) == WIN_PROC_16
)
385 result
= LOWORD(result
);
388 if (!result
&& IsWindow(hwnd
))
390 /* callback didn't process this message */
404 case WM_ENTERMENULOOP
:
406 case WM_NCLBUTTONDOWN
:
407 return DEFDLG_Proc( hwnd
, msg
, wParam
, lParam
, DIALOG_get_info(hwnd
) );
415 return DefWindowProcW( hwnd
, msg
, wParam
, lParam
);
418 return DEFDLG_Epilog(hwnd
, msg
, result
);