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);