rlm@1
|
1 /*----------------------------------------------------------------------
|
rlm@1
|
2 Copyright (c) Gipsysoft. All Rights Reserved.
|
rlm@1
|
3 File: DialogSizer_Set.cpp
|
rlm@1
|
4 Web site: http://gipsysoft.com
|
rlm@1
|
5
|
rlm@1
|
6 This software is provided 'as-is', without any express or implied warranty.
|
rlm@1
|
7
|
rlm@1
|
8 In no event will the author be held liable for any damages arising from the
|
rlm@1
|
9 use of this software.
|
rlm@1
|
10
|
rlm@1
|
11 Permission is granted to anyone to use this software for any purpose, including
|
rlm@1
|
12 commercial applications, and to alter it and redistribute it freely, subject
|
rlm@1
|
13 to the following restrictions:
|
rlm@1
|
14
|
rlm@1
|
15 1) The origin of this software must not be misrepresented; you must not claim
|
rlm@1
|
16 that you wrote the original software. If you use this software in a product,
|
rlm@1
|
17 an acknowledgment in the product documentation is requested but not required.
|
rlm@1
|
18 2) Altered source versions must be plainly marked as such, and must not be
|
rlm@1
|
19 misrepresented as being the original software. Altered source is encouraged
|
rlm@1
|
20 to be submitted back to the original author so it can be shared with the
|
rlm@1
|
21 community. Please share your changes.
|
rlm@1
|
22 3) This notice may not be removed or altered from any source distribution.
|
rlm@1
|
23
|
rlm@1
|
24 Owner: russf@gipsysoft.com
|
rlm@1
|
25 Purpose: Main functionality for sizeable dialogs
|
rlm@1
|
26
|
rlm@1
|
27 Store a local copy of the user settings
|
rlm@1
|
28 Subclass the window
|
rlm@1
|
29 Respond to various messages withinn the subclassed window.
|
rlm@1
|
30
|
rlm@1
|
31 ----------------------------------------------------------------------*/
|
rlm@1
|
32 // modified by the VBA-rr Team
|
rlm@1
|
33
|
rlm@1
|
34 #include "stdafx.h"
|
rlm@1
|
35 #include "ResizeDlg.h"
|
rlm@1
|
36 #include "VBA.h"
|
rlm@1
|
37 #include "Sound.h"
|
rlm@1
|
38 #include "WinHelper.h"
|
rlm@1
|
39
|
rlm@1
|
40 IMPLEMENT_DYNAMIC(ResizeDlg, CDialog)
|
rlm@1
|
41
|
rlm@1
|
42 // moved functions to this file to reduce number of files
|
rlm@1
|
43
|
rlm@1
|
44 struct RegistryData
|
rlm@1
|
45 {
|
rlm@1
|
46 WINDOWPLACEMENT m_wpl;
|
rlm@1
|
47 };
|
rlm@1
|
48
|
rlm@1
|
49 struct DialogData // dd
|
rlm@1
|
50 {
|
rlm@1
|
51 HKEY hkRootSave;
|
rlm@1
|
52 LPCTSTR pcszName;
|
rlm@1
|
53
|
rlm@1
|
54 //
|
rlm@1
|
55 // The number of items contained in the psd member.
|
rlm@1
|
56 // Used in the DeferWindowPos structure and in allocating memory
|
rlm@1
|
57 int nItemCount;
|
rlm@1
|
58 DialogSizerSizingItem *psd;
|
rlm@1
|
59
|
rlm@1
|
60 //
|
rlm@1
|
61 // We need the smallest to respond to the WM_GETMINMAXINFO message
|
rlm@1
|
62 POINT m_ptSmallest;
|
rlm@1
|
63
|
rlm@1
|
64 //
|
rlm@1
|
65 // We don't strictly speaking need to say how big the biggest can be but
|
rlm@1
|
66 POINT m_ptLargest;
|
rlm@1
|
67 bool m_bLargestSet;
|
rlm@1
|
68
|
rlm@1
|
69 //
|
rlm@1
|
70 // we need this to decide how much the window has changed size when we get a WM_SIZE message
|
rlm@1
|
71 SIZE m_sizeClient;
|
rlm@1
|
72
|
rlm@1
|
73 //
|
rlm@1
|
74 // Draw the sizing grip...or not
|
rlm@1
|
75 bool m_bMaximised;
|
rlm@1
|
76 BOOL m_bShowSizingGrip;
|
rlm@1
|
77
|
rlm@1
|
78 WinHelper::CRect m_rcGrip;
|
rlm@1
|
79 };
|
rlm@1
|
80
|
rlm@1
|
81 extern bool regEnabled;
|
rlm@1
|
82 extern const char *regGetINIPath();
|
rlm@1
|
83
|
rlm@1
|
84 void AssertFailed(char *file, int line, char *exp)
|
rlm@1
|
85 {
|
rlm@1
|
86 char buffer[1024];
|
rlm@1
|
87
|
rlm@1
|
88 sprintf(buffer, "File %s\nLine %d\nExpression %s\nPress Retry to debug",
|
rlm@1
|
89 file, line, exp);
|
rlm@1
|
90 systemSoundClearBuffer();
|
rlm@1
|
91 int res = MessageBox(*theApp.m_pMainWnd, buffer, "Assertion failed!",
|
rlm@1
|
92 MB_ICONHAND | MB_SETFOREGROUND | MB_TASKMODAL |
|
rlm@1
|
93 MB_ABORTRETRYIGNORE);
|
rlm@1
|
94
|
rlm@1
|
95 if (res == IDRETRY)
|
rlm@1
|
96 {
|
rlm@1
|
97 __asm int 3;
|
rlm@1
|
98 }
|
rlm@1
|
99 else if (res == IDABORT)
|
rlm@1
|
100 SendMessage(*theApp.m_pMainWnd, WM_QUIT, 0, 0);
|
rlm@1
|
101 }
|
rlm@1
|
102
|
rlm@1
|
103 void ApiFailure(char *pcszFilename, int nLine, char *pcszExpression)
|
rlm@1
|
104 {
|
rlm@1
|
105 const DWORD dwLastError = ::GetLastError();
|
rlm@1
|
106 LPCTSTR lpMsgBuf;
|
rlm@1
|
107 (void)::FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
rlm@1
|
108 FORMAT_MESSAGE_FROM_SYSTEM |
|
rlm@1
|
109 FORMAT_MESSAGE_IGNORE_INSERTS,
|
rlm@1
|
110 NULL, dwLastError,
|
rlm@1
|
111 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
rlm@1
|
112 (LPTSTR) &lpMsgBuf, 0, NULL);
|
rlm@1
|
113
|
rlm@1
|
114 char szExeName[ MAX_PATH ];
|
rlm@1
|
115
|
rlm@1
|
116 if (!GetModuleFileName(NULL, szExeName, countof(szExeName)))
|
rlm@1
|
117 strcpy(szExeName, "<No Program Name>");
|
rlm@1
|
118
|
rlm@1
|
119 char szMessage[ 1024 ];
|
rlm@1
|
120 _snprintf(szMessage, countof(szMessage),
|
rlm@1
|
121 "API VERIFY Failure!"
|
rlm@1
|
122 "\nProgram: %s"
|
rlm@1
|
123 "\n"
|
rlm@1
|
124 "\nFile %s"
|
rlm@1
|
125 "\nLine %d"
|
rlm@1
|
126 "\n"
|
rlm@1
|
127 "\nExpression %s"
|
rlm@1
|
128 "\n"
|
rlm@1
|
129 "\nLast Error %d"
|
rlm@1
|
130 "\n %s"
|
rlm@1
|
131 "\n\nPress Retry to debug the application",
|
rlm@1
|
132 szExeName,
|
rlm@1
|
133 pcszFilename,
|
rlm@1
|
134 nLine,
|
rlm@1
|
135 pcszExpression,
|
rlm@1
|
136 dwLastError,
|
rlm@1
|
137 lpMsgBuf
|
rlm@1
|
138 );
|
rlm@1
|
139
|
rlm@1
|
140 (void)LocalFree((LPVOID)lpMsgBuf);
|
rlm@1
|
141 HWND hwndParent = ::GetActiveWindow();
|
rlm@1
|
142 hwndParent = ::GetLastActivePopup(hwndParent);
|
rlm@1
|
143 systemSoundClearBuffer();
|
rlm@1
|
144 int nCode = ::MessageBoxA(hwndParent,
|
rlm@1
|
145 szMessage,
|
rlm@1
|
146 "Debug Helper",
|
rlm@1
|
147 MB_TASKMODAL | MB_ICONHAND | MB_ABORTRETRYIGNORE |
|
rlm@1
|
148 MB_SETFOREGROUND);
|
rlm@1
|
149 if (nCode == IDABORT)
|
rlm@1
|
150 {
|
rlm@1
|
151 ::SendMessage(*theApp.m_pMainWnd, WM_QUIT, 0, 0);
|
rlm@1
|
152 }
|
rlm@1
|
153 else if (nCode == IDRETRY)
|
rlm@1
|
154 __asm int 3;
|
rlm@1
|
155 }
|
rlm@1
|
156
|
rlm@1
|
157 long FASTCALL RegQueryValueExRecursive(HKEY hKey,
|
rlm@1
|
158 LPCTSTR lpValueName,
|
rlm@1
|
159 LPDWORD lpReserved,
|
rlm@1
|
160 LPDWORD lpType,
|
rlm@1
|
161 LPBYTE lpData,
|
rlm@1
|
162 LPDWORD lpcbData)
|
rlm@1
|
163 {
|
rlm@1
|
164 TCHAR szBuffer[ 256 ];
|
rlm@1
|
165 R_ASSERT(lstrlen(lpValueName) < countof(szBuffer));
|
rlm@1
|
166 (void)lstrcpy(szBuffer, lpValueName);
|
rlm@1
|
167
|
rlm@1
|
168 LPTSTR pszBuffer = szBuffer;
|
rlm@1
|
169 LPTSTR pszLast = szBuffer;
|
rlm@1
|
170 while (*pszBuffer)
|
rlm@1
|
171 {
|
rlm@1
|
172 if (*pszBuffer == _T('\\') || *pszBuffer == _T('/'))
|
rlm@1
|
173 {
|
rlm@1
|
174 pszLast = pszBuffer;
|
rlm@1
|
175 lpValueName = pszLast + 1;
|
rlm@1
|
176 }
|
rlm@1
|
177 pszBuffer++;
|
rlm@1
|
178 }
|
rlm@1
|
179
|
rlm@1
|
180 if (!regEnabled)
|
rlm@1
|
181 {
|
rlm@1
|
182 if (GetPrivateProfileStruct("Viewer",
|
rlm@1
|
183 lpValueName,
|
rlm@1
|
184 lpData,
|
rlm@1
|
185 *lpcbData,
|
rlm@1
|
186 regGetINIPath()))
|
rlm@1
|
187 {
|
rlm@1
|
188 *lpType = REG_BINARY;
|
rlm@1
|
189 return ERROR_SUCCESS;
|
rlm@1
|
190 }
|
rlm@1
|
191 return -1;
|
rlm@1
|
192 }
|
rlm@1
|
193
|
rlm@1
|
194 bool m_bNeedToCloseKey = false;
|
rlm@1
|
195 if (pszLast != szBuffer)
|
rlm@1
|
196 {
|
rlm@1
|
197 *pszLast = _T('\000');
|
rlm@1
|
198 HKEY hkeyTemp;
|
rlm@1
|
199 long lRet = RegOpenKey(hKey, szBuffer, &hkeyTemp);
|
rlm@1
|
200 if (lRet != ERROR_SUCCESS)
|
rlm@1
|
201 {
|
rlm@1
|
202 return lRet;
|
rlm@1
|
203 }
|
rlm@1
|
204 hKey = hkeyTemp;
|
rlm@1
|
205 m_bNeedToCloseKey = true;
|
rlm@1
|
206 }
|
rlm@1
|
207
|
rlm@1
|
208 long lRet = RegQueryValueEx(hKey, lpValueName, lpReserved, lpType, lpData, lpcbData);
|
rlm@1
|
209 if (m_bNeedToCloseKey)
|
rlm@1
|
210 {
|
rlm@1
|
211 R_VERIFY(RegCloseKey(hKey) == ERROR_SUCCESS);
|
rlm@1
|
212 }
|
rlm@1
|
213 return lRet;
|
rlm@1
|
214 }
|
rlm@1
|
215
|
rlm@1
|
216 long FASTCALL RegSetValueExRecursive(HKEY hKey,
|
rlm@1
|
217 LPCTSTR lpValueName,
|
rlm@1
|
218 DWORD Reserved,
|
rlm@1
|
219 DWORD dwType,
|
rlm@1
|
220 CONST BYTE*lpData,
|
rlm@1
|
221 DWORD cbData)
|
rlm@1
|
222 {
|
rlm@1
|
223 TCHAR szBuffer[ 256 ];
|
rlm@1
|
224 R_ASSERT(lstrlen(lpValueName) < countof(szBuffer));
|
rlm@1
|
225 (void)lstrcpy(szBuffer, lpValueName);
|
rlm@1
|
226
|
rlm@1
|
227 LPTSTR pszBuffer = szBuffer;
|
rlm@1
|
228 LPTSTR pszLast = szBuffer;
|
rlm@1
|
229 while (*pszBuffer)
|
rlm@1
|
230 {
|
rlm@1
|
231 if (*pszBuffer == _T('\\') || *pszBuffer == _T('/'))
|
rlm@1
|
232 {
|
rlm@1
|
233 pszLast = pszBuffer;
|
rlm@1
|
234 lpValueName = pszLast + 1;
|
rlm@1
|
235 }
|
rlm@1
|
236 pszBuffer++;
|
rlm@1
|
237 }
|
rlm@1
|
238
|
rlm@1
|
239 if (!regEnabled)
|
rlm@1
|
240 {
|
rlm@1
|
241 if (WritePrivateProfileStruct("Viewer",
|
rlm@1
|
242 lpValueName,
|
rlm@1
|
243 (LPVOID)lpData,
|
rlm@1
|
244 cbData,
|
rlm@1
|
245 regGetINIPath()))
|
rlm@1
|
246 {
|
rlm@1
|
247 return ERROR_SUCCESS;
|
rlm@1
|
248 }
|
rlm@1
|
249 return -1;
|
rlm@1
|
250 }
|
rlm@1
|
251
|
rlm@1
|
252 bool m_bNeedToCloseKey = false;
|
rlm@1
|
253 if (pszLast != szBuffer)
|
rlm@1
|
254 {
|
rlm@1
|
255 *pszLast = _T('\000');
|
rlm@1
|
256 HKEY hkeyTemp;
|
rlm@1
|
257 long lRet = RegOpenKey(hKey, szBuffer, &hkeyTemp);
|
rlm@1
|
258 if (lRet != ERROR_SUCCESS)
|
rlm@1
|
259 {
|
rlm@1
|
260 lRet = RegCreateKey(hKey, szBuffer, &hkeyTemp);
|
rlm@1
|
261 if (lRet != ERROR_SUCCESS)
|
rlm@1
|
262 return lRet;
|
rlm@1
|
263 }
|
rlm@1
|
264 hKey = hkeyTemp;
|
rlm@1
|
265 m_bNeedToCloseKey = true;
|
rlm@1
|
266 }
|
rlm@1
|
267
|
rlm@1
|
268 long lRet = RegSetValueEx(hKey, lpValueName, Reserved, dwType, lpData, cbData);
|
rlm@1
|
269 if (m_bNeedToCloseKey)
|
rlm@1
|
270 {
|
rlm@1
|
271 R_VERIFY(RegCloseKey(hKey) == ERROR_SUCCESS);
|
rlm@1
|
272 }
|
rlm@1
|
273 return lRet;
|
rlm@1
|
274 }
|
rlm@1
|
275
|
rlm@1
|
276 int ResizeDlgGetItemCount(const DialogSizerSizingItem *psd)
|
rlm@1
|
277 {
|
rlm@1
|
278 R_ASSERT(psd);
|
rlm@1
|
279 int nCount = 0;
|
rlm@1
|
280 while (psd->uSizeInfo != 0xFFFFFFFF)
|
rlm@1
|
281 {
|
rlm@1
|
282 nCount++;
|
rlm@1
|
283 psd++;
|
rlm@1
|
284 }
|
rlm@1
|
285 return nCount;
|
rlm@1
|
286 }
|
rlm@1
|
287
|
rlm@1
|
288 void ResizeDlgUpdateGripperRect(const int cx, const int cy, WinHelper::CRect &rcGrip)
|
rlm@1
|
289 {
|
rlm@1
|
290 const int nGripWidth = GetSystemMetrics(SM_CYVSCROLL);
|
rlm@1
|
291 const int nGripHeight = GetSystemMetrics(SM_CXVSCROLL);
|
rlm@1
|
292 rcGrip.left = cx - nGripWidth;
|
rlm@1
|
293 rcGrip.top = cy - nGripHeight;
|
rlm@1
|
294 rcGrip.right = cx;
|
rlm@1
|
295 rcGrip.bottom = cy;
|
rlm@1
|
296 }
|
rlm@1
|
297
|
rlm@1
|
298 void ResizeDlgUpdateGripper(HWND hwnd, DialogData *pdd)
|
rlm@1
|
299 {
|
rlm@1
|
300 if (pdd->m_bShowSizingGrip)
|
rlm@1
|
301 {
|
rlm@1
|
302 WinHelper::CRect rcOld(pdd->m_rcGrip);
|
rlm@1
|
303
|
rlm@1
|
304 ResizeDlgUpdateGripperRect(pdd->m_sizeClient.cx, pdd->m_sizeClient.cy, pdd->m_rcGrip);
|
rlm@1
|
305
|
rlm@1
|
306 //
|
rlm@1
|
307 // We also need to invalidate the combined area of the old and new rectangles
|
rlm@1
|
308 // otherwise we would have trail of grippers when we sized the dialog larger
|
rlm@1
|
309 // in any axis
|
rlm@1
|
310 (void)UnionRect(&rcOld, &rcOld, &pdd->m_rcGrip);
|
rlm@1
|
311 (void)InvalidateRect(hwnd, &rcOld, TRUE);
|
rlm@1
|
312 }
|
rlm@1
|
313 }
|
rlm@1
|
314
|
rlm@1
|
315 void ResizeDlgCopyItems(DialogSizerSizingItem *psdDest, const DialogSizerSizingItem *psdSource)
|
rlm@1
|
316 //
|
rlm@1
|
317 // Will copy all of the items in psdSource into psdDest.
|
rlm@1
|
318 {
|
rlm@1
|
319 //
|
rlm@1
|
320 // Loop til we reach the end
|
rlm@1
|
321 while (psdSource->uSizeInfo != 0xFFFFFFFF)
|
rlm@1
|
322 {
|
rlm@1
|
323 *psdDest = *psdSource;
|
rlm@1
|
324 psdDest++;
|
rlm@1
|
325 psdSource++;
|
rlm@1
|
326 }
|
rlm@1
|
327 // And when we do copy the last item
|
rlm@1
|
328 *psdDest = *psdSource;
|
rlm@1
|
329 }
|
rlm@1
|
330
|
rlm@1
|
331 ResizeDlg::ResizeDlg(UINT id, CWnd *parent)
|
rlm@1
|
332 : CDialog(id, parent)
|
rlm@1
|
333 {
|
rlm@1
|
334 dd = NULL;
|
rlm@1
|
335 }
|
rlm@1
|
336
|
rlm@1
|
337 void *ResizeDlg::AddDialogData()
|
rlm@1
|
338 //
|
rlm@1
|
339 // Firstly determine if the data already exists, if it does then return that, if not then we will
|
rlm@1
|
340 // create and initialise a brand new structure.
|
rlm@1
|
341 {
|
rlm@1
|
342 DialogData *pdd = (DialogData *)dd;
|
rlm@1
|
343 if (!pdd)
|
rlm@1
|
344 {
|
rlm@1
|
345 pdd = (DialogData *)calloc(1, sizeof(DialogData));
|
rlm@1
|
346 }
|
rlm@1
|
347
|
rlm@1
|
348 if (pdd)
|
rlm@1
|
349 {
|
rlm@1
|
350 //
|
rlm@1
|
351 // Store some sizes etc. for later.
|
rlm@1
|
352 CRect rc;
|
rlm@1
|
353 GetWindowRect(rc);
|
rlm@1
|
354 pdd->m_ptSmallest.x = rc.Width();
|
rlm@1
|
355 pdd->m_ptSmallest.y = rc.Height();
|
rlm@1
|
356
|
rlm@1
|
357 GetClientRect(rc);
|
rlm@1
|
358 pdd->m_sizeClient = rc.Size();
|
rlm@1
|
359 dd = pdd;
|
rlm@1
|
360 ResizeDlgUpdateGripperRect(pdd->m_sizeClient.cx, pdd->m_sizeClient.cy, pdd->m_rcGrip);
|
rlm@1
|
361 }
|
rlm@1
|
362 return pdd;
|
rlm@1
|
363 }
|
rlm@1
|
364
|
rlm@1
|
365 BOOL ResizeDlg::SetData(const DialogSizerSizingItem *psd,
|
rlm@1
|
366 BOOL bShowSizingGrip,
|
rlm@1
|
367 HKEY hkRootSave,
|
rlm@1
|
368 LPCTSTR pcszName,
|
rlm@1
|
369 SIZE *psizeMax)
|
rlm@1
|
370 //
|
rlm@1
|
371 // Setting a dialog sizeable involves subclassing the window and handling it's
|
rlm@1
|
372 // WM_SIZE messages, if we have a hkRootSave and pcszName then we will also be loading/saving
|
rlm@1
|
373 // the size and position of the window from the registry. We load from the registry when we
|
rlm@1
|
374 // subclass the window and we save to the registry when we get a WM_DESTROY.
|
rlm@1
|
375 //
|
rlm@1
|
376 // It will return non-zero for success and zero if it fails
|
rlm@1
|
377 {
|
rlm@1
|
378 R_ASSERT(psd);
|
rlm@1
|
379 R_ASSERT((hkRootSave != NULL && pcszName != NULL)
|
rlm@1
|
380 || (hkRootSave == NULL && pcszName == NULL));
|
rlm@1
|
381 //
|
rlm@1
|
382 // Make sure all of the parameters are valid.
|
rlm@1
|
383 if (::IsWindow(*this)
|
rlm@1
|
384 && psd
|
rlm@1
|
385 && ((hkRootSave != NULL && pcszName != NULL &&
|
rlm@1
|
386 !IsBadStringPtr(pcszName, 0xFFFF)) ||
|
rlm@1
|
387 (hkRootSave == NULL && pcszName == NULL))
|
rlm@1
|
388 && (psizeMax == NULL || !IsBadReadPtr(psizeMax, sizeof(SIZE)))
|
rlm@1
|
389 )
|
rlm@1
|
390 {
|
rlm@1
|
391 DialogData *pdd = (DialogData *)AddDialogData();
|
rlm@1
|
392 if (pdd)
|
rlm@1
|
393 {
|
rlm@1
|
394 pdd->hkRootSave = hkRootSave;
|
rlm@1
|
395 pdd->pcszName = pcszName;
|
rlm@1
|
396 pdd->m_bShowSizingGrip = bShowSizingGrip;
|
rlm@1
|
397 pdd->nItemCount = ResizeDlgGetItemCount(psd) + 1;
|
rlm@1
|
398 pdd->psd = (DialogSizerSizingItem *)
|
rlm@1
|
399 calloc(pdd->nItemCount,
|
rlm@1
|
400 sizeof(DialogSizerSizingItem));
|
rlm@1
|
401 if (pdd->psd)
|
rlm@1
|
402 {
|
rlm@1
|
403 //
|
rlm@1
|
404 // Copy all of the user controls etc. for later, this way the user can quite happily
|
rlm@1
|
405 // let the structure go out of scope.
|
rlm@1
|
406 ResizeDlgCopyItems(pdd->psd, psd);
|
rlm@1
|
407 if (psizeMax)
|
rlm@1
|
408 {
|
rlm@1
|
409 pdd->m_ptLargest.x = psizeMax->cx;
|
rlm@1
|
410 pdd->m_ptLargest.y = psizeMax->cy;
|
rlm@1
|
411 pdd->m_bLargestSet = true;
|
rlm@1
|
412 }
|
rlm@1
|
413
|
rlm@1
|
414 //
|
rlm@1
|
415 // If the there was save info passed in then we need to make damn good use of it
|
rlm@1
|
416 // by attempting to load the RegistryData structure
|
rlm@1
|
417 if (hkRootSave && pcszName)
|
rlm@1
|
418 {
|
rlm@1
|
419 RegistryData rd;
|
rlm@1
|
420 DWORD dwSize = sizeof(RegistryData);
|
rlm@1
|
421 DWORD dwType = REG_BINARY;
|
rlm@1
|
422 if (RegQueryValueExRecursive(hkRootSave, pcszName, NULL, &dwType, reinterpret_cast<LPBYTE>(&rd),
|
rlm@1
|
423 &dwSize) == ERROR_SUCCESS && dwSize == sizeof(rd))
|
rlm@1
|
424 {
|
rlm@1
|
425 if (!(GetWindowLong(*this, GWL_STYLE) & WS_VISIBLE))
|
rlm@1
|
426 rd.m_wpl.showCmd = SW_HIDE;
|
rlm@1
|
427
|
rlm@1
|
428 VAPI(SetWindowPlacement(&rd.m_wpl));
|
rlm@1
|
429 }
|
rlm@1
|
430 }
|
rlm@1
|
431 return TRUE;
|
rlm@1
|
432 }
|
rlm@1
|
433 else
|
rlm@1
|
434 {
|
rlm@1
|
435 free(pdd);
|
rlm@1
|
436 }
|
rlm@1
|
437 }
|
rlm@1
|
438 }
|
rlm@1
|
439 return FALSE;
|
rlm@1
|
440 }
|
rlm@1
|
441
|
rlm@1
|
442 void ResizeDlg::UpdateWindowSize(const int cx, const int cy, HWND hwnd)
|
rlm@1
|
443 {
|
rlm@1
|
444 DialogData *pdd = (DialogData *)dd;
|
rlm@1
|
445 if (pdd)
|
rlm@1
|
446 {
|
rlm@1
|
447 const int nDeltaX = cx - pdd->m_sizeClient.cx;
|
rlm@1
|
448 const int nDeltaY = cy - pdd->m_sizeClient.cy;
|
rlm@1
|
449 WinHelper::CDeferWindowPos def(pdd->nItemCount);
|
rlm@1
|
450 WinHelper::CRect rc;
|
rlm@1
|
451 const DialogSizerSizingItem *psd = pdd->psd;
|
rlm@1
|
452 while (psd->uSizeInfo != 0xFFFFFFFF)
|
rlm@1
|
453 {
|
rlm@1
|
454 HWND hwndChild = ::GetDlgItem(*this, psd->uControlID);
|
rlm@1
|
455 if (::IsWindow(hwndChild))
|
rlm@1
|
456 {
|
rlm@1
|
457 VAPI(::GetWindowRect(hwndChild, rc));
|
rlm@1
|
458 (void)::MapWindowPoints(::GetDesktopWindow(), hwnd,
|
rlm@1
|
459 (LPPOINT)&rc, 2);
|
rlm@1
|
460
|
rlm@1
|
461 //
|
rlm@1
|
462 // Adjust the window horizontally
|
rlm@1
|
463 if (psd->uSizeInfo & DS_MoveX)
|
rlm@1
|
464 {
|
rlm@1
|
465 rc.left += nDeltaX;
|
rlm@1
|
466 rc.right += nDeltaX;
|
rlm@1
|
467 }
|
rlm@1
|
468
|
rlm@1
|
469 //
|
rlm@1
|
470 // Adjust the window vertically
|
rlm@1
|
471 if (psd->uSizeInfo & DS_MoveY)
|
rlm@1
|
472 {
|
rlm@1
|
473 rc.top += nDeltaY;
|
rlm@1
|
474 rc.bottom += nDeltaY;
|
rlm@1
|
475 }
|
rlm@1
|
476
|
rlm@1
|
477 //
|
rlm@1
|
478 // Size the window horizontally
|
rlm@1
|
479 if (psd->uSizeInfo & DS_SizeX)
|
rlm@1
|
480 {
|
rlm@1
|
481 rc.right += nDeltaX;
|
rlm@1
|
482 }
|
rlm@1
|
483
|
rlm@1
|
484 //
|
rlm@1
|
485 // Size the window vertically
|
rlm@1
|
486 if (psd->uSizeInfo & DS_SizeY)
|
rlm@1
|
487 {
|
rlm@1
|
488 rc.bottom += nDeltaY;
|
rlm@1
|
489 }
|
rlm@1
|
490
|
rlm@1
|
491 (void)def.DeferWindowPos(hwndChild, NULL, rc,
|
rlm@1
|
492 SWP_NOACTIVATE | SWP_NOZORDER);
|
rlm@1
|
493 }
|
rlm@1
|
494 psd++;
|
rlm@1
|
495 }
|
rlm@1
|
496
|
rlm@1
|
497 pdd->m_sizeClient.cx = cx;
|
rlm@1
|
498 pdd->m_sizeClient.cy = cy;
|
rlm@1
|
499
|
rlm@1
|
500 //
|
rlm@1
|
501 // If we have a sizing grip enabled then adjust it's position
|
rlm@1
|
502 ResizeDlgUpdateGripper(hwnd, pdd);
|
rlm@1
|
503 }
|
rlm@1
|
504 }
|
rlm@1
|
505
|
rlm@1
|
506 BOOL ResizeDlg::OnWndMsg(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT *res)
|
rlm@1
|
507 // Actual window procedure that will handle saving window size/position and moving
|
rlm@1
|
508 // the controls whilst the window sizes.
|
rlm@1
|
509 {
|
rlm@1
|
510 if (dd == NULL)
|
rlm@1
|
511 {
|
rlm@1
|
512 return CDialog::OnWndMsg(msg, wParam, lParam, res);
|
rlm@1
|
513 }
|
rlm@1
|
514 switch (msg)
|
rlm@1
|
515 {
|
rlm@1
|
516 case WM_ERASEBKGND:
|
rlm@1
|
517 {
|
rlm@1
|
518 BOOL r = CDialog::OnWndMsg(msg, wParam, lParam, res);
|
rlm@1
|
519 DialogData *pdd = (DialogData *)dd;
|
rlm@1
|
520 if (pdd && pdd->m_bShowSizingGrip && !pdd->m_bMaximised)
|
rlm@1
|
521 {
|
rlm@1
|
522 VAPI(::DrawFrameControl(reinterpret_cast<HDC>(wParam),
|
rlm@1
|
523 pdd->m_rcGrip,
|
rlm@1
|
524 DFC_SCROLL, DFCS_SCROLLSIZEGRIP));
|
rlm@1
|
525 }
|
rlm@1
|
526 return r;
|
rlm@1
|
527 }
|
rlm@1
|
528 case WM_SIZE:
|
rlm@1
|
529 {
|
rlm@1
|
530 DialogData *pdd = (DialogData *)dd;
|
rlm@1
|
531 if (pdd && wParam != SIZE_MINIMIZED)
|
rlm@1
|
532 {
|
rlm@1
|
533 pdd->m_bMaximised = (wParam == SIZE_MAXIMIZED ? true : false);
|
rlm@1
|
534 UpdateWindowSize(LOWORD(lParam), HIWORD(lParam), *this);
|
rlm@1
|
535 }
|
rlm@1
|
536 break;
|
rlm@1
|
537 }
|
rlm@1
|
538 case WM_NCHITTEST:
|
rlm@1
|
539 {
|
rlm@1
|
540 //
|
rlm@1
|
541 // If the gripper is enabled then perform a simple hit test on our gripper area.
|
rlm@1
|
542 DialogData *pdd = (DialogData *)dd;
|
rlm@1
|
543 if (pdd && pdd->m_bShowSizingGrip)
|
rlm@1
|
544 {
|
rlm@1
|
545 POINT pt = { LOWORD(lParam), HIWORD(lParam) };
|
rlm@1
|
546 (void)ScreenToClient(&pt);
|
rlm@1
|
547 if (PtInRect(pdd->m_rcGrip, pt))
|
rlm@1
|
548 return (BOOL)HTBOTTOMRIGHT;
|
rlm@1
|
549 }
|
rlm@1
|
550 break;
|
rlm@1
|
551 }
|
rlm@1
|
552 case WM_GETMINMAXINFO:
|
rlm@1
|
553 {
|
rlm@1
|
554 //
|
rlm@1
|
555 // Our opportunity to say that we do not want the dialog to grow or shrink any more.
|
rlm@1
|
556 DialogData * pdd = (DialogData *)dd;
|
rlm@1
|
557 LPMINMAXINFO lpmmi = reinterpret_cast<LPMINMAXINFO>(lParam);
|
rlm@1
|
558 lpmmi->ptMinTrackSize = pdd->m_ptSmallest;
|
rlm@1
|
559 if (pdd->m_bLargestSet)
|
rlm@1
|
560 {
|
rlm@1
|
561 lpmmi->ptMaxTrackSize = pdd->m_ptLargest;
|
rlm@1
|
562 }
|
rlm@1
|
563 }
|
rlm@1
|
564 return (BOOL)0;
|
rlm@1
|
565 case WM_NOTIFY:
|
rlm@1
|
566 {
|
rlm@1
|
567 if (reinterpret_cast<LPNMHDR>(lParam)->code == PSN_SETACTIVE)
|
rlm@1
|
568 {
|
rlm@1
|
569 CRect rc;
|
rlm@1
|
570 VAPI(::GetClientRect(*GetParent(), &rc));
|
rlm@1
|
571 UpdateWindowSize(rc.Width(), rc.Height(), *GetParent());
|
rlm@1
|
572 }
|
rlm@1
|
573 break;
|
rlm@1
|
574 }
|
rlm@1
|
575 case WM_DESTROY:
|
rlm@1
|
576 {
|
rlm@1
|
577 //
|
rlm@1
|
578 // Our opportunty for cleanup.
|
rlm@1
|
579 // Simply acquire all of our objects, free the appropriate memory and remove the
|
rlm@1
|
580 // properties from the window. If we do not remove the properties then they will constitute
|
rlm@1
|
581 // a resource leak.
|
rlm@1
|
582 DialogData *pdd = (DialogData *)dd;
|
rlm@1
|
583 if (pdd)
|
rlm@1
|
584 {
|
rlm@1
|
585 RegistryData rd;
|
rlm@1
|
586 rd.m_wpl.length = sizeof(rd.m_wpl);
|
rlm@1
|
587 VAPI(GetWindowPlacement(&rd.m_wpl));
|
rlm@1
|
588
|
rlm@1
|
589 if (pdd->hkRootSave && pdd->pcszName)
|
rlm@1
|
590 {
|
rlm@1
|
591 (void)RegSetValueExRecursive(pdd->hkRootSave, pdd->pcszName,
|
rlm@1
|
592 NULL, REG_BINARY,
|
rlm@1
|
593 reinterpret_cast<LPBYTE>(&rd),
|
rlm@1
|
594 sizeof(rd));
|
rlm@1
|
595 }
|
rlm@1
|
596
|
rlm@1
|
597 if (pdd->psd)
|
rlm@1
|
598 {
|
rlm@1
|
599 free(pdd->psd);
|
rlm@1
|
600 }
|
rlm@1
|
601 free(pdd);
|
rlm@1
|
602 }
|
rlm@1
|
603
|
rlm@1
|
604 break;
|
rlm@1
|
605 }
|
rlm@1
|
606 }
|
rlm@1
|
607 return CDialog::OnWndMsg(msg, wParam, lParam, res);
|
rlm@1
|
608 }
|
rlm@1
|
609
|