Release 960606
[wine.git] / windows / defdlg.c
blob9379e07667b0c60a65a3061b2bc9dee5ad640f08
1 /*
2 * Default dialog procedure
4 * Copyright 1993, 1996 Alexandre Julliard
6 */
8 #include "windows.h"
9 #include "dialog.h"
10 #include "win.h"
11 #include "winproc.h"
14 /***********************************************************************
15 * DEFDLG_SetFocus
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_SETSEL, TRUE, MAKELONG( -1, 0 ) );
29 if (SendMessage16( hwndCtrl, WM_GETDLGCODE, 0, 0 ) & DLGC_HASSETSEL)
30 SendMessage16( hwndCtrl, EM_SETSEL, FALSE, MAKELONG( 0, -1 ) );
31 SetFocus( hwndCtrl );
35 /***********************************************************************
36 * DEFDLG_SaveFocus
38 static BOOL DEFDLG_SaveFocus( HWND hwnd, DIALOGINFO *infoPtr )
40 HWND hwndFocus = GetFocus();
42 if (!hwndFocus || !IsChild( hwnd, hwndFocus )) return FALSE;
43 if (!infoPtr->hwndFocus) return FALSE; /* Already saved */
44 infoPtr->hwndFocus = hwndFocus;
45 /* Remove default button */
46 return TRUE;
50 /***********************************************************************
51 * DEFDLG_RestoreFocus
53 static BOOL DEFDLG_RestoreFocus( HWND hwnd, DIALOGINFO *infoPtr )
55 if (!infoPtr->hwndFocus || IsIconic(hwnd)) return FALSE;
56 if (!IsWindow( infoPtr->hwndFocus )) return FALSE;
57 DEFDLG_SetFocus( hwnd, infoPtr->hwndFocus );
58 infoPtr->hwndFocus = 0;
59 return TRUE;
63 #ifdef SUPERFLUOUS_FUNCTIONS
64 /***********************************************************************
65 * DEFDLG_FindDefButton
67 * Find the current default push-button.
69 static HWND DEFDLG_FindDefButton( HWND hwndDlg )
71 HWND hwndChild = GetWindow( hwndDlg, GW_CHILD );
72 while (hwndChild)
74 if (SendMessage16( hwndChild, WM_GETDLGCODE, 0, 0 ) & DLGC_DEFPUSHBUTTON)
75 break;
76 hwndChild = GetWindow( hwndChild, GW_HWNDNEXT );
78 return hwndChild;
80 #endif
83 /***********************************************************************
84 * DEFDLG_SetDefButton
86 * Set the new default button to be hwndNew.
88 static BOOL DEFDLG_SetDefButton( HWND hwndDlg, DIALOGINFO *dlgInfo,
89 HWND hwndNew )
91 if (hwndNew &&
92 !(SendMessage16(hwndNew, WM_GETDLGCODE, 0, 0 ) & DLGC_UNDEFPUSHBUTTON))
93 return FALSE; /* Destination is not a push button */
95 if (dlgInfo->msgResult) /* There's already a default pushbutton */
97 HWND hwndOld = GetDlgItem( hwndDlg, dlgInfo->msgResult );
98 if (SendMessage32A( hwndOld, WM_GETDLGCODE, 0, 0) & DLGC_DEFPUSHBUTTON)
99 SendMessage32A( hwndOld, BM_SETSTYLE32, BS_PUSHBUTTON, TRUE );
101 if (hwndNew)
103 SendMessage32A( hwndNew, BM_SETSTYLE32, BS_DEFPUSHBUTTON, TRUE );
104 dlgInfo->msgResult = GetDlgCtrlID( hwndNew );
106 else dlgInfo->msgResult = 0;
107 return TRUE;
111 /***********************************************************************
112 * DEFDLG_Proc
114 * Implementation of DefDlgProc(). Only handle messages that need special
115 * handling for dialogs.
117 static LRESULT DEFDLG_Proc( HWND32 hwnd, UINT32 msg, WPARAM32 wParam,
118 LPARAM lParam, DIALOGINFO *dlgInfo )
120 switch(msg)
122 case WM_INITDIALOG:
123 return 0;
125 case WM_ERASEBKGND:
126 FillWindow( hwnd, hwnd, (HDC)wParam, (HBRUSH)CTLCOLOR_DLG );
127 return 1;
129 case WM_NCDESTROY:
131 /* Free dialog heap (if created) */
132 if (dlgInfo->hDialogHeap)
134 GlobalUnlock16(dlgInfo->hDialogHeap);
135 GlobalFree16(dlgInfo->hDialogHeap);
136 dlgInfo->hDialogHeap = 0;
139 /* Delete font */
140 if (dlgInfo->hUserFont)
142 DeleteObject( dlgInfo->hUserFont );
143 dlgInfo->hUserFont = 0;
146 /* Delete menu */
147 if (dlgInfo->hMenu)
149 DestroyMenu( dlgInfo->hMenu );
150 dlgInfo->hMenu = 0;
153 /* Delete window procedure */
154 if (dlgInfo->dlgProc)
156 WINPROC_FreeWinProc( dlgInfo->dlgProc );
157 dlgInfo->dlgProc = 0;
160 /* Window clean-up */
161 return DefWindowProc32A( hwnd, msg, wParam, lParam );
163 case WM_SHOWWINDOW:
164 if (!wParam) DEFDLG_SaveFocus( hwnd, dlgInfo );
165 return DefWindowProc32A( hwnd, msg, wParam, lParam );
167 case WM_ACTIVATE:
168 if (wParam) DEFDLG_RestoreFocus( hwnd, dlgInfo );
169 else DEFDLG_SaveFocus( hwnd, dlgInfo );
170 return 0;
172 case WM_SETFOCUS:
173 DEFDLG_RestoreFocus( hwnd, dlgInfo );
174 return 0;
176 case DM_SETDEFID:
177 if (dlgInfo->fEnd) return 1;
178 DEFDLG_SetDefButton( hwnd, dlgInfo,
179 wParam ? GetDlgItem( hwnd, wParam ) : 0 );
180 return 1;
182 case DM_GETDEFID:
183 if (dlgInfo->fEnd || !dlgInfo->msgResult) return 0;
184 return MAKELONG( dlgInfo->msgResult, DC_HASDEFID );
186 case WM_NEXTDLGCTL:
188 HWND hwndDest = (HWND)wParam;
189 if (!lParam)
191 HWND hwndPrev = GetFocus();
192 if (!hwndPrev) /* Set focus to the first item */
193 hwndDest = DIALOG_GetFirstTabItem( hwnd );
194 else
195 hwndDest = GetNextDlgTabItem( hwnd, hwndPrev, wParam );
197 if (hwndDest) DEFDLG_SetFocus( hwnd, hwndDest );
198 DEFDLG_SetDefButton( hwnd, dlgInfo, hwndDest );
200 return 0;
202 case WM_CLOSE:
203 EndDialog( hwnd, TRUE );
204 DestroyWindow( hwnd );
205 return 0;
207 return 0;
211 /***********************************************************************
212 * DefDlgProc16 (USER.308)
214 LRESULT DefDlgProc16( HWND16 hwnd, UINT16 msg, WPARAM16 wParam, LPARAM lParam )
216 DIALOGINFO * dlgInfo;
217 BOOL16 result = FALSE;
218 WND * wndPtr = WIN_FindWndPtr( hwnd );
220 if (!wndPtr) return 0;
221 dlgInfo = (DIALOGINFO *)&wndPtr->wExtra;
223 dlgInfo->msgResult = 0;
224 if (dlgInfo->dlgProc)
226 /* Call dialog procedure */
227 result = (BOOL16)CallWindowProc16( (WNDPROC16)dlgInfo->dlgProc, hwnd,
228 msg, wParam, lParam );
230 /* Check if window was destroyed by dialog procedure */
231 if (result || !IsWindow( hwnd )) return result;
234 switch(msg)
236 case WM_INITDIALOG:
237 case WM_ERASEBKGND:
238 case WM_NCDESTROY:
239 case WM_SHOWWINDOW:
240 case WM_ACTIVATE:
241 case WM_SETFOCUS:
242 case DM_SETDEFID:
243 case DM_GETDEFID:
244 case WM_NEXTDLGCTL:
245 case WM_CLOSE:
246 return DEFDLG_Proc( (HWND32)hwnd, msg, (WPARAM32)wParam,
247 lParam, dlgInfo );
249 default:
250 return DefWindowProc16( hwnd, msg, wParam, lParam );
255 /***********************************************************************
256 * DefDlgProc32A (USER32.119)
258 LRESULT DefDlgProc32A( HWND32 hwnd, UINT32 msg, WPARAM32 wParam, LPARAM lParam)
260 DIALOGINFO * dlgInfo;
261 BOOL16 result = FALSE;
262 WND * wndPtr = WIN_FindWndPtr( hwnd );
264 if (!wndPtr) return 0;
265 dlgInfo = (DIALOGINFO *)&wndPtr->wExtra;
267 dlgInfo->msgResult = 0;
268 if (dlgInfo->dlgProc)
270 /* Call dialog procedure */
271 result = (BOOL16)CallWindowProc32A( (WNDPROC32)dlgInfo->dlgProc, hwnd,
272 msg, wParam, lParam );
274 /* Check if window was destroyed by dialog procedure */
275 if (result || !IsWindow( hwnd )) return result;
278 switch(msg)
280 case WM_INITDIALOG:
281 case WM_ERASEBKGND:
282 case WM_NCDESTROY:
283 case WM_SHOWWINDOW:
284 case WM_ACTIVATE:
285 case WM_SETFOCUS:
286 case DM_SETDEFID:
287 case DM_GETDEFID:
288 case WM_NEXTDLGCTL:
289 case WM_CLOSE:
290 return DEFDLG_Proc( hwnd, msg, wParam, lParam, dlgInfo );
292 default:
293 return DefWindowProc32A( hwnd, msg, wParam, lParam );
298 /***********************************************************************
299 * DefDlgProc32W (USER32.120)
301 LRESULT DefDlgProc32W( HWND32 hwnd, UINT32 msg, WPARAM32 wParam, LPARAM lParam)
303 DIALOGINFO * dlgInfo;
304 BOOL16 result = FALSE;
305 WND * wndPtr = WIN_FindWndPtr( hwnd );
307 if (!wndPtr) return 0;
308 dlgInfo = (DIALOGINFO *)&wndPtr->wExtra;
310 dlgInfo->msgResult = 0;
311 if (dlgInfo->dlgProc)
313 /* Call dialog procedure */
314 result = (BOOL16)CallWindowProc32W( (WNDPROC32)dlgInfo->dlgProc, hwnd,
315 msg, wParam, lParam );
317 /* Check if window was destroyed by dialog procedure */
318 if (result || !IsWindow( hwnd )) return result;
321 switch(msg)
323 case WM_INITDIALOG:
324 case WM_ERASEBKGND:
325 case WM_NCDESTROY:
326 case WM_SHOWWINDOW:
327 case WM_ACTIVATE:
328 case WM_SETFOCUS:
329 case DM_SETDEFID:
330 case DM_GETDEFID:
331 case WM_NEXTDLGCTL:
332 case WM_CLOSE:
333 return DEFDLG_Proc( hwnd, msg, wParam, lParam, dlgInfo );
335 default:
336 return DefWindowProc32W( hwnd, msg, wParam, lParam );