Release 941107
[wine.git] / windows / defdlg.c
blobcadc47efe39bf6e7c3907bd1baca2aef6d7db866
1 /*
2 * Default dialog procedure
4 * Copyright 1993 Alexandre Julliard
5 */
7 static char Copyright[] = "Copyright Alexandre Julliard, 1993";
9 #include "windows.h"
10 #include "dialog.h"
11 #include "win.h"
12 #include "stddebug.h"
13 /* #define DEBUG_DIALOG /* */
14 /* #undef DEBUG_DIALOG /* */
15 #include "debug.h"
18 extern HWND DIALOG_GetFirstTabItem( HWND hwndDlg ); /* windows/dialog.c */
21 /***********************************************************************
22 * DEFDLG_SetFocus
24 * Set the focus to a control of the dialog, selecting the text if
25 * the control is an edit dialog.
27 static void DEFDLG_SetFocus( HWND hwndDlg, HWND hwndCtrl )
29 HWND hwndPrev = GetFocus();
31 if (IsChild( hwndDlg, hwndPrev ))
33 if (SendMessage( hwndPrev, WM_GETDLGCODE, 0, 0 ) & DLGC_HASSETSEL)
34 SendMessage( hwndPrev, EM_SETSEL, TRUE, MAKELONG( -1, 0 ) );
36 if (SendMessage( hwndCtrl, WM_GETDLGCODE, 0, 0 ) & DLGC_HASSETSEL)
37 SendMessage( hwndCtrl, EM_SETSEL, FALSE, MAKELONG( 0, -1 ) );
38 SetFocus( hwndCtrl );
42 /***********************************************************************
43 * DEFDLG_SaveFocus
45 static BOOL DEFDLG_SaveFocus( HWND hwnd, DIALOGINFO *infoPtr )
47 HWND hwndFocus = GetFocus();
49 if (!hwndFocus || !IsChild( hwnd, hwndFocus )) return FALSE;
50 if (!infoPtr->hwndFocus) return FALSE; /* Already saved */
51 infoPtr->hwndFocus = hwndFocus;
52 /* Remove default button */
53 return TRUE;
57 /***********************************************************************
58 * DEFDLG_RestoreFocus
60 static BOOL DEFDLG_RestoreFocus( HWND hwnd, DIALOGINFO *infoPtr )
62 if (!infoPtr->hwndFocus || IsIconic(hwnd)) return FALSE;
63 if (!IsWindow( infoPtr->hwndFocus )) return FALSE;
64 DEFDLG_SetFocus( hwnd, infoPtr->hwndFocus );
65 infoPtr->hwndFocus = 0;
66 return TRUE;
70 /***********************************************************************
71 * DEFDLG_FindDefButton
73 * Find the current default push-button.
75 static HWND DEFDLG_FindDefButton( HWND hwndDlg )
77 HWND hwndChild = GetWindow( hwndDlg, GW_CHILD );
78 while (hwndChild)
80 if (SendMessage( hwndChild, WM_GETDLGCODE, 0, 0 ) & DLGC_DEFPUSHBUTTON)
81 break;
82 hwndChild = GetWindow( hwndChild, GW_HWNDNEXT );
84 return hwndChild;
88 /***********************************************************************
89 * DEFDLG_SetDefButton
91 * Set the new default button to be hwndNew.
93 static BOOL DEFDLG_SetDefButton( HWND hwndDlg, DIALOGINFO *dlgInfo,
94 HWND hwndNew )
96 if (hwndNew &&
97 !(SendMessage( hwndNew, WM_GETDLGCODE, 0, 0 ) & DLGC_UNDEFPUSHBUTTON))
98 return FALSE; /* Destination is not a push button */
100 if (dlgInfo->msgResult) /* There's already a default pushbutton */
102 HWND hwndOld = GetDlgItem( hwndDlg, dlgInfo->msgResult );
103 if (SendMessage( hwndOld, WM_GETDLGCODE, 0, 0 ) & DLGC_DEFPUSHBUTTON)
104 SendMessage( hwndOld, BM_SETSTYLE, BS_PUSHBUTTON, TRUE );
106 if (hwndNew)
108 SendMessage( hwndNew, BM_SETSTYLE, BS_DEFPUSHBUTTON, TRUE );
109 dlgInfo->msgResult = GetDlgCtrlID( hwndNew );
111 else dlgInfo->msgResult = 0;
112 return TRUE;
116 /***********************************************************************
117 * DefDlgProc (USER.308)
119 LONG DefDlgProc( HWND hwnd, WORD msg, WORD wParam, LONG lParam )
121 DIALOGINFO * dlgInfo;
122 BOOL result = FALSE;
123 WND * wndPtr = WIN_FindWndPtr( hwnd );
125 if (!wndPtr) return 0;
126 dlgInfo = (DIALOGINFO *)&wndPtr->wExtra;
128 dprintf_dialog(stddeb, "DefDlgProc: %d %04x %d %08lx\n",
129 hwnd, msg, wParam, lParam );
131 dlgInfo->msgResult = 0;
132 if (dlgInfo->dlgProc)
134 /* Call dialog procedure */
135 result = (BOOL)CallWindowProc( dlgInfo->dlgProc, hwnd,
136 msg, wParam, lParam );
138 /* Check if window destroyed by dialog procedure */
139 wndPtr = WIN_FindWndPtr( hwnd );
140 if (!wndPtr) return result;
143 if (!result) switch(msg)
145 case WM_INITDIALOG:
146 break;
148 case WM_ERASEBKGND:
149 FillWindow( hwnd, hwnd, (HDC)wParam, (HBRUSH)CTLCOLOR_DLG );
150 return TRUE;
152 case WM_NCDESTROY:
154 /* Free dialog heap (if created) */
155 if (dlgInfo->hDialogHeap)
157 GlobalUnlock(dlgInfo->hDialogHeap);
158 GlobalFree(dlgInfo->hDialogHeap);
159 dlgInfo->hDialogHeap = 0;
162 /* Delete font */
163 if (dlgInfo->hUserFont)
165 DeleteObject( dlgInfo->hUserFont );
166 dlgInfo->hUserFont = 0;
169 /* Delete menu */
170 if (dlgInfo->hMenu)
172 DestroyMenu( dlgInfo->hMenu );
173 dlgInfo->hMenu = 0;
176 /* Window clean-up */
177 DefWindowProc( hwnd, msg, wParam, lParam );
178 break;
180 case WM_SHOWWINDOW:
181 if (!wParam) DEFDLG_SaveFocus( hwnd, dlgInfo );
182 return DefWindowProc( hwnd, msg, wParam, lParam );
184 case WM_ACTIVATE:
185 if (wParam) DEFDLG_RestoreFocus( hwnd, dlgInfo );
186 else DEFDLG_SaveFocus( hwnd, dlgInfo );
187 break;
189 case WM_SETFOCUS:
190 DEFDLG_RestoreFocus( hwnd, dlgInfo );
191 break;
193 case DM_SETDEFID:
194 if (dlgInfo->fEnd) return TRUE;
195 DEFDLG_SetDefButton( hwnd, dlgInfo,
196 wParam ? GetDlgItem( hwnd, wParam ) : 0 );
197 return TRUE;
199 case DM_GETDEFID:
200 if (dlgInfo->fEnd || !dlgInfo->msgResult) return 0;
201 return MAKELONG( dlgInfo->msgResult, DC_HASDEFID );
203 case WM_NEXTDLGCTL:
205 HWND hwndDest = wParam;
206 if (!lParam)
208 HWND hwndPrev = GetFocus();
209 if (!hwndPrev) /* Set focus to the first item */
210 hwndDest = DIALOG_GetFirstTabItem( hwnd );
211 else
212 hwndDest = GetNextDlgTabItem( hwnd, hwndPrev, wParam );
214 if (hwndDest) DEFDLG_SetFocus( hwnd, hwndDest );
215 DEFDLG_SetDefButton( hwnd, dlgInfo, hwndDest );
217 break;
219 default:
220 return DefWindowProc( hwnd, msg, wParam, lParam );
223 return result;