Release 970824
[wine/multimedia.git] / windows / defdlg.c
blob1285d735257180fd69f9af1c91c6e99281239c36
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( HWND32 hwndDlg, HWND32 hwndCtrl )
22 HWND32 hwndPrev = GetFocus32();
24 if (IsChild32( 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 ) );
31 SetFocus32( hwndCtrl );
35 /***********************************************************************
36 * DEFDLG_SaveFocus
38 static BOOL32 DEFDLG_SaveFocus( HWND32 hwnd, DIALOGINFO *infoPtr )
40 HWND32 hwndFocus = GetFocus32();
42 if (!hwndFocus || !IsChild32( hwnd, hwndFocus )) return FALSE;
43 infoPtr->hwndFocus = hwndFocus;
44 /* Remove default button */
45 return TRUE;
49 /***********************************************************************
50 * DEFDLG_RestoreFocus
52 static BOOL32 DEFDLG_RestoreFocus( HWND32 hwnd, DIALOGINFO *infoPtr )
54 if (!infoPtr->hwndFocus || IsIconic32(hwnd)) return FALSE;
55 if (!IsWindow32( infoPtr->hwndFocus )) return FALSE;
56 DEFDLG_SetFocus( hwnd, infoPtr->hwndFocus );
57 infoPtr->hwndFocus = 0;
58 return TRUE;
62 /***********************************************************************
63 * DEFDLG_FindDefButton
65 * Find the current default push-button.
67 static HWND32 DEFDLG_FindDefButton( HWND32 hwndDlg )
69 HWND32 hwndChild = GetWindow32( hwndDlg, GW_CHILD );
70 while (hwndChild)
72 if (SendMessage16( hwndChild, WM_GETDLGCODE, 0, 0 ) & DLGC_DEFPUSHBUTTON)
73 break;
74 hwndChild = GetWindow32( hwndChild, GW_HWNDNEXT );
76 return hwndChild;
80 /***********************************************************************
81 * DEFDLG_SetDefButton
83 * Set the new default button to be hwndNew.
85 static BOOL32 DEFDLG_SetDefButton( HWND32 hwndDlg, DIALOGINFO *dlgInfo,
86 HWND32 hwndNew )
88 if (hwndNew &&
89 !(SendMessage16(hwndNew, WM_GETDLGCODE, 0, 0 ) & DLGC_UNDEFPUSHBUTTON))
90 return FALSE; /* Destination is not a push button */
92 if (dlgInfo->idResult) /* There's already a default pushbutton */
94 HWND32 hwndOld = GetDlgItem32( hwndDlg, dlgInfo->idResult );
95 if (SendMessage32A( hwndOld, WM_GETDLGCODE, 0, 0) & DLGC_DEFPUSHBUTTON)
96 SendMessage32A( hwndOld, BM_SETSTYLE32, BS_PUSHBUTTON, TRUE );
98 if (hwndNew)
100 SendMessage32A( hwndNew, BM_SETSTYLE32, BS_DEFPUSHBUTTON, TRUE );
101 dlgInfo->idResult = GetDlgCtrlID32( hwndNew );
103 else dlgInfo->idResult = 0;
104 return TRUE;
108 /***********************************************************************
109 * DEFDLG_Proc
111 * Implementation of DefDlgProc(). Only handle messages that need special
112 * handling for dialogs.
114 static LRESULT DEFDLG_Proc( HWND32 hwnd, UINT32 msg, WPARAM32 wParam,
115 LPARAM lParam, DIALOGINFO *dlgInfo )
117 switch(msg)
119 case WM_ERASEBKGND:
120 FillWindow( hwnd, hwnd, (HDC16)wParam, (HBRUSH16)CTLCOLOR_DLG );
121 return 1;
123 case WM_NCDESTROY:
125 /* Free dialog heap (if created) */
126 if (dlgInfo->hDialogHeap)
128 GlobalUnlock16(dlgInfo->hDialogHeap);
129 GlobalFree16(dlgInfo->hDialogHeap);
130 dlgInfo->hDialogHeap = 0;
133 /* Delete font */
134 if (dlgInfo->hUserFont)
136 DeleteObject32( dlgInfo->hUserFont );
137 dlgInfo->hUserFont = 0;
140 /* Delete menu */
141 if (dlgInfo->hMenu)
143 DestroyMenu32( dlgInfo->hMenu );
144 dlgInfo->hMenu = 0;
147 /* Delete window procedure */
148 WINPROC_FreeProc( dlgInfo->dlgProc, WIN_PROC_WINDOW );
149 dlgInfo->dlgProc = (HWINDOWPROC)0;
150 dlgInfo->flags |= DF_END; /* just in case */
152 /* Window clean-up */
153 return DefWindowProc32A( hwnd, msg, wParam, lParam );
155 case WM_SHOWWINDOW:
156 if (!wParam) DEFDLG_SaveFocus( hwnd, dlgInfo );
157 return DefWindowProc32A( hwnd, msg, wParam, lParam );
159 case WM_ACTIVATE:
160 if (wParam) DEFDLG_RestoreFocus( hwnd, dlgInfo );
161 else DEFDLG_SaveFocus( hwnd, dlgInfo );
162 return 0;
164 case WM_SETFOCUS:
165 DEFDLG_RestoreFocus( hwnd, dlgInfo );
166 return 0;
168 case DM_SETDEFID:
169 if (dlgInfo->flags & DF_END) return 1;
170 DEFDLG_SetDefButton( hwnd, dlgInfo,
171 wParam ? GetDlgItem32( hwnd, wParam ) : 0 );
172 return 1;
174 case DM_GETDEFID:
176 HWND32 hwndDefId;
177 if (dlgInfo->flags & DF_END) return 0;
178 if (dlgInfo->idResult)
179 return MAKELONG( dlgInfo->idResult, DC_HASDEFID );
180 if ((hwndDefId = DEFDLG_FindDefButton( hwnd )))
181 return MAKELONG( GetDlgCtrlID32( hwndDefId ), DC_HASDEFID);
183 return 0;
185 case WM_NEXTDLGCTL:
187 HWND32 hwndDest = (HWND32)wParam;
188 if (!lParam)
189 hwndDest = GetNextDlgTabItem32(hwnd, GetFocus32(), wParam);
190 if (hwndDest) DEFDLG_SetFocus( hwnd, hwndDest );
191 DEFDLG_SetDefButton( hwnd, dlgInfo, hwndDest );
193 return 0;
195 case WM_ENTERMENULOOP:
196 case WM_LBUTTONDOWN:
197 case WM_NCLBUTTONDOWN:
199 HWND32 hwndFocus = GetFocus32();
200 if (hwndFocus)
202 WND *wnd = WIN_FindWndPtr( hwndFocus );
204 if( wnd )
206 /* always make combo box hide its listbox control */
208 if( WIDGETS_IsControl32( wnd, BIC32_COMBO ) )
209 SendMessage32A( hwndFocus, CB_SHOWDROPDOWN32,
210 FALSE, 0 );
211 else if( WIDGETS_IsControl32( wnd, BIC32_EDIT ) &&
212 WIDGETS_IsControl32( wnd->parent,
213 BIC32_COMBO ))
214 SendMessage32A( wnd->parent->hwndSelf,
215 CB_SHOWDROPDOWN32, FALSE, 0 );
219 return DefWindowProc32A( hwnd, msg, wParam, lParam );
221 case WM_GETFONT:
222 return dlgInfo->hUserFont;
224 case WM_CLOSE:
225 EndDialog32( hwnd, TRUE );
226 DestroyWindow32( hwnd );
227 return 0;
229 return 0;
232 /***********************************************************************
233 * DEFDLG_Epilog
235 static LRESULT DEFDLG_Epilog(DIALOGINFO* dlgInfo, UINT32 msg, BOOL16 fResult)
237 /* see SDK 3.1 */
239 if ((msg >= WM_CTLCOLORMSGBOX && msg <= WM_CTLCOLORSTATIC) ||
240 msg == WM_CTLCOLOR || msg == WM_COMPAREITEM ||
241 msg == WM_VKEYTOITEM || msg == WM_CHARTOITEM ||
242 msg == WM_QUERYDRAGICON || msg == WM_INITDIALOG)
243 return fResult;
245 return dlgInfo->msgResult;
248 /***********************************************************************
249 * DefDlgProc16 (USER.308)
251 LRESULT WINAPI DefDlgProc16( HWND16 hwnd, UINT16 msg, WPARAM16 wParam,
252 LPARAM lParam )
254 DIALOGINFO * dlgInfo;
255 BOOL16 result = FALSE;
256 WND * wndPtr = WIN_FindWndPtr( hwnd );
258 if (!wndPtr) return 0;
259 dlgInfo = (DIALOGINFO *)&wndPtr->wExtra;
260 dlgInfo->msgResult = 0;
262 if (dlgInfo->dlgProc) /* Call dialog procedure */
263 result = (BOOL16)CallWindowProc16( (WNDPROC16)dlgInfo->dlgProc,
264 hwnd, msg, wParam, lParam );
266 /* Check if window was destroyed by dialog procedure */
268 if (!result && IsWindow32(hwnd))
270 /* callback didn't process this message */
272 switch(msg)
274 case WM_ERASEBKGND:
275 case WM_SHOWWINDOW:
276 case WM_ACTIVATE:
277 case WM_SETFOCUS:
278 case DM_SETDEFID:
279 case DM_GETDEFID:
280 case WM_NEXTDLGCTL:
281 case WM_GETFONT:
282 case WM_CLOSE:
283 case WM_NCDESTROY:
284 case WM_ENTERMENULOOP:
285 case WM_LBUTTONDOWN:
286 case WM_NCLBUTTONDOWN:
287 return DEFDLG_Proc( (HWND32)hwnd, msg,
288 (WPARAM32)wParam, lParam, dlgInfo );
289 case WM_INITDIALOG:
290 case WM_VKEYTOITEM:
291 case WM_COMPAREITEM:
292 case WM_CHARTOITEM:
293 break;
295 default:
296 return DefWindowProc16( hwnd, msg, wParam, lParam );
299 return DEFDLG_Epilog(dlgInfo, msg, result);
303 /***********************************************************************
304 * DefDlgProc32A (USER32.119)
306 LRESULT WINAPI DefDlgProc32A( HWND32 hwnd, UINT32 msg,
307 WPARAM32 wParam, LPARAM lParam )
309 DIALOGINFO * dlgInfo;
310 BOOL16 result = FALSE;
311 WND * wndPtr = WIN_FindWndPtr( hwnd );
313 if (!wndPtr) return 0;
314 dlgInfo = (DIALOGINFO *)&wndPtr->wExtra;
315 dlgInfo->msgResult = 0;
317 if (dlgInfo->dlgProc) /* Call dialog procedure */
318 result = (BOOL16)CallWindowProc32A( (WNDPROC32)dlgInfo->dlgProc,
319 hwnd, msg, wParam, lParam );
321 /* Check if window was destroyed by dialog procedure */
323 if (!result && IsWindow32(hwnd))
325 /* callback didn't process this message */
327 switch(msg)
329 case WM_ERASEBKGND:
330 case WM_SHOWWINDOW:
331 case WM_ACTIVATE:
332 case WM_SETFOCUS:
333 case DM_SETDEFID:
334 case DM_GETDEFID:
335 case WM_NEXTDLGCTL:
336 case WM_GETFONT:
337 case WM_CLOSE:
338 case WM_NCDESTROY:
339 case WM_ENTERMENULOOP:
340 case WM_LBUTTONDOWN:
341 case WM_NCLBUTTONDOWN:
342 return DEFDLG_Proc( (HWND32)hwnd, msg,
343 (WPARAM32)wParam, lParam, dlgInfo );
344 case WM_INITDIALOG:
345 case WM_VKEYTOITEM:
346 case WM_COMPAREITEM:
347 case WM_CHARTOITEM:
348 break;
350 default:
351 return DefWindowProc32A( hwnd, msg, wParam, lParam );
354 return DEFDLG_Epilog(dlgInfo, msg, result);
358 /***********************************************************************
359 * DefDlgProc32W (USER32.120)
361 LRESULT WINAPI DefDlgProc32W( HWND32 hwnd, UINT32 msg, WPARAM32 wParam,
362 LPARAM lParam )
364 DIALOGINFO * dlgInfo;
365 BOOL16 result = FALSE;
366 WND * wndPtr = WIN_FindWndPtr( hwnd );
368 if (!wndPtr) return 0;
369 dlgInfo = (DIALOGINFO *)&wndPtr->wExtra;
370 dlgInfo->msgResult = 0;
372 if (dlgInfo->dlgProc) /* Call dialog procedure */
373 result = (BOOL16)CallWindowProc32W( (WNDPROC32)dlgInfo->dlgProc,
374 hwnd, msg, wParam, lParam );
376 /* Check if window was destroyed by dialog procedure */
378 if (!result && IsWindow32(hwnd))
380 /* callback didn't process this message */
382 switch(msg)
384 case WM_ERASEBKGND:
385 case WM_SHOWWINDOW:
386 case WM_ACTIVATE:
387 case WM_SETFOCUS:
388 case DM_SETDEFID:
389 case DM_GETDEFID:
390 case WM_NEXTDLGCTL:
391 case WM_GETFONT:
392 case WM_CLOSE:
393 case WM_NCDESTROY:
394 case WM_ENTERMENULOOP:
395 case WM_LBUTTONDOWN:
396 case WM_NCLBUTTONDOWN:
397 return DEFDLG_Proc( (HWND32)hwnd, msg,
398 (WPARAM32)wParam, lParam, dlgInfo );
399 case WM_INITDIALOG:
400 case WM_VKEYTOITEM:
401 case WM_COMPAREITEM:
402 case WM_CHARTOITEM:
403 break;
405 default:
406 return DefWindowProc32W( hwnd, msg, wParam, lParam );
409 return DEFDLG_Epilog(dlgInfo, msg, result);