Made sleep_on usable from all requests.
[wine/multimedia.git] / windows / defdlg.c
blob133dd095d45ac07e0f70a12e3ce617938bac01dc
1 /*
2 * Default dialog procedure
4 * Copyright 1993, 1996 Alexandre Julliard
6 */
8 #include "wine/winuser16.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_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 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 infoPtr->hwndFocus = hwndFocus;
44 /* Remove default button */
45 return TRUE;
49 /***********************************************************************
50 * DEFDLG_RestoreFocus
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. */
63 return TRUE;
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 );
75 while (hwndChild)
77 if (SendMessage16( hwndChild, WM_GETDLGCODE, 0, 0 ) & DLGC_DEFPUSHBUTTON)
78 break;
79 hwndChild = GetWindow( hwndChild, GW_HWNDNEXT );
81 return hwndChild;
85 /***********************************************************************
86 * DEFDLG_SetDefButton
88 * Set the new default button to be hwndNew.
90 static BOOL DEFDLG_SetDefButton( HWND hwndDlg, DIALOGINFO *dlgInfo,
91 HWND hwndNew )
93 if (hwndNew &&
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 );
103 if (hwndNew)
105 SendMessageA( hwndNew, BM_SETSTYLE, BS_DEFPUSHBUTTON, TRUE );
106 dlgInfo->idResult = GetDlgCtrlID( hwndNew );
108 else dlgInfo->idResult = 0;
109 return TRUE;
113 /***********************************************************************
114 * DEFDLG_Proc
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 )
122 switch(msg)
124 case WM_ERASEBKGND:
125 FillWindow16( hwnd, hwnd, (HDC16)wParam, (HBRUSH16)CTLCOLOR_DLG );
126 return 1;
128 case WM_NCDESTROY:
130 /* Free dialog heap (if created) */
131 if (dlgInfo->hDialogHeap)
133 GlobalUnlock16(dlgInfo->hDialogHeap);
134 GlobalFree16(dlgInfo->hDialogHeap);
135 dlgInfo->hDialogHeap = 0;
138 /* Delete font */
139 if (dlgInfo->hUserFont)
141 DeleteObject( dlgInfo->hUserFont );
142 dlgInfo->hUserFont = 0;
145 /* Delete menu */
146 if (dlgInfo->hMenu)
148 DestroyMenu( dlgInfo->hMenu );
149 dlgInfo->hMenu = 0;
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 );
160 case WM_SHOWWINDOW:
161 if (!wParam) DEFDLG_SaveFocus( hwnd, dlgInfo );
162 return DefWindowProcA( hwnd, msg, wParam, lParam );
164 case WM_ACTIVATE:
165 if (wParam) DEFDLG_RestoreFocus( hwnd, dlgInfo );
166 else DEFDLG_SaveFocus( hwnd, dlgInfo );
167 return 0;
169 case WM_SETFOCUS:
170 DEFDLG_RestoreFocus( hwnd, dlgInfo );
171 return 0;
173 case DM_SETDEFID:
174 if (dlgInfo->flags & DF_END) return 1;
175 DEFDLG_SetDefButton( hwnd, dlgInfo,
176 wParam ? GetDlgItem( hwnd, wParam ) : 0 );
177 return 1;
179 case DM_GETDEFID:
181 HWND hwndDefId;
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);
188 return 0;
190 case WM_NEXTDLGCTL:
192 HWND hwndDest = (HWND)wParam;
193 if (!lParam)
194 hwndDest = GetNextDlgTabItem(hwnd, GetFocus(), wParam);
195 if (hwndDest) DEFDLG_SetFocus( hwnd, hwndDest );
196 DEFDLG_SetDefButton( hwnd, dlgInfo, hwndDest );
198 return 0;
200 case WM_ENTERMENULOOP:
201 case WM_LBUTTONDOWN:
202 case WM_NCLBUTTONDOWN:
204 HWND hwndFocus = GetFocus();
205 if (hwndFocus)
207 WND *wnd = WIN_FindWndPtr( hwndFocus );
209 if( wnd )
211 /* always make combo box hide its listbox control */
213 if( WIDGETS_IsControl( wnd, BIC32_COMBO ) )
214 SendMessageA( hwndFocus, CB_SHOWDROPDOWN,
215 FALSE, 0 );
216 else if( WIDGETS_IsControl( wnd, BIC32_EDIT ) &&
217 WIDGETS_IsControl( wnd->parent,
218 BIC32_COMBO ))
219 SendMessageA( wnd->parent->hwndSelf,
220 CB_SHOWDROPDOWN, FALSE, 0 );
222 WIN_ReleaseWndPtr(wnd);
225 return DefWindowProcA( hwnd, msg, wParam, lParam );
227 case WM_GETFONT:
228 return dlgInfo->hUserFont;
230 case WM_CLOSE:
231 PostMessageA( hwnd, WM_COMMAND, IDCANCEL,
232 (LPARAM)GetDlgItem( hwnd, IDCANCEL ) );
233 return 0;
235 case WM_NOTIFYFORMAT:
236 return DefWindowProcA( hwnd, msg, wParam, lParam );
238 return 0;
241 /***********************************************************************
242 * DEFDLG_Epilog
244 static LRESULT DEFDLG_Epilog(DIALOGINFO* dlgInfo, UINT msg, BOOL fResult)
246 /* see SDK 3.1 */
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)
252 return fResult;
254 return dlgInfo->msgResult;
257 /***********************************************************************
258 * DefDlgProc16 (USER.308)
260 LRESULT WINAPI DefDlgProc16( HWND16 hwnd, UINT16 msg, WPARAM16 wParam,
261 LPARAM lParam )
263 DIALOGINFO * dlgInfo;
264 BOOL result = FALSE;
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 */
283 switch(msg)
285 case WM_ERASEBKGND:
286 case WM_SHOWWINDOW:
287 case WM_ACTIVATE:
288 case WM_SETFOCUS:
289 case DM_SETDEFID:
290 case DM_GETDEFID:
291 case WM_NEXTDLGCTL:
292 case WM_GETFONT:
293 case WM_CLOSE:
294 case WM_NCDESTROY:
295 case WM_ENTERMENULOOP:
296 case WM_LBUTTONDOWN:
297 case WM_NCLBUTTONDOWN:
298 WIN_ReleaseWndPtr(wndPtr);
299 return DEFDLG_Proc( (HWND)hwnd, msg,
300 (WPARAM)wParam, lParam, dlgInfo );
301 case WM_INITDIALOG:
302 case WM_VKEYTOITEM:
303 case WM_COMPAREITEM:
304 case WM_CHARTOITEM:
305 break;
307 default:
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;
324 BOOL result = FALSE;
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 */
343 switch(msg)
345 case WM_ERASEBKGND:
346 case WM_SHOWWINDOW:
347 case WM_ACTIVATE:
348 case WM_SETFOCUS:
349 case DM_SETDEFID:
350 case DM_GETDEFID:
351 case WM_NEXTDLGCTL:
352 case WM_GETFONT:
353 case WM_CLOSE:
354 case WM_NCDESTROY:
355 case WM_ENTERMENULOOP:
356 case WM_LBUTTONDOWN:
357 case WM_NCLBUTTONDOWN:
358 WIN_ReleaseWndPtr(wndPtr);
359 return DEFDLG_Proc( (HWND)hwnd, msg,
360 (WPARAM)wParam, lParam, dlgInfo );
361 case WM_INITDIALOG:
362 case WM_VKEYTOITEM:
363 case WM_COMPAREITEM:
364 case WM_CHARTOITEM:
365 break;
367 default:
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,
381 LPARAM lParam )
383 DIALOGINFO * dlgInfo;
384 BOOL result = FALSE;
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 */
403 switch(msg)
405 case WM_ERASEBKGND:
406 case WM_SHOWWINDOW:
407 case WM_ACTIVATE:
408 case WM_SETFOCUS:
409 case DM_SETDEFID:
410 case DM_GETDEFID:
411 case WM_NEXTDLGCTL:
412 case WM_GETFONT:
413 case WM_CLOSE:
414 case WM_NCDESTROY:
415 case WM_ENTERMENULOOP:
416 case WM_LBUTTONDOWN:
417 case WM_NCLBUTTONDOWN:
418 WIN_ReleaseWndPtr(wndPtr);
419 return DEFDLG_Proc( (HWND)hwnd, msg,
420 (WPARAM)wParam, lParam, dlgInfo );
421 case WM_INITDIALOG:
422 case WM_VKEYTOITEM:
423 case WM_COMPAREITEM:
424 case WM_CHARTOITEM:
425 break;
427 default:
428 WIN_ReleaseWndPtr(wndPtr);
429 return DefWindowProcW( hwnd, msg, wParam, lParam );
432 WIN_ReleaseWndPtr(wndPtr);
433 return DEFDLG_Epilog(dlgInfo, msg, result);