Fixed some issues found by winapi_check.
[wine/dcerpc.git] / windows / defdlg.c
blobc35bf2ce2b091e6feee86ffb5c290daed5ee7349
1 /*
2 * Default dialog procedure
4 * Copyright 1993, 1996 Alexandre Julliard
6 */
8 #include "windef.h"
9 #include "wingdi.h"
10 #include "wine/winuser16.h"
11 #include "dialog.h"
12 #include "win.h"
13 #include "winproc.h"
16 /***********************************************************************
17 * DEFDLG_SetFocus
19 * Set the focus to a control of the dialog, selecting the text if
20 * the control is an edit dialog.
22 static void DEFDLG_SetFocus( HWND hwndDlg, HWND hwndCtrl )
24 HWND hwndPrev = GetFocus();
26 if (IsChild( hwndDlg, hwndPrev ))
28 if (SendMessage16( hwndPrev, WM_GETDLGCODE, 0, 0 ) & DLGC_HASSETSEL)
29 SendMessage16( hwndPrev, EM_SETSEL16, TRUE, MAKELONG( -1, 0 ) );
31 if (SendMessage16( hwndCtrl, WM_GETDLGCODE, 0, 0 ) & DLGC_HASSETSEL)
32 SendMessage16( hwndCtrl, EM_SETSEL16, FALSE, MAKELONG( 0, -1 ) );
33 SetFocus( hwndCtrl );
37 /***********************************************************************
38 * DEFDLG_SaveFocus
40 static BOOL DEFDLG_SaveFocus( HWND hwnd, DIALOGINFO *infoPtr )
42 HWND hwndFocus = GetFocus();
44 if (!hwndFocus || !IsChild( hwnd, hwndFocus )) return FALSE;
45 infoPtr->hwndFocus = hwndFocus;
46 /* Remove default button */
47 return TRUE;
51 /***********************************************************************
52 * DEFDLG_RestoreFocus
54 static BOOL DEFDLG_RestoreFocus( HWND hwnd, DIALOGINFO *infoPtr )
56 if (!infoPtr->hwndFocus || IsIconic(hwnd)) return FALSE;
57 if (!IsWindow( infoPtr->hwndFocus )) return FALSE;
59 /* Don't set the focus back to controls if EndDialog is already called.*/
60 if (!(infoPtr->flags & DF_END))
61 DEFDLG_SetFocus( hwnd, infoPtr->hwndFocus );
63 /* This used to set infoPtr->hwndFocus to NULL for no apparent reason,
64 sometimes losing focus when receiving WM_SETFOCUS messages. */
65 return TRUE;
69 /***********************************************************************
70 * DEFDLG_FindDefButton
72 * Find the current default push-button.
74 static HWND DEFDLG_FindDefButton( HWND hwndDlg )
76 HWND hwndChild = GetWindow( hwndDlg, GW_CHILD );
77 while (hwndChild)
79 if (SendMessage16( hwndChild, WM_GETDLGCODE, 0, 0 ) & DLGC_DEFPUSHBUTTON)
80 break;
81 hwndChild = GetWindow( hwndChild, GW_HWNDNEXT );
83 return hwndChild;
87 /***********************************************************************
88 * DEFDLG_SetDefButton
90 * Set the new default button to be hwndNew.
92 static BOOL DEFDLG_SetDefButton( HWND hwndDlg, DIALOGINFO *dlgInfo,
93 HWND hwndNew )
95 if (hwndNew &&
96 !(SendMessage16(hwndNew, WM_GETDLGCODE, 0, 0 ) & DLGC_UNDEFPUSHBUTTON))
97 return FALSE; /* Destination is not a push button */
99 if (dlgInfo->idResult) /* There's already a default pushbutton */
101 HWND hwndOld = GetDlgItem( hwndDlg, dlgInfo->idResult );
102 if (SendMessageA( hwndOld, WM_GETDLGCODE, 0, 0) & DLGC_DEFPUSHBUTTON)
103 SendMessageA( hwndOld, BM_SETSTYLE, BS_PUSHBUTTON, TRUE );
105 if (hwndNew)
107 SendMessageA( hwndNew, BM_SETSTYLE, BS_DEFPUSHBUTTON, TRUE );
108 dlgInfo->idResult = GetDlgCtrlID( hwndNew );
110 else dlgInfo->idResult = 0;
111 return TRUE;
115 /***********************************************************************
116 * DEFDLG_Proc
118 * Implementation of DefDlgProc(). Only handle messages that need special
119 * handling for dialogs.
121 static LRESULT DEFDLG_Proc( HWND hwnd, UINT msg, WPARAM wParam,
122 LPARAM lParam, DIALOGINFO *dlgInfo )
124 switch(msg)
126 case WM_ERASEBKGND:
127 FillWindow16( hwnd, hwnd, (HDC16)wParam, (HBRUSH16)CTLCOLOR_DLG );
128 return 1;
130 case WM_NCDESTROY:
132 /* Free dialog heap (if created) */
133 if (dlgInfo->hDialogHeap)
135 GlobalUnlock16(dlgInfo->hDialogHeap);
136 GlobalFree16(dlgInfo->hDialogHeap);
137 dlgInfo->hDialogHeap = 0;
140 /* Delete font */
141 if (dlgInfo->hUserFont)
143 DeleteObject( dlgInfo->hUserFont );
144 dlgInfo->hUserFont = 0;
147 /* Delete menu */
148 if (dlgInfo->hMenu)
150 DestroyMenu( dlgInfo->hMenu );
151 dlgInfo->hMenu = 0;
154 /* Delete window procedure */
155 WINPROC_FreeProc( dlgInfo->dlgProc, WIN_PROC_WINDOW );
156 dlgInfo->dlgProc = (HWINDOWPROC)0;
157 dlgInfo->flags |= DF_END; /* just in case */
159 /* Window clean-up */
160 return DefWindowProcA( hwnd, msg, wParam, lParam );
162 case WM_SHOWWINDOW:
163 if (!wParam) DEFDLG_SaveFocus( hwnd, dlgInfo );
164 return DefWindowProcA( hwnd, msg, wParam, lParam );
166 case WM_ACTIVATE:
167 if (wParam) DEFDLG_RestoreFocus( hwnd, dlgInfo );
168 else DEFDLG_SaveFocus( hwnd, dlgInfo );
169 return 0;
171 case WM_SETFOCUS:
172 DEFDLG_RestoreFocus( hwnd, dlgInfo );
173 return 0;
175 case DM_SETDEFID:
176 if (dlgInfo->flags & DF_END) return 1;
177 DEFDLG_SetDefButton( hwnd, dlgInfo,
178 wParam ? GetDlgItem( hwnd, wParam ) : 0 );
179 return 1;
181 case DM_GETDEFID:
183 HWND hwndDefId;
184 if (dlgInfo->flags & DF_END) return 0;
185 if (dlgInfo->idResult)
186 return MAKELONG( dlgInfo->idResult, DC_HASDEFID );
187 if ((hwndDefId = DEFDLG_FindDefButton( hwnd )))
188 return MAKELONG( GetDlgCtrlID( hwndDefId ), DC_HASDEFID);
190 return 0;
192 case WM_NEXTDLGCTL:
194 HWND hwndDest = (HWND)wParam;
195 if (!lParam)
196 hwndDest = GetNextDlgTabItem(hwnd, GetFocus(), wParam);
197 if (hwndDest) DEFDLG_SetFocus( hwnd, hwndDest );
198 DEFDLG_SetDefButton( hwnd, dlgInfo, hwndDest );
200 return 0;
202 case WM_ENTERMENULOOP:
203 case WM_LBUTTONDOWN:
204 case WM_NCLBUTTONDOWN:
206 HWND hwndFocus = GetFocus();
207 if (hwndFocus)
209 WND *wnd = WIN_FindWndPtr( hwndFocus );
211 if( wnd )
213 /* always make combo box hide its listbox control */
215 if( WIDGETS_IsControl( wnd, BIC32_COMBO ) )
216 SendMessageA( hwndFocus, CB_SHOWDROPDOWN,
217 FALSE, 0 );
218 else if( WIDGETS_IsControl( wnd, BIC32_EDIT ) &&
219 WIDGETS_IsControl( wnd->parent,
220 BIC32_COMBO ))
221 SendMessageA( wnd->parent->hwndSelf,
222 CB_SHOWDROPDOWN, FALSE, 0 );
224 WIN_ReleaseWndPtr(wnd);
227 return DefWindowProcA( hwnd, msg, wParam, lParam );
229 case WM_GETFONT:
230 return dlgInfo->hUserFont;
232 case WM_CLOSE:
233 PostMessageA( hwnd, WM_COMMAND, IDCANCEL,
234 (LPARAM)GetDlgItem( hwnd, IDCANCEL ) );
235 return 0;
237 case WM_NOTIFYFORMAT:
238 return DefWindowProcA( hwnd, msg, wParam, lParam );
240 return 0;
243 /***********************************************************************
244 * DEFDLG_Epilog
246 static LRESULT DEFDLG_Epilog(DIALOGINFO* dlgInfo, UINT msg, BOOL fResult)
248 /* see SDK 3.1 */
250 if ((msg >= WM_CTLCOLORMSGBOX && msg <= WM_CTLCOLORSTATIC) ||
251 msg == WM_CTLCOLOR || msg == WM_COMPAREITEM ||
252 msg == WM_VKEYTOITEM || msg == WM_CHARTOITEM ||
253 msg == WM_QUERYDRAGICON || msg == WM_INITDIALOG)
254 return fResult;
256 return dlgInfo->msgResult;
259 /***********************************************************************
260 * DefDlgProc16 (USER.308)
262 LRESULT WINAPI DefDlgProc16( HWND16 hwnd, UINT16 msg, WPARAM16 wParam,
263 LPARAM lParam )
265 DIALOGINFO * dlgInfo;
266 BOOL result = FALSE;
267 WND * wndPtr = WIN_FindWndPtr( hwnd );
269 if (!wndPtr) return 0;
270 dlgInfo = (DIALOGINFO *)&wndPtr->wExtra;
271 dlgInfo->msgResult = 0;
273 if (dlgInfo->dlgProc) { /* Call dialog procedure */
274 result = CallWindowProc16( (WNDPROC16)dlgInfo->dlgProc,
275 hwnd, msg, wParam, lParam );
276 /* 16 bit dlg procs only return BOOL16 */
277 if( WINPROC_GetProcType( dlgInfo->dlgProc ) == WIN_PROC_16 )
278 result = LOWORD(result);
281 if (!result && IsWindow(hwnd))
283 /* callback didn't process this message */
285 switch(msg)
287 case WM_ERASEBKGND:
288 case WM_SHOWWINDOW:
289 case WM_ACTIVATE:
290 case WM_SETFOCUS:
291 case DM_SETDEFID:
292 case DM_GETDEFID:
293 case WM_NEXTDLGCTL:
294 case WM_GETFONT:
295 case WM_CLOSE:
296 case WM_NCDESTROY:
297 case WM_ENTERMENULOOP:
298 case WM_LBUTTONDOWN:
299 case WM_NCLBUTTONDOWN:
300 WIN_ReleaseWndPtr(wndPtr);
301 return DEFDLG_Proc( (HWND)hwnd, msg,
302 (WPARAM)wParam, lParam, dlgInfo );
303 case WM_INITDIALOG:
304 case WM_VKEYTOITEM:
305 case WM_COMPAREITEM:
306 case WM_CHARTOITEM:
307 break;
309 default:
310 WIN_ReleaseWndPtr(wndPtr);
311 return DefWindowProc16( hwnd, msg, wParam, lParam );
314 WIN_ReleaseWndPtr(wndPtr);
315 return DEFDLG_Epilog(dlgInfo, msg, result);
319 /***********************************************************************
320 * DefDlgProc32A (USER32.120)
322 LRESULT WINAPI DefDlgProcA( HWND hwnd, UINT msg,
323 WPARAM wParam, LPARAM lParam )
325 DIALOGINFO * dlgInfo;
326 BOOL result = FALSE;
327 WND * wndPtr = WIN_FindWndPtr( hwnd );
329 if (!wndPtr) return 0;
330 dlgInfo = (DIALOGINFO *)&wndPtr->wExtra;
331 dlgInfo->msgResult = 0;
333 if (dlgInfo->dlgProc) { /* Call dialog procedure */
334 result = CallWindowProcA( (WNDPROC)dlgInfo->dlgProc,
335 hwnd, msg, wParam, lParam );
336 /* 16 bit dlg procs only return BOOL16 */
337 if( WINPROC_GetProcType( dlgInfo->dlgProc ) == WIN_PROC_16 )
338 result = LOWORD(result);
341 if (!result && IsWindow(hwnd))
343 /* callback didn't process this message */
345 switch(msg)
347 case WM_ERASEBKGND:
348 case WM_SHOWWINDOW:
349 case WM_ACTIVATE:
350 case WM_SETFOCUS:
351 case DM_SETDEFID:
352 case DM_GETDEFID:
353 case WM_NEXTDLGCTL:
354 case WM_GETFONT:
355 case WM_CLOSE:
356 case WM_NCDESTROY:
357 case WM_ENTERMENULOOP:
358 case WM_LBUTTONDOWN:
359 case WM_NCLBUTTONDOWN:
360 WIN_ReleaseWndPtr(wndPtr);
361 return DEFDLG_Proc( (HWND)hwnd, msg,
362 (WPARAM)wParam, lParam, dlgInfo );
363 case WM_INITDIALOG:
364 case WM_VKEYTOITEM:
365 case WM_COMPAREITEM:
366 case WM_CHARTOITEM:
367 break;
369 default:
370 WIN_ReleaseWndPtr(wndPtr);
371 return DefWindowProcA( hwnd, msg, wParam, lParam );
374 WIN_ReleaseWndPtr(wndPtr);
375 return DEFDLG_Epilog(dlgInfo, msg, result);
379 /***********************************************************************
380 * DefDlgProc32W (USER32.121)
382 LRESULT WINAPI DefDlgProcW( HWND hwnd, UINT msg, WPARAM wParam,
383 LPARAM lParam )
385 DIALOGINFO * dlgInfo;
386 BOOL result = FALSE;
387 WND * wndPtr = WIN_FindWndPtr( hwnd );
389 if (!wndPtr) return 0;
390 dlgInfo = (DIALOGINFO *)&wndPtr->wExtra;
391 dlgInfo->msgResult = 0;
393 if (dlgInfo->dlgProc) { /* Call dialog procedure */
394 result = CallWindowProcW( (WNDPROC)dlgInfo->dlgProc,
395 hwnd, msg, wParam, lParam );
396 /* 16 bit dlg procs only return BOOL16 */
397 if( WINPROC_GetProcType( dlgInfo->dlgProc ) == WIN_PROC_16 )
398 result = LOWORD(result);
401 if (!result && IsWindow(hwnd))
403 /* callback didn't process this message */
405 switch(msg)
407 case WM_ERASEBKGND:
408 case WM_SHOWWINDOW:
409 case WM_ACTIVATE:
410 case WM_SETFOCUS:
411 case DM_SETDEFID:
412 case DM_GETDEFID:
413 case WM_NEXTDLGCTL:
414 case WM_GETFONT:
415 case WM_CLOSE:
416 case WM_NCDESTROY:
417 case WM_ENTERMENULOOP:
418 case WM_LBUTTONDOWN:
419 case WM_NCLBUTTONDOWN:
420 WIN_ReleaseWndPtr(wndPtr);
421 return DEFDLG_Proc( (HWND)hwnd, msg,
422 (WPARAM)wParam, lParam, dlgInfo );
423 case WM_INITDIALOG:
424 case WM_VKEYTOITEM:
425 case WM_COMPAREITEM:
426 case WM_CHARTOITEM:
427 break;
429 default:
430 WIN_ReleaseWndPtr(wndPtr);
431 return DefWindowProcW( hwnd, msg, wParam, lParam );
434 WIN_ReleaseWndPtr(wndPtr);
435 return DEFDLG_Epilog(dlgInfo, msg, result);