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