]>
Commit | Line | Data |
---|---|---|
df62e023 RC |
1 | /* |
2 | * Copyright (c) 2001, Gary R. Van Sickle. | |
3 | * | |
4 | * This program is free software; you can redistribute it and/or modify | |
5 | * it under the terms of the GNU General Public License as published by | |
6 | * the Free Software Foundation; either version 2 of the License, or | |
7 | * (at your option) any later version. | |
8 | * | |
9 | * A copy of the GNU General Public License can be found at | |
10 | * http://www.gnu.org/ | |
11 | * | |
12 | * Written by Gary R. Van Sickle <g.r.vansickle@worldnet.att.net> | |
13 | * | |
14 | */ | |
15 | ||
16 | // This is the implementation of the PropSheet class. This class encapsulates | |
17 | // a Windows property sheet / wizard and interfaces with the PropertyPage class. | |
18 | // It's named PropSheet instead of PropertySheet because the latter conflicts with | |
19 | // the Windows function of the same name. | |
20 | ||
21 | #include "propsheet.h" | |
22 | #include "proppage.h" | |
23 | ||
24 | //#include <shlwapi.h> | |
25 | // ...but since there is no shlwapi.h in mingw yet: | |
26 | typedef struct _DllVersionInfo | |
27 | { | |
28 | DWORD cbSize; | |
29 | DWORD dwMajorVersion; | |
30 | DWORD dwMinorVersion; | |
31 | DWORD dwBuildNumber; | |
32 | DWORD dwPlatformID; | |
33 | } | |
34 | DLLVERSIONINFO; | |
35 | typedef HRESULT CALLBACK (*DLLGETVERSIONPROC) (DLLVERSIONINFO * pdvi); | |
36 | #define PROPSHEETHEADER_V1_SIZE 40 | |
37 | ||
b7301c43 RC |
38 | // Sort of a "hidden" Windows structure. Used in the PropSheetCallback. |
39 | #include <pshpack1.h> | |
40 | typedef struct DLGTEMPLATEEX | |
41 | { | |
42 | WORD dlgVer; | |
43 | WORD signature; | |
44 | DWORD helpID; | |
45 | DWORD exStyle; | |
46 | DWORD style; | |
47 | WORD cDlgItems; | |
48 | short x; | |
49 | short y; | |
50 | short cx; | |
51 | short cy; | |
52 | } | |
53 | DLGTEMPLATEEX, *LPDLGTEMPLATEEX; | |
54 | #include <poppack.h> | |
df62e023 RC |
55 | |
56 | PropSheet::PropSheet () | |
57 | { | |
58 | NumPropPages = 0; | |
59 | } | |
60 | ||
61 | PropSheet::~PropSheet () | |
62 | { | |
63 | } | |
64 | ||
65 | HPROPSHEETPAGE * | |
66 | PropSheet::CreatePages () | |
67 | { | |
68 | HPROPSHEETPAGE *retarray; | |
69 | ||
70 | // Create the return array | |
71 | retarray = new HPROPSHEETPAGE[NumPropPages]; | |
72 | ||
73 | // Create the pages with CreatePropertySheetPage(). | |
74 | // We do it here rather than in the PropertyPages themselves | |
75 | // because, for reasons known only to Microsoft, these handles will be | |
76 | // destroyed by the property sheet before the PropertySheet() call returns, | |
77 | // at least if it's modal (don't know about modeless). | |
78 | int i; | |
79 | for (i = 0; i < NumPropPages; i++) | |
80 | { | |
81 | retarray[i] = | |
82 | CreatePropertySheetPage (PropertyPages[i]->GetPROPSHEETPAGEPtr ()); | |
83 | ||
84 | // Set position info | |
85 | if (i == 0) | |
86 | { | |
87 | PropertyPages[i]->YouAreFirst (); | |
88 | } | |
89 | else if (i == NumPropPages - 1) | |
90 | { | |
91 | PropertyPages[i]->YouAreLast (); | |
92 | } | |
93 | else | |
94 | { | |
95 | PropertyPages[i]->YouAreMiddle (); | |
96 | } | |
97 | } | |
98 | ||
99 | return retarray; | |
100 | } | |
101 | ||
b7301c43 RC |
102 | static int CALLBACK |
103 | PropSheetProc (HWND hwndDlg, UINT uMsg, LPARAM lParam) | |
104 | { | |
105 | switch (uMsg) | |
106 | { | |
107 | case PSCB_PRECREATE: | |
108 | { | |
109 | // Add a minimize box to the sheet/wizard. | |
110 | if (((LPDLGTEMPLATEEX) lParam)->signature == 0xFFFF) | |
111 | { | |
112 | ((LPDLGTEMPLATEEX) lParam)->style |= WS_MINIMIZEBOX; | |
113 | } | |
114 | else | |
115 | { | |
116 | ((LPDLGTEMPLATE) lParam)->style |= WS_MINIMIZEBOX; | |
117 | } | |
118 | } | |
119 | return TRUE; | |
120 | } | |
121 | return TRUE; | |
122 | } | |
123 | ||
df62e023 RC |
124 | static DWORD |
125 | GetPROPSHEETHEADERSize () | |
126 | { | |
127 | // For compatibility with all versions of comctl32.dll, we have to do this. | |
128 | ||
129 | DLLVERSIONINFO vi; | |
130 | HMODULE mod; | |
131 | DLLGETVERSIONPROC DllGetVersion; | |
132 | DWORD retval = 0; | |
133 | ||
134 | ||
135 | // This 'isn't safe' in a DLL, according to MSDN | |
136 | mod = LoadLibrary ("comctl32.dll"); | |
137 | ||
138 | DllGetVersion = (DLLGETVERSIONPROC) GetProcAddress (mod, "DllGetVersion"); | |
139 | if (DllGetVersion == NULL) | |
140 | { | |
141 | // Something's wildly broken, punt. | |
142 | retval = PROPSHEETHEADER_V1_SIZE; | |
143 | } | |
144 | else | |
145 | { | |
146 | vi.cbSize = sizeof (DLLVERSIONINFO); | |
147 | DllGetVersion (&vi); | |
148 | ||
149 | if ((vi.dwMajorVersion < 4) || | |
150 | ((vi.dwMajorVersion == 4) && (vi.dwMinorVersion < 71))) | |
151 | { | |
152 | // Recent. | |
153 | retval = sizeof (PROPSHEETHEADER); | |
154 | } | |
155 | else | |
156 | { | |
157 | // Old (== Win95/NT4 w/o IE 4 or better) | |
158 | retval = PROPSHEETHEADER_V1_SIZE; | |
159 | } | |
160 | } | |
161 | ||
162 | FreeLibrary (mod); | |
163 | ||
164 | return retval; | |
165 | } | |
166 | ||
b7301c43 RC |
167 | bool |
168 | PropSheet::Create (const Window * Parent, DWORD Style) | |
df62e023 | 169 | { |
b7301c43 | 170 | PROPSHEETHEADER p; |
df62e023 RC |
171 | |
172 | PageHandles = CreatePages (); | |
173 | ||
174 | p.dwSize = GetPROPSHEETHEADERSize (); | |
b7301c43 RC |
175 | p.dwFlags = |
176 | PSH_NOAPPLYNOW | PSH_WIZARD | PSH_USECALLBACK /*| PSH_MODELESS */ ; | |
df62e023 RC |
177 | if (Parent != NULL) |
178 | { | |
179 | p.hwndParent = Parent->GetHWND (); | |
180 | } | |
181 | else | |
182 | { | |
183 | p.hwndParent = NULL; | |
184 | } | |
185 | p.hInstance = GetInstance (); | |
186 | p.nPages = NumPropPages; | |
187 | p.nStartPage = 0; | |
188 | p.phpage = PageHandles; | |
b7301c43 | 189 | p.pfnCallback = PropSheetProc; |
df62e023 RC |
190 | |
191 | ||
192 | PropertySheet (&p); | |
193 | ||
194 | // Do a modeless property sheet... | |
195 | //SetHWND((HWND)PropertySheet(&p)); | |
196 | /*Show(SW_SHOWNORMAL); | |
197 | ||
198 | // ...but pretend it's modal | |
199 | MessageLoop(); | |
200 | MessageBox(NULL, "DONE", NULL, MB_OK); | |
201 | ||
202 | // FIXME: Enable the parent before destroying this window to prevent another window | |
203 | // from becoming the foreground window | |
204 | // ala: EnableWindow(<parent_hwnd>, TRUE); | |
205 | //DestroyWindow(WindowHandle); | |
206 | */ | |
207 | SetHWND (NULL); | |
208 | ||
209 | ||
210 | return true; | |
211 | } | |
212 | ||
213 | void | |
214 | PropSheet::SetHWNDFromPage (HWND h) | |
215 | { | |
216 | // If we're a modal dialog, there's no way for us to know our window handle unless | |
217 | // one of our pages tells us through this function. | |
218 | SetHWND (h); | |
219 | } | |
220 | ||
221 | void | |
222 | PropSheet::AddPage (PropertyPage * p) | |
223 | { | |
224 | // Add a page to the property sheet. | |
225 | p->YouAreBeingAddedToASheet (this); | |
226 | PropertyPages[NumPropPages] = p; | |
227 | NumPropPages++; | |
228 | } | |
229 | ||
b7301c43 RC |
230 | bool |
231 | PropSheet::SetActivePage (int i) | |
df62e023 RC |
232 | { |
233 | // Posts a message to the message queue, so this won't block | |
234 | return static_cast < bool > (::PropSheet_SetCurSel (GetHWND (), NULL, i)); | |
235 | } | |
236 | ||
b7301c43 RC |
237 | bool |
238 | PropSheet::SetActivePageByID (int resource_id) | |
df62e023 RC |
239 | { |
240 | // Posts a message to the message queue, so this won't block | |
241 | return static_cast < bool > | |
242 | (::PropSheet_SetCurSelByID (GetHWND (), resource_id)); | |
243 | } | |
244 | ||
245 | void | |
246 | PropSheet::SetButtons (DWORD flags) | |
247 | { | |
248 | // Posts a message to the message queue, so this won't block | |
249 | ::PropSheet_SetWizButtons (GetHWND (), flags); | |
250 | } | |
251 | ||
252 | void | |
253 | PropSheet::PressButton (int button) | |
254 | { | |
255 | ::PropSheet_PressButton (GetHWND (), button); | |
256 | } |