Release 950216
[wine.git] / windows / defdlg.c
blob4bd8592e05ea6dfd727f9a06244597c321466c9a
1 /*
2 * Default dialog procedure
4 * Copyright 1993 Alexandre Julliard
6 static char Copyright[] = "Copyright Alexandre Julliard, 1993";
7 */
9 #include "windows.h"
10 #include "dialog.h"
11 #include "win.h"
12 #include "stddebug.h"
13 /* #define DEBUG_DIALOG */
14 #include "debug.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 (SendMessage( hwndPrev, WM_GETDLGCODE, 0, 0 ) & DLGC_HASSETSEL)
29 SendMessage( hwndPrev, EM_SETSEL, TRUE, MAKELONG( -1, 0 ) );
31 if (SendMessage( hwndCtrl, WM_GETDLGCODE, 0, 0 ) & DLGC_HASSETSEL)
32 SendMessage( hwndCtrl, EM_SETSEL, 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 if (!infoPtr->hwndFocus) return FALSE; /* Already saved */
46 infoPtr->hwndFocus = hwndFocus;
47 /* Remove default button */
48 return TRUE;
52 /***********************************************************************
53 * DEFDLG_RestoreFocus
55 static BOOL DEFDLG_RestoreFocus( HWND hwnd, DIALOGINFO *infoPtr )
57 if (!infoPtr->hwndFocus || IsIconic(hwnd)) return FALSE;
58 if (!IsWindow( infoPtr->hwndFocus )) return FALSE;
59 DEFDLG_SetFocus( hwnd, infoPtr->hwndFocus );
60 infoPtr->hwndFocus = 0;
61 return TRUE;
65 /***********************************************************************
66 * DEFDLG_FindDefButton
68 * Find the current default push-button.
70 static HWND DEFDLG_FindDefButton( HWND hwndDlg )
72 HWND hwndChild = GetWindow( hwndDlg, GW_CHILD );
73 while (hwndChild)
75 if (SendMessage( hwndChild, WM_GETDLGCODE, 0, 0 ) & DLGC_DEFPUSHBUTTON)
76 break;
77 hwndChild = GetWindow( hwndChild, GW_HWNDNEXT );
79 return hwndChild;
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 !(SendMessage( 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 (SendMessage( hwndOld, WM_GETDLGCODE, 0, 0 ) & DLGC_DEFPUSHBUTTON)
99 SendMessage( hwndOld, BM_SETSTYLE, BS_PUSHBUTTON, TRUE );
101 if (hwndNew)
103 SendMessage( hwndNew, BM_SETSTYLE, BS_DEFPUSHBUTTON, TRUE );
104 dlgInfo->msgResult = GetDlgCtrlID( hwndNew );
106 else dlgInfo->msgResult = 0;
107 return TRUE;
111 /***********************************************************************
112 * DefDlgProc (USER.308)
114 LONG DefDlgProc( HWND hwnd, WORD msg, WORD wParam, LONG lParam )
116 DIALOGINFO * dlgInfo;
117 BOOL result = FALSE;
118 WND * wndPtr = WIN_FindWndPtr( hwnd );
120 if (!wndPtr) return 0;
121 dlgInfo = (DIALOGINFO *)&wndPtr->wExtra;
123 dprintf_dialog(stddeb, "DefDlgProc: %d %04x %d %08lx\n",
124 hwnd, msg, wParam, lParam );
126 dlgInfo->msgResult = 0;
127 if (dlgInfo->dlgProc)
129 /* Call dialog procedure */
130 result = (BOOL)CallWindowProc( dlgInfo->dlgProc, hwnd,
131 msg, wParam, lParam );
133 /* Check if window destroyed by dialog procedure */
134 wndPtr = WIN_FindWndPtr( hwnd );
135 if (!wndPtr) return result;
138 if (!result) switch(msg)
140 case WM_INITDIALOG:
141 break;
143 case WM_ERASEBKGND:
144 FillWindow( hwnd, hwnd, (HDC)wParam, (HBRUSH)CTLCOLOR_DLG );
145 return TRUE;
147 case WM_NCDESTROY:
149 /* Free dialog heap (if created) */
150 if (dlgInfo->hDialogHeap)
152 GlobalUnlock(dlgInfo->hDialogHeap);
153 GlobalFree(dlgInfo->hDialogHeap);
154 dlgInfo->hDialogHeap = 0;
157 /* Delete font */
158 if (dlgInfo->hUserFont)
160 DeleteObject( dlgInfo->hUserFont );
161 dlgInfo->hUserFont = 0;
164 /* Delete menu */
165 if (dlgInfo->hMenu)
167 DestroyMenu( dlgInfo->hMenu );
168 dlgInfo->hMenu = 0;
171 /* Window clean-up */
172 DefWindowProc( hwnd, msg, wParam, lParam );
173 break;
175 case WM_SHOWWINDOW:
176 if (!wParam) DEFDLG_SaveFocus( hwnd, dlgInfo );
177 return DefWindowProc( hwnd, msg, wParam, lParam );
179 case WM_ACTIVATE:
180 if (wParam) DEFDLG_RestoreFocus( hwnd, dlgInfo );
181 else DEFDLG_SaveFocus( hwnd, dlgInfo );
182 break;
184 case WM_SETFOCUS:
185 DEFDLG_RestoreFocus( hwnd, dlgInfo );
186 break;
188 case DM_SETDEFID:
189 if (dlgInfo->fEnd) return TRUE;
190 DEFDLG_SetDefButton( hwnd, dlgInfo,
191 wParam ? GetDlgItem( hwnd, wParam ) : 0 );
192 return TRUE;
194 case DM_GETDEFID:
195 if (dlgInfo->fEnd || !dlgInfo->msgResult) return 0;
196 return MAKELONG( dlgInfo->msgResult, DC_HASDEFID );
198 case WM_NEXTDLGCTL:
200 HWND hwndDest = wParam;
201 if (!lParam)
203 HWND hwndPrev = GetFocus();
204 if (!hwndPrev) /* Set focus to the first item */
205 hwndDest = DIALOG_GetFirstTabItem( hwnd );
206 else
207 hwndDest = GetNextDlgTabItem( hwnd, hwndPrev, wParam );
209 if (hwndDest) DEFDLG_SetFocus( hwnd, hwndDest );
210 DEFDLG_SetDefButton( hwnd, dlgInfo, hwndDest );
212 break;
214 default:
215 return DefWindowProc( hwnd, msg, wParam, lParam );
218 return result;