Release 941017
[wine/gsoc-2012-control.git] / windows / defdlg.c
blobc223035347daeaa16746da7bc6cf0ea9791569e3
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 int dlgCode;
30 HWND hwndPrev = GetFocus();
32 if (IsChild( hwndDlg, hwndPrev ))
34 if (SendMessage( hwndPrev, WM_GETDLGCODE, 0, 0 ) & DLGC_HASSETSEL)
35 SendMessage( hwndPrev, EM_SETSEL, TRUE, MAKELONG( -1, 0 ) );
37 if (SendMessage( hwndCtrl, WM_GETDLGCODE, 0, 0 ) & DLGC_HASSETSEL)
38 SendMessage( hwndCtrl, EM_SETSEL, FALSE, MAKELONG( 0, -1 ) );
39 SetFocus( hwndCtrl );
43 /***********************************************************************
44 * DEFDLG_SaveFocus
46 static BOOL DEFDLG_SaveFocus( HWND hwnd, DIALOGINFO *infoPtr )
48 HWND hwndFocus = GetFocus();
50 if (!hwndFocus || !IsChild( hwnd, hwndFocus )) return FALSE;
51 if (!infoPtr->hwndFocus) return FALSE; /* Already saved */
52 infoPtr->hwndFocus = hwndFocus;
53 /* Remove default button */
54 return TRUE;
58 /***********************************************************************
59 * DEFDLG_RestoreFocus
61 static BOOL DEFDLG_RestoreFocus( HWND hwnd, DIALOGINFO *infoPtr )
63 if (!infoPtr->hwndFocus || IsIconic(hwnd)) return FALSE;
64 if (!IsWindow( infoPtr->hwndFocus )) return FALSE;
65 DEFDLG_SetFocus( hwnd, infoPtr->hwndFocus );
66 infoPtr->hwndFocus = 0;
67 return TRUE;
71 /***********************************************************************
72 * DEFDLG_FindDefButton
74 * Find the current default push-button.
76 static HWND DEFDLG_FindDefButton( HWND hwndDlg )
78 HWND hwndChild = GetWindow( hwndDlg, GW_CHILD );
79 while (hwndChild)
81 if (SendMessage( hwndChild, WM_GETDLGCODE, 0, 0 ) & DLGC_DEFPUSHBUTTON)
82 break;
83 hwndChild = GetWindow( hwndChild, GW_HWNDNEXT );
85 return hwndChild;
89 /***********************************************************************
90 * DEFDLG_SetDefButton
92 * Set the new default button to be hwndNew.
94 static BOOL DEFDLG_SetDefButton( HWND hwndDlg, DIALOGINFO *dlgInfo,
95 HWND hwndNew )
97 if (hwndNew &&
98 !(SendMessage( hwndNew, WM_GETDLGCODE, 0, 0 ) & DLGC_UNDEFPUSHBUTTON))
99 return FALSE; /* Destination is not a push button */
101 if (dlgInfo->msgResult) /* There's already a default pushbutton */
103 HWND hwndOld = GetDlgItem( hwndDlg, dlgInfo->msgResult );
104 if (SendMessage( hwndOld, WM_GETDLGCODE, 0, 0 ) & DLGC_DEFPUSHBUTTON)
105 SendMessage( hwndOld, BM_SETSTYLE, BS_PUSHBUTTON, TRUE );
107 if (hwndNew)
109 SendMessage( hwndNew, BM_SETSTYLE, BS_DEFPUSHBUTTON, TRUE );
110 dlgInfo->msgResult = GetDlgCtrlID( hwndNew );
112 else dlgInfo->msgResult = 0;
113 return TRUE;
117 /***********************************************************************
118 * DefDlgProc (USER.308)
120 LONG DefDlgProc( HWND hwnd, WORD msg, WORD wParam, LONG lParam )
122 DIALOGINFO * dlgInfo;
123 BOOL result = FALSE;
124 WND * wndPtr = WIN_FindWndPtr( hwnd );
126 if (!wndPtr) return 0;
127 dlgInfo = (DIALOGINFO *)&wndPtr->wExtra;
129 dprintf_dialog(stddeb, "DefDlgProc: %d %04x %d %08x\n",
130 hwnd, msg, wParam, lParam );
132 dlgInfo->msgResult = 0;
133 if (dlgInfo->dlgProc)
135 /* Call dialog procedure */
136 result = (BOOL)CallWindowProc( dlgInfo->dlgProc, hwnd,
137 msg, wParam, lParam );
139 /* Check if window destroyed by dialog procedure */
140 wndPtr = WIN_FindWndPtr( hwnd );
141 if (!wndPtr) return result;
144 if (!result) switch(msg)
146 case WM_INITDIALOG:
147 break;
149 case WM_ERASEBKGND:
150 FillWindow( hwnd, hwnd, (HDC)wParam, (HBRUSH)CTLCOLOR_DLG );
151 return TRUE;
153 case WM_NCDESTROY:
155 /* Free dialog heap (if created) */
156 if (dlgInfo->hDialogHeap)
158 GlobalUnlock(dlgInfo->hDialogHeap);
159 GlobalFree(dlgInfo->hDialogHeap);
160 dlgInfo->hDialogHeap = 0;
163 /* Delete font */
164 if (dlgInfo->hUserFont)
166 DeleteObject( dlgInfo->hUserFont );
167 dlgInfo->hUserFont = 0;
170 /* Delete menu */
171 if (dlgInfo->hMenu)
173 DestroyMenu( dlgInfo->hMenu );
174 dlgInfo->hMenu = 0;
177 /* Window clean-up */
178 DefWindowProc( hwnd, msg, wParam, lParam );
179 break;
181 case WM_SHOWWINDOW:
182 if (!wParam) DEFDLG_SaveFocus( hwnd, dlgInfo );
183 return DefWindowProc( hwnd, msg, wParam, lParam );
185 case WM_ACTIVATE:
186 if (wParam) DEFDLG_RestoreFocus( hwnd, dlgInfo );
187 else DEFDLG_SaveFocus( hwnd, dlgInfo );
188 break;
190 case WM_SETFOCUS:
191 DEFDLG_RestoreFocus( hwnd, dlgInfo );
192 break;
194 case DM_SETDEFID:
195 if (dlgInfo->fEnd) return TRUE;
196 DEFDLG_SetDefButton( hwnd, dlgInfo,
197 wParam ? GetDlgItem( hwnd, wParam ) : 0 );
198 return TRUE;
200 case DM_GETDEFID:
201 if (dlgInfo->fEnd || !dlgInfo->msgResult) return 0;
202 return MAKELONG( dlgInfo->msgResult, DC_HASDEFID );
204 case WM_NEXTDLGCTL:
206 HWND hwndDest = wParam;
207 if (!lParam)
209 HWND hwndPrev = GetFocus();
210 if (!hwndPrev) /* Set focus to the first item */
211 hwndDest = DIALOG_GetFirstTabItem( hwnd );
212 else
213 hwndDest = GetNextDlgTabItem( hwnd, hwndPrev, wParam );
215 if (hwndDest) DEFDLG_SetFocus( hwnd, hwndDest );
216 DEFDLG_SetDefButton( hwnd, dlgInfo, hwndDest );
218 break;
220 default:
221 return DefWindowProc( hwnd, msg, wParam, lParam );
224 return result;