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;
56 DEFDLG_SetFocus( hwnd, infoPtr->hwndFocus );
57 /* This used to set infoPtr->hwndFocus to NULL for no apparent reason,
58 sometimes losing focus when receiving WM_SETFOCUS messages. */
63 /***********************************************************************
64 * DEFDLG_FindDefButton
66 * Find the current default push-button.
68 static HWND DEFDLG_FindDefButton( HWND hwndDlg )
70 HWND hwndChild = GetWindow( hwndDlg, GW_CHILD );
73 if (SendMessage16( hwndChild, WM_GETDLGCODE, 0, 0 ) & DLGC_DEFPUSHBUTTON)
75 hwndChild = GetWindow( hwndChild, GW_HWNDNEXT );
81 /***********************************************************************
84 * Set the new default button to be hwndNew.
86 static BOOL DEFDLG_SetDefButton( HWND hwndDlg, DIALOGINFO *dlgInfo,
90 !(SendMessage16(hwndNew, WM_GETDLGCODE, 0, 0 ) & DLGC_UNDEFPUSHBUTTON))
91 return FALSE; /* Destination is not a push button */
93 if (dlgInfo->idResult) /* There's already a default pushbutton */
95 HWND hwndOld = GetDlgItem( hwndDlg, dlgInfo->idResult );
96 if (SendMessageA( hwndOld, WM_GETDLGCODE, 0, 0) & DLGC_DEFPUSHBUTTON)
97 SendMessageA( hwndOld, BM_SETSTYLE, BS_PUSHBUTTON, TRUE );
101 SendMessageA( hwndNew, BM_SETSTYLE, BS_DEFPUSHBUTTON, TRUE );
102 dlgInfo->idResult = GetDlgCtrlID( hwndNew );
104 else dlgInfo->idResult = 0;
109 /***********************************************************************
112 * Implementation of DefDlgProc(). Only handle messages that need special
113 * handling for dialogs.
115 static LRESULT DEFDLG_Proc( HWND hwnd, UINT msg, WPARAM wParam,
116 LPARAM lParam, DIALOGINFO *dlgInfo )
121 FillWindow16( hwnd, hwnd, (HDC16)wParam, (HBRUSH16)CTLCOLOR_DLG );
126 /* Free dialog heap (if created) */
127 if (dlgInfo->hDialogHeap)
129 GlobalUnlock16(dlgInfo->hDialogHeap);
130 GlobalFree16(dlgInfo->hDialogHeap);
131 dlgInfo->hDialogHeap = 0;
135 if (dlgInfo->hUserFont)
137 DeleteObject( dlgInfo->hUserFont );
138 dlgInfo->hUserFont = 0;
144 DestroyMenu( dlgInfo->hMenu );
148 /* Delete window procedure */
149 WINPROC_FreeProc( dlgInfo->dlgProc, WIN_PROC_WINDOW );
150 dlgInfo->dlgProc = (HWINDOWPROC)0;
151 dlgInfo->flags |= DF_END; /* just in case */
153 /* Window clean-up */
154 return DefWindowProcA( hwnd, msg, wParam, lParam );
157 if (!wParam) DEFDLG_SaveFocus( hwnd, dlgInfo );
158 return DefWindowProcA( hwnd, msg, wParam, lParam );
161 if (wParam) DEFDLG_RestoreFocus( hwnd, dlgInfo );
162 else DEFDLG_SaveFocus( hwnd, dlgInfo );
166 DEFDLG_RestoreFocus( hwnd, dlgInfo );
170 if (dlgInfo->flags & DF_END) return 1;
171 DEFDLG_SetDefButton( hwnd, dlgInfo,
172 wParam ? GetDlgItem( hwnd, wParam ) : 0 );
178 if (dlgInfo->flags & DF_END) return 0;
179 if (dlgInfo->idResult)
180 return MAKELONG( dlgInfo->idResult, DC_HASDEFID );
181 if ((hwndDefId = DEFDLG_FindDefButton( hwnd )))
182 return MAKELONG( GetDlgCtrlID( hwndDefId ), DC_HASDEFID);
188 HWND hwndDest = (HWND)wParam;
190 hwndDest = GetNextDlgTabItem(hwnd, GetFocus(), wParam);
191 if (hwndDest) DEFDLG_SetFocus( hwnd, hwndDest );
192 DEFDLG_SetDefButton( hwnd, dlgInfo, hwndDest );
196 case WM_ENTERMENULOOP:
198 case WM_NCLBUTTONDOWN:
200 HWND hwndFocus = GetFocus();
203 WND *wnd = WIN_FindWndPtr( hwndFocus );
207 /* always make combo box hide its listbox control */
209 if( WIDGETS_IsControl( wnd, BIC32_COMBO ) )
210 SendMessageA( hwndFocus, CB_SHOWDROPDOWN,
212 else if( WIDGETS_IsControl( wnd, BIC32_EDIT ) &&
213 WIDGETS_IsControl( wnd->parent,
215 SendMessageA( wnd->parent->hwndSelf,
216 CB_SHOWDROPDOWN, FALSE, 0 );
220 return DefWindowProcA( hwnd, msg, wParam, lParam );
223 return dlgInfo->hUserFont;
226 PostMessageA( hwnd, WM_COMMAND, IDCANCEL,
227 (LPARAM)GetDlgItem( hwnd, IDCANCEL ) );
233 /***********************************************************************
236 static LRESULT DEFDLG_Epilog(DIALOGINFO* dlgInfo, UINT msg, BOOL fResult)
240 if ((msg >= WM_CTLCOLORMSGBOX && msg <= WM_CTLCOLORSTATIC) ||
241 msg == WM_CTLCOLOR || msg == WM_COMPAREITEM ||
242 msg == WM_VKEYTOITEM || msg == WM_CHARTOITEM ||
243 msg == WM_QUERYDRAGICON || msg == WM_INITDIALOG)
246 return dlgInfo->msgResult;
249 /***********************************************************************
250 * DefDlgProc16 (USER.308)
252 LRESULT WINAPI DefDlgProc16( HWND16 hwnd, UINT16 msg, WPARAM16 wParam,
255 DIALOGINFO * dlgInfo;
257 WND * wndPtr = WIN_FindWndPtr( hwnd );
259 if (!wndPtr) return 0;
260 dlgInfo = (DIALOGINFO *)&wndPtr->wExtra;
261 dlgInfo->msgResult = 0;
263 if (dlgInfo->dlgProc) { /* Call dialog procedure */
264 result = CallWindowProc16( (WNDPROC16)dlgInfo->dlgProc,
265 hwnd, msg, wParam, lParam );
266 /* 16 bit dlg procs only return BOOL16 */
267 if( WINPROC_GetProcType( dlgInfo->dlgProc ) == WIN_PROC_16 )
268 result = LOWORD(result);
271 if (!result && IsWindow(hwnd))
273 /* callback didn't process this message */
287 case WM_ENTERMENULOOP:
289 case WM_NCLBUTTONDOWN:
290 return DEFDLG_Proc( (HWND)hwnd, msg,
291 (WPARAM)wParam, lParam, dlgInfo );
299 return DefWindowProc16( hwnd, msg, wParam, lParam );
302 return DEFDLG_Epilog(dlgInfo, msg, result);
306 /***********************************************************************
307 * DefDlgProc32A (USER32.120)
309 LRESULT WINAPI DefDlgProcA( HWND hwnd, UINT msg,
310 WPARAM wParam, LPARAM lParam )
312 DIALOGINFO * dlgInfo;
314 WND * wndPtr = WIN_FindWndPtr( hwnd );
316 if (!wndPtr) return 0;
317 dlgInfo = (DIALOGINFO *)&wndPtr->wExtra;
318 dlgInfo->msgResult = 0;
320 if (dlgInfo->dlgProc) { /* Call dialog procedure */
321 result = CallWindowProcA( (WNDPROC)dlgInfo->dlgProc,
322 hwnd, msg, wParam, lParam );
323 /* 16 bit dlg procs only return BOOL16 */
324 if( WINPROC_GetProcType( dlgInfo->dlgProc ) == WIN_PROC_16 )
325 result = LOWORD(result);
328 if (!result && IsWindow(hwnd))
330 /* callback didn't process this message */
344 case WM_ENTERMENULOOP:
346 case WM_NCLBUTTONDOWN:
347 return DEFDLG_Proc( (HWND)hwnd, msg,
348 (WPARAM)wParam, lParam, dlgInfo );
356 return DefWindowProcA( hwnd, msg, wParam, lParam );
359 return DEFDLG_Epilog(dlgInfo, msg, result);
363 /***********************************************************************
364 * DefDlgProc32W (USER32.121)
366 LRESULT WINAPI DefDlgProcW( HWND hwnd, UINT msg, WPARAM wParam,
369 DIALOGINFO * dlgInfo;
371 WND * wndPtr = WIN_FindWndPtr( hwnd );
373 if (!wndPtr) return 0;
374 dlgInfo = (DIALOGINFO *)&wndPtr->wExtra;
375 dlgInfo->msgResult = 0;
377 if (dlgInfo->dlgProc) { /* Call dialog procedure */
378 result = CallWindowProcW( (WNDPROC)dlgInfo->dlgProc,
379 hwnd, msg, wParam, lParam );
380 /* 16 bit dlg procs only return BOOL16 */
381 if( WINPROC_GetProcType( dlgInfo->dlgProc ) == WIN_PROC_16 )
382 result = LOWORD(result);
385 if (!result && IsWindow(hwnd))
387 /* callback didn't process this message */
401 case WM_ENTERMENULOOP:
403 case WM_NCLBUTTONDOWN:
404 return DEFDLG_Proc( (HWND)hwnd, msg,
405 (WPARAM)wParam, lParam, dlgInfo );
413 return DefWindowProcW( hwnd, msg, wParam, lParam );
416 return DEFDLG_Epilog(dlgInfo, msg, result);