- move async activation into the server
[wine/dcerpc.git] / windows / defdlg.c
blobd63c9e330395c64dfd9f74dbcbaa55b8a45d345c
1 /*
2 * Default dialog procedure
4 * Copyright 1993, 1996 Alexandre Julliard
6 */
8 #include "windef.h"
9 #include "winbase.h"
10 #include "wingdi.h"
11 #include "wine/winuser16.h"
12 #include "controls.h"
13 #include "win.h"
14 #include "winproc.h"
15 #include "debugtools.h"
17 DEFAULT_DEBUG_CHANNEL(dialog);
20 /***********************************************************************
21 * DEFDLG_GetDlgProc
23 static WNDPROC DEFDLG_GetDlgProc( HWND hwnd )
25 WNDPROC ret;
26 WND *wndPtr = WIN_GetPtr( hwnd );
28 if (!wndPtr) return 0;
29 if (wndPtr == WND_OTHER_PROCESS)
31 ERR( "cannot get dlg proc %x from other process\n", hwnd );
32 return 0;
34 ret = *(WNDPROC *)((char *)wndPtr->wExtra + DWL_DLGPROC);
35 WIN_ReleasePtr( wndPtr );
36 return ret;
39 /***********************************************************************
40 * DEFDLG_SetFocus
42 * Set the focus to a control of the dialog, selecting the text if
43 * the control is an edit dialog.
45 static void DEFDLG_SetFocus( HWND hwndDlg, HWND hwndCtrl )
47 HWND hwndPrev = GetFocus();
49 if (IsChild( hwndDlg, hwndPrev ))
51 if (SendMessageW( hwndPrev, WM_GETDLGCODE, 0, 0 ) & DLGC_HASSETSEL)
52 SendMessageW( hwndPrev, EM_SETSEL, -1, 0 );
54 if (SendMessageW( hwndCtrl, WM_GETDLGCODE, 0, 0 ) & DLGC_HASSETSEL)
55 SendMessageW( hwndCtrl, EM_SETSEL, 0, -1 );
56 SetFocus( hwndCtrl );
60 /***********************************************************************
61 * DEFDLG_SaveFocus
63 static void DEFDLG_SaveFocus( HWND hwnd )
65 DIALOGINFO *infoPtr;
66 HWND hwndFocus = GetFocus();
68 if (!hwndFocus || !IsChild( hwnd, hwndFocus )) return;
69 if (!(infoPtr = DIALOG_get_info( hwnd ))) return;
70 infoPtr->hwndFocus = hwndFocus;
71 /* Remove default button */
75 /***********************************************************************
76 * DEFDLG_RestoreFocus
78 static void DEFDLG_RestoreFocus( HWND hwnd )
80 DIALOGINFO *infoPtr;
82 if (IsIconic( hwnd )) return;
83 if (!(infoPtr = DIALOG_get_info( hwnd ))) return;
84 if (!IsWindow( infoPtr->hwndFocus )) return;
85 /* Don't set the focus back to controls if EndDialog is already called.*/
86 if (!(infoPtr->flags & DF_END))
88 DEFDLG_SetFocus( hwnd, infoPtr->hwndFocus );
89 return;
91 /* This used to set infoPtr->hwndFocus to NULL for no apparent reason,
92 sometimes losing focus when receiving WM_SETFOCUS messages. */
96 /***********************************************************************
97 * DEFDLG_FindDefButton
99 * Find the current default push-button.
101 static HWND DEFDLG_FindDefButton( HWND hwndDlg )
103 HWND hwndChild = GetWindow( hwndDlg, GW_CHILD );
104 while (hwndChild)
106 if (SendMessageW( hwndChild, WM_GETDLGCODE, 0, 0 ) & DLGC_DEFPUSHBUTTON)
107 break;
108 hwndChild = GetWindow( hwndChild, GW_HWNDNEXT );
110 return hwndChild;
114 /***********************************************************************
115 * DEFDLG_SetDefButton
117 * Set the new default button to be hwndNew.
119 static BOOL DEFDLG_SetDefButton( HWND hwndDlg, DIALOGINFO *dlgInfo,
120 HWND hwndNew )
122 if (hwndNew &&
123 !(SendMessageW(hwndNew, WM_GETDLGCODE, 0, 0 ) & DLGC_UNDEFPUSHBUTTON))
124 return FALSE; /* Destination is not a push button */
126 if (dlgInfo->idResult) /* There's already a default pushbutton */
128 HWND hwndOld = GetDlgItem( hwndDlg, dlgInfo->idResult );
129 if (SendMessageA( hwndOld, WM_GETDLGCODE, 0, 0) & DLGC_DEFPUSHBUTTON)
130 SendMessageA( hwndOld, BM_SETSTYLE, BS_PUSHBUTTON, TRUE );
132 if (hwndNew)
134 SendMessageA( hwndNew, BM_SETSTYLE, BS_DEFPUSHBUTTON, TRUE );
135 dlgInfo->idResult = GetDlgCtrlID( hwndNew );
137 else dlgInfo->idResult = 0;
138 return TRUE;
142 /***********************************************************************
143 * DEFDLG_Proc
145 * Implementation of DefDlgProc(). Only handle messages that need special
146 * handling for dialogs.
148 static LRESULT DEFDLG_Proc( HWND hwnd, UINT msg, WPARAM wParam,
149 LPARAM lParam, DIALOGINFO *dlgInfo )
151 switch(msg)
153 case WM_ERASEBKGND:
155 HBRUSH brush = SendMessageW( hwnd, WM_CTLCOLORDLG, wParam, (LPARAM)hwnd );
156 if (!brush) brush = DefWindowProcW( hwnd, WM_CTLCOLORDLG, wParam, (LPARAM)hwnd );
157 if (brush)
159 RECT rect;
160 HDC hdc = (HDC)wParam;
161 GetClientRect( hwnd, &rect );
162 DPtoLP( hdc, (LPPOINT)&rect, 2 );
163 FillRect( hdc, &rect, brush );
165 return 1;
167 case WM_NCDESTROY:
168 if ((dlgInfo = (DIALOGINFO *)SetWindowLongW( hwnd, DWL_WINE_DIALOGINFO, 0 )))
170 /* Free dialog heap (if created) */
171 if (dlgInfo->hDialogHeap)
173 GlobalUnlock16(dlgInfo->hDialogHeap);
174 GlobalFree16(dlgInfo->hDialogHeap);
176 if (dlgInfo->hUserFont) DeleteObject( dlgInfo->hUserFont );
177 if (dlgInfo->hMenu) DestroyMenu( dlgInfo->hMenu );
178 WINPROC_FreeProc( DEFDLG_GetDlgProc( hwnd ), WIN_PROC_WINDOW );
179 HeapFree( GetProcessHeap(), 0, dlgInfo );
181 /* Window clean-up */
182 return DefWindowProcA( hwnd, msg, wParam, lParam );
184 case WM_SHOWWINDOW:
185 if (!wParam) DEFDLG_SaveFocus( hwnd );
186 return DefWindowProcA( hwnd, msg, wParam, lParam );
188 case WM_ACTIVATE:
189 if (wParam) DEFDLG_RestoreFocus( hwnd );
190 else DEFDLG_SaveFocus( hwnd );
191 return 0;
193 case WM_SETFOCUS:
194 DEFDLG_RestoreFocus( hwnd );
195 return 0;
197 case DM_SETDEFID:
198 if (dlgInfo->flags & DF_END) return 1;
199 DEFDLG_SetDefButton( hwnd, dlgInfo,
200 wParam ? GetDlgItem( hwnd, wParam ) : 0 );
201 return 1;
203 case DM_GETDEFID:
205 HWND hwndDefId;
206 if (dlgInfo->flags & DF_END) return 0;
207 if (dlgInfo->idResult)
208 return MAKELONG( dlgInfo->idResult, DC_HASDEFID );
209 if ((hwndDefId = DEFDLG_FindDefButton( hwnd )))
210 return MAKELONG( GetDlgCtrlID( hwndDefId ), DC_HASDEFID);
212 return 0;
214 case WM_NEXTDLGCTL:
216 HWND hwndDest = (HWND)wParam;
217 if (!lParam)
218 hwndDest = GetNextDlgTabItem(hwnd, GetFocus(), wParam);
219 if (hwndDest) DEFDLG_SetFocus( hwnd, hwndDest );
220 DEFDLG_SetDefButton( hwnd, dlgInfo, hwndDest );
222 return 0;
224 case WM_ENTERMENULOOP:
225 case WM_LBUTTONDOWN:
226 case WM_NCLBUTTONDOWN:
228 HWND hwndFocus = GetFocus();
229 if (hwndFocus)
231 /* always make combo box hide its listbox control */
232 if (!SendMessageA( hwndFocus, CB_SHOWDROPDOWN, FALSE, 0 ))
233 SendMessageA( GetParent(hwndFocus), CB_SHOWDROPDOWN, FALSE, 0 );
236 return DefWindowProcA( hwnd, msg, wParam, lParam );
238 case WM_GETFONT:
239 return dlgInfo->hUserFont;
241 case WM_CLOSE:
242 PostMessageA( hwnd, WM_COMMAND, IDCANCEL,
243 (LPARAM)GetDlgItem( hwnd, IDCANCEL ) );
244 return 0;
246 case WM_NOTIFYFORMAT:
247 return DefWindowProcA( hwnd, msg, wParam, lParam );
249 return 0;
252 /***********************************************************************
253 * DEFDLG_Epilog
255 static LRESULT DEFDLG_Epilog(HWND hwnd, UINT msg, BOOL fResult)
257 /* see SDK 3.1 */
259 if ((msg >= WM_CTLCOLORMSGBOX && msg <= WM_CTLCOLORSTATIC) ||
260 msg == WM_CTLCOLOR || msg == WM_COMPAREITEM ||
261 msg == WM_VKEYTOITEM || msg == WM_CHARTOITEM ||
262 msg == WM_QUERYDRAGICON || msg == WM_INITDIALOG)
263 return fResult;
265 return GetWindowLongA( hwnd, DWL_MSGRESULT );
268 /***********************************************************************
269 * DefDlgProc (USER.308)
271 LRESULT WINAPI DefDlgProc16( HWND16 hwnd, UINT16 msg, WPARAM16 wParam,
272 LPARAM lParam )
274 WNDPROC16 dlgproc;
275 HWND hwnd32 = WIN_Handle32( hwnd );
276 BOOL result = FALSE;
278 SetWindowLongW( hwnd32, DWL_MSGRESULT, 0 );
280 if ((dlgproc = (WNDPROC16)DEFDLG_GetDlgProc( hwnd32 )))
282 /* Call dialog procedure */
283 result = CallWindowProc16( dlgproc, hwnd, msg, wParam, lParam );
284 /* 16 bit dlg procs only return BOOL16 */
285 if( WINPROC_GetProcType( dlgproc ) == WIN_PROC_16 )
286 result = LOWORD(result);
289 if (!result && IsWindow(hwnd32))
291 /* callback didn't process this message */
293 switch(msg)
295 case WM_ERASEBKGND:
296 case WM_SHOWWINDOW:
297 case WM_ACTIVATE:
298 case WM_SETFOCUS:
299 case DM_SETDEFID:
300 case DM_GETDEFID:
301 case WM_NEXTDLGCTL:
302 case WM_GETFONT:
303 case WM_CLOSE:
304 case WM_NCDESTROY:
305 case WM_ENTERMENULOOP:
306 case WM_LBUTTONDOWN:
307 case WM_NCLBUTTONDOWN:
308 return DEFDLG_Proc( hwnd32, msg, (WPARAM)wParam, lParam, DIALOG_get_info(hwnd32) );
309 case WM_INITDIALOG:
310 case WM_VKEYTOITEM:
311 case WM_COMPAREITEM:
312 case WM_CHARTOITEM:
313 break;
315 default:
316 return DefWindowProc16( hwnd, msg, wParam, lParam );
319 return DEFDLG_Epilog( hwnd32, msg, result);
323 /***********************************************************************
324 * DefDlgProcA (USER32.@)
326 LRESULT WINAPI DefDlgProcA( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
328 WNDPROC dlgproc;
329 BOOL result = FALSE;
331 SetWindowLongW( hwnd, DWL_MSGRESULT, 0 );
333 if ((dlgproc = DEFDLG_GetDlgProc( hwnd )))
335 /* Call dialog procedure */
336 result = CallWindowProcA( dlgproc, hwnd, msg, wParam, lParam );
337 /* 16 bit dlg procs only return BOOL16 */
338 if( WINPROC_GetProcType( dlgproc ) == WIN_PROC_16 )
339 result = LOWORD(result);
342 if (!result && IsWindow(hwnd))
344 /* callback didn't process this message */
346 switch(msg)
348 case WM_ERASEBKGND:
349 case WM_SHOWWINDOW:
350 case WM_ACTIVATE:
351 case WM_SETFOCUS:
352 case DM_SETDEFID:
353 case DM_GETDEFID:
354 case WM_NEXTDLGCTL:
355 case WM_GETFONT:
356 case WM_CLOSE:
357 case WM_NCDESTROY:
358 case WM_ENTERMENULOOP:
359 case WM_LBUTTONDOWN:
360 case WM_NCLBUTTONDOWN:
361 return DEFDLG_Proc( hwnd, msg, wParam, lParam, DIALOG_get_info(hwnd) );
362 case WM_INITDIALOG:
363 case WM_VKEYTOITEM:
364 case WM_COMPAREITEM:
365 case WM_CHARTOITEM:
366 break;
368 default:
369 return DefWindowProcA( hwnd, msg, wParam, lParam );
372 return DEFDLG_Epilog(hwnd, msg, result);
376 /***********************************************************************
377 * DefDlgProcW (USER32.@)
379 LRESULT WINAPI DefDlgProcW( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
381 BOOL result = FALSE;
382 WNDPROC dlgproc;
384 SetWindowLongW( hwnd, DWL_MSGRESULT, 0 );
386 if ((dlgproc = DEFDLG_GetDlgProc( hwnd )))
388 /* Call dialog procedure */
389 result = CallWindowProcW( dlgproc, hwnd, msg, wParam, lParam );
390 /* 16 bit dlg procs only return BOOL16 */
391 if( WINPROC_GetProcType( dlgproc ) == WIN_PROC_16 )
392 result = LOWORD(result);
395 if (!result && IsWindow(hwnd))
397 /* callback didn't process this message */
399 switch(msg)
401 case WM_ERASEBKGND:
402 case WM_SHOWWINDOW:
403 case WM_ACTIVATE:
404 case WM_SETFOCUS:
405 case DM_SETDEFID:
406 case DM_GETDEFID:
407 case WM_NEXTDLGCTL:
408 case WM_GETFONT:
409 case WM_CLOSE:
410 case WM_NCDESTROY:
411 case WM_ENTERMENULOOP:
412 case WM_LBUTTONDOWN:
413 case WM_NCLBUTTONDOWN:
414 return DEFDLG_Proc( hwnd, msg, wParam, lParam, DIALOG_get_info(hwnd) );
415 case WM_INITDIALOG:
416 case WM_VKEYTOITEM:
417 case WM_COMPAREITEM:
418 case WM_CHARTOITEM:
419 break;
421 default:
422 return DefWindowProcW( hwnd, msg, wParam, lParam );
425 return DEFDLG_Epilog(hwnd, msg, result);