annotate src/win32/ResizeDlg.cpp @ 2:3549bbe597ed

adding makefile.am
author Robert McIntyre <rlm@mit.edu>
date Sat, 03 Mar 2012 10:31:47 -0600
parents f9f4f1b99eed
children
rev   line source
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