--- /dev/null
+#pragma once\r
+\r
+// Client crash callback\r
+typedef BOOL (CALLBACK *LPGETLOGFILE) (LPVOID lpvState);\r
+// Stack trace callback\r
+typedef void (*TraceCallbackFunction)(DWORD_PTR address, const char *ImageName,\r
+ const char *FunctionName, DWORD functionDisp,\r
+ const char *Filename, DWORD LineNumber, DWORD lineDisp,\r
+ void *data);\r
+\r
+typedef LPVOID (*InstallEx)(LPGETLOGFILE pfn, LPCSTR lpcszTo, LPCSTR lpcszSubject, BOOL bUseUI);\r
+typedef void (*UninstallEx)(LPVOID lpState);\r
+typedef void (*EnableUI)(void);\r
+typedef void (*DisableUI)(void);\r
+typedef void (*EnableHandler)(void);\r
+typedef void (*DisableHandler)(void);\r
+typedef void (*AddFileEx)(LPVOID lpState, LPCSTR lpFile, LPCSTR lpDesc);\r
+typedef void (*AddRegistryEx)(LPVOID lpState, LPCSTR lpRegistry, LPCSTR lpDesc);\r
+typedef void (*AddEventLogEx)(LPVOID lpState, LPCSTR lpEventLog, LPCSTR lpDesc);\r
+\r
+/**\r
+ * \ingroup CrashRpt\r
+ * This class wraps the most important functions the CrashRpt-library\r
+ * offers. To learn more about the CrashRpt-library go to\r
+ * http://www.codeproject.com/debug/crash_report.asp \n\r
+ * To compile the library you need the WTL. You can get the WTL\r
+ * directly from Microsoft: \r
+ * http://www.microsoft.com/downloads/details.aspx?FamilyID=128e26ee-2112-4cf7-b28e-7727d9a1f288&DisplayLang=en \n\r
+ * \n\r
+ * Many changes were made to the library so if you read the\r
+ * article on CodeProject also read the change log in the source\r
+ * folder.\n\r
+ * The most important changes are:\r
+ * - stack trace is included in the report, with symbols/linenumbers if available\r
+ * - "save" button so the user can save the report instead of directly send it\r
+ * - can be used by multiple applications\r
+ * - zlib linked statically, so no need to ship the zlib.dll separately\r
+ * \n\r
+ * To use the library just include the header file "CrashReport.h"\r
+ * \code\r
+ * #include "CrashReport.h"\r
+ * \endcode\r
+ * Then you can either declare an instance of the class CCrashReport\r
+ * somewhere globally in your application like this:\r
+ * \code\r
+ * CCrashReport g_crasher("report@mycompany.com", "Crash report for MyApplication");\r
+ * \endcode\r
+ * that way you can't add registry keys or additional files to the report, but\r
+ * it's the fastest and easiest way to use the library.\r
+ * Another way is to declare a global variable and initialize it in e.g. InitInstance()\r
+ * \code\r
+ * CCrashReport g_crasher;\r
+ * //then somewhere in InitInstance.\r
+ * g_crasher.AddFile("mylogfile.log", "this is a log file");\r
+ * g_crasher.AddRegistry("HKCU\\Software\\MyCompany\\MyProgram");\r
+ * \endcode\r
+ *\r
+ *\r
+ * \remark the dll is dynamically linked at runtime. So the main application\r
+ * will still work even if the dll is not shipped. \r
+ *\r
+ */\r
+class CCrashReport\r
+{\r
+public:\r
+ /**\r
+ * Construct the CrashReport-Object. This loads the dll\r
+ * and initializes it.\r
+ * \param lpTo the mail address the crash report should be sent to\r
+ * \param lpSubject the mail subject\r
+ */\r
+ CCrashReport(LPCSTR lpTo = NULL, LPCSTR lpSubject = NULL, BOOL bUseUI = TRUE)\r
+ {\r
+ InstallEx pfnInstallEx;\r
+ TCHAR szFileName[_MAX_PATH];\r
+ GetModuleFileName(NULL, szFileName, _MAX_FNAME);\r
+\r
+ // C:\Programme\TortoiseSVN\bin\TortoiseProc.exe -> C:\Programme\TortoiseSVN\bin\CrashRpt.dll\r
+ CString strFilename = szFileName;\r
+ strFilename = strFilename.Left(strFilename.ReverseFind(_T('\\')) + 1);\r
+ strFilename += _T("CrashRpt.dll");\r
+\r
+ m_hDll = LoadLibrary(strFilename);\r
+ if (m_hDll)\r
+ {\r
+ pfnInstallEx = (InstallEx)GetProcAddress(m_hDll, "InstallEx");\r
+ if ( pfnInstallEx )\r
+ {\r
+ m_lpvState = pfnInstallEx(NULL, lpTo, lpSubject, bUseUI);\r
+ }\r
+ }\r
+ }\r
+ ~CCrashReport()\r
+ {\r
+ UninstallEx pfnUninstallEx;\r
+ if ((m_hDll)&&(m_lpvState))\r
+ {\r
+ pfnUninstallEx = (UninstallEx)GetProcAddress(m_hDll, "UninstallEx");\r
+ pfnUninstallEx(m_lpvState);\r
+ }\r
+ FreeLibrary(m_hDll);\r
+ }\r
+ /**\r
+ * Adds a file which will be included in the crash report. Use this\r
+ * if your application generates log-files or the like.\r
+ * \param lpFile the full path to the file\r
+ * \param lpDesc a description of the file, used in the crash report dialog\r
+ */\r
+ void AddFile(LPCSTR lpFile, LPCSTR lpDesc)\r
+ {\r
+ AddFileEx pfnAddFileEx;\r
+ if ((m_hDll)&&(m_lpvState))\r
+ {\r
+ pfnAddFileEx = (AddFileEx)GetProcAddress(m_hDll, "AddFileEx");\r
+ (pfnAddFileEx)(m_lpvState, lpFile, lpDesc);\r
+ }\r
+ }\r
+ /**\r
+ * Adds a whole registry tree to the crash report. \r
+ * \param lpFile the full registry path, e.g. "HKLM\\Software\\MyApplication"\r
+ * \param lpDesc a description of the generated registry file, used in the crash report dialog\r
+ */\r
+ void AddRegistry(LPCSTR lpFile, LPCSTR lpDesc)\r
+ {\r
+ AddRegistryEx pfnAddRegistryEx;\r
+ if ((m_hDll)&&(m_lpvState))\r
+ {\r
+ pfnAddRegistryEx = (AddRegistryEx)GetProcAddress(m_hDll, "AddRegistryHiveEx");\r
+ (pfnAddRegistryEx)(m_lpvState, lpFile, lpDesc);\r
+ }\r
+ }\r
+ /**\r
+ * Adds a system Event Log to the crash report.\r
+ * \param lpFile \r
+ * \param lpDesc \r
+ */\r
+ void AddEventLog(LPCSTR lpFile, LPCSTR lpDesc)\r
+ {\r
+ AddEventLogEx pfnAddEventLogEx;\r
+ if ((m_hDll)&&(m_lpvState))\r
+ {\r
+ pfnAddEventLogEx = (AddEventLogEx)GetProcAddress(m_hDll, "AddEventLogEx");\r
+ (pfnAddEventLogEx)(m_lpvState, lpFile, lpDesc);\r
+ }\r
+ }\r
+\r
+\r
+ void Enable(BOOL bEnable)\r
+ {\r
+ EnableHandler pfnEnableHandler;\r
+ DisableHandler pfnDisableHandler;\r
+ if ((m_hDll)&&(m_lpvState))\r
+ {\r
+ if (bEnable)\r
+ {\r
+ pfnEnableHandler = (EnableHandler)GetProcAddress(m_hDll, "EnableHandlerEx");\r
+ (pfnEnableHandler)();\r
+ }\r
+ else\r
+ {\r
+ OutputDebugString(_T("Calling DisableHandlerEx\n"));\r
+\r
+ pfnDisableHandler = (DisableHandler)GetProcAddress(m_hDll, "DisableHandlerEx");\r
+ (pfnDisableHandler)();\r
+ }\r
+ }\r
+ }\r
+\r
+private:\r
+ HMODULE m_hDll;\r
+ LPVOID m_lpvState;\r
+};
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="gb2312"?>\r
+<VisualStudioProject\r
+ ProjectType="Visual C++"\r
+ Version="9.00"\r
+ Name="Git"\r
+ ProjectGUID="{7CA5B1EB-8CC9-40A6-96D8-83649C1A870B}"\r
+ RootNamespace="Git"\r
+ Keyword="Win32Proj"\r
+ TargetFrameworkVersion="196613"\r
+ >\r
+ <Platforms>\r
+ <Platform\r
+ Name="Win32"\r
+ />\r
+ </Platforms>\r
+ <ToolFiles>\r
+ </ToolFiles>\r
+ <Configurations>\r
+ <Configuration\r
+ Name="Debug|Win32"\r
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"\r
+ IntermediateDirectory="$(ConfigurationName)"\r
+ ConfigurationType="4"\r
+ UseOfMFC="2"\r
+ UseOfATL="1"\r
+ CharacterSet="1"\r
+ >\r
+ <Tool\r
+ Name="VCPreBuildEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ />\r
+ <Tool\r
+ Name="VCXMLDataGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebServiceProxyGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCMIDLTool"\r
+ />\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ Optimization="0"\r
+ AdditionalIncludeDirectories="../utils"\r
+ PreprocessorDefinitions="WIN32;_DEBUG;_LIB"\r
+ MinimalRebuild="true"\r
+ BasicRuntimeChecks="3"\r
+ RuntimeLibrary="3"\r
+ UsePrecompiledHeader="2"\r
+ WarningLevel="3"\r
+ DebugInformationFormat="4"\r
+ />\r
+ <Tool\r
+ Name="VCManagedResourceCompilerTool"\r
+ />\r
+ <Tool\r
+ Name="VCResourceCompilerTool"\r
+ />\r
+ <Tool\r
+ Name="VCPreLinkEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCLibrarianTool"\r
+ />\r
+ <Tool\r
+ Name="VCALinkTool"\r
+ />\r
+ <Tool\r
+ Name="VCXDCMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCBscMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCFxCopTool"\r
+ />\r
+ <Tool\r
+ Name="VCPostBuildEventTool"\r
+ />\r
+ </Configuration>\r
+ <Configuration\r
+ Name="Release|Win32"\r
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"\r
+ IntermediateDirectory="$(ConfigurationName)"\r
+ ConfigurationType="4"\r
+ UseOfMFC="2"\r
+ CharacterSet="1"\r
+ WholeProgramOptimization="1"\r
+ >\r
+ <Tool\r
+ Name="VCPreBuildEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ />\r
+ <Tool\r
+ Name="VCXMLDataGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebServiceProxyGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCMIDLTool"\r
+ />\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ Optimization="2"\r
+ EnableIntrinsicFunctions="true"\r
+ PreprocessorDefinitions="WIN32;NDEBUG;_LIB"\r
+ RuntimeLibrary="2"\r
+ EnableFunctionLevelLinking="true"\r
+ UsePrecompiledHeader="2"\r
+ WarningLevel="3"\r
+ DebugInformationFormat="3"\r
+ />\r
+ <Tool\r
+ Name="VCManagedResourceCompilerTool"\r
+ />\r
+ <Tool\r
+ Name="VCResourceCompilerTool"\r
+ />\r
+ <Tool\r
+ Name="VCPreLinkEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCLibrarianTool"\r
+ />\r
+ <Tool\r
+ Name="VCALinkTool"\r
+ />\r
+ <Tool\r
+ Name="VCXDCMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCBscMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCFxCopTool"\r
+ />\r
+ <Tool\r
+ Name="VCPostBuildEventTool"\r
+ />\r
+ </Configuration>\r
+ </Configurations>\r
+ <References>\r
+ </References>\r
+ <Files>\r
+ <Filter\r
+ Name="Source Files"\r
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"\r
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"\r
+ >\r
+ <File\r
+ RelativePath=".\GitAdminDir.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\GitRev.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\GitStatus.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\stdafx.cpp"\r
+ >\r
+ <FileConfiguration\r
+ Name="Debug|Win32"\r
+ >\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ UsePrecompiledHeader="1"\r
+ />\r
+ </FileConfiguration>\r
+ <FileConfiguration\r
+ Name="Release|Win32"\r
+ >\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ UsePrecompiledHeader="1"\r
+ />\r
+ </FileConfiguration>\r
+ </File>\r
+ <File\r
+ RelativePath=".\TGitPath.cpp"\r
+ >\r
+ </File>\r
+ </Filter>\r
+ <Filter\r
+ Name="Header Files"\r
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"\r
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"\r
+ >\r
+ <File\r
+ RelativePath=".\stdafx.h"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\targetver.h"\r
+ >\r
+ </File>\r
+ </Filter>\r
+ <Filter\r
+ Name="Resource Files"\r
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"\r
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"\r
+ >\r
+ </Filter>\r
+ <File\r
+ RelativePath=".\ReadMe.txt"\r
+ >\r
+ </File>\r
+ </Files>\r
+ <Globals>\r
+ </Globals>\r
+</VisualStudioProject>\r
--- /dev/null
+#include "StdAfx.h"\r
+#include "GitRev.h"\r
+\r
+GitRev::GitRev(void)\r
+{\r
+}\r
+\r
+GitRev::~GitRev(void)\r
+{\r
+}\r
--- /dev/null
+#pragma once\r
+\r
+class GitRev\r
+{\r
+public:\r
+ GitRev(void);\r
+ ~GitRev(void);\r
+};\r
//\r
\r
#include "stdafx.h"\r
-#include "resource.h"\r
+//#include "resource.h"\r
#include "..\TortoiseShell\resource.h"\r
//#include "git_config.h"\r
#include "GitStatus.h"\r
//#include "GitGlobal.h"\r
//#include "GitHelpers.h"\r
#ifdef _MFC_VER\r
-# include "Git.h"\r
-# include "MessageBox.h"\r
-# include "registry.h"\r
-# include "TGitPath.h"\r
-# include "PathUtils.h"\r
+//# include "Git.h"\r
+//# include "MessageBox.h"\r
+//# include "registry.h"\r
+//# include "TGitPath.h"\r
+//# include "PathUtils.h"\r
#endif\r
\r
GitStatus::GitStatus(bool * pbCanceled)\r
#ifdef _MFC_VER\r
CString GitStatus::GetLastErrorMsg() const\r
{\r
- return Git::GetErrorString(m_err);\r
+// return Git::GetErrorString(m_err);\r
+ return CString("");\r
}\r
#else\r
stdstring GitStatus::GetLastErrorMsg() const\r
\r
return youngest;\r
#endif\r
- return "";\r
+ return CString("");\r
}\r
git_wc_status2_t * GitStatus::GetFirstFileStatus(const CTGitPath& path, CTGitPath& retPath, bool update, git_depth_t depth, bool bNoIgnore /* = true */, bool bNoExternals /* = false */)\r
{\r
#ifdef _MFC_VER\r
CString GitStatus::GetDepthString(git_depth_t depth)\r
{\r
+#if 0\r
CString sDepth;\r
switch (depth)\r
{\r
break;\r
}\r
return sDepth;\r
+#endif\r
+ return CString("");\r
}\r
#endif\r
\r
m_filterFileList.clear();\r
for(int fileIndex = 0; fileIndex < fileList.GetCount(); fileIndex++)\r
{\r
- m_filterFileList.push_back(fileList[fileIndex].GetGitApiPath(m_pool));\r
+// m_filterFileList.push_back(fileList[fileIndex].GetGitApiPath(m_pool));\r
}\r
// Sort the list so that we can do binary searches\r
std::sort(m_filterFileList.begin(), m_filterFileList.end());\r
#pragma once\r
\r
#ifdef _MFC_VER\r
-# include "SVNPrompt.h"\r
+//# include "SVNPrompt.h"\r
#endif\r
#include "TGitPath.h"\r
\r
* Returns the string representation of a depth.\r
*/\r
#ifdef _MFC_VER\r
- static CString GetDepthString(Git_depth_t depth);\r
+ static CString GetDepthString(git_depth_t depth);\r
#endif\r
static void GetDepthString(HINSTANCE hInst, git_depth_t depth, TCHAR * string, int size, WORD lang);\r
\r
git_error_t * m_err; ///< Subversion error baton\r
\r
#ifdef _MFC_VER\r
- GitPrompt m_prompt;\r
+// GitPrompt m_prompt;\r
#endif\r
\r
/**\r
--- /dev/null
+========================================================================\r
+ STATIC LIBRARY : Git Project Overview\r
+========================================================================\r
+\r
+AppWizard has created this Git library project for you.\r
+\r
+This file contains a summary of what you will find in each of the files that\r
+make up your Git application.\r
+\r
+\r
+Git.vcproj\r
+ This is the main project file for VC++ projects generated using an Application Wizard.\r
+ It contains information about the version of Visual C++ that generated the file, and\r
+ information about the platforms, configurations, and project features selected with the\r
+ Application Wizard.\r
+\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+StdAfx.h, StdAfx.cpp\r
+ These files are used to build a precompiled header (PCH) file\r
+ named Git.pch and a precompiled types file named StdAfx.obj.\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+The compiler and linker switches have been modified to support MFC. Using the\r
+MFC ClassWizard with this project requires that you add several files to the\r
+project, including "resource.h", "Git.rc" and a "Git.h" that\r
+includes resource.h. If you add an rc file to a static library, you may\r
+experience difficulties due to the limitation that only one rc file may be\r
+present in a Dll or Exe. This problem may be overcome by including the\r
+library's .rc file into the parent project's .rc file.\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+Other notes:\r
+\r
+AppWizard uses "TODO:" comments to indicate parts of the source code you\r
+should add to or customize.\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
#include <regex>\r
\r
#if defined(_MFC_VER)\r
-#include "MessageBox.h"\r
-#include "AppUtils.h"\r
+//#include "MessageBox.h"\r
+//#include "AppUtils.h"\r
#endif\r
\r
using namespace std;\r
TRACE("CFileException loading target file list\n");\r
TCHAR error[10000] = {0};\r
pE->GetErrorMessage(error, 10000);\r
- CMessageBox::Show(NULL, error, _T("TortoiseGit"), MB_ICONERROR);\r
+// CMessageBox::Show(NULL, error, _T("TortoiseGit"), MB_ICONERROR);\r
pE->Delete();\r
return false;\r
}\r
public:\r
CTGitPath(void);\r
~CTGitPath(void);\r
-explicit CTGitPath(const CString& sUnknownPath);\r
+ CTGitPath(const CString& sUnknownPath);\r
public:\r
/**\r
* Set the path as an UTF8 string with forward slashes\r
--- /dev/null
+// stdafx.cpp : source file that includes just the standard includes\r
+// Git.pch will be the pre-compiled header\r
+// stdafx.obj will contain the pre-compiled type information\r
+\r
+#include "stdafx.h"\r
+\r
+// TODO: reference any additional headers you need in STDAFX.H\r
+// and not in this file\r
--- /dev/null
+// stdafx.h : include file for standard system include files,\r
+// or project specific include files that are used frequently, but\r
+// are changed infrequently\r
+//\r
+\r
+#pragma once\r
+\r
+#include "targetver.h"\r
+\r
+#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers\r
+#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit\r
+\r
+#ifndef VC_EXTRALEAN\r
+#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers\r
+#endif\r
+\r
+#include <afx.h>\r
+#include <afxwin.h> // MFC core and standard components\r
+\r
+#include <atlbase.h>\r
+#include <atlexcept.h>\r
+#include <atlstr.h>\r
+\r
+#pragma warning(push)\r
+#pragma warning(disable: 4702) // Unreachable code warnings in xtree\r
+#include <string>\r
+#include <set>\r
+#include <map>\r
+#include <vector> \r
+#include <algorithm> \r
+#pragma warning(pop)\r
+\r
+\r
+#include <afxdtctl.h> // MFC support for Internet Explorer 4 Common Controls\r
+#ifndef _AFX_NO_AFXCMN_SUPPORT\r
+#include <afxcmn.h> // MFC support for Windows Common Controls\r
+#endif // _AFX_NO_AFXCMN_SUPPORT\r
+#include <afxdlgs.h>\r
+#include <afxctl.h>\r
+#include <afxtempl.h>\r
+#include <afxmt.h>\r
+#include <afxext.h> // MFC extensions\r
+#include <afxcontrolbars.h> // MFC support for ribbons and control bars\r
+\r
+#include <atlbase.h>\r
+\r
+// TODO: reference additional headers your program requires here\r
--- /dev/null
+#pragma once\r
+\r
+// The following macros define the minimum required platform. The minimum required platform\r
+// is the earliest version of Windows, Internet Explorer etc. that has the necessary features to run \r
+// your application. The macros work by enabling all features available on platform versions up to and \r
+// including the version specified.\r
+\r
+// Modify the following defines if you have to target a platform prior to the ones specified below.\r
+// Refer to MSDN for the latest info on corresponding values for different platforms.\r
+#ifndef WINVER // Specifies that the minimum required platform is Windows Vista.\r
+#define WINVER 0x0600 // Change this to the appropriate value to target other versions of Windows.\r
+#endif\r
+\r
+#ifndef _WIN32_WINNT // Specifies that the minimum required platform is Windows Vista.\r
+#define _WIN32_WINNT 0x0600 // Change this to the appropriate value to target other versions of Windows.\r
+#endif\r
+\r
+#ifndef _WIN32_WINDOWS // Specifies that the minimum required platform is Windows 98.\r
+#define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later.\r
+#endif\r
+\r
+#ifndef _WIN32_IE // Specifies that the minimum required platform is Internet Explorer 7.0.\r
+#define _WIN32_IE 0x0700 // Change this to the appropriate value to target other versions of IE.\r
+#endif\r
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
//\r
#pragma once\r
-#include "TSVNPath.h"\r
+#include "TGitPath.h"\r
\r
struct CBugTraqProvider\r
{\r
-// TortoiseSVN - a Windows shell extension for easy version control\r
+// TortoiseGit - a Windows shell extension for easy version control\r
\r
-// Copyright (C) 2006-2008 - TortoiseSVN\r
+// Copyright (C) 2006-2008 - TortoiseGit\r
\r
// This program is free software; you can redistribute it and/or\r
// modify it under the terms of the GNU General Public License\r
#pragma once\r
#include <map>\r
#include "registry.h"\r
-#include "TSVNPath.h"\r
-#include "SVNRev.h"\r
+#include "TGitPath.h"\r
+#include "GitRev.h"\r
+#include "GitStatus.h"\r
\r
/**\r
* \ingroup TortoiseProc\r
{\r
public:\r
hooktype htype;\r
- CTSVNPath path;\r
+ CTGitPath path;\r
\r
bool operator < (const hookkey& hk) const \r
{\r
private:\r
CHooks();\r
~CHooks();\r
- void AddPathParam(CString& sCmd, const CTSVNPathList& pathList);\r
- void AddDepthParam(CString& sCmd, svn_depth_t depth);\r
- void AddCWDParam(CString& sCmd, const CTSVNPathList& pathList);\r
+ void AddPathParam(CString& sCmd, const CTGitPathList& pathList);\r
+ void AddDepthParam(CString& sCmd, git_depth_t depth);\r
+ void AddCWDParam(CString& sCmd, const CTGitPathList& pathList);\r
void AddErrorParam(CString& sCmd, const CString& error);\r
void AddParam(CString& sCmd, const CString& param);\r
- CTSVNPath AddMessageFileParam(CString& sCmd, const CString& message);\r
+ CTGitPath AddMessageFileParam(CString& sCmd, const CString& message);\r
public:\r
/// Create the singleton. Call this at the start of the program.\r
static bool Create();\r
/**\r
* Adds a new hook script. To make the change persistent, call Save().\r
*/\r
- void Add(hooktype ht, const CTSVNPath& Path, LPCTSTR szCmd, \r
+ void Add(hooktype ht, const CTGitPath& Path, LPCTSTR szCmd, \r
bool bWait, bool bShow);\r
\r
/// returns the string representation of the hook type.\r
* in \c pathList, separated by newlines. The hook script can parse this\r
* file to get all the paths the update is about to be done on.\r
*/\r
- bool StartUpdate(const CTSVNPathList& pathList, DWORD& exitcode, \r
+ bool StartUpdate(const CTGitPathList& pathList, DWORD& exitcode, \r
CString& error);\r
/**\r
* Executes the Pre-Update-Hook that first matches one of the paths in\r
* to the \c bRecursive parameter. And the string "%REVISION%" is replaced with\r
* the string representation of \c rev.\r
*/\r
- bool PreUpdate(const CTSVNPathList& pathList, svn_depth_t depth, \r
- SVNRev rev, DWORD& exitcode, CString& error);\r
+ bool PreUpdate(const CTGitPathList& pathList, git_depth_t depth, \r
+ GitRev rev, DWORD& exitcode, CString& error);\r
/**\r
* Executes the Post-Update-Hook that first matches one of the paths in\r
* \c pathList.\r
* to the \c bRecursive parameter. And the string "%REVISION%" is replaced with\r
* the string representation of \c rev.\r
*/\r
- bool PostUpdate(const CTSVNPathList& pathList, svn_depth_t depth, \r
- SVNRev rev, DWORD& exitcode, CString& error);\r
+ bool PostUpdate(const CTGitPathList& pathList, git_depth_t depth, \r
+ GitRev rev, DWORD& exitcode, CString& error);\r
\r
/**\r
* Executes the Start-Commit-Hook that first matches one of the paths in\r
* \c message. If the script finishes successfully, contents of this file\r
* is read back into \c message parameter.\r
*/\r
- bool StartCommit(const CTSVNPathList& pathList, CString& message,\r
+ bool StartCommit(const CTGitPathList& pathList, CString& message,\r
DWORD& exitcode, CString& error);\r
/**\r
* Executes the Pre-Commit-Hook that first matches one of the paths in\r
* in \c pathList, separated by newlines. The hook script can parse this\r
* file to get all the paths the update is about to be done on.\r
* The string "%DEPTH%" is replaced with the numerical value (string) of the\r
- * svn_depth_t parameter. See the Subversion source documentation about the\r
+ * Git_depth_t parameter. See the Subversion source documentation about the\r
* values.\r
*/\r
- bool PreCommit(const CTSVNPathList& pathList, svn_depth_t depth, \r
+ bool PreCommit(const CTGitPathList& pathList, git_depth_t depth, \r
const CString& message, DWORD& exitcode, \r
CString& error);\r
/**\r
* in \c pathList, separated by newlines. The hook script can parse this\r
* file to get all the paths the commit is about to be done on.\r
* The string "%DEPTH%" is replaced with the numerical value (string) of the\r
- * svn_depth_t parameter. See the Subversion source documentation about the\r
+ * Git_depth_t parameter. See the Subversion source documentation about the\r
* values.\r
*/\r
- bool PostCommit(const CTSVNPathList& pathList, svn_depth_t depth, \r
- SVNRev rev, const CString& message, \r
+ bool PostCommit(const CTGitPathList& pathList, git_depth_t depth, \r
+ GitRev rev, const CString& message, \r
DWORD& exitcode, CString& error);\r
\r
private:\r
* Find the hook script information for the hook type \c t which matches a\r
* path in \c pathList.\r
*/\r
- hookiterator FindItem(hooktype t, const CTSVNPathList& pathList);\r
+ hookiterator FindItem(hooktype t, const CTGitPathList& pathList);\r
static CHooks * m_pInstance;\r
};\r
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
//\r
#include "stdafx.h"\r
-#include "stdex_vector.h"\r
+#include "../stdex_vector.h"\r
#include "DIB.h"\r
\r
CDib::CDib()\r
//\r
#pragma once\r
\r
-#include "DragDropImpl.h"\r
-#include "UnicodeUtils.h"\r
+#include "../DragDropImpl.h"\r
+#include "../UnicodeUtils.h"\r
\r
/**\r
* \ingroup Utils\r
//\r
#include "stdafx.h"\r
#include "HistoryCombo.h"\r
-#include "registry.h"\r
+#include "../registry.h"\r
\r
#ifdef HISTORYCOMBO_WITH_SYSIMAGELIST\r
#include "SysImageList.h"\r
m_UnderlineFont.DeleteObject();\r
}\r
\r
-\r
BOOL CHyperLink::DestroyWindow() \r
{\r
KillTimer(m_nTimerID);\r
m_hCompPort = INVALID_HANDLE_VALUE;\r
}\r
\r
-bool CPathWatcher::RemovePathAndChildren(const CTSVNPath& path)\r
+bool CPathWatcher::RemovePathAndChildren(const CTGitPath& path)\r
{\r
bool bRemoved = false;\r
AutoLocker lock(m_critSec);\r
return bRemoved;\r
}\r
\r
-bool CPathWatcher::AddPath(const CTSVNPath& path)\r
+bool CPathWatcher::AddPath(const CTGitPath& path)\r
{\r
AutoLocker lock(m_critSec);\r
for (int i=0; i<watchedPaths.GetCount(); ++i)\r
}\r
\r
// now check if with the new path we might have a new root\r
- CTSVNPath newroot;\r
+ CTGitPath newroot;\r
for (int i=0; i<watchedPaths.GetCount(); ++i)\r
{\r
const CString& watched = watchedPaths[i].GetWinPathString();\r
{\r
if (sPath.GetAt(len)=='\\')\r
{\r
- newroot = CTSVNPath(sPath.Left(len));\r
+ newroot = CTGitPath(sPath.Left(len));\r
}\r
else if (watched.GetAt(len)=='\\')\r
{\r
- newroot = CTSVNPath(watched.Left(len));\r
+ newroot = CTGitPath(watched.Left(len));\r
}\r
}\r
break;\r
{\r
if (sPath.GetAt(len)=='\\')\r
{\r
- newroot = CTSVNPath(watched);\r
+ newroot = CTGitPath(watched);\r
}\r
else if (watched.GetLength() == 3 && watched[1] == ':')\r
{\r
- newroot = CTSVNPath(watched);\r
+ newroot = CTGitPath(watched);\r
}\r
}\r
}\r
buf[min(MAX_PATH*4-1, pdi->m_DirPath.GetLength()+(pnotify->FileNameLength/sizeof(WCHAR)))] = 0;\r
pnotify = (PFILE_NOTIFY_INFORMATION)((LPBYTE)pnotify + nOffset);\r
ATLTRACE(_T("change notification: %s\n"), buf);\r
- m_changedPaths.AddPath(CTSVNPath(buf));\r
+ m_changedPaths.AddPath(CTGitPath(buf));\r
if ((ULONG_PTR)pnotify - (ULONG_PTR)pdi->m_Buffer > READ_DIR_CHANGE_BUFFER_SIZE)\r
break;\r
} while (nOffset);\r
m_hCompPort = INVALID_HANDLE_VALUE;\r
}\r
\r
-CPathWatcher::CDirWatchInfo::CDirWatchInfo(HANDLE hDir, const CTSVNPath& DirectoryName) :\r
+CPathWatcher::CDirWatchInfo::CDirWatchInfo(HANDLE hDir, const CTGitPath& DirectoryName) :\r
m_hDir(hDir),\r
m_DirName(DirectoryName)\r
{\r
-// TortoiseSVN - a Windows shell extension for easy version control\r
+// TortoiseGit - a Windows shell extension for easy version control\r
\r
// External Cache Copyright (C) 2007-2008 - TortoiseSVN\r
\r
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
//\r
#pragma once\r
-#include "TSVNPath.h"\r
+#include "TGitPath.h"\r
\r
#define READ_DIR_CHANGE_BUFFER_SIZE 4096\r
\r
* watched recursively, then the new path is just ignored and the method\r
* returns false.\r
*/\r
- bool AddPath(const CTSVNPath& path);\r
+ bool AddPath(const CTGitPath& path);\r
/**\r
* Removes a path and all its children from the watched list.\r
*/\r
- bool RemovePathAndChildren(const CTSVNPath& path);\r
+ bool RemovePathAndChildren(const CTGitPath& path);\r
\r
/**\r
* Returns the number of recursively watched paths.\r
* Returns the list of paths which maybe got changed, i.e., for which\r
* a change notification was received.\r
*/\r
- CTSVNPathList GetChangedPaths() {return m_changedPaths;}\r
+ CTGitPathList GetChangedPaths() {return m_changedPaths;}\r
\r
/**\r
* Clears the list of changed paths\r
HANDLE m_hCompPort;\r
volatile LONG m_bRunning;\r
\r
- CTSVNPathList watchedPaths; ///< list of watched paths.\r
- CTSVNPathList m_changedPaths; ///< list of paths which got changed\r
+ CTGitPathList watchedPaths; ///< list of watched paths.\r
+ CTGitPathList m_changedPaths; ///< list of paths which got changed\r
\r
/**\r
* Helper class: provides information about watched directories.\r
CDirWatchInfo(); // private & not implemented\r
CDirWatchInfo & operator=(const CDirWatchInfo & rhs);//so that they're aren't accidentally used. -- you'll get a linker error\r
public:\r
- CDirWatchInfo(HANDLE hDir, const CTSVNPath& DirectoryName);\r
+ CDirWatchInfo(HANDLE hDir, const CTGitPath& DirectoryName);\r
~CDirWatchInfo();\r
\r
protected:\r
bool CloseDirectoryHandle();\r
\r
HANDLE m_hDir; ///< handle to the directory that we're watching\r
- CTSVNPath m_DirName; ///< the directory that we're watching\r
+ CTGitPath m_DirName; ///< the directory that we're watching\r
CHAR m_Buffer[READ_DIR_CHANGE_BUFFER_SIZE]; ///< buffer for ReadDirectoryChangesW\r
DWORD m_dwBufLength; ///< length or returned data from ReadDirectoryChangesW -- ignored?...\r
OVERLAPPED m_Overlapped;\r
//\r
#include "stdafx.h"\r
#include "SysImageList.h"\r
-#include "TSVNPath.h"\r
+#include "TGitPath.h"\r
\r
\r
// Singleton constructor and destructor (private)\r
return sfi.iIcon;\r
}\r
\r
-int CSysImageList::GetPathIconIndex(const CTSVNPath& filePath) const\r
+int CSysImageList::GetPathIconIndex(const CTGitPath& filePath) const\r
{\r
CString strExtension = filePath.GetFileExtension();\r
strExtension.MakeUpper();\r
//\r
#pragma once\r
\r
-class CTSVNPath;\r
+class CTGitPath;\r
\r
/**\r
* \ingroup Utils\r
int GetFileIconIndex(const CString& file) const;\r
\r
/**\r
- * Get the index for a SVN-style path file. \r
+ * Get the index for a Git-style path file. \r
* Uses a cache to speed things up\r
*/\r
- int GetPathIconIndex(const CTSVNPath& file) const;\r
+ int GetPathIconIndex(const CTGitPath& file) const;\r
\r
private:\r
static CSysImageList *instance;\r
//\r
#pragma once\r
\r
-#include "TSVNPath.h"\r
-#include "SVNRev.h"\r
+#include "TGitPath.h"\r
+#include "GitRev.h"\r
\r
/**\r
* \ingroup Utils\r
#pragma once\r
\r
#include <string>\r
-\r
+#include <WinDef.h>\r
#pragma warning (push,1)\r
#ifndef stdstring\r
typedef std::wstring wide_string;\r
--- /dev/null
+<?xml version="1.0" encoding="gb2312"?>\r
+<VisualStudioProject\r
+ ProjectType="Visual C++"\r
+ Version="9.00"\r
+ Name="Utils"\r
+ ProjectGUID="{A2C38606-3D96-4A2C-B5C5-22CEAC523B37}"\r
+ RootNamespace="Utils"\r
+ Keyword="Win32Proj"\r
+ TargetFrameworkVersion="196613"\r
+ >\r
+ <Platforms>\r
+ <Platform\r
+ Name="Win32"\r
+ />\r
+ </Platforms>\r
+ <ToolFiles>\r
+ </ToolFiles>\r
+ <Configurations>\r
+ <Configuration\r
+ Name="Debug|Win32"\r
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"\r
+ IntermediateDirectory="$(ConfigurationName)"\r
+ ConfigurationType="4"\r
+ UseOfMFC="2"\r
+ CharacterSet="1"\r
+ >\r
+ <Tool\r
+ Name="VCPreBuildEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ />\r
+ <Tool\r
+ Name="VCXMLDataGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebServiceProxyGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCMIDLTool"\r
+ />\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ Optimization="0"\r
+ AdditionalIncludeDirectories="../git;../;"\r
+ PreprocessorDefinitions="WIN32;_DEBUG;_LIB"\r
+ MinimalRebuild="true"\r
+ BasicRuntimeChecks="3"\r
+ RuntimeLibrary="3"\r
+ UsePrecompiledHeader="2"\r
+ WarningLevel="3"\r
+ DebugInformationFormat="4"\r
+ />\r
+ <Tool\r
+ Name="VCManagedResourceCompilerTool"\r
+ />\r
+ <Tool\r
+ Name="VCResourceCompilerTool"\r
+ />\r
+ <Tool\r
+ Name="VCPreLinkEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCLibrarianTool"\r
+ />\r
+ <Tool\r
+ Name="VCALinkTool"\r
+ />\r
+ <Tool\r
+ Name="VCXDCMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCBscMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCFxCopTool"\r
+ />\r
+ <Tool\r
+ Name="VCPostBuildEventTool"\r
+ />\r
+ </Configuration>\r
+ <Configuration\r
+ Name="Release|Win32"\r
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"\r
+ IntermediateDirectory="$(ConfigurationName)"\r
+ ConfigurationType="4"\r
+ UseOfMFC="2"\r
+ CharacterSet="1"\r
+ WholeProgramOptimization="1"\r
+ >\r
+ <Tool\r
+ Name="VCPreBuildEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ />\r
+ <Tool\r
+ Name="VCXMLDataGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebServiceProxyGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCMIDLTool"\r
+ />\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ Optimization="2"\r
+ EnableIntrinsicFunctions="true"\r
+ PreprocessorDefinitions="WIN32;NDEBUG;_LIB"\r
+ RuntimeLibrary="2"\r
+ EnableFunctionLevelLinking="true"\r
+ UsePrecompiledHeader="2"\r
+ WarningLevel="3"\r
+ DebugInformationFormat="3"\r
+ />\r
+ <Tool\r
+ Name="VCManagedResourceCompilerTool"\r
+ />\r
+ <Tool\r
+ Name="VCResourceCompilerTool"\r
+ />\r
+ <Tool\r
+ Name="VCPreLinkEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCLibrarianTool"\r
+ />\r
+ <Tool\r
+ Name="VCALinkTool"\r
+ />\r
+ <Tool\r
+ Name="VCXDCMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCBscMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCFxCopTool"\r
+ />\r
+ <Tool\r
+ Name="VCPostBuildEventTool"\r
+ />\r
+ </Configuration>\r
+ </Configurations>\r
+ <References>\r
+ </References>\r
+ <Files>\r
+ <Filter\r
+ Name="Source Files"\r
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"\r
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"\r
+ >\r
+ <File\r
+ RelativePath=".\CmdLineParser.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\DebugHelpers.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\DirFileEnum.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\LangDll.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\PathWatcher.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\PersonalDictionary.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\ProfilingInfo.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\RegHistory.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\Registry.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\RWSection.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\stdafx.cpp"\r
+ >\r
+ <FileConfiguration\r
+ Name="Debug|Win32"\r
+ >\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ UsePrecompiledHeader="1"\r
+ />\r
+ </FileConfiguration>\r
+ <FileConfiguration\r
+ Name="Release|Win32"\r
+ >\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ UsePrecompiledHeader="1"\r
+ />\r
+ </FileConfiguration>\r
+ </File>\r
+ <File\r
+ RelativePath=".\StdioFileT.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\StringUtils.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\SysImageList.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\UnicodeUtils.cpp"\r
+ >\r
+ </File>\r
+ </Filter>\r
+ <Filter\r
+ Name="Header Files"\r
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"\r
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"\r
+ >\r
+ <File\r
+ RelativePath=".\stdafx.h"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\targetver.h"\r
+ >\r
+ </File>\r
+ </Filter>\r
+ <Filter\r
+ Name="Resource Files"\r
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"\r
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"\r
+ >\r
+ </Filter>\r
+ <Filter\r
+ Name="MiscUi"\r
+ >\r
+ <File\r
+ RelativePath=".\MiscUI\Balloon.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\MiscUI\BaseWindow.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\MiscUI\BrowseFolder.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\MiscUI\BufferDC.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\MiscUI\DIB.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\MiscUI\FileDropEdit.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\MiscUI\FilterEdit.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\MiscUI\Gradient.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\MiscUI\HintListCtrl.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\MiscUI\HistoryCombo.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\MiscUI\HTMLFormatter.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\MiscUI\HyperLink.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\MiscUI\IconMenu.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\MiscUI\MenuButton.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\MiscUI\MyGraph.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\MiscUI\OddButton.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\MiscUI\Picture.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\MiscUI\ProgressDlg.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\MiscUI\ScrollTool.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\MiscUI\SplitterControl.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\MiscUI\Tooltip.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\MiscUI\WaterEffect.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\MiscUI\XPImageButton.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\MiscUI\XPTheme.cpp"\r
+ >\r
+ </File>\r
+ </Filter>\r
+ <Filter\r
+ Name="Tree"\r
+ >\r
+ <File\r
+ RelativePath=".\TreePropSheet\PropPageFrame.cpp"\r
+ >\r
+ </File>\r
+ </Filter>\r
+ <File\r
+ RelativePath=".\ReadMe.txt"\r
+ >\r
+ </File>\r
+ </Files>\r
+ <Globals>\r
+ </Globals>\r
+</VisualStudioProject>\r
--- /dev/null
+// stdafx.cpp : source file that includes just the standard includes\r
+// Utils.pch will be the pre-compiled header\r
+// stdafx.obj will contain the pre-compiled type information\r
+\r
+#include "stdafx.h"\r
+\r
+// TODO: reference any additional headers you need in STDAFX.H\r
+// and not in this file\r
--- /dev/null
+// stdafx.h : include file for standard system include files,\r
+// or project specific include files that are used frequently, but\r
+// are changed infrequently\r
+//\r
+\r
+#pragma once\r
+\r
+#include "targetver.h"\r
+\r
+#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers\r
+#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit\r
+\r
+#ifndef VC_EXTRALEAN\r
+#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers\r
+#endif\r
+\r
+#include <afx.h>\r
+#include <afxwin.h> // MFC core and standard components\r
+\r
+#include <atlbase.h>\r
+#include <atlexcept.h>\r
+#include <atlstr.h>\r
+\r
+#pragma warning(push)\r
+#pragma warning(disable: 4702) // Unreachable code warnings in xtree\r
+#include <string>\r
+#include <set>\r
+#include <map>\r
+#include <vector> \r
+#include <algorithm> \r
+#pragma warning(pop)\r
+\r
+\r
+#include <afxdtctl.h> // MFC support for Internet Explorer 4 Common Controls\r
+#ifndef _AFX_NO_AFXCMN_SUPPORT\r
+#include <afxcmn.h> // MFC support for Windows Common Controls\r
+#endif // _AFX_NO_AFXCMN_SUPPORT\r
+#include <afxdlgs.h>\r
+#include <afxctl.h>\r
+#include <afxtempl.h>\r
+#include <afxmt.h>\r
+#include <afxext.h> // MFC extensions\r
+#include <afxcontrolbars.h> // MFC support for ribbons and control bars\r
+\r
+#include <atlbase.h>\r
+\r
+// TODO: reference additional headers your program requires here\r
--- /dev/null
+#pragma once\r
+\r
+// The following macros define the minimum required platform. The minimum required platform\r
+// is the earliest version of Windows, Internet Explorer etc. that has the necessary features to run \r
+// your application. The macros work by enabling all features available on platform versions up to and \r
+// including the version specified.\r
+\r
+// Modify the following defines if you have to target a platform prior to the ones specified below.\r
+// Refer to MSDN for the latest info on corresponding values for different platforms.\r
+#ifndef WINVER // Specifies that the minimum required platform is Windows Vista.\r
+#define WINVER 0x0600 // Change this to the appropriate value to target other versions of Windows.\r
+#endif\r
+\r
+#ifndef _WIN32_WINNT // Specifies that the minimum required platform is Windows Vista.\r
+#define _WIN32_WINNT 0x0600 // Change this to the appropriate value to target other versions of Windows.\r
+#endif\r
+\r
+#ifndef _WIN32_WINDOWS // Specifies that the minimum required platform is Windows 98.\r
+#define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later.\r
+#endif\r
+\r
+#ifndef _WIN32_IE // Specifies that the minimum required platform is Internet Explorer 7.0.\r
+#define _WIN32_IE 0x0700 // Change this to the appropriate value to target other versions of IE.\r
+#endif\r
--- /dev/null
+// ResizableComboBox.cpp : implementation file\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// Copyright (C) 2000-2004 by Paolo Messina\r
+// (http://www.geocities.com/ppescher - ppescher@hotmail.com)\r
+//\r
+// The contents of this file are subject to the Artistic License (the "License").\r
+// You may not use this file except in compliance with the License. \r
+// You may obtain a copy of the License at:\r
+// http://www.opensource.org/licenses/artistic-license.html\r
+//\r
+// If you find this code useful, credits would be nice!\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+#include "stdafx.h"\r
+#include "ResizableComboBox.h"\r
+\r
+#ifdef _DEBUG\r
+#define new DEBUG_NEW\r
+#undef THIS_FILE\r
+static char THIS_FILE[] = __FILE__;\r
+#endif\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+// CResizableComboBox\r
+\r
+CResizableComboBox::CResizableComboBox()\r
+{\r
+ m_bClipMaxHeight = TRUE;\r
+ m_bIntegralHeight = TRUE;\r
+}\r
+\r
+CResizableComboBox::~CResizableComboBox()\r
+{\r
+ if (m_ctrlListBox.GetSafeHwnd() != NULL)\r
+ m_ctrlListBox.UnsubclassWindow();\r
+}\r
+\r
+\r
+BEGIN_MESSAGE_MAP(CResizableComboBox, CComboBox)\r
+ //{{AFX_MSG_MAP(CResizableComboBox)\r
+ ON_WM_CTLCOLOR()\r
+ //}}AFX_MSG_MAP\r
+END_MESSAGE_MAP()\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+// CResizableComboBox message handlers\r
+\r
+HBRUSH CResizableComboBox::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) \r
+{\r
+ HBRUSH hbr = CComboBox::OnCtlColor(pDC, pWnd, nCtlColor);\r
+ \r
+ if (nCtlColor == CTLCOLOR_LISTBOX)\r
+ {\r
+ if (!(GetStyle() & CBS_SIMPLE)\r
+ && (m_ctrlListBox.m_hWnd == NULL))\r
+ {\r
+ TRACE("ComboLBox: 0x%08X\n", pWnd->m_hWnd);\r
+\r
+ // attach to the owned listbox\r
+ m_ctrlListBox.m_pOwnerCombo = this;\r
+ m_ctrlListBox.SubclassWindow(pWnd->m_hWnd);\r
+ }\r
+ }\r
+\r
+ return hbr;\r
+}\r
+\r
+LRESULT CResizableComboBox::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) \r
+{\r
+ switch (message)\r
+ {\r
+ case CB_GETDROPPEDCONTROLRECT:\r
+ *(LPRECT)lParam = m_rectDropDown;\r
+ MapWindowPoints(NULL, (LPRECT)lParam);\r
+ return TRUE;\r
+ }\r
+\r
+ LRESULT lResult = CComboBox::WindowProc(message, wParam, lParam);\r
+\r
+ // if listbox is attached, update horizontal extent\r
+\r
+ switch (message)\r
+ {\r
+ case CB_INSERTSTRING:\r
+ case CB_ADDSTRING:\r
+ if (lResult != CB_ERR && lResult != CB_ERRSPACE)\r
+ UpdateHorizontalExtent((LPCTSTR)lParam);\r
+ break;\r
+\r
+ case CB_DIR:\r
+ if (lResult != CB_ERR && lResult != CB_ERRSPACE)\r
+ InitHorizontalExtent();\r
+ break;\r
+\r
+ case CB_RESETCONTENT:\r
+ InitHorizontalExtent();\r
+ break;\r
+ }\r
+\r
+ return lResult;\r
+}\r
+\r
+void CResizableComboBox::InitHorizontalExtent()\r
+{\r
+ CClientDC dc(this);\r
+ CFont* pOldFont = dc.SelectObject(GetFont());\r
+\r
+ CString str;\r
+ \r
+ m_iExtent = 0;\r
+ int n = GetCount();\r
+ for (int i=0; i<n; i++)\r
+ {\r
+ GetLBText(i, str);\r
+ int cx = dc.GetTextExtent(str).cx;\r
+ if (cx > m_iExtent)\r
+ m_iExtent = cx;\r
+ }\r
+\r
+ SetHorizontalExtent(m_iExtent\r
+ + LOWORD(GetDialogBaseUnits()));\r
+\r
+ dc.SelectObject(pOldFont);\r
+}\r
+\r
+void CResizableComboBox::UpdateHorizontalExtent(LPCTSTR szText)\r
+{\r
+ CClientDC dc(this);\r
+ CFont* pOldFont = dc.SelectObject(GetFont());\r
+\r
+ int cx = dc.GetTextExtent(szText, lstrlen(szText)).cx;\r
+ if (cx > m_iExtent)\r
+ {\r
+ m_iExtent = cx;\r
+\r
+ SetHorizontalExtent(m_iExtent\r
+ + LOWORD(GetDialogBaseUnits()));\r
+ }\r
+\r
+ dc.SelectObject(pOldFont);\r
+}\r
+\r
+void CResizableComboBox::PreSubclassWindow() \r
+{\r
+ ASSERT(GetStyle() & CBS_NOINTEGRALHEIGHT);\r
+\r
+ InitHorizontalExtent();\r
+ \r
+ GetDroppedControlRect(&m_rectDropDown);\r
+ ::MapWindowPoints(NULL, GetSafeHwnd(),\r
+ (LPPOINT)&m_rectDropDown, 2);\r
+ \r
+ CComboBox::PreSubclassWindow();\r
+}\r
+\r
+int CResizableComboBox::MakeIntegralHeight(const int height)\r
+{\r
+ int inth = height; // integral height (result)\r
+ int availh = height; // available height\r
+ int n = GetCount();\r
+\r
+ DWORD dwStyle = GetStyle();\r
+\r
+ if (!m_bIntegralHeight || n == 0)\r
+ return inth;\r
+ \r
+ if (dwStyle & CBS_OWNERDRAWVARIABLE)\r
+ {\r
+ inth = 0; // try to reach availh by integral steps\r
+ int i = 0;\r
+ // use items below the first visible\r
+ for (i=GetTopIndex(); availh>0 && i<n; i++)\r
+ {\r
+ int h = GetItemHeight(i);\r
+ if (h == CB_ERR)\r
+ break;\r
+\r
+ inth += h;\r
+ availh -= h;\r
+ }\r
+ // to fill the remaining height, use items above\r
+ for (i=GetTopIndex()-1; availh>0 && i>=0; i--)\r
+ {\r
+ int h = GetItemHeight(i);\r
+ if (h == CB_ERR)\r
+ break;\r
+\r
+ inth += h;\r
+ availh -= h;\r
+ }\r
+ // scroll into view\r
+ SetTopIndex(i);\r
+\r
+ if (!m_bClipMaxHeight) // it can be higher than all the items\r
+ {\r
+ // to fill the remaining height, use last item\r
+ int h = GetItemHeight(n-1);\r
+ if (h != CB_ERR)\r
+ {\r
+ inth += availh - availh % h;\r
+ }\r
+ }\r
+ }\r
+ else\r
+ {\r
+ // every item has the same height (take the first)\r
+ int h = GetItemHeight(0);\r
+ if (h != CB_ERR && n != CB_ERR)\r
+ {\r
+ int rows = availh / h;\r
+ // can't be higher than all the items\r
+ if (m_bClipMaxHeight && rows > n)\r
+ rows = n;\r
+ inth = rows * h;\r
+ // scroll into view\r
+ if (n - rows < GetTopIndex())\r
+ SetTopIndex(n-rows);\r
+ }\r
+ }\r
+\r
+ return inth;\r
+}\r
--- /dev/null
+#if !defined(AFX_RESIZABLECOMBOBOX_H__CAEDF06D_C4F5_49E4_A783_AD7D894CF9A0__INCLUDED_)\r
+#define AFX_RESIZABLECOMBOBOX_H__CAEDF06D_C4F5_49E4_A783_AD7D894CF9A0__INCLUDED_\r
+\r
+#if _MSC_VER > 1000\r
+#pragma once\r
+#endif // _MSC_VER > 1000\r
+\r
+// ResizableComboBox.h : header file\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// Copyright (C) 2000-2004 by Paolo Messina\r
+// (http://www.geocities.com/ppescher - ppescher@hotmail.com)\r
+//\r
+// The contents of this file are subject to the Artistic License (the "License").\r
+// You may not use this file except in compliance with the License. \r
+// You may obtain a copy of the License at:\r
+// http://www.opensource.org/licenses/artistic-license.html\r
+//\r
+// If you find this code useful, credits would be nice!\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+#include "ResizableComboLBox.h"\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+// CResizableComboBox window\r
+\r
+class CResizableComboBox : public CComboBox\r
+{\r
+ friend class CResizableComboLBox;\r
+\r
+// Construction\r
+public:\r
+ CResizableComboBox();\r
+\r
+// Attributes\r
+public:\r
+\r
+protected:\r
+ CResizableComboLBox m_ctrlListBox;\r
+\r
+// Operations\r
+public:\r
+\r
+// Overrides\r
+ // ClassWizard generated virtual function overrides\r
+ //{{AFX_VIRTUAL(CResizableComboBox)\r
+ protected:\r
+ virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);\r
+ virtual void PreSubclassWindow();\r
+ //}}AFX_VIRTUAL\r
+\r
+// Implementation\r
+public:\r
+ virtual ~CResizableComboBox();\r
+\r
+protected:\r
+ RECT m_rectDropDown;\r
+ BOOL m_bClipMaxHeight;\r
+ BOOL m_bIntegralHeight;\r
+ int m_iExtent;\r
+\r
+ void InitHorizontalExtent();\r
+ void UpdateHorizontalExtent(LPCTSTR szText);\r
+ int MakeIntegralHeight(const int height);\r
+\r
+// Generated message map functions\r
+protected:\r
+ //{{AFX_MSG(CResizableComboBox)\r
+ afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);\r
+ //}}AFX_MSG\r
+\r
+ DECLARE_MESSAGE_MAP()\r
+};\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+//{{AFX_INSERT_LOCATION}}\r
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.\r
+\r
+#endif // !defined(AFX_RESIZABLECOMBOBOX_H__CAEDF06D_C4F5_49E4_A783_AD7D894CF9A0__INCLUDED_)\r
--- /dev/null
+// ResizableComboLBox.cpp : implementation file\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// Copyright (C) 2000-2004 by Paolo Messina\r
+// (http://www.geocities.com/ppescher - ppescher@hotmail.com)\r
+//\r
+// The contents of this file are subject to the Artistic License (the "License").\r
+// You may not use this file except in compliance with the License. \r
+// You may obtain a copy of the License at:\r
+// http://www.opensource.org/licenses/artistic-license.html\r
+//\r
+// If you find this code useful, credits would be nice!\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+#include "stdafx.h"\r
+#include "ResizableComboLBox.h"\r
+#include "ResizableComboBox.h"\r
+\r
+#ifdef _DEBUG\r
+#define new DEBUG_NEW\r
+#undef THIS_FILE\r
+static char THIS_FILE[] = __FILE__;\r
+#endif\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+// CResizableComboLBox\r
+\r
+CResizableComboLBox::CResizableComboLBox()\r
+{\r
+ m_dwAddToStyle = WS_THICKFRAME;\r
+ m_dwAddToStyleEx = 0;//WS_EX_CLIENTEDGE;\r
+ m_bSizing = FALSE;\r
+}\r
+\r
+CResizableComboLBox::~CResizableComboLBox()\r
+{\r
+\r
+}\r
+\r
+\r
+BEGIN_MESSAGE_MAP(CResizableComboLBox, CWnd)\r
+ //{{AFX_MSG_MAP(CResizableComboLBox)\r
+ ON_WM_MOUSEMOVE()\r
+ ON_WM_LBUTTONDOWN()\r
+ ON_WM_LBUTTONUP()\r
+ ON_WM_NCHITTEST()\r
+ ON_WM_CAPTURECHANGED()\r
+ ON_WM_WINDOWPOSCHANGING()\r
+ ON_WM_WINDOWPOSCHANGED()\r
+ //}}AFX_MSG_MAP\r
+END_MESSAGE_MAP()\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+// CResizableComboLBox message handlers\r
+\r
+void CResizableComboLBox::PreSubclassWindow() \r
+{\r
+ CWnd::PreSubclassWindow();\r
+\r
+ InitializeControl();\r
+}\r
+\r
+BOOL CResizableComboLBox::IsRTL()\r
+{\r
+ return (GetExStyle() & WS_EX_LAYOUTRTL);\r
+}\r
+\r
+void CResizableComboLBox::InitializeControl()\r
+{\r
+ CRect rect;\r
+ m_pOwnerCombo->GetWindowRect(&rect);\r
+ m_sizeAfterSizing.cx = rect.Width();\r
+ m_sizeAfterSizing.cy = -rect.Height();\r
+ m_pOwnerCombo->GetDroppedControlRect(&rect);\r
+ m_sizeAfterSizing.cy += rect.Height();\r
+ m_sizeMin.cy = m_sizeAfterSizing.cy-2;\r
+\r
+ // change window's style\r
+ ModifyStyleEx(0, m_dwAddToStyleEx);\r
+ ModifyStyle(0, m_dwAddToStyle, SWP_FRAMECHANGED);\r
+\r
+ // count hscroll if present\r
+ if (GetStyle() & WS_HSCROLL)\r
+ m_sizeAfterSizing.cy += GetSystemMetrics(SM_CYHSCROLL);\r
+\r
+ SetWindowPos(NULL, 0, 0, m_sizeAfterSizing.cx, m_sizeAfterSizing.cy,\r
+ SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOMOVE);\r
+}\r
+\r
+void CResizableComboLBox::OnMouseMove(UINT nFlags, CPoint point) \r
+{\r
+ CPoint pt = point;\r
+ MapWindowPoints(NULL, &pt, 1); // to screen coord\r
+\r
+ if (!m_bSizing)\r
+ {\r
+ // since mouse is captured we need to change the cursor manually\r
+ LRESULT ht = SendMessage(WM_NCHITTEST, 0, MAKELPARAM(pt.x, pt.y));\r
+ SendMessage(WM_SETCURSOR, (WPARAM)m_hWnd, MAKELPARAM(ht, WM_MOUSEMOVE));\r
+\r
+ CWnd::OnMouseMove(nFlags, point);\r
+ return;\r
+ }\r
+\r
+ // during resize\r
+ CRect rect = m_rcBeforeSizing;\r
+ CSize relMove = pt - m_ptBeforeSizing;\r
+\r
+ switch (m_nHitTest)\r
+ {\r
+ case HTBOTTOM:\r
+ rect.bottom += relMove.cy;\r
+ break;\r
+ case HTBOTTOMRIGHT:\r
+ rect.bottom += relMove.cy;\r
+ rect.right += relMove.cx;\r
+ break;\r
+ case HTRIGHT:\r
+ rect.right += relMove.cx;\r
+ break;\r
+ case HTBOTTOMLEFT:\r
+ rect.bottom += relMove.cy;\r
+ rect.left += relMove.cx;\r
+ break;\r
+ case HTLEFT:\r
+ rect.left += relMove.cx;\r
+ break;\r
+ }\r
+\r
+ // move window (if right-aligned it needs refresh)\r
+ UINT nCopyFlag = (GetExStyle() & WS_EX_RIGHT) ? SWP_NOCOPYBITS : 0;\r
+ SetWindowPos(NULL, rect.left, rect.top, rect.Width(), rect.Height(),\r
+ SWP_NOACTIVATE|SWP_NOZORDER|nCopyFlag);\r
+}\r
+\r
+void CResizableComboLBox::OnLButtonDown(UINT nFlags, CPoint point) \r
+{\r
+ CPoint pt = point;\r
+ MapWindowPoints(NULL, &pt, 1); // to screen coord\r
+\r
+ LRESULT ht = SendMessage(WM_NCHITTEST, 0, MAKELPARAM(pt.x, pt.y));\r
+\r
+ if (ht == HTBOTTOM || ht == HTRIGHT || ht == HTBOTTOMRIGHT\r
+ || ht == HTLEFT || ht == HTBOTTOMLEFT)\r
+ {\r
+ // start resizing\r
+ m_bSizing = TRUE;\r
+ m_nHitTest = ht;\r
+ GetWindowRect(&m_rcBeforeSizing);\r
+ m_ptBeforeSizing = pt;\r
+ }\r
+ else\r
+ CWnd::OnLButtonDown(nFlags, point);\r
+}\r
+\r
+void CResizableComboLBox::OnLButtonUp(UINT nFlags, CPoint point) \r
+{\r
+ CWnd::OnLButtonUp(nFlags, point);\r
+\r
+ EndSizing();\r
+}\r
+\r
+#if _MSC_VER < 1400\r
+UINT CResizableComboLBox::OnNcHitTest(CPoint point) \r
+#else\r
+LRESULT CResizableComboLBox::OnNcHitTest(CPoint point) \r
+#endif\r
+{\r
+ CRect rcClient;\r
+ GetClientRect(&rcClient);\r
+ MapWindowPoints(NULL, &rcClient);\r
+\r
+ // ask for default hit-test value\r
+ UINT_PTR ht = CWnd::OnNcHitTest(point);\r
+\r
+ // disable improper resizing (based on layout setting)\r
+ switch (ht)\r
+ {\r
+ case HTTOPRIGHT:\r
+ if (!IsRTL() && point.y > rcClient.top)\r
+ ht = HTRIGHT;\r
+ else\r
+ ht = HTBORDER;\r
+ break;\r
+ case HTTOPLEFT:\r
+ if (IsRTL() && point.y > rcClient.top)\r
+ ht = HTLEFT;\r
+ else\r
+ ht = HTBORDER;\r
+ break;\r
+\r
+ case HTBOTTOMLEFT:\r
+ if (!IsRTL() && point.y > rcClient.bottom)\r
+ ht = HTBOTTOM;\r
+ else if (!IsRTL())\r
+ ht = HTBORDER;\r
+ break;\r
+ case HTBOTTOMRIGHT:\r
+ if (IsRTL() && point.y > rcClient.bottom)\r
+ ht = HTBOTTOM;\r
+ else if (IsRTL())\r
+ ht = HTBORDER;\r
+ break;\r
+\r
+ case HTLEFT:\r
+ if (!IsRTL())\r
+ ht = HTBORDER;\r
+ break;\r
+ case HTRIGHT:\r
+ if (IsRTL())\r
+ ht = HTBORDER;\r
+ break;\r
+\r
+ case HTTOP:\r
+ ht = HTBORDER;\r
+ }\r
+\r
+ return ht;\r
+}\r
+\r
+void CResizableComboLBox::OnCaptureChanged(CWnd *pWnd) \r
+{\r
+ EndSizing();\r
+\r
+ CWnd::OnCaptureChanged(pWnd);\r
+}\r
+\r
+void CResizableComboLBox::EndSizing()\r
+{\r
+ m_bSizing = FALSE;\r
+ CRect rect;\r
+ GetWindowRect(&rect);\r
+ m_sizeAfterSizing = rect.Size();\r
+}\r
+\r
+void CResizableComboLBox::OnWindowPosChanging(WINDOWPOS FAR* lpwndpos) \r
+{\r
+ if (!m_bSizing)\r
+ {\r
+ // restore the size when the drop-down list becomes visible\r
+ lpwndpos->cx = m_sizeAfterSizing.cx;\r
+ lpwndpos->cy = m_sizeAfterSizing.cy;\r
+ }\r
+ ApplyLimitsToPos(lpwndpos);\r
+\r
+ CWnd::OnWindowPosChanging(lpwndpos);\r
+}\r
+\r
+void CResizableComboLBox::OnWindowPosChanged(WINDOWPOS FAR* lpwndpos) \r
+{\r
+ // default implementation sends a WM_SIZE message\r
+ // that can change the size again to force integral height\r
+\r
+ // since we do that manually during resize, we should also\r
+ // update the horizontal scrollbar \r
+ SendMessage(WM_HSCROLL, SB_ENDSCROLL, 0);\r
+\r
+ GetWindowRect(&m_pOwnerCombo->m_rectDropDown);\r
+ ::MapWindowPoints(NULL, m_pOwnerCombo->GetSafeHwnd(),\r
+ (LPPOINT)&m_pOwnerCombo->m_rectDropDown, 2);\r
+\r
+ CWnd::OnWindowPosChanged(lpwndpos);\r
+}\r
+\r
+void CResizableComboLBox::ApplyLimitsToPos(WINDOWPOS* lpwndpos)\r
+{\r
+ //TRACE(">H w(%d)\n", lpwndpos->cy);\r
+ // to adjust horizontally, use window rect\r
+\r
+ // min width can't be less than combo's\r
+ CRect rect;\r
+ m_pOwnerCombo->GetWindowRect(&rect);\r
+ m_sizeMin.cx = rect.Width();\r
+\r
+ // apply horizontal limits\r
+ if (lpwndpos->cx < m_sizeMin.cx)\r
+ lpwndpos->cx = m_sizeMin.cx;\r
+\r
+ // fix horizontal alignment\r
+ rect = CRect(0, 0, lpwndpos->cx, lpwndpos->cy);\r
+ m_pOwnerCombo->MapWindowPoints(NULL, &rect);\r
+ lpwndpos->x = rect.left;\r
+\r
+ // to adjust vertically, use client rect\r
+\r
+ // get client rect\r
+ rect = CRect(CPoint(lpwndpos->x, lpwndpos->y),\r
+ CSize(lpwndpos->cx, lpwndpos->cy));\r
+ SendMessage(WM_NCCALCSIZE, FALSE, (LPARAM)&rect);\r
+ CSize sizeClient = rect.Size();\r
+\r
+ // apply vertical limits\r
+ if (sizeClient.cy < m_sizeMin.cy)\r
+ sizeClient.cy = m_sizeMin.cy;\r
+\r
+ //TRACE(">H c(%d)\n", sizeClient.cy);\r
+ // adjust height, if needed\r
+ sizeClient.cy = m_pOwnerCombo->MakeIntegralHeight(sizeClient.cy);\r
+ //TRACE(">H c(%d)\n", sizeClient.cy);\r
+\r
+ // back to window rect\r
+ rect = CRect(0, 0, 1, sizeClient.cy);\r
+ DWORD dwStyle = GetStyle();\r
+ ::AdjustWindowRectEx(&rect, dwStyle, FALSE, GetExStyle());\r
+ lpwndpos->cy = rect.Height();\r
+ if (dwStyle & WS_HSCROLL)\r
+ lpwndpos->cy += GetSystemMetrics(SM_CYHSCROLL);\r
+\r
+ //TRACE("H c(%d) w(%d)\n", sizeClient.cy, lpwndpos->cy);\r
+}\r
+\r
--- /dev/null
+#if !defined(AFX_RESIZABLECOMBOLBOX_H__INCLUDED_)\r
+#define AFX_RESIZABLECOMBOLBOX_H__INCLUDED_\r
+\r
+#if _MSC_VER > 1000\r
+#pragma once\r
+#endif // _MSC_VER > 1000\r
+\r
+// ResizableComboLBox.h : header file\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// This file is part of ResizableLib\r
+// http://sourceforge.net/projects/resizablelib\r
+//\r
+// Copyright (C) 2000-2004 by Paolo Messina\r
+// http://www.geocities.com/ppescher - mailto:ppescher@hotmail.com\r
+//\r
+// The contents of this file are subject to the Artistic License (the "License").\r
+// You may not use this file except in compliance with the License. \r
+// You may obtain a copy of the License at:\r
+// http://www.opensource.org/licenses/artistic-license.html\r
+//\r
+// If you find this code useful, credits would be nice!\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+#include "ResizableGrip.h"\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+// CResizableComboLBox window\r
+\r
+class CResizableComboBox;\r
+\r
+class CResizableComboLBox : public CWnd, public CResizableGrip\r
+{\r
+ friend class CResizableComboBox;\r
+\r
+// Construction\r
+public:\r
+ CResizableComboLBox();\r
+\r
+// Attributes\r
+public:\r
+\r
+// Operations\r
+public:\r
+\r
+// Overrides\r
+ // ClassWizard generated virtual function overrides\r
+ //{{AFX_VIRTUAL(CResizableComboLBox)\r
+ protected:\r
+ virtual void PreSubclassWindow();\r
+ virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);\r
+ //}}AFX_VIRTUAL\r
+\r
+// Implementation\r
+public:\r
+ virtual ~CResizableComboLBox();\r
+\r
+private:\r
+ CPoint m_ptBeforeSizing; // screen coords\r
+ CRect m_rcBeforeSizing; // screen coords\r
+ CSize m_sizeAfterSizing; // screen coords\r
+ LONG_PTR m_nHitTest; // current resize operation\r
+ BOOL m_bSizing;\r
+\r
+ void InitializeControl();\r
+\r
+protected:\r
+ DWORD m_dwAddToStyle;\r
+ DWORD m_dwAddToStyleEx;\r
+ CSize m_sizeMin; // initial size (minimum)\r
+ CResizableComboBox* m_pOwnerCombo; // owner combobox\r
+\r
+ void ApplyLimitsToPos(WINDOWPOS* lpwndpos);\r
+ void EndSizing();\r
+\r
+ BOOL IsRTL();\r
+\r
+ virtual CWnd* GetResizableWnd() const\r
+ {\r
+ // make the layout know its parent window\r
+ return CWnd::FromHandle(m_hWnd);\r
+ };\r
+\r
+ // Generated message map functions\r
+protected:\r
+ //{{AFX_MSG(CResizableComboLBox)\r
+ afx_msg void OnMouseMove(UINT nFlags, CPoint point);\r
+ afx_msg void OnLButtonDown(UINT nFlags, CPoint point);\r
+ afx_msg void OnLButtonUp(UINT nFlags, CPoint point);\r
+#if _MSC_VER < 1400\r
+ afx_msg UINT OnNcHitTest(CPoint point);\r
+#else\r
+ afx_msg LRESULT OnNcHitTest(CPoint point);\r
+#endif\r
+ afx_msg void OnCaptureChanged(CWnd *pWnd);\r
+ afx_msg void OnWindowPosChanging(WINDOWPOS FAR* lpwndpos);\r
+ afx_msg void OnWindowPosChanged(WINDOWPOS FAR* lpwndpos);\r
+ //}}AFX_MSG\r
+\r
+ DECLARE_MESSAGE_MAP()\r
+};\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+//{{AFX_INSERT_LOCATION}}\r
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.\r
+\r
+#endif // !defined(AFX_RESIZABLECOMBOLBOX_H__INCLUDED_)\r
--- /dev/null
+// ResizableDialog.cpp : implementation file\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// This file is part of ResizableLib\r
+// http://sourceforge.net/projects/resizablelib\r
+//\r
+// Copyright (C) 2000-2004 by Paolo Messina\r
+// http://www.geocities.com/ppescher - mailto:ppescher@hotmail.com\r
+//\r
+// The contents of this file are subject to the Artistic License (the "License").\r
+// You may not use this file except in compliance with the License. \r
+// You may obtain a copy of the License at:\r
+// http://www.opensource.org/licenses/artistic-license.html\r
+//\r
+// If you find this code useful, credits would be nice!\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+#include "stdafx.h"\r
+#include "ResizableDialog.h"\r
+\r
+#ifdef _DEBUG\r
+#define new DEBUG_NEW\r
+#undef THIS_FILE\r
+static char THIS_FILE[] = __FILE__;\r
+#endif\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+// CResizableDialog\r
+\r
+inline void CResizableDialog::PrivateConstruct()\r
+{\r
+ m_bEnableSaveRestore = FALSE;\r
+ m_dwGripTempState = 1;\r
+}\r
+\r
+CResizableDialog::CResizableDialog()\r
+{\r
+ PrivateConstruct();\r
+}\r
+\r
+CResizableDialog::CResizableDialog(UINT nIDTemplate, CWnd* pParentWnd)\r
+ : CDialog(nIDTemplate, pParentWnd)\r
+{\r
+ PrivateConstruct();\r
+}\r
+\r
+CResizableDialog::CResizableDialog(LPCTSTR lpszTemplateName, CWnd* pParentWnd)\r
+ : CDialog(lpszTemplateName, pParentWnd)\r
+{\r
+ PrivateConstruct();\r
+}\r
+\r
+CResizableDialog::~CResizableDialog()\r
+{\r
+}\r
+\r
+\r
+BEGIN_MESSAGE_MAP(CResizableDialog, CDialog)\r
+ //{{AFX_MSG_MAP(CResizableDialog)\r
+ ON_WM_GETMINMAXINFO()\r
+ ON_WM_SIZE()\r
+ ON_WM_DESTROY()\r
+ ON_WM_ERASEBKGND()\r
+ ON_WM_NCCREATE()\r
+ //}}AFX_MSG_MAP\r
+END_MESSAGE_MAP()\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+// CResizableDialog message handlers\r
+\r
+BOOL CResizableDialog::OnNcCreate(LPCREATESTRUCT lpCreateStruct) \r
+{\r
+ if (!CDialog::OnNcCreate(lpCreateStruct))\r
+ return FALSE;\r
+\r
+ // child dialogs don't want resizable border or size grip,\r
+ // nor they can handle the min/max size constraints\r
+ BOOL bChild = lpCreateStruct->style & WS_CHILD;\r
+\r
+ // create and init the size-grip\r
+ if (!CreateSizeGrip(!bChild))\r
+ return FALSE;\r
+\r
+ if (!bChild)\r
+ {\r
+ // set the initial size as the min track size\r
+ SetMinTrackSize(CSize(lpCreateStruct->cx, lpCreateStruct->cy));\r
+ }\r
+ \r
+ MakeResizable(lpCreateStruct);\r
+\r
+ return TRUE;\r
+}\r
+\r
+void CResizableDialog::OnDestroy() \r
+{\r
+ if (m_bEnableSaveRestore)\r
+ SaveWindowRect(m_sSection, m_bRectOnly);\r
+\r
+ // remove child windows\r
+ RemoveAllAnchors();\r
+\r
+ CDialog::OnDestroy();\r
+}\r
+\r
+void CResizableDialog::OnSize(UINT nType, int cx, int cy) \r
+{\r
+ CWnd::OnSize(nType, cx, cy);\r
+ \r
+ if (nType == SIZE_MAXHIDE || nType == SIZE_MAXSHOW)\r
+ return; // arrangement not needed\r
+\r
+ if (nType == SIZE_MAXIMIZED)\r
+ HideSizeGrip(&m_dwGripTempState);\r
+ else\r
+ ShowSizeGrip(&m_dwGripTempState);\r
+\r
+ // update grip and layout\r
+ UpdateSizeGrip();\r
+ ArrangeLayout();\r
+ // on Vista, the redrawing doesn't work right, so we have to work\r
+ // around this by invalidating the whole dialog so the DWM recognizes\r
+ // that it has to update the application window.\r
+ OSVERSIONINFOEX inf;\r
+ SecureZeroMemory(&inf, sizeof(OSVERSIONINFOEX));\r
+ inf.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);\r
+ GetVersionEx((OSVERSIONINFO *)&inf);\r
+ WORD fullver = MAKEWORD(inf.dwMinorVersion, inf.dwMajorVersion);\r
+ if (fullver >= 0x0600)\r
+ Invalidate();\r
+}\r
+\r
+void CResizableDialog::OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI) \r
+{\r
+ MinMaxInfo(lpMMI);\r
+}\r
+\r
+// NOTE: this must be called after setting the layout\r
+// to have the dialog and its controls displayed properly\r
+void CResizableDialog::EnableSaveRestore(LPCTSTR pszSection, BOOL bRectOnly)\r
+{\r
+ m_sSection = pszSection;\r
+\r
+ m_bEnableSaveRestore = TRUE;\r
+ m_bRectOnly = bRectOnly;\r
+\r
+ // restore immediately\r
+ LoadWindowRect(pszSection, bRectOnly);\r
+\r
+ CMenu* pMenu = GetMenu();\r
+ if ( pMenu )\r
+ DrawMenuBar();\r
+}\r
+\r
+BOOL CResizableDialog::OnEraseBkgnd(CDC* pDC) \r
+{\r
+ ClipChildren(pDC, FALSE);\r
+\r
+ BOOL bRet = CDialog::OnEraseBkgnd(pDC);\r
+\r
+ ClipChildren(pDC, TRUE);\r
+\r
+ return bRet;\r
+}\r
+\r
+LRESULT CResizableDialog::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) \r
+{\r
+ if (message != WM_NCCALCSIZE || wParam == 0)\r
+ return CDialog::WindowProc(message, wParam, lParam);\r
+\r
+ LRESULT lResult = 0;\r
+ HandleNcCalcSize(FALSE, (LPNCCALCSIZE_PARAMS)lParam, lResult);\r
+ lResult = CDialog::WindowProc(message, wParam, lParam);\r
+ HandleNcCalcSize(TRUE, (LPNCCALCSIZE_PARAMS)lParam, lResult);\r
+ return lResult;\r
+}\r
--- /dev/null
+#if !defined(AFX_RESIZABLEDIALOG_H__INCLUDED_)\r
+#define AFX_RESIZABLEDIALOG_H__INCLUDED_\r
+\r
+#if _MSC_VER > 1000\r
+#pragma once\r
+#endif // _MSC_VER > 1000\r
+\r
+// ResizableDialog.h : header file\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// This file is part of ResizableLib\r
+// http://sourceforge.net/projects/resizablelib\r
+//\r
+// Copyright (C) 2000-2004 by Paolo Messina\r
+// http://www.geocities.com/ppescher - mailto:ppescher@hotmail.com\r
+//\r
+// The contents of this file are subject to the Artistic License (the "License").\r
+// You may not use this file except in compliance with the License. \r
+// You may obtain a copy of the License at:\r
+// http://www.opensource.org/licenses/artistic-license.html\r
+//\r
+// If you find this code useful, credits would be nice!\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+#include "ResizableLayout.h"\r
+#include "ResizableGrip.h"\r
+#include "ResizableMinMax.h"\r
+#include "ResizableWndState.h"\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+// CResizableDialog window\r
+\r
+class CResizableDialog : public CDialog, public CResizableLayout,\r
+ public CResizableGrip, public CResizableMinMax,\r
+ public CResizableWndState\r
+{\r
+\r
+// Construction\r
+public:\r
+ CResizableDialog();\r
+ CResizableDialog(UINT nIDTemplate, CWnd* pParentWnd = NULL);\r
+ CResizableDialog(LPCTSTR lpszTemplateName, CWnd* pParentWnd = NULL);\r
+\r
+// Attributes\r
+private:\r
+ // support for temporarily hiding the grip\r
+ DWORD m_dwGripTempState;\r
+\r
+ // flags\r
+ BOOL m_bEnableSaveRestore;\r
+ BOOL m_bRectOnly;\r
+\r
+ // internal status\r
+ CString m_sSection; // section name (identifies a parent window)\r
+\r
+// Operations\r
+public:\r
+\r
+// Overrides\r
+ // ClassWizard generated virtual function overrides\r
+ //{{AFX_VIRTUAL(CResizableDialog)\r
+ protected:\r
+ virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);\r
+ //}}AFX_VIRTUAL\r
+\r
+// Implementation\r
+public:\r
+ virtual ~CResizableDialog();\r
+\r
+// used internally\r
+private:\r
+ void PrivateConstruct();\r
+\r
+// callable from derived classes\r
+protected:\r
+ // section to use in app's profile\r
+ void EnableSaveRestore(LPCTSTR pszSection, BOOL bRectOnly = FALSE);\r
+\r
+ virtual CWnd* GetResizableWnd() const\r
+ {\r
+ // make the layout know its parent window\r
+ return CWnd::FromHandle(m_hWnd);\r
+ };\r
+\r
+// Generated message map functions\r
+protected:\r
+ //{{AFX_MSG(CResizableDialog)\r
+ afx_msg void OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI);\r
+ afx_msg void OnSize(UINT nType, int cx, int cy);\r
+ afx_msg void OnDestroy();\r
+ afx_msg BOOL OnEraseBkgnd(CDC* pDC);\r
+ afx_msg BOOL OnNcCreate(LPCREATESTRUCT lpCreateStruct);\r
+ //}}AFX_MSG\r
+ DECLARE_MESSAGE_MAP()\r
+};\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+//{{AFX_INSERT_LOCATION}}\r
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.\r
+\r
+#endif // !defined(AFX_RESIZABLEDIALOG_H__INCLUDED_)\r
--- /dev/null
+// ResizableFormView.cpp : implementation file\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// This file is part of ResizableLib\r
+// http://sourceforge.net/projects/resizablelib\r
+//\r
+// Copyright (C) 2000-2004 by Paolo Messina\r
+// http://www.geocities.com/ppescher - mailto:ppescher@hotmail.com\r
+//\r
+// The contents of this file are subject to the Artistic License (the "License").\r
+// You may not use this file except in compliance with the License. \r
+// You may obtain a copy of the License at:\r
+// http://www.opensource.org/licenses/artistic-license.html\r
+//\r
+// If you find this code useful, credits would be nice!\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+#include "stdafx.h"\r
+#include "ResizableFormView.h"\r
+\r
+#ifdef _DEBUG\r
+#define new DEBUG_NEW\r
+#undef THIS_FILE\r
+static char THIS_FILE[] = __FILE__;\r
+#endif\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+// CResizableFormView\r
+\r
+IMPLEMENT_DYNAMIC(CResizableFormView, CFormView)\r
+\r
+inline void CResizableFormView::PrivateConstruct()\r
+{\r
+ m_dwGripTempState = GHR_SCROLLBAR | GHR_ALIGNMENT | GHR_MAXIMIZED;\r
+}\r
+\r
+CResizableFormView::CResizableFormView(UINT nIDTemplate)\r
+ : CFormView(nIDTemplate)\r
+{\r
+ PrivateConstruct();\r
+}\r
+\r
+CResizableFormView::CResizableFormView(LPCTSTR lpszTemplateName)\r
+ : CFormView(lpszTemplateName)\r
+{\r
+ PrivateConstruct();\r
+}\r
+\r
+CResizableFormView::~CResizableFormView()\r
+{\r
+}\r
+\r
+\r
+BEGIN_MESSAGE_MAP(CResizableFormView, CFormView)\r
+ //{{AFX_MSG_MAP(CResizableFormView)\r
+ ON_WM_SIZE()\r
+ ON_WM_ERASEBKGND()\r
+ ON_WM_GETMINMAXINFO()\r
+ ON_WM_DESTROY()\r
+ ON_WM_NCCREATE()\r
+ //}}AFX_MSG_MAP\r
+END_MESSAGE_MAP()\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+// CResizableFormView diagnostics\r
+\r
+#ifdef _DEBUG\r
+void CResizableFormView::AssertValid() const\r
+{\r
+ CFormView::AssertValid();\r
+}\r
+\r
+void CResizableFormView::Dump(CDumpContext& dc) const\r
+{\r
+ CFormView::Dump(dc);\r
+}\r
+#endif //_DEBUG\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+// CResizableFormView message handlers\r
+\r
+void CResizableFormView::OnSize(UINT nType, int cx, int cy) \r
+{\r
+ CFormView::OnSize(nType, cx, cy);\r
+\r
+ CWnd* pParent = GetParentFrame();\r
+\r
+ // hide size grip when parent is maximized\r
+ if (pParent->IsZoomed())\r
+ HideSizeGrip(&m_dwGripTempState, GHR_MAXIMIZED);\r
+ else\r
+ ShowSizeGrip(&m_dwGripTempState, GHR_MAXIMIZED);\r
+\r
+ // hide size grip when there are scrollbars\r
+ CSize size = GetTotalSize();\r
+ if ((cx < size.cx || cy < size.cy) && (m_nMapMode >= 0))\r
+ HideSizeGrip(&m_dwGripTempState, GHR_SCROLLBAR);\r
+ else\r
+ ShowSizeGrip(&m_dwGripTempState, GHR_SCROLLBAR);\r
+\r
+ // hide size grip when the parent frame window is not resizable\r
+ // or the form is not bottom-right aligned (e.g. there's a statusbar)\r
+ DWORD dwStyle = pParent->GetStyle();\r
+ CRect rect, rectChild;\r
+ GetWindowRect(rect);\r
+\r
+ BOOL bCanResize = TRUE; // whether the grip can size the frame\r
+ for (HWND hWndChild = ::GetWindow(m_hWnd, GW_HWNDFIRST); hWndChild != NULL;\r
+ hWndChild = ::GetNextWindow(hWndChild, GW_HWNDNEXT))\r
+ {\r
+ ::GetWindowRect(hWndChild, rectChild);\r
+ //! @todo check RTL layouts!\r
+ if (rectChild.right > rect.right || rectChild.bottom > rect.bottom)\r
+ {\r
+ bCanResize = FALSE;\r
+ break;\r
+ }\r
+ }\r
+ if ((dwStyle & WS_THICKFRAME) && bCanResize)\r
+ ShowSizeGrip(&m_dwGripTempState, GHR_ALIGNMENT);\r
+ else\r
+ HideSizeGrip(&m_dwGripTempState, GHR_ALIGNMENT);\r
+\r
+ // update grip and layout\r
+ UpdateSizeGrip();\r
+ ArrangeLayout();\r
+}\r
+\r
+void CResizableFormView::GetTotalClientRect(LPRECT lpRect) const\r
+{\r
+ GetClientRect(lpRect);\r
+\r
+ // get dialog template's size\r
+ // (this is set in CFormView::Create)\r
+ CSize sizeTotal, sizePage, sizeLine;\r
+ int nMapMode = 0;\r
+ GetDeviceScrollSizes(nMapMode, sizeTotal, sizePage, sizeLine);\r
+\r
+ // otherwise, give the correct size if scrollbars active\r
+\r
+ if (nMapMode < 0) // scrollbars disabled\r
+ return;\r
+\r
+ // enlarge reported client area when needed\r
+ CRect rect(lpRect);\r
+ if (rect.Width() < sizeTotal.cx)\r
+ rect.right = rect.left + sizeTotal.cx;\r
+ if (rect.Height() < sizeTotal.cy)\r
+ rect.bottom = rect.top + sizeTotal.cy;\r
+\r
+ rect.OffsetRect(-GetDeviceScrollPosition());\r
+ *lpRect = rect;\r
+}\r
+\r
+BOOL CResizableFormView::OnEraseBkgnd(CDC* pDC) \r
+{\r
+ ClipChildren(pDC, FALSE);\r
+\r
+ BOOL bRet = CFormView::OnEraseBkgnd(pDC);\r
+\r
+ ClipChildren(pDC, TRUE);\r
+\r
+ return bRet;\r
+}\r
+\r
+void CResizableFormView::OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI) \r
+{\r
+ MinMaxInfo(lpMMI);\r
+}\r
+\r
+void CResizableFormView::OnDestroy() \r
+{\r
+ RemoveAllAnchors();\r
+\r
+ CFormView::OnDestroy();\r
+}\r
+\r
+LRESULT CResizableFormView::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) \r
+{\r
+ if (message == WM_INITDIALOG)\r
+ return (LRESULT)OnInitDialog();\r
+\r
+ if (message != WM_NCCALCSIZE || wParam == 0)\r
+ return CFormView::WindowProc(message, wParam, lParam);\r
+\r
+ // specifying valid rects needs controls already anchored\r
+ LRESULT lResult = 0;\r
+ HandleNcCalcSize(FALSE, (LPNCCALCSIZE_PARAMS)lParam, lResult);\r
+ lResult = CFormView::WindowProc(message, wParam, lParam);\r
+ HandleNcCalcSize(TRUE, (LPNCCALCSIZE_PARAMS)lParam, lResult);\r
+ return lResult;\r
+}\r
+\r
+BOOL CResizableFormView::OnInitDialog() \r
+{\r
+ const MSG* pMsg = GetCurrentMessage();\r
+\r
+ BOOL bRet = (BOOL)CFormView::WindowProc(pMsg->message, pMsg->wParam, pMsg->lParam);\r
+\r
+ // we need to associate member variables with control IDs\r
+ UpdateData(FALSE);\r
+ \r
+ // set default scroll size\r
+ CRect rectTemplate;\r
+ GetWindowRect(rectTemplate);\r
+ SetScrollSizes(MM_TEXT, rectTemplate.Size());\r
+\r
+ return bRet;\r
+}\r
+\r
+BOOL CResizableFormView::OnNcCreate(LPCREATESTRUCT lpCreateStruct) \r
+{\r
+ if (!CFormView::OnNcCreate(lpCreateStruct))\r
+ return FALSE;\r
+ \r
+ // create and init the size-grip\r
+ if (!CreateSizeGrip())\r
+ return FALSE;\r
+\r
+ return TRUE;\r
+}\r
--- /dev/null
+#if !defined(AFX_RESIZABLEFORMVIEW_H__INCLUDED_)\r
+#define AFX_RESIZABLEFORMVIEW_H__INCLUDED_\r
+\r
+#if _MSC_VER > 1000\r
+#pragma once\r
+#endif // _MSC_VER > 1000\r
+\r
+// ResizableFormView.h : header file\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// This file is part of ResizableLib\r
+// http://sourceforge.net/projects/resizablelib\r
+//\r
+// Copyright (C) 2000-2004 by Paolo Messina\r
+// http://www.geocities.com/ppescher - mailto:ppescher@hotmail.com\r
+//\r
+// The contents of this file are subject to the Artistic License (the "License").\r
+// You may not use this file except in compliance with the License. \r
+// You may obtain a copy of the License at:\r
+// http://www.opensource.org/licenses/artistic-license.html\r
+//\r
+// If you find this code useful, credits would be nice!\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+#include "ResizableLayout.h"\r
+#include "ResizableGrip.h"\r
+#include "ResizableMinMax.h"\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+// CResizableFormView form view\r
+\r
+#include <afxext.h>\r
+\r
+class CResizableFormView : public CFormView, public CResizableLayout,\r
+ public CResizableGrip, public CResizableMinMax\r
+{\r
+ DECLARE_DYNAMIC(CResizableFormView)\r
+\r
+// Construction\r
+protected: // must derive your own class\r
+ CResizableFormView(UINT nIDTemplate);\r
+ CResizableFormView(LPCTSTR lpszTemplateName);\r
+ virtual ~CResizableFormView();\r
+\r
+private:\r
+ void PrivateConstruct();\r
+ \r
+ // support for temporarily hiding the grip\r
+ DWORD m_dwGripTempState;\r
+ enum GripHideReason // bitmask\r
+ {\r
+ GHR_MAXIMIZED = 0x01,\r
+ GHR_SCROLLBAR = 0x02,\r
+ GHR_ALIGNMENT = 0x04,\r
+ };\r
+\r
+// called from base class\r
+protected:\r
+\r
+ virtual void GetTotalClientRect(LPRECT lpRect) const;\r
+\r
+ virtual CWnd* GetResizableWnd() const\r
+ {\r
+ // make the layout know its parent window\r
+ return CWnd::FromHandle(m_hWnd);\r
+ };\r
+\r
+\r
+// Attributes\r
+public:\r
+\r
+// Operations\r
+public:\r
+\r
+// Overrides\r
+public:\r
+ // ClassWizard generated virtual function overrides\r
+ //{{AFX_VIRTUAL(CResizableFormView)\r
+ protected:\r
+ virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);\r
+ //}}AFX_VIRTUAL\r
+\r
+// Implementation\r
+protected:\r
+\r
+#ifdef _DEBUG\r
+ virtual void AssertValid() const;\r
+ virtual void Dump(CDumpContext& dc) const;\r
+#endif\r
+\r
+ // Generated message map functions\r
+ //{{AFX_MSG(CResizableFormView)\r
+ afx_msg void OnSize(UINT nType, int cx, int cy);\r
+ afx_msg BOOL OnEraseBkgnd(CDC* pDC);\r
+ afx_msg void OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI);\r
+ afx_msg void OnDestroy();\r
+ virtual BOOL OnInitDialog();\r
+ afx_msg BOOL OnNcCreate(LPCREATESTRUCT lpCreateStruct);\r
+ //}}AFX_MSG\r
+ DECLARE_MESSAGE_MAP()\r
+};\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+//{{AFX_INSERT_LOCATION}}\r
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.\r
+\r
+#endif // !defined(AFX_RESIZABLEFORMVIEW_H__INCLUDED_)\r
--- /dev/null
+// ResizableFrame.cpp : implementation file\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// This file is part of ResizableLib\r
+// http://sourceforge.net/projects/resizablelib\r
+//\r
+// Copyright (C) 2000-2004 by Paolo Messina\r
+// http://www.geocities.com/ppescher - mailto:ppescher@hotmail.com\r
+//\r
+// The contents of this file are subject to the Artistic License (the "License").\r
+// You may not use this file except in compliance with the License. \r
+// You may obtain a copy of the License at:\r
+// http://www.opensource.org/licenses/artistic-license.html\r
+//\r
+// If you find this code useful, credits would be nice!\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+#include "stdafx.h"\r
+#include "ResizableFrame.h"\r
+\r
+#ifdef _DEBUG\r
+#define new DEBUG_NEW\r
+#undef THIS_FILE\r
+static char THIS_FILE[] = __FILE__;\r
+#endif\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+// CResizableFrame\r
+\r
+IMPLEMENT_DYNCREATE(CResizableFrame, CFrameWnd)\r
+\r
+CResizableFrame::CResizableFrame()\r
+{\r
+ m_bEnableSaveRestore = FALSE;\r
+}\r
+\r
+CResizableFrame::~CResizableFrame()\r
+{\r
+}\r
+\r
+\r
+BEGIN_MESSAGE_MAP(CResizableFrame, CFrameWnd)\r
+ //{{AFX_MSG_MAP(CResizableFrame)\r
+ ON_WM_GETMINMAXINFO()\r
+ ON_WM_DESTROY()\r
+ ON_WM_NCCREATE()\r
+ ON_WM_WINDOWPOSCHANGING()\r
+ //}}AFX_MSG_MAP\r
+END_MESSAGE_MAP()\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+// CResizableFrame message handlers\r
+\r
+void CResizableFrame::OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI) \r
+{\r
+ MinMaxInfo(lpMMI);\r
+\r
+ CView* pView = GetActiveView();\r
+ if (pView == NULL)\r
+ return;\r
+\r
+ ChainMinMaxInfo(lpMMI, this, pView);\r
+}\r
+\r
+// NOTE: this must be called after setting the layout\r
+// to have the view and its controls displayed properly\r
+BOOL CResizableFrame::EnableSaveRestore(LPCTSTR pszSection, BOOL bRectOnly)\r
+{\r
+ m_sSection = pszSection;\r
+\r
+ m_bEnableSaveRestore = TRUE;\r
+ m_bRectOnly = bRectOnly;\r
+\r
+ // restore immediately\r
+ return LoadWindowRect(pszSection, bRectOnly);\r
+}\r
+\r
+void CResizableFrame::OnDestroy() \r
+{\r
+ if (m_bEnableSaveRestore)\r
+ SaveWindowRect(m_sSection, m_bRectOnly);\r
+\r
+ CFrameWnd::OnDestroy();\r
+}\r
+\r
+BOOL CResizableFrame::OnNcCreate(LPCREATESTRUCT lpCreateStruct) \r
+{\r
+ if (!CFrameWnd::OnNcCreate(lpCreateStruct))\r
+ return FALSE;\r
+\r
+ MakeResizable(lpCreateStruct);\r
+\r
+ return TRUE;\r
+}\r
+\r
+LRESULT CResizableFrame::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) \r
+{\r
+ if (message != WM_NCCALCSIZE || wParam == 0)\r
+ return CFrameWnd::WindowProc(message, wParam, lParam);\r
+\r
+ // specifying valid rects needs controls already anchored\r
+ LRESULT lResult = 0;\r
+ HandleNcCalcSize(FALSE, (LPNCCALCSIZE_PARAMS)lParam, lResult);\r
+ lResult = CFrameWnd::WindowProc(message, wParam, lParam);\r
+ HandleNcCalcSize(TRUE, (LPNCCALCSIZE_PARAMS)lParam, lResult);\r
+ return lResult;\r
+}\r
+\r
+// TODO: implement this in CResizableMinMax\r
+// We definitely need pluggable message handlers ala WTL!\r
+void CResizableFrame::OnWindowPosChanging(WINDOWPOS FAR* lpwndpos) \r
+{\r
+ if ((lpwndpos->flags & (SWP_NOSIZE|SWP_NOMOVE)) != (SWP_NOSIZE|SWP_NOMOVE))\r
+ CFrameWnd::OnWindowPosChanging(lpwndpos);\r
+}\r
--- /dev/null
+#if !defined(AFX_RESIZABLEFRAME_H__INCLUDED_)\r
+#define AFX_RESIZABLEFRAME_H__INCLUDED_\r
+\r
+#if _MSC_VER > 1000\r
+#pragma once\r
+#endif // _MSC_VER > 1000\r
+// ResizableFrame.h : header file\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// This file is part of ResizableLib\r
+// http://sourceforge.net/projects/resizablelib\r
+//\r
+// Copyright (C) 2000-2004 by Paolo Messina\r
+// http://www.geocities.com/ppescher - mailto:ppescher@hotmail.com\r
+//\r
+// The contents of this file are subject to the Artistic License (the "License").\r
+// You may not use this file except in compliance with the License. \r
+// You may obtain a copy of the License at:\r
+// http://www.opensource.org/licenses/artistic-license.html\r
+//\r
+// If you find this code useful, credits would be nice!\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+#include "ResizableMinMax.h"\r
+#include "ResizableWndState.h"\r
+#include "ResizableLayout.h"\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+// CResizableFrame frame\r
+\r
+class CResizableFrame : public CFrameWnd, public CResizableMinMax,\r
+ public CResizableWndState, public CResizableLayout\r
+{\r
+ DECLARE_DYNCREATE(CResizableFrame)\r
+protected:\r
+ CResizableFrame(); // protected constructor used by dynamic creation\r
+\r
+// Attributes\r
+protected:\r
+\r
+// Operations\r
+public:\r
+\r
+// Overrides\r
+ // ClassWizard generated virtual function overrides\r
+ //{{AFX_VIRTUAL(CResizableFrame)\r
+ protected:\r
+ virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);\r
+ //}}AFX_VIRTUAL\r
+\r
+// Implementation\r
+protected:\r
+ virtual ~CResizableFrame();\r
+\r
+ BOOL EnableSaveRestore(LPCTSTR pszSection, BOOL bRectOnly = FALSE);\r
+\r
+ virtual CWnd* GetResizableWnd() const\r
+ {\r
+ // make the layout know its parent window\r
+ return CWnd::FromHandle(m_hWnd);\r
+ };\r
+\r
+private:\r
+ // flags\r
+ BOOL m_bEnableSaveRestore;\r
+ BOOL m_bRectOnly;\r
+\r
+ // internal status\r
+ CString m_sSection; // section name (identifies a parent window)\r
+\r
+protected:\r
+ // Generated message map functions\r
+ //{{AFX_MSG(CResizableFrame)\r
+ afx_msg void OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI);\r
+ afx_msg void OnDestroy();\r
+ afx_msg BOOL OnNcCreate(LPCREATESTRUCT lpCreateStruct);\r
+ afx_msg void OnWindowPosChanging(WINDOWPOS FAR* lpwndpos);\r
+ //}}AFX_MSG\r
+ DECLARE_MESSAGE_MAP()\r
+};\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+//{{AFX_INSERT_LOCATION}}\r
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.\r
+\r
+#endif // !defined(AFX_RESIZABLEFRAME_H__INCLUDED_)\r
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// This file is part of ResizableLib\r
+// http://sourceforge.net/projects/resizablelib\r
+//\r
+// Copyright (C) 2000-2004 by Paolo Messina\r
+// http://www.geocities.com/ppescher - mailto:ppescher@hotmail.com\r
+//\r
+// The contents of this file are subject to the Artistic License (the "License").\r
+// You may not use this file except in compliance with the License. \r
+// You may obtain a copy of the License at:\r
+// http://www.opensource.org/licenses/artistic-license.html\r
+//\r
+// If you find this code useful, credits would be nice!\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+/*!\r
+ * @file\r
+ * @brief Implementation of the CResizableGrip class.\r
+ */\r
+\r
+#include "stdafx.h"\r
+#include "ResizableGrip.h"\r
+\r
+#ifdef _DEBUG\r
+#undef THIS_FILE\r
+static char THIS_FILE[]=__FILE__;\r
+#define new DEBUG_NEW\r
+#endif\r
+\r
+//////////////////////////////////////////////////////////////////////\r
+// Construction/Destruction\r
+//////////////////////////////////////////////////////////////////////\r
+\r
+CResizableGrip::CResizableGrip()\r
+{\r
+ m_nShowCount = 0;\r
+}\r
+\r
+CResizableGrip::~CResizableGrip()\r
+{\r
+\r
+}\r
+\r
+void CResizableGrip::UpdateSizeGrip()\r
+{\r
+ if (!::IsWindow(m_wndGrip.m_hWnd))\r
+ return;\r
+\r
+ // size-grip goes bottom right in the client area\r
+ // (any right-to-left adjustment should go here)\r
+\r
+ RECT rect;\r
+ GetResizableWnd()->GetClientRect(&rect);\r
+\r
+ rect.left = rect.right - m_wndGrip.m_size.cx;\r
+ rect.top = rect.bottom - m_wndGrip.m_size.cy;\r
+\r
+ // must stay below other children\r
+ m_wndGrip.SetWindowPos(&CWnd::wndBottom, rect.left, rect.top, 0, 0,\r
+ SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOREPOSITION\r
+ | (IsSizeGripVisible() ? SWP_SHOWWINDOW : SWP_HIDEWINDOW));\r
+}\r
+\r
+// pbStatus points to a variable, maintained by the caller, that\r
+// holds its visibility status. Initialize the variable with 1\r
+// to allow to temporarily hide the grip, 0 to allow to\r
+// temporarily show the grip (with respect to the dwMask bit).\r
+\r
+// NB: visibility is effective only after an update\r
+\r
+void CResizableGrip::ShowSizeGrip(DWORD* pStatus, DWORD dwMask /*= 1*/)\r
+{\r
+ ASSERT(pStatus != NULL);\r
+\r
+ if (!(*pStatus & dwMask))\r
+ {\r
+ m_nShowCount++;\r
+ (*pStatus) |= dwMask;\r
+ }\r
+}\r
+\r
+void CResizableGrip::HideSizeGrip(DWORD* pStatus, DWORD dwMask /*= 1*/)\r
+{\r
+ ASSERT(pStatus != NULL);\r
+\r
+ if (*pStatus & dwMask)\r
+ {\r
+ m_nShowCount--;\r
+ (*pStatus) &= ~dwMask;\r
+ }\r
+}\r
+\r
+BOOL CResizableGrip::IsSizeGripVisible()\r
+{\r
+ // NB: visibility is effective only after an update\r
+ return (m_nShowCount > 0);\r
+}\r
+\r
+void CResizableGrip::SetSizeGripVisibility(BOOL bVisible)\r
+{\r
+ if (bVisible)\r
+ m_nShowCount = 1;\r
+ else\r
+ m_nShowCount = 0;\r
+}\r
+\r
+BOOL CResizableGrip::SetSizeGripBkMode(int nBkMode)\r
+{\r
+ if (::IsWindow(m_wndGrip.m_hWnd))\r
+ {\r
+ if (nBkMode == OPAQUE)\r
+ m_wndGrip.SetTransparency(FALSE);\r
+ else if (nBkMode == TRANSPARENT)\r
+ m_wndGrip.SetTransparency(TRUE);\r
+ else\r
+ return FALSE;\r
+ return TRUE;\r
+ }\r
+ return FALSE;\r
+}\r
+\r
+void CResizableGrip::SetSizeGripShape(BOOL bTriangular)\r
+{\r
+ if (::IsWindow(m_wndGrip.m_hWnd))\r
+ m_wndGrip.SetTriangularShape(bTriangular);\r
+}\r
+\r
+BOOL CResizableGrip::CreateSizeGrip(BOOL bVisible /*= TRUE*/,\r
+ BOOL bTriangular /*= TRUE*/, BOOL bTransparent /*= FALSE*/)\r
+{\r
+ // create grip\r
+ CRect rect(0 , 0, m_wndGrip.m_size.cx, m_wndGrip.m_size.cy);\r
+ BOOL bRet = m_wndGrip.Create(WS_CHILD | WS_CLIPSIBLINGS\r
+ | SBS_SIZEGRIP, rect, GetResizableWnd(), 0);\r
+\r
+ if (bRet)\r
+ {\r
+ // set options\r
+ m_wndGrip.SetTriangularShape(bTriangular);\r
+ m_wndGrip.SetTransparency(bTransparent);\r
+ SetSizeGripVisibility(bVisible);\r
+ \r
+ // update position\r
+ UpdateSizeGrip();\r
+ }\r
+\r
+ return bRet;\r
+}\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+// CSizeGrip implementation\r
+\r
+BOOL CResizableGrip::CSizeGrip::IsRTL()\r
+{\r
+ return GetExStyle() & WS_EX_LAYOUTRTL;\r
+}\r
+\r
+BOOL CResizableGrip::CSizeGrip::PreCreateWindow(CREATESTRUCT& cs) \r
+{\r
+ // set window size\r
+ m_size.cx = GetSystemMetrics(SM_CXVSCROLL);\r
+ m_size.cy = GetSystemMetrics(SM_CYHSCROLL);\r
+\r
+ cs.cx = m_size.cx;\r
+ cs.cy = m_size.cy;\r
+ \r
+ return CScrollBar::PreCreateWindow(cs);\r
+}\r
+\r
+LRESULT CResizableGrip::CSizeGrip::WindowProc(UINT message,\r
+ WPARAM wParam, LPARAM lParam)\r
+{\r
+ switch (message)\r
+ {\r
+ case WM_GETDLGCODE:\r
+ // fix to prevent the control to gain focus, using arrow keys\r
+ // (standard grip returns DLGC_WANTARROWS, like any standard scrollbar)\r
+ return DLGC_STATIC;\r
+\r
+ case WM_SETFOCUS:\r
+ // fix to prevent the control to gain focus, if set directly\r
+ // (for example when it's the only one control in a dialog)\r
+ return 0;\r
+\r
+ case WM_NCHITTEST:\r
+ // choose proper cursor shape\r
+ if (IsRTL())\r
+ return HTBOTTOMLEFT;\r
+ else\r
+ return HTBOTTOMRIGHT;\r
+ break;\r
+\r
+ case WM_SETTINGCHANGE:\r
+ {\r
+ // update grip's size\r
+ CSize sizeOld = m_size;\r
+ m_size.cx = GetSystemMetrics(SM_CXVSCROLL);\r
+ m_size.cy = GetSystemMetrics(SM_CYHSCROLL);\r
+\r
+ // resize transparency bitmaps\r
+ if (m_bTransparent)\r
+ {\r
+ CClientDC dc(this);\r
+\r
+ // destroy bitmaps\r
+ m_bmGrip.DeleteObject();\r
+ m_bmMask.DeleteObject();\r
+\r
+ // re-create bitmaps\r
+ m_bmGrip.CreateCompatibleBitmap(&dc, m_size.cx, m_size.cy);\r
+ m_bmMask.CreateBitmap(m_size.cx, m_size.cy, 1, 1, NULL);\r
+ }\r
+\r
+ // re-calc shape\r
+ if (m_bTriangular)\r
+ SetTriangularShape(m_bTriangular);\r
+\r
+ // reposition the grip\r
+ CRect rect;\r
+ GetWindowRect(rect);\r
+ rect.InflateRect(m_size.cx - sizeOld.cx, m_size.cy - sizeOld.cy, 0, 0);\r
+ ::MapWindowPoints(NULL, GetParent()->GetSafeHwnd(), (LPPOINT)&rect, 2);\r
+ MoveWindow(rect, TRUE);\r
+ }\r
+ break;\r
+\r
+ case WM_DESTROY:\r
+ // perform clean up\r
+ if (m_bTransparent)\r
+ SetTransparency(FALSE);\r
+ break;\r
+\r
+ case WM_PAINT:\r
+ case WM_PRINTCLIENT:\r
+ if (m_bTransparent)\r
+ {\r
+ PAINTSTRUCT ps;\r
+ CDC* pDC = (message == WM_PAINT && wParam == 0) ?\r
+ BeginPaint(&ps) : CDC::FromHandle((HDC)wParam);\r
+\r
+ // select bitmaps\r
+ CBitmap *pOldGrip, *pOldMask;\r
+\r
+ pOldGrip = m_dcGrip.SelectObject(&m_bmGrip);\r
+ pOldMask = m_dcMask.SelectObject(&m_bmMask);\r
+\r
+ // obtain original grip bitmap, make the mask and prepare masked bitmap\r
+ CScrollBar::WindowProc(message, (WPARAM)m_dcGrip.GetSafeHdc(), lParam);\r
+ m_dcGrip.SetBkColor(m_dcGrip.GetPixel(0, 0));\r
+ m_dcMask.BitBlt(0, 0, m_size.cx, m_size.cy, &m_dcGrip, 0, 0, SRCCOPY);\r
+ m_dcGrip.BitBlt(0, 0, m_size.cx, m_size.cy, &m_dcMask, 0, 0, 0x00220326);\r
+ \r
+ // draw transparently\r
+ pDC->BitBlt(0, 0, m_size.cx, m_size.cy, &m_dcMask, 0, 0, SRCAND);\r
+ pDC->BitBlt(0, 0, m_size.cx, m_size.cy, &m_dcGrip, 0, 0, SRCPAINT);\r
+\r
+ // unselect bitmaps\r
+ m_dcGrip.SelectObject(pOldGrip);\r
+ m_dcMask.SelectObject(pOldMask);\r
+\r
+ if (message == WM_PAINT && wParam == 0)\r
+ EndPaint(&ps);\r
+ return 0;\r
+ }\r
+ break;\r
+ }\r
+\r
+ return CScrollBar::WindowProc(message, wParam, lParam);\r
+}\r
+\r
+void CResizableGrip::CSizeGrip::SetTransparency(BOOL bActivate)\r
+{\r
+ // creates or deletes DCs and Bitmaps used for\r
+ // implementing a transparent size grip\r
+\r
+ if (bActivate && !m_bTransparent)\r
+ {\r
+ m_bTransparent = TRUE;\r
+\r
+ CClientDC dc(this);\r
+\r
+ // create memory DCs and bitmaps\r
+ m_dcGrip.CreateCompatibleDC(&dc);\r
+ m_bmGrip.CreateCompatibleBitmap(&dc, m_size.cx, m_size.cy);\r
+\r
+ m_dcMask.CreateCompatibleDC(&dc);\r
+ m_bmMask.CreateBitmap(m_size.cx, m_size.cy, 1, 1, NULL);\r
+ }\r
+ else if (!bActivate && m_bTransparent)\r
+ {\r
+ m_bTransparent = FALSE;\r
+\r
+ // destroy memory DCs and bitmaps\r
+ m_dcGrip.DeleteDC();\r
+ m_bmGrip.DeleteObject();\r
+\r
+ m_dcMask.DeleteDC();\r
+ m_bmMask.DeleteObject();\r
+ }\r
+}\r
+\r
+void CResizableGrip::CSizeGrip::SetTriangularShape(BOOL bEnable)\r
+{\r
+ m_bTriangular = bEnable;\r
+\r
+ if (bEnable)\r
+ {\r
+ // set a triangular window region\r
+ CRect rect;\r
+ GetWindowRect(rect);\r
+ rect.OffsetRect(-rect.TopLeft());\r
+ POINT arrPoints[] =\r
+ {\r
+ { rect.left, rect.bottom },\r
+ { rect.right, rect.bottom },\r
+ { rect.right, rect.top }\r
+ };\r
+ CRgn rgnGrip;\r
+ rgnGrip.CreatePolygonRgn(arrPoints, 3, WINDING);\r
+ SetWindowRgn((HRGN)rgnGrip.Detach(), IsWindowVisible());\r
+ }\r
+ else\r
+ {\r
+ SetWindowRgn((HRGN)NULL, IsWindowVisible());\r
+ }\r
+}\r
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// This file is part of ResizableLib\r
+// http://sourceforge.net/projects/resizablelib\r
+//\r
+// Copyright (C) 2000-2004 by Paolo Messina\r
+// http://www.geocities.com/ppescher - mailto:ppescher@hotmail.com\r
+//\r
+// The contents of this file are subject to the Artistic License (the "License").\r
+// You may not use this file except in compliance with the License. \r
+// You may obtain a copy of the License at:\r
+// http://www.opensource.org/licenses/artistic-license.html\r
+//\r
+// If you find this code useful, credits would be nice!\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+/*!\r
+ * @file\r
+ * @brief Interface for the CResizableGrip class.\r
+ */\r
+\r
+#if !defined(AFX_RESIZABLEGRIP_H__INCLUDED_)\r
+#define AFX_RESIZABLEGRIP_H__INCLUDED_\r
+\r
+#if _MSC_VER > 1000\r
+#pragma once\r
+#endif // _MSC_VER > 1000\r
+\r
+/*! @addtogroup CoreComponents\r
+ * @{\r
+ */\r
+\r
+//! @brief brief_description\r
+/*!\r
+ * long_description\r
+ */\r
+class CResizableGrip \r
+{\r
+private:\r
+ class CSizeGrip : public CScrollBar\r
+ {\r
+ public:\r
+ CSizeGrip()\r
+ {\r
+ m_bTransparent = FALSE;\r
+ m_bTriangular = FALSE;\r
+ }\r
+\r
+ void SetTriangularShape(BOOL bEnable);\r
+ void SetTransparency(BOOL bActivate);\r
+\r
+ BOOL IsRTL(); // right-to-left layout support\r
+\r
+ virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);\r
+\r
+ SIZE m_size; // holds grip size\r
+\r
+ protected:\r
+ virtual BOOL PreCreateWindow(CREATESTRUCT& cs);\r
+\r
+ BOOL m_bTriangular; // triangular shape active\r
+ BOOL m_bTransparent; // transparency active\r
+\r
+ // memory DCs and bitmaps for transparent grip\r
+ CDC m_dcGrip, m_dcMask;\r
+ CBitmap m_bmGrip, m_bmMask;\r
+ };\r
+\r
+ CSizeGrip m_wndGrip; // grip control\r
+ int m_nShowCount; // support for hiding the grip\r
+\r
+protected:\r
+ // create a size grip, with options\r
+ BOOL CreateSizeGrip(BOOL bVisible = TRUE,\r
+ BOOL bTriangular = TRUE, BOOL bTransparent = FALSE);\r
+\r
+ BOOL IsSizeGripVisible(); // TRUE if grip is set to be visible\r
+ void SetSizeGripVisibility(BOOL bVisible); // set default visibility\r
+ void UpdateSizeGrip(); // update the grip's visibility and position\r
+ void ShowSizeGrip(DWORD* pStatus, DWORD dwMask = 1); // temp show the size grip\r
+ void HideSizeGrip(DWORD* pStatus, DWORD dwMask = 1); // temp hide the size grip\r
+ BOOL SetSizeGripBkMode(int nBkMode); // like CDC::SetBkMode\r
+ void SetSizeGripShape(BOOL bTriangular);\r
+\r
+ virtual CWnd* GetResizableWnd() const = 0;\r
+\r
+public:\r
+ CResizableGrip();\r
+ virtual ~CResizableGrip();\r
+};\r
+\r
+// @}\r
+#endif // !defined(AFX_RESIZABLEGRIP_H__INCLUDED_)\r
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// This file is part of ResizableLib\r
+// http://sourceforge.net/projects/resizablelib\r
+//\r
+// Copyright (C) 2000-2004 by Paolo Messina\r
+// http://www.geocities.com/ppescher - mailto:ppescher@hotmail.com\r
+//\r
+// The contents of this file are subject to the Artistic License (the "License").\r
+// You may not use this file except in compliance with the License. \r
+// You may obtain a copy of the License at:\r
+// http://www.opensource.org/licenses/artistic-license.html\r
+//\r
+// If you find this code useful, credits would be nice!\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+/*!\r
+ * @file\r
+ * @brief Implementation of the CResizableLayout class.\r
+ */\r
+\r
+#include "stdafx.h"\r
+#include "ResizableLayout.h"\r
+#include "ResizableVersion.h"\r
+\r
+#ifdef _DEBUG\r
+#undef THIS_FILE\r
+static char THIS_FILE[]=__FILE__;\r
+#define new DEBUG_NEW\r
+#endif\r
+\r
+/*!\r
+ * @internal Constant used to detect clipping and refresh properties\r
+ *\r
+ * @note In August 2002 Platform SDK, some guy at MS thought it was time\r
+ * to add the missing symbol BS_TYPEMASK, but forgot its original\r
+ * meaning and so now he's telling us not to use that symbol because\r
+ * its value is likely to change in the future SDK releases, including\r
+ * all the BS_* style bits in the mask, not just the button's type\r
+ * as the symbol's name suggests.\r
+ * @n So now we're forced to define another symbol, great!\r
+ */\r
+#define _BS_TYPEMASK 0x0000000FL\r
+\r
+/*!\r
+ * This function adds a new control to the layout manager and sets anchor\r
+ * points for its top-left and bottom-right corners.\r
+ * \r
+ * @param hWnd Window handle to the control to be added\r
+ * @param anchorTopLeft Anchor point for the top-left corner\r
+ * @param anchorBottomRight Anchor point for the bottom-right corner\r
+ *\r
+ * @remarks Overlapping controls, like group boxes and the controls inside,\r
+ * must be added from the outer controls to the inner ones, to let\r
+ * the clipping routines work correctly.\r
+ *\r
+ * @sa AddAnchorCallback RemoveAnchor\r
+ */\r
+void CResizableLayout::AddAnchor(HWND hWnd, ANCHOR anchorTopLeft, ANCHOR anchorBottomRight)\r
+{\r
+ CWnd* pParent = GetResizableWnd();\r
+\r
+ // child window must be valid\r
+ ASSERT(::IsWindow(hWnd));\r
+ // must be child of parent window\r
+ ASSERT(::IsChild(pParent->GetSafeHwnd(), hWnd));\r
+\r
+ // get parent window's rect\r
+ CRect rectParent;\r
+ GetTotalClientRect(&rectParent);\r
+ // and child control's rect\r
+ CRect rectChild;\r
+ ::GetWindowRect(hWnd, &rectChild);\r
+ ::MapWindowPoints(NULL, pParent->m_hWnd, (LPPOINT)&rectChild, 2);\r
+\r
+ // adjust position, if client area has been scrolled\r
+ rectChild.OffsetRect(-rectParent.TopLeft());\r
+\r
+ // go calculate margins\r
+ CSize marginTopLeft, marginBottomRight;\r
+\r
+ // calculate margin for the top-left corner\r
+\r
+ marginTopLeft.cx = rectChild.left - rectParent.Width() * anchorTopLeft.cx / 100;\r
+ marginTopLeft.cy = rectChild.top - rectParent.Height() * anchorTopLeft.cy / 100;\r
+ \r
+ // calculate margin for the bottom-right corner\r
+\r
+ marginBottomRight.cx = rectChild.right - rectParent.Width() * anchorBottomRight.cx / 100;\r
+ marginBottomRight.cy = rectChild.bottom - rectParent.Height() * anchorBottomRight.cy / 100;\r
+\r
+ // prepare the structure\r
+ LAYOUTINFO layout(hWnd, anchorTopLeft, marginTopLeft,\r
+ anchorBottomRight, marginBottomRight);\r
+\r
+ // get control's window class\r
+ GetClassName(hWnd, layout.sWndClass, MAX_PATH);\r
+\r
+ // initialize resize properties (overridable)\r
+ InitResizeProperties(layout);\r
+\r
+ // must not be already there!\r
+ // (this is probably due to a duplicate call to AddAnchor)\r
+ POSITION pos;\r
+ ASSERT(!m_mapLayout.Lookup(hWnd, pos));\r
+\r
+ // add to the list and the map\r
+ pos = m_listLayout.AddTail(layout);\r
+ m_mapLayout.SetAt(hWnd, pos);\r
+}\r
+\r
+/*!\r
+ * This function adds a placeholder to the layout manager, that will be\r
+ * dinamically set by a callback function whenever required.\r
+ *\r
+ * @return The return value is an integer used to distinguish between\r
+ * different placeholders in the callback implementation.\r
+ *\r
+ * @remarks You must override @ref ArrangeLayoutCallback to provide layout\r
+ * information.\r
+ *\r
+ * @sa AddAnchor ArrangeLayoutCallback ArrangeLayout\r
+ */\r
+UINT_PTR CResizableLayout::AddAnchorCallback()\r
+{\r
+ // one callback control cannot rely upon another callback control's\r
+ // size and/or position (they're updated all together at the end)\r
+ // it can however use a non-callback control, calling GetAnchorPosition()\r
+\r
+ // add to the list\r
+ LAYOUTINFO layout;\r
+ layout.nCallbackID = m_listLayoutCB.GetCount() + 1;\r
+ m_listLayoutCB.AddTail(layout);\r
+ return layout.nCallbackID;\r
+}\r
+\r
+/*!\r
+ * This function is called for each placeholder added to the layout manager\r
+ * and must be overridden to provide the necessary layout information.\r
+ * \r
+ * @param layout Reference to a LAYOUTINFO structure to be filled with\r
+ * layout information for the specified placeholder.\r
+ * On input, nCallbackID is the identification number\r
+ * returned by AddAnchorCallback. On output, anchor points and\r
+ * the window handle must be set and valid.\r
+ * \r
+ * @return The return value is @c TRUE if the layout information has been\r
+ * provided successfully, @c FALSE to skip this placeholder.\r
+ *\r
+ * @remarks When implementing this function, unknown placeholders should be\r
+ * passed to the base class. Unhandled cases will fire an assertion\r
+ * in the debug version.\r
+ *\r
+ * @sa AddAnchorCallback ArrangeLayout LAYOUTINFO\r
+ */\r
+BOOL CResizableLayout::ArrangeLayoutCallback(LAYOUTINFO& layout) const\r
+{\r
+ UNREFERENCED_PARAMETER(layout);\r
+ \r
+ ASSERT(FALSE); // must be overridden, if callback is used\r
+ \r
+ return FALSE; // no useful output data\r
+}\r
+\r
+/*!\r
+ * This function should be called in resizable window classes whenever the\r
+ * controls layout should be updated, usually after a resize operation.\r
+ *\r
+ * @remarks All the controls added to the layout are moved and resized at\r
+ * once for performace reasons, so all the controls are in their\r
+ * old position when AddAnchorCallback is called.\r
+ * To know where a control will be placed use GetAnchorPosition.\r
+ * \r
+ * @sa AddAnchor AddAnchorCallback ArrangeLayoutCallback GetAnchorPosition\r
+ */\r
+void CResizableLayout::ArrangeLayout() const\r
+{\r
+ // common vars\r
+ UINT uFlags;\r
+ LAYOUTINFO layout;\r
+ CRect rectParent, rectChild;\r
+ INT_PTR count = m_listLayout.GetCount();\r
+ INT_PTR countCB = m_listLayoutCB.GetCount();\r
+\r
+ if (count + countCB == 0)\r
+ return;\r
+\r
+ // get parent window's rect\r
+ GetTotalClientRect(&rectParent);\r
+\r
+ // reposition child windows\r
+ HDWP hdwp = ::BeginDeferWindowPos (static_cast<int>(count + countCB));\r
+ \r
+ POSITION pos = m_listLayout.GetHeadPosition();\r
+ while (pos != NULL)\r
+ {\r
+ // get layout info\r
+ layout = m_listLayout.GetNext(pos);\r
+ \r
+ // calculate new child's position, size and flags for SetWindowPos\r
+ CalcNewChildPosition(layout, rectParent, rectChild, uFlags);\r
+\r
+ // only if size or position changed\r
+ if ((uFlags & (SWP_NOMOVE|SWP_NOSIZE)) != (SWP_NOMOVE|SWP_NOSIZE))\r
+ {\r
+ hdwp = ::DeferWindowPos(hdwp, layout.hWnd, NULL, rectChild.left,\r
+ rectChild.top, rectChild.Width(), rectChild.Height(), uFlags);\r
+ }\r
+ }\r
+\r
+ // for callback items you may use GetAnchorPosition to know the\r
+ // new position and size of a non-callback item after resizing\r
+\r
+ pos = m_listLayoutCB.GetHeadPosition();\r
+ while (pos != NULL)\r
+ {\r
+ // get layout info\r
+ layout = m_listLayoutCB.GetNext(pos);\r
+ // request layout data\r
+ if (!ArrangeLayoutCallback(layout))\r
+ continue;\r
+\r
+ // calculate new child's position, size and flags for SetWindowPos\r
+ CalcNewChildPosition(layout, rectParent, rectChild, uFlags);\r
+\r
+ // only if size or position changed\r
+ if ((uFlags & (SWP_NOMOVE|SWP_NOSIZE)) != (SWP_NOMOVE|SWP_NOSIZE))\r
+ {\r
+ hdwp = ::DeferWindowPos(hdwp, layout.hWnd, NULL, rectChild.left,\r
+ rectChild.top, rectChild.Width(), rectChild.Height(), uFlags);\r
+ }\r
+ }\r
+\r
+ // finally move all the windows at once\r
+ ::EndDeferWindowPos(hdwp);\r
+}\r
+\r
+/*!\r
+ * @internal This function adds or removes a control window region\r
+ * to or from the specified clipping region, according to its layout\r
+ * properties.\r
+ */\r
+void CResizableLayout::ClipChildWindow(const LAYOUTINFO& layout,\r
+ CRgn* pRegion) const\r
+{\r
+ // obtain window position\r
+ CRect rect;\r
+ ::GetWindowRect(layout.hWnd, &rect);\r
+#if (_WIN32_WINNT >= 0x0501)\r
+ //! @todo decide when to clip client only or non-client too (themes?)\r
+ //! (leave disabled meanwhile, until I find a good solution)\r
+ //! @note wizard97 with watermark bitmap and themes won't look good!\r
+ // if (real_WIN32_WINNT >= 0x501)\r
+ // ::SendMessage(layout.hWnd, WM_NCCALCSIZE, FALSE, (LPARAM)&rect);\r
+#endif\r
+ ::MapWindowPoints(NULL, GetResizableWnd()->m_hWnd, (LPPOINT)&rect, 2);\r
+\r
+ // use window region if any\r
+ CRgn rgn;\r
+ rgn.CreateRectRgn(0,0,0,0);\r
+ switch (::GetWindowRgn(layout.hWnd, rgn))\r
+ {\r
+ case COMPLEXREGION:\r
+ case SIMPLEREGION:\r
+ rgn.OffsetRgn(rect.TopLeft());\r
+ break;\r
+\r
+ default:\r
+ rgn.SetRectRgn(&rect);\r
+ }\r
+\r
+ // get the clipping property\r
+ BOOL bClipping = layout.properties.bAskClipping ?\r
+ LikesClipping(layout) : layout.properties.bCachedLikesClipping;\r
+\r
+ // modify region accordingly\r
+ if (bClipping)\r
+ pRegion->CombineRgn(pRegion, &rgn, RGN_DIFF);\r
+ else\r
+ pRegion->CombineRgn(pRegion, &rgn, RGN_OR);\r
+}\r
+\r
+/*!\r
+ * This function retrieves the clipping region for the current layout.\r
+ * It can be used to draw directly inside the region, without applying\r
+ * clipping as the ClipChildren function does.\r
+ * \r
+ * @param pRegion Pointer to a CRegion object that holds the\r
+ * calculated clipping region upon return\r
+ *\r
+ * @deprecated For anti-flickering ClipChildren should be preferred\r
+ * as it is more complete for platform compatibility.\r
+ * It will probably become a private function.\r
+ */\r
+void CResizableLayout::GetClippingRegion(CRgn* pRegion) const\r
+{\r
+ CWnd* pWnd = GetResizableWnd();\r
+\r
+ // System's default clipping area is screen's size,\r
+ // not enough for max track size, for example:\r
+ // if screen is 1024 x 768 and resizing border is 4 pixels,\r
+ // maximized size is 1024+4*2=1032 x 768+4*2=776,\r
+ // but max track size is 4 pixels bigger 1036 x 780 (don't ask me why!)\r
+ // So, if you resize the window to maximum size, the last 4 pixels\r
+ // are clipped out by the default clipping region, that gets created\r
+ // as soon as you call clipping functions (my guess).\r
+\r
+ // reset clipping region to the whole client area\r
+ CRect rect;\r
+ pWnd->GetClientRect(&rect);\r
+ pRegion->CreateRectRgnIndirect(&rect);\r
+\r
+ // clip only anchored controls\r
+ LAYOUTINFO layout;\r
+ POSITION pos = m_listLayout.GetHeadPosition();\r
+ while (pos != NULL)\r
+ {\r
+ // get layout info\r
+ layout = m_listLayout.GetNext(pos);\r
+ \r
+ if (::IsWindowVisible(layout.hWnd))\r
+ ClipChildWindow(layout, pRegion);\r
+ }\r
+ pos = m_listLayoutCB.GetHeadPosition();\r
+ while (pos != NULL)\r
+ {\r
+ // get layout info\r
+ layout = m_listLayoutCB.GetNext(pos);\r
+ // request data\r
+ if (!ArrangeLayoutCallback(layout))\r
+ continue;\r
+\r
+ if (::IsWindowVisible(layout.hWnd))\r
+ ClipChildWindow(layout, pRegion);\r
+ }\r
+//! @todo Has XP changed this??? It doesn't seem correct anymore!\r
+/*\r
+ // fix for RTL layouts (1 pixel of horz offset)\r
+ if (pWnd->GetExStyle() & WS_EX_LAYOUTRTL)\r
+ pRegion->OffsetRgn(-1,0);\r
+*/\r
+}\r
+\r
+//! @internal @brief Implements GetAncestor(pWnd->GetSafeHwnd(), GA_ROOT)\r
+inline CWnd* GetRootParentWnd(CWnd* pWnd)\r
+{\r
+ // GetAncestor API not present, emulate\r
+ if (!(pWnd->GetStyle() & WS_CHILD))\r
+ return NULL;\r
+ while (pWnd->GetStyle() & WS_CHILD)\r
+ pWnd = pWnd->GetParent();\r
+ return pWnd;\r
+}\r
+\r
+/*!\r
+ * This function enables or restores clipping on the specified DC when\r
+ * appropriate. It should be called whenever drawing on the window client\r
+ * area to avoid flickering.\r
+ * \r
+ * @param pDC Pointer to the target device context \r
+ * @param bUndo Flag that specifies wether to restore the clipping region\r
+ * \r
+ * @return The return value is @c TRUE if the clipping region has been\r
+ * modified, @c FALSE if clipping was not necessary.\r
+ *\r
+ * @remarks For anti-flickering to work, you should wrap your\r
+ * @c WM_ERASEBKGND message handler inside a pair of calls to\r
+ * this function, with the last parameter set to @c TRUE first\r
+ * and to @c FALSE at the end.\r
+ */\r
+BOOL CResizableLayout::ClipChildren(CDC* pDC, BOOL bUndo)\r
+{\r
+#if (_WIN32_WINNT >= 0x0501 && !defined(RSZLIB_NO_XP_DOUBLE_BUFFER))\r
+ // clipping not necessary when double-buffering enabled\r
+ if (real_WIN32_WINNT >= 0x0501)\r
+ {\r
+ CWnd *pWnd = GetRootParentWnd(GetResizableWnd());\r
+ if (pWnd == NULL)\r
+ pWnd = GetResizableWnd();\r
+ if (pWnd->GetExStyle() & WS_EX_COMPOSITED)\r
+ return FALSE;\r
+ }\r
+#endif\r
+\r
+ HDC hDC = pDC->GetSafeHdc();\r
+ HWND hWnd = GetResizableWnd()->GetSafeHwnd();\r
+\r
+ m_nOldClipRgn = -1; // invalid region by default\r
+\r
+ // Some controls (such as transparent toolbars and standard controls\r
+ // with XP theme enabled) send a WM_ERASEBKGND msg to the parent\r
+ // to draw themselves, in which case we must not enable clipping.\r
+\r
+ // We check that the window associated with the DC is the\r
+ // resizable window and not a child control.\r
+\r
+ if (!bUndo && (hWnd == ::WindowFromDC(hDC)))\r
+ {\r
+ // save old DC clipping region\r
+ m_nOldClipRgn = ::GetClipRgn(hDC, m_hOldClipRgn);\r
+\r
+ // clip out supported child windows\r
+ CRgn rgnClip;\r
+ GetClippingRegion(&rgnClip);\r
+ ::ExtSelectClipRgn(hDC, rgnClip, RGN_AND);\r
+\r
+ return TRUE;\r
+ }\r
+\r
+ // restore old clipping region, only if modified and valid\r
+ if (bUndo && m_nOldClipRgn >= 0)\r
+ {\r
+ if (m_nOldClipRgn == 1)\r
+ ::SelectClipRgn(hDC, m_hOldClipRgn);\r
+ else\r
+ ::SelectClipRgn(hDC, NULL);\r
+ \r
+ return TRUE;\r
+ }\r
+\r
+ return FALSE;\r
+}\r
+\r
+/*!\r
+ * This function is used by this class, and should be used by derived\r
+ * classes too, in place of the standard GetClientRect. It can be useful\r
+ * for windows with scrollbars or expanding windows, to provide the true\r
+ * client area, including even those parts which are not visible.\r
+ * \r
+ * @param lpRect Pointer to the RECT structure that holds the result\r
+ *\r
+ * @remarks Override this function to provide the client area the class uses\r
+ * to perform layout calculations, both when adding controls and\r
+ * when rearranging the layout.\r
+ * @n The base implementation simply calls @c GetClientRect\r
+ */\r
+void CResizableLayout::GetTotalClientRect(LPRECT lpRect) const\r
+{\r
+ GetResizableWnd()->GetClientRect(lpRect);\r
+}\r
+\r
+/*!\r
+ * This function is used to determine if a control needs to be painted when\r
+ * it is moved or resized by the layout manager.\r
+ * \r
+ * @param layout Reference to a @c LAYOUTINFO structure for the control\r
+ * @param rectOld Reference to a @c RECT structure that holds the control\r
+ * position and size before the layout update\r
+ * @param rectNew Reference to a @c RECT structure that holds the control\r
+ * position and size after the layout update\r
+ * \r
+ * @return The return value is @c TRUE if the control should be freshly\r
+ * painted after a layout update, @c FALSE if not necessary.\r
+ *\r
+ * @remarks The default implementation tries to identify windows that\r
+ * need refresh by their class name and window style.\r
+ * @n Override this function if you need a different behavior or if\r
+ * you have custom controls that fail to be identified.\r
+ *\r
+ * @sa LikesClipping InitResizeProperties\r
+ */\r
+BOOL CResizableLayout::NeedsRefresh(const LAYOUTINFO& layout,\r
+ const CRect& rectOld, const CRect& rectNew) const\r
+{\r
+ if (layout.bMsgSupport)\r
+ {\r
+ REFRESHPROPERTY refresh;\r
+ refresh.rcOld = rectOld;\r
+ refresh.rcNew = rectNew;\r
+ if (Send_NeedsRefresh(layout.hWnd, &refresh))\r
+ return refresh.bNeedsRefresh;\r
+ }\r
+\r
+ int nDiffWidth = (rectNew.Width() - rectOld.Width());\r
+ int nDiffHeight = (rectNew.Height() - rectOld.Height());\r
+\r
+ // is the same size?\r
+ if (nDiffWidth == 0 && nDiffHeight == 0)\r
+ return FALSE;\r
+\r
+ // optimistic, no need to refresh\r
+ BOOL bRefresh = FALSE;\r
+\r
+ // window classes that need refresh when resized\r
+ if (0 == lstrcmp(layout.sWndClass, WC_STATIC))\r
+ {\r
+ DWORD style = ::GetWindowLong(layout.hWnd, GWL_STYLE);\r
+\r
+ switch (style & SS_TYPEMASK)\r
+ {\r
+ case SS_LEFT:\r
+ case SS_CENTER:\r
+ case SS_RIGHT:\r
+ // word-wrapped text\r
+ bRefresh = bRefresh || (nDiffWidth != 0);\r
+ // vertically centered text\r
+ if (style & SS_CENTERIMAGE)\r
+ bRefresh = bRefresh || (nDiffHeight != 0);\r
+ break;\r
+\r
+ case SS_LEFTNOWORDWRAP:\r
+ // text with ellipsis\r
+ if (style & SS_ELLIPSISMASK)\r
+ bRefresh = bRefresh || (nDiffWidth != 0);\r
+ // vertically centered text\r
+ if (style & SS_CENTERIMAGE)\r
+ bRefresh = bRefresh || (nDiffHeight != 0);\r
+ break;\r
+\r
+ case SS_ENHMETAFILE:\r
+ case SS_BITMAP:\r
+ case SS_ICON:\r
+ // images\r
+ case SS_BLACKFRAME:\r
+ case SS_GRAYFRAME:\r
+ case SS_WHITEFRAME:\r
+ case SS_ETCHEDFRAME:\r
+ // and frames\r
+ bRefresh = TRUE;\r
+ break;\r
+ }\r
+ return bRefresh;\r
+ }\r
+\r
+ // window classes that don't redraw client area correctly\r
+ // when the hor scroll pos changes due to a resizing\r
+ BOOL bHScroll = FALSE;\r
+ if (0 == lstrcmp(layout.sWndClass, WC_LISTBOX))\r
+ bHScroll = TRUE;\r
+\r
+ // fix for horizontally scrollable windows, if wider\r
+ if (bHScroll && (nDiffWidth > 0))\r
+ {\r
+ // get max scroll position\r
+ SCROLLINFO info;\r
+ info.cbSize = sizeof(SCROLLINFO);\r
+ info.fMask = SIF_PAGE | SIF_POS | SIF_RANGE;\r
+ if (::GetScrollInfo(layout.hWnd, SB_HORZ, &info))\r
+ {\r
+ // subtract the page size\r
+ info.nMax -= __max(info.nPage - 1, 0);\r
+ }\r
+\r
+ // resizing will cause the text to scroll on the right\r
+ // because the scrollbar is going beyond the right limit\r
+ if ((info.nMax > 0) && (info.nPos + nDiffWidth > info.nMax))\r
+ {\r
+ // needs repainting, due to horiz scrolling\r
+ bRefresh = TRUE;\r
+ }\r
+ }\r
+\r
+ return bRefresh;\r
+}\r
+\r
+/*!\r
+ * This function is used to determine if a control can be safely clipped\r
+ * out of the parent window client area when it is repainted, usually\r
+ * after a resize operation.\r
+ * \r
+ * @param layout Reference to a @c LAYOUTINFO structure for the control\r
+ * \r
+ * @return The return value is @c TRUE if clipping is supported by the\r
+ * control, @c FALSE otherwise.\r
+ *\r
+ * @remarks The default implementation tries to identify @a clippable\r
+ * windows by their class name and window style.\r
+ * @n Override this function if you need a different behavior or if\r
+ * you have custom controls that fail to be identified.\r
+ *\r
+ * @sa NeedsRefresh InitResizeProperties\r
+ */\r
+BOOL CResizableLayout::LikesClipping(const LAYOUTINFO& layout) const\r
+{\r
+ if (layout.bMsgSupport)\r
+ {\r
+ CLIPPINGPROPERTY clipping;\r
+ if (Send_LikesClipping(layout.hWnd, &clipping))\r
+ return clipping.bLikesClipping;\r
+ }\r
+\r
+ DWORD style = ::GetWindowLong(layout.hWnd, GWL_STYLE);\r
+\r
+ // skip windows that wants background repainted\r
+ if (0 == lstrcmp(layout.sWndClass, WC_BUTTON))\r
+ {\r
+ CRect rect;\r
+ switch (style & _BS_TYPEMASK)\r
+ {\r
+ case BS_GROUPBOX:\r
+ return FALSE;\r
+\r
+ case BS_OWNERDRAW:\r
+ // ownerdraw buttons must return correct hittest code\r
+ // to notify their transparency to the system and this library\r
+ // or they could use the registered message (more reliable)\r
+ ::GetWindowRect(layout.hWnd, &rect);\r
+ ::SendMessage(layout.hWnd, WM_NCCALCSIZE, FALSE, (LPARAM)&rect);\r
+ if ( HTTRANSPARENT == ::SendMessage(layout.hWnd,\r
+ WM_NCHITTEST, 0, MAKELPARAM(rect.left, rect.top)) )\r
+ return FALSE;\r
+ break;\r
+ }\r
+ return TRUE;\r
+ }\r
+ else if (0 == lstrcmp(layout.sWndClass, WC_STATIC))\r
+ {\r
+ switch (style & SS_TYPEMASK)\r
+ {\r
+ case SS_LEFT:\r
+ case SS_CENTER:\r
+ case SS_RIGHT:\r
+ case SS_LEFTNOWORDWRAP:\r
+ // text\r
+ case SS_BLACKRECT:\r
+ case SS_GRAYRECT:\r
+ case SS_WHITERECT:\r
+ // filled rects\r
+ case SS_ETCHEDHORZ:\r
+ case SS_ETCHEDVERT:\r
+ // etched lines\r
+ case SS_BITMAP:\r
+ // bitmaps\r
+ return TRUE;\r
+ break;\r
+\r
+ case SS_ICON:\r
+ case SS_ENHMETAFILE:\r
+ if (style & SS_CENTERIMAGE)\r
+ return FALSE;\r
+ return TRUE;\r
+ break;\r
+\r
+ default:\r
+ return FALSE;\r
+ }\r
+ }\r
+\r
+ // assume the others like clipping\r
+ return TRUE;\r
+}\r
+\r
+\r
+/*!\r
+ * @internal This function calculates the new size and position of a\r
+ * control in the layout and flags for @c SetWindowPos\r
+ */\r
+void CResizableLayout::CalcNewChildPosition(const LAYOUTINFO& layout,\r
+ const CRect &rectParent, CRect &rectChild, UINT& uFlags) const\r
+{\r
+ CWnd* pParent = GetResizableWnd();\r
+\r
+ ::GetWindowRect(layout.hWnd, &rectChild);\r
+ ::MapWindowPoints(NULL, pParent->m_hWnd, (LPPOINT)&rectChild, 2);\r
+ \r
+ CRect rectNew;\r
+\r
+ // calculate new top-left corner\r
+ rectNew.left = layout.marginTopLeft.cx + rectParent.Width() * layout.anchorTopLeft.cx / 100;\r
+ rectNew.top = layout.marginTopLeft.cy + rectParent.Height() * layout.anchorTopLeft.cy / 100;\r
+ \r
+ // calculate new bottom-right corner\r
+ rectNew.right = layout.marginBottomRight.cx + rectParent.Width() * layout.anchorBottomRight.cx / 100;\r
+ rectNew.bottom = layout.marginBottomRight.cy + rectParent.Height() * layout.anchorBottomRight.cy / 100;\r
+\r
+ // adjust position, if client area has been scrolled\r
+ rectNew.OffsetRect(rectParent.TopLeft());\r
+\r
+ // get the refresh property\r
+ BOOL bRefresh = layout.properties.bAskRefresh ?\r
+ NeedsRefresh(layout, rectChild, rectNew) : layout.properties.bCachedNeedsRefresh;\r
+\r
+ // set flags \r
+ uFlags = SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREPOSITION;\r
+ if (bRefresh)\r
+ uFlags |= SWP_NOCOPYBITS;\r
+ if (rectNew.TopLeft() == rectChild.TopLeft())\r
+ uFlags |= SWP_NOMOVE;\r
+ if (rectNew.Size() == rectChild.Size())\r
+ uFlags |= SWP_NOSIZE;\r
+\r
+ // update rect\r
+ rectChild = rectNew;\r
+}\r
+\r
+/*!\r
+ * This function calculates the top, left, bottom, right margins for a\r
+ * given size of the specified control.\r
+ * \r
+ * @param hWnd Window handle to a control in the layout\r
+ * @param sizeChild Size of the control to use in calculations\r
+ * @param rectMargins Holds the calculated margins\r
+ * \r
+ * @return The return value is @c TRUE if successful, @c FALSE otherwise\r
+ *\r
+ * @remarks This function can be used to infer the parent window size\r
+ * from the size of one of its child controls.\r
+ * It is used to implement cascading of size constraints.\r
+ */\r
+BOOL CResizableLayout::GetAnchorMargins(HWND hWnd, const CSize &sizeChild, CRect &rectMargins) const\r
+{\r
+ POSITION pos;\r
+ if (!m_mapLayout.Lookup(hWnd, pos))\r
+ return FALSE;\r
+\r
+ const LAYOUTINFO& layout = m_listLayout.GetAt(pos);\r
+\r
+ // augmented size, relative to anchor points\r
+ CSize size = sizeChild + layout.marginTopLeft - layout.marginBottomRight;\r
+\r
+ // percent of parent size occupied by this control\r
+ CSize percent(layout.anchorBottomRight.cx - layout.anchorTopLeft.cx,\r
+ layout.anchorBottomRight.cy - layout.anchorTopLeft.cy);\r
+\r
+ // calculate total margins\r
+ rectMargins.left = size.cx * layout.anchorTopLeft.cx / percent.cx + layout.marginTopLeft.cx;\r
+ rectMargins.top = size.cy * layout.anchorTopLeft.cy / percent.cy + layout.marginTopLeft.cy;\r
+ rectMargins.right = size.cx * (100 - layout.anchorBottomRight.cx) / percent.cx - layout.marginBottomRight.cx;\r
+ rectMargins.bottom = size.cy * (100 - layout.anchorBottomRight.cy) / percent.cy - layout.marginBottomRight.cy;\r
+\r
+ return TRUE;\r
+}\r
+\r
+/*!\r
+ * This function is used to set the initial resize properties of a control\r
+ * in the layout, that are stored in the @c properties member of the\r
+ * related @c LAYOUTINFO structure.\r
+ * \r
+ * @param layout Reference to the @c LAYOUTINFO structure to be set\r
+ *\r
+ * @remarks The various flags are used to specify whether the resize\r
+ * properties (clipping, refresh) can change at run-time, and a new\r
+ * call to the property querying functions is needed at every\r
+ * layout update, or they are static properties, and the cached\r
+ * value is used whenever necessary.\r
+ * @n The default implementation sends a registered message to the \r
+ * control, giving it the opportunity to specify its resize\r
+ * properties, which takes precedence if the message is supported.\r
+ * It then sets the @a clipping property as static, calling\r
+ * @c LikesClipping only once, and the @a refresh property as\r
+ * dynamic, causing @c NeedsRefresh to be called every time.\r
+ * @n This should be right for most situations, as the need for\r
+ * @a refresh usually depends on the size fo a control, while the\r
+ * support for @a clipping is usually linked to the specific type\r
+ * of control, which is unlikely to change at run-time, but you can\r
+ * still override this function if a different beahvior is needed.\r
+ *\r
+ * @sa LikesClipping NeedsRefresh LAYOUTINFO RESIZEPROPERTIES\r
+ */\r
+void CResizableLayout::InitResizeProperties(LAYOUTINFO &layout) const\r
+{\r
+ // check if custom window supports this library\r
+ // (properties must be correctly set by the window)\r
+ layout.bMsgSupport = Send_QueryProperties(layout.hWnd, &layout.properties);\r
+\r
+ // default properties\r
+ if (!layout.bMsgSupport)\r
+ {\r
+ // clipping property is assumed as static\r
+ layout.properties.bAskClipping = FALSE;\r
+ layout.properties.bCachedLikesClipping = LikesClipping(layout);\r
+ // refresh property is assumed as dynamic\r
+ layout.properties.bAskRefresh = TRUE;\r
+ }\r
+}\r
+\r
+/*!\r
+ * This function modifies a window to enable resizing functionality.\r
+ * This affects the window style, size, system menu and appearance.\r
+ * \r
+ * @param lpCreateStruct Pointer to a @c CREATESTRUCT structure, usually\r
+ * passed by the system to the window procedure in a @c WM_CREATE\r
+ * or @c WM_NCCREATE\r
+ * \r
+ * @remarks The function is intended to be called only inside a @c WM_CREATE\r
+ * or @c WM_NCCREATE message handler.\r
+ */\r
+void CResizableLayout::MakeResizable(LPCREATESTRUCT lpCreateStruct)\r
+{\r
+ if (lpCreateStruct->style & WS_CHILD)\r
+ return;\r
+\r
+ CWnd* pWnd = GetResizableWnd();\r
+\r
+#if (_WIN32_WINNT >= 0x0501 && !defined(RSZLIB_NO_XP_DOUBLE_BUFFER))\r
+ // enable double-buffering on supported platforms\r
+ pWnd->ModifyStyleEx(0, WS_EX_COMPOSITED);\r
+#endif\r
+\r
+ if (!(lpCreateStruct->style & WS_THICKFRAME))\r
+ {\r
+ // set resizable style\r
+ pWnd->ModifyStyle(DS_MODALFRAME, WS_THICKFRAME);\r
+ // keep client area\r
+ CRect rect(CPoint(lpCreateStruct->x, lpCreateStruct->y),\r
+ CSize(lpCreateStruct->cx, lpCreateStruct->cy));\r
+ pWnd->SendMessage(WM_NCCALCSIZE, FALSE, (LPARAM)&rect);\r
+ // adjust size to reflect new style\r
+ ::AdjustWindowRectEx(&rect, pWnd->GetStyle(),\r
+ ::IsMenu(pWnd->GetMenu()->GetSafeHmenu()), pWnd->GetExStyle());\r
+ pWnd->SetWindowPos(NULL, 0, 0, rect.Width(), rect.Height(),\r
+ SWP_NOSENDCHANGING|SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOREPOSITION);\r
+ // update dimensions\r
+ lpCreateStruct->cx = rect.Width();\r
+ lpCreateStruct->cy = rect.Height();\r
+ }\r
+}\r
+\r
+/*!\r
+ * This function should be called inside the parent window @c WM_NCCALCSIZE\r
+ * message handler to help eliminate flickering.\r
+ * \r
+ * @param bAfterDefault Flag that specifies wether the call is made before\r
+ * or after the default handler\r
+ * @param lpncsp Pointer to the @c NCCALCSIZE_PARAMS structure that is\r
+ * passed to the message handler\r
+ * @param lResult Reference to the result of the message handler.\r
+ * It contains the default handler result on input and the value to\r
+ * return from the window procedure on output.\r
+ * \r
+ * @remarks This function fixes the annoying flickering effect that is\r
+ * visible when resizing the top or left edges of the window\r
+ * (at least on a "left to right" Windows localized version).\r
+ */\r
+void CResizableLayout::HandleNcCalcSize(BOOL bAfterDefault, LPNCCALCSIZE_PARAMS lpncsp, LRESULT &lResult)\r
+{\r
+ // prevent useless complication when size is not changing\r
+ // prevent recursion when resetting the window region (see below)\r
+ if ((lpncsp->lppos->flags & SWP_NOSIZE)\r
+#if (_WIN32_WINNT >= 0x0501)\r
+ || m_bNoRecursion\r
+#endif\r
+ )\r
+ return;\r
+\r
+ if (!bAfterDefault)\r
+ {\r
+ // save a copy before default handler gets called\r
+ m_rectClientBefore = lpncsp->rgrc[2];\r
+ }\r
+ else // after default WM_NCCALCSIZE msg processing\r
+ {\r
+ if (lResult != 0)\r
+ {\r
+ // default handler already uses an advanced validation policy, give up\r
+ return;\r
+ }\r
+ // default calculated client rect\r
+ RECT &rectClientAfter = lpncsp->rgrc[0];\r
+\r
+ // intersection between old and new client area is to be preserved\r
+ // set source and destination rects to this intersection\r
+ RECT &rectPreserve = lpncsp->rgrc[1];\r
+ ::IntersectRect(&rectPreserve, &rectClientAfter, &m_rectClientBefore);\r
+ lpncsp->rgrc[2] = rectPreserve;\r
+\r
+ lResult = WVR_VALIDRECTS;\r
+\r
+ // FIX: window region must be updated before the result of the\r
+ // WM_NCCALCSIZE message gets processed by the system,\r
+ // otherwise the old window region will clip the client\r
+ // area during the preservation process.\r
+ // This is especially evident on WinXP when the non-client\r
+ // area is rendered with Visual Styles enabled and the\r
+ // windows have a non rectangular region.\r
+#if (_WIN32_WINNT >= 0x0501)\r
+ //! @todo change rt check to only if themed frame. what about custom wnd region?\r
+ if (real_WIN32_WINNT >= 0x0501)\r
+ {\r
+ CWnd* pWnd = GetResizableWnd();\r
+ DWORD dwStyle = pWnd->GetStyle();\r
+ if ((dwStyle & (WS_CAPTION|WS_MAXIMIZE)) == WS_CAPTION)\r
+ {\r
+ m_bNoRecursion = TRUE;\r
+ pWnd->SetWindowRgn(NULL, FALSE);\r
+ m_bNoRecursion = FALSE;\r
+ }\r
+ }\r
+#endif\r
+ }\r
+}\r
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// This file is part of ResizableLib\r
+// http://sourceforge.net/projects/resizablelib\r
+//\r
+// Copyright (C) 2000-2004 by Paolo Messina\r
+// http://www.geocities.com/ppescher - mailto:ppescher@hotmail.com\r
+//\r
+// The contents of this file are subject to the Artistic License (the "License").\r
+// You may not use this file except in compliance with the License. \r
+// You may obtain a copy of the License at:\r
+// http://www.opensource.org/licenses/artistic-license.html\r
+//\r
+// If you find this code useful, credits would be nice!\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+/*!\r
+ * @file\r
+ * @brief Interface for the CResizableLayout class.\r
+ */\r
+\r
+#if !defined(AFX_RESIZABLELAYOUT_H__INCLUDED_)\r
+#define AFX_RESIZABLELAYOUT_H__INCLUDED_\r
+\r
+#include <afxtempl.h>\r
+#include "ResizableMsgSupport.h"\r
+\r
+#if _MSC_VER > 1000\r
+#pragma once\r
+#endif // _MSC_VER > 1000\r
+\r
+/*! @addtogroup CoreComponents\r
+ * @{\r
+ */\r
+\r
+//! @brief Special type for layout alignment\r
+/*!\r
+ * Implements anchor points as a percentage of the parent window client area.\r
+ * Control corners are always kept at a fixed distance from their anchor points,\r
+ * thus allowing a control to resize proportionally as the parent window is resized.\r
+ */\r
+typedef struct tagANCHOR\r
+{\r
+ int cx; //!< horizontal component, in percent\r
+ int cy; //!< vertical component, in percent\r
+\r
+ tagANCHOR() {}\r
+\r
+ tagANCHOR(int x, int y)\r
+ {\r
+ cx = x;\r
+ cy = y;\r
+ }\r
+\r
+} ANCHOR, *PANCHOR, *LPANCHOR;\r
+\r
+/*! @defgroup ConstAnchors Alignment Constants\r
+ * Define common layout alignment constants for anchor points.\r
+ * @{\r
+ */\r
+ //! Anchor to the top-left corner\r
+ const ANCHOR TOP_LEFT(0, 0);\r
+ //! Anchor to the top edge and center horizontally\r
+ const ANCHOR TOP_CENTER(50, 0);\r
+ //! Anchor to the top-right corner\r
+ const ANCHOR TOP_RIGHT(100, 0);\r
+ //! Anchor to the left edge and center vertically\r
+ const ANCHOR MIDDLE_LEFT(0, 50);\r
+ //! Anchor to the center\r
+ const ANCHOR MIDDLE_CENTER(50, 50);\r
+ //! Anchor to the right edge and center vertically\r
+ const ANCHOR MIDDLE_RIGHT(100, 50);\r
+ //! Anchor to the bottom-left corner\r
+ const ANCHOR BOTTOM_LEFT(0, 100);\r
+ //! Anchor to the bottom edge and center horizontally\r
+ const ANCHOR BOTTOM_CENTER(50, 100);\r
+ //! Anchor to the bottom-right corner\r
+ const ANCHOR BOTTOM_RIGHT(100, 100);\r
+// @}\r
+\r
+//! @brief Holds a control layout settings\r
+/*!\r
+ * Layout settings specify how a control must be moved and resized with respect to\r
+ * the parent window and how it reacts to dynamic changes to its size when painting\r
+ * its client area, with special care for flickering.\r
+ */\r
+typedef struct tagLAYOUTINFO\r
+{\r
+ //! Handle of the window the layout of which is being defined\r
+ HWND hWnd;\r
+ //! Identification number assigned to the callback slot\r
+ UINT_PTR nCallbackID;\r
+\r
+ //! Window class name to identify standard controls\r
+ TCHAR sWndClass[MAX_PATH];\r
+\r
+ //! Anchor point for the top-left corner\r
+ ANCHOR anchorTopLeft;\r
+ //! Fixed distance for the top-left corner\r
+ SIZE marginTopLeft;\r
+ \r
+ //! Anchor point for the bottom-right corner\r
+ ANCHOR anchorBottomRight;\r
+ //! Fixed distance for the bottom-right corner\r
+ SIZE marginBottomRight;\r
+\r
+ //! Flag that enables support for custom windows\r
+ BOOL bMsgSupport;\r
+ //! Redraw settings for anti-flickering and proper painting\r
+ RESIZEPROPERTIES properties;\r
+\r
+ tagLAYOUTINFO() : hWnd(NULL), nCallbackID(0), bMsgSupport(FALSE)\r
+ {\r
+ sWndClass[0] = 0;\r
+ }\r
+\r
+ tagLAYOUTINFO(HWND hwnd, ANCHOR tl_type, SIZE tl_margin, \r
+ ANCHOR br_type, SIZE br_margin)\r
+ :\r
+ hWnd(hwnd), nCallbackID(0), bMsgSupport(FALSE),\r
+ anchorTopLeft(tl_type), marginTopLeft(tl_margin),\r
+ anchorBottomRight(br_type), marginBottomRight(br_margin)\r
+ {\r
+ sWndClass[0] = 0;\r
+ }\r
+\r
+} LAYOUTINFO, *PLAYOUTINFO, *LPLAYOUTINFO;\r
+\r
+//! @brief Layout manager implementation\r
+/*!\r
+ * Derive from this class to implement resizable windows, adding the ability\r
+ * to dinamically resize and reposition child controls.\r
+ * Special care is taken to ensure a smooth animation during the resize\r
+ * operations performed by the users, without annoying flickering effects.\r
+ */\r
+class CResizableLayout\r
+{\r
+private:\r
+ //@{\r
+ //! @brief Collection of layout settings for each control\r
+ CMap<HWND, HWND, POSITION, POSITION> m_mapLayout;\r
+ CList<LAYOUTINFO, LAYOUTINFO&> m_listLayout;\r
+ CList<LAYOUTINFO, LAYOUTINFO&> m_listLayoutCB;\r
+ //@}\r
+\r
+ //@{\r
+ //! @brief Used for clipping implementation\r
+ HRGN m_hOldClipRgn;\r
+ int m_nOldClipRgn;\r
+ //@}\r
+\r
+ //@{\r
+ //! @brief Used for advanced anti-flickering\r
+ RECT m_rectClientBefore;\r
+ BOOL m_bNoRecursion;\r
+ //@}\r
+\r
+ //! @brief Apply clipping settings for the specified control\r
+ void ClipChildWindow(const LAYOUTINFO &layout, CRgn* pRegion) const;\r
+\r
+ //! @brief Helper function to calculate new layout\r
+ void CalcNewChildPosition(const LAYOUTINFO &layout,\r
+ const CRect &rectParent, CRect &rectChild, UINT& uFlags) const;\r
+\r
+protected:\r
+ //! @brief Override to initialize resize properties (clipping, refresh)\r
+ virtual void InitResizeProperties(LAYOUTINFO& layout) const;\r
+\r
+ //! @brief Override to specify clipping for unsupported windows\r
+ virtual BOOL LikesClipping(const LAYOUTINFO &layout) const;\r
+\r
+ //! @brief Override to specify refresh for unsupported windows\r
+ virtual BOOL NeedsRefresh(const LAYOUTINFO &layout,\r
+ const CRect &rectOld, const CRect &rectNew) const;\r
+\r
+ //! @brief Clip controls in the layout out of the specified device context\r
+ BOOL ClipChildren(CDC* pDC, BOOL bUndo);\r
+\r
+ //! @brief Get the layout clipping region\r
+ void GetClippingRegion(CRgn* pRegion) const;\r
+ \r
+ //! @brief Override for scrollable or expanding parent windows\r
+ virtual void GetTotalClientRect(LPRECT lpRect) const;\r
+\r
+ //@{\r
+ //! @brief Add anchor points for the specified control to the layout\r
+ void AddAnchor(HWND hWnd, ANCHOR anchorTopLeft, ANCHOR anchorBottomRight);\r
+\r
+ void AddAnchor(HWND hWnd, ANCHOR anchorTopLeft)\r
+ {\r
+ AddAnchor(hWnd, anchorTopLeft, anchorTopLeft);\r
+ }\r
+\r
+ void AddAnchor(UINT nID, ANCHOR anchorTopLeft, ANCHOR anchorBottomRight)\r
+ {\r
+ AddAnchor(::GetDlgItem(GetResizableWnd()->GetSafeHwnd(), nID),\r
+ anchorTopLeft, anchorBottomRight);\r
+ }\r
+\r
+ void AddAnchor(UINT nID, ANCHOR anchorTopLeft)\r
+ {\r
+ AddAnchor(::GetDlgItem(GetResizableWnd()->GetSafeHwnd(), nID),\r
+ anchorTopLeft, anchorTopLeft);\r
+ }\r
+ //@}\r
+\r
+ //! @brief Add a callback slot to the layout for dynamic controls or anchor points\r
+ UINT_PTR AddAnchorCallback();\r
+\r
+ //@{\r
+ //! @brief Get position and size of a control in the layout from the parent's client area\r
+ BOOL GetAnchorPosition(HWND hWnd, const CRect &rectParent,\r
+ CRect &rectChild, UINT* lpFlags = NULL) const\r
+ {\r
+ POSITION pos;\r
+ if (!m_mapLayout.Lookup(hWnd, pos))\r
+ return FALSE;\r
+\r
+ UINT uTmpFlags;\r
+ CalcNewChildPosition(m_listLayout.GetAt(pos), rectParent, rectChild,\r
+ (lpFlags != NULL) ? (*lpFlags) : uTmpFlags);\r
+ return TRUE;\r
+ }\r
+\r
+ BOOL GetAnchorPosition(UINT nID, const CRect &rectParent,\r
+ CRect &rectChild, UINT* lpFlags = NULL) const\r
+ {\r
+ return GetAnchorPosition(::GetDlgItem(GetResizableWnd()->GetSafeHwnd(), nID),\r
+ rectParent, rectChild, lpFlags);\r
+ }\r
+ //@}\r
+\r
+ //@{\r
+ //! @brief Get margins surrounding a control in the layout with the given size\r
+ BOOL GetAnchorMargins(HWND hWnd, const CSize &sizeChild, CRect &rectMargins) const;\r
+\r
+ BOOL GetAnchorMargins(UINT nID, const CSize &sizeChild, CRect &rectMargins) const\r
+ {\r
+ return GetAnchorMargins(::GetDlgItem(GetResizableWnd()->GetSafeHwnd(), nID),\r
+ sizeChild, rectMargins);\r
+ }\r
+ //@}\r
+\r
+ //@{\r
+ //! @brief Remove a control from the layout\r
+ BOOL RemoveAnchor(HWND hWnd)\r
+ {\r
+ POSITION pos;\r
+ if (!m_mapLayout.Lookup(hWnd, pos))\r
+ return FALSE;\r
+\r
+ m_listLayout.RemoveAt(pos);\r
+ return m_mapLayout.RemoveKey(hWnd);\r
+ }\r
+\r
+ BOOL RemoveAnchor(UINT nID)\r
+ {\r
+ return RemoveAnchor(::GetDlgItem(GetResizableWnd()->GetSafeHwnd(), nID));\r
+ }\r
+ //@}\r
+\r
+ //! @brief Reset the layout content\r
+ void RemoveAllAnchors()\r
+ {\r
+ m_mapLayout.RemoveAll();\r
+ m_listLayout.RemoveAll();\r
+ m_listLayoutCB.RemoveAll();\r
+ }\r
+\r
+ //! @brief Reposition and size all the controls in the layout\r
+ void ArrangeLayout() const;\r
+\r
+ //! @brief Override to provide dynamic control's layout info\r
+ virtual BOOL ArrangeLayoutCallback(LAYOUTINFO& layout) const;\r
+\r
+ //! @brief Override to provide the parent window\r
+ virtual CWnd* GetResizableWnd() const = 0;\r
+\r
+ //! @brief Enhance anti-flickering\r
+ void HandleNcCalcSize(BOOL bAfterDefault, LPNCCALCSIZE_PARAMS lpncsp, LRESULT& lResult);\r
+ \r
+ //! @brief Enable resizable style for top level parent windows\r
+ void MakeResizable(LPCREATESTRUCT lpCreateStruct);\r
+\r
+public:\r
+ CResizableLayout()\r
+ {\r
+ m_bNoRecursion = FALSE;\r
+ m_hOldClipRgn = ::CreateRectRgn(0,0,0,0);\r
+ m_nOldClipRgn = 0;\r
+ }\r
+\r
+ virtual ~CResizableLayout()\r
+ {\r
+ // just for safety\r
+ RemoveAllAnchors();\r
+\r
+ DeleteObject(m_hOldClipRgn); \r
+ }\r
+};\r
+\r
+// @}\r
+#endif // !defined(AFX_RESIZABLELAYOUT_H__INCLUDED_)\r
--- /dev/null
+<?xml version="1.0" encoding="Windows-1252"?>\r
+<VisualStudioProject\r
+ ProjectType="Visual C++"\r
+ Version="9.00"\r
+ Name="ResizableLib"\r
+ ProjectGUID="{4BE529FB-C2F2-49F7-A897-054B955564CF}"\r
+ RootNamespace="ResizableLib"\r
+ Keyword="MFCProj"\r
+ TargetFrameworkVersion="131072"\r
+ >\r
+ <Platforms>\r
+ <Platform\r
+ Name="Win32"\r
+ />\r
+ <Platform\r
+ Name="x64"\r
+ />\r
+ </Platforms>\r
+ <ToolFiles>\r
+ </ToolFiles>\r
+ <Configurations>\r
+ <Configuration\r
+ Name="Release|Win32"\r
+ OutputDirectory="..\..\obj\ResizableLib\Release"\r
+ IntermediateDirectory="..\..\obj\ResizableLib\Release"\r
+ ConfigurationType="4"\r
+ UseOfMFC="2"\r
+ ATLMinimizesCRunTimeLibraryUsage="false"\r
+ CharacterSet="1"\r
+ WholeProgramOptimization="1"\r
+ >\r
+ <Tool\r
+ Name="VCPreBuildEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ />\r
+ <Tool\r
+ Name="VCXMLDataGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebServiceProxyGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCMIDLTool"\r
+ />\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ Optimization="3"\r
+ InlineFunctionExpansion="1"\r
+ FavorSizeOrSpeed="2"\r
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"\r
+ StringPooling="true"\r
+ RuntimeLibrary="2"\r
+ EnableFunctionLevelLinking="true"\r
+ TreatWChar_tAsBuiltInType="true"\r
+ ForceConformanceInForLoopScope="true"\r
+ UsePrecompiledHeader="2"\r
+ PrecompiledHeaderThrough="stdafx.h"\r
+ PrecompiledHeaderFile="$(IntDir)/$(TargetName).pch"\r
+ AssemblerListingLocation=""\r
+ ObjectFile="$(IntDir)/"\r
+ ProgramDataBaseFileName="$(IntDir)/vc70.pdb"\r
+ WarningLevel="4"\r
+ SuppressStartupBanner="true"\r
+ />\r
+ <Tool\r
+ Name="VCManagedResourceCompilerTool"\r
+ />\r
+ <Tool\r
+ Name="VCResourceCompilerTool"\r
+ PreprocessorDefinitions="_AFXDLL;NDEBUG"\r
+ Culture="0"\r
+ />\r
+ <Tool\r
+ Name="VCPreLinkEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCLibrarianTool"\r
+ OutputFile="$(OutDir)/$(ProjectName).lib"\r
+ SuppressStartupBanner="true"\r
+ />\r
+ <Tool\r
+ Name="VCALinkTool"\r
+ />\r
+ <Tool\r
+ Name="VCXDCMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCBscMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCFxCopTool"\r
+ />\r
+ <Tool\r
+ Name="VCPostBuildEventTool"\r
+ />\r
+ </Configuration>\r
+ <Configuration\r
+ Name="Debug|Win32"\r
+ OutputDirectory="..\obj\ResizableLib\Debug"\r
+ IntermediateDirectory="..\obj\ResizableLib\Debug"\r
+ ConfigurationType="4"\r
+ UseOfMFC="2"\r
+ ATLMinimizesCRunTimeLibraryUsage="false"\r
+ CharacterSet="1"\r
+ >\r
+ <Tool\r
+ Name="VCPreBuildEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ />\r
+ <Tool\r
+ Name="VCXMLDataGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebServiceProxyGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCMIDLTool"\r
+ />\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ Optimization="0"\r
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"\r
+ BasicRuntimeChecks="0"\r
+ RuntimeLibrary="3"\r
+ DisableLanguageExtensions="false"\r
+ TreatWChar_tAsBuiltInType="true"\r
+ ForceConformanceInForLoopScope="true"\r
+ UsePrecompiledHeader="2"\r
+ PrecompiledHeaderThrough="stdafx.h"\r
+ PrecompiledHeaderFile="$(IntDir)/$(TargetName).pch"\r
+ AssemblerListingLocation=""\r
+ ObjectFile="$(IntDir)/"\r
+ ProgramDataBaseFileName="$(IntDir)/vc70.pdb"\r
+ WarningLevel="4"\r
+ SuppressStartupBanner="true"\r
+ DebugInformationFormat="4"\r
+ />\r
+ <Tool\r
+ Name="VCManagedResourceCompilerTool"\r
+ />\r
+ <Tool\r
+ Name="VCResourceCompilerTool"\r
+ PreprocessorDefinitions="_AFXDLL;_DEBUG"\r
+ Culture="0"\r
+ />\r
+ <Tool\r
+ Name="VCPreLinkEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCLibrarianTool"\r
+ OutputFile="$(OutDir)/$(ProjectName).lib"\r
+ SuppressStartupBanner="true"\r
+ />\r
+ <Tool\r
+ Name="VCALinkTool"\r
+ />\r
+ <Tool\r
+ Name="VCXDCMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCBscMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCFxCopTool"\r
+ />\r
+ <Tool\r
+ Name="VCPostBuildEventTool"\r
+ />\r
+ </Configuration>\r
+ <Configuration\r
+ Name="Release|x64"\r
+ OutputDirectory="..\..\obj\ResizableLib\Release64"\r
+ IntermediateDirectory="..\..\obj\ResizableLib\Release64"\r
+ ConfigurationType="4"\r
+ UseOfMFC="2"\r
+ ATLMinimizesCRunTimeLibraryUsage="false"\r
+ CharacterSet="1"\r
+ WholeProgramOptimization="1"\r
+ >\r
+ <Tool\r
+ Name="VCPreBuildEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ />\r
+ <Tool\r
+ Name="VCXMLDataGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebServiceProxyGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCMIDLTool"\r
+ TargetEnvironment="3"\r
+ />\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ Optimization="3"\r
+ InlineFunctionExpansion="1"\r
+ FavorSizeOrSpeed="2"\r
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"\r
+ StringPooling="true"\r
+ RuntimeLibrary="2"\r
+ EnableFunctionLevelLinking="true"\r
+ TreatWChar_tAsBuiltInType="true"\r
+ ForceConformanceInForLoopScope="true"\r
+ UsePrecompiledHeader="2"\r
+ PrecompiledHeaderThrough="stdafx.h"\r
+ PrecompiledHeaderFile="$(IntDir)/$(TargetName).pch"\r
+ AssemblerListingLocation=""\r
+ ObjectFile="$(IntDir)/"\r
+ ProgramDataBaseFileName="$(IntDir)/vc70.pdb"\r
+ WarningLevel="4"\r
+ SuppressStartupBanner="true"\r
+ />\r
+ <Tool\r
+ Name="VCManagedResourceCompilerTool"\r
+ />\r
+ <Tool\r
+ Name="VCResourceCompilerTool"\r
+ PreprocessorDefinitions="_AFXDLL;NDEBUG"\r
+ Culture="0"\r
+ />\r
+ <Tool\r
+ Name="VCPreLinkEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCLibrarianTool"\r
+ OutputFile="$(OutDir)/$(ProjectName).lib"\r
+ SuppressStartupBanner="true"\r
+ />\r
+ <Tool\r
+ Name="VCALinkTool"\r
+ />\r
+ <Tool\r
+ Name="VCXDCMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCBscMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCFxCopTool"\r
+ />\r
+ <Tool\r
+ Name="VCPostBuildEventTool"\r
+ />\r
+ </Configuration>\r
+ <Configuration\r
+ Name="Debug|x64"\r
+ OutputDirectory="..\..\obj\ResizableLib\Debug64"\r
+ IntermediateDirectory="..\..\obj\ResizableLib\Debug64"\r
+ ConfigurationType="4"\r
+ UseOfMFC="2"\r
+ ATLMinimizesCRunTimeLibraryUsage="false"\r
+ CharacterSet="1"\r
+ >\r
+ <Tool\r
+ Name="VCPreBuildEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ />\r
+ <Tool\r
+ Name="VCXMLDataGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebServiceProxyGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCMIDLTool"\r
+ TargetEnvironment="3"\r
+ />\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ Optimization="0"\r
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"\r
+ BasicRuntimeChecks="0"\r
+ RuntimeLibrary="3"\r
+ DisableLanguageExtensions="false"\r
+ TreatWChar_tAsBuiltInType="true"\r
+ ForceConformanceInForLoopScope="true"\r
+ UsePrecompiledHeader="2"\r
+ PrecompiledHeaderThrough="stdafx.h"\r
+ PrecompiledHeaderFile="$(IntDir)/$(TargetName).pch"\r
+ AssemblerListingLocation=""\r
+ ObjectFile="$(IntDir)/"\r
+ ProgramDataBaseFileName="$(IntDir)/vc70.pdb"\r
+ WarningLevel="4"\r
+ SuppressStartupBanner="true"\r
+ DebugInformationFormat="3"\r
+ />\r
+ <Tool\r
+ Name="VCManagedResourceCompilerTool"\r
+ />\r
+ <Tool\r
+ Name="VCResourceCompilerTool"\r
+ PreprocessorDefinitions="_AFXDLL;_DEBUG"\r
+ Culture="0"\r
+ />\r
+ <Tool\r
+ Name="VCPreLinkEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCLibrarianTool"\r
+ OutputFile="$(OutDir)/$(ProjectName).lib"\r
+ SuppressStartupBanner="true"\r
+ />\r
+ <Tool\r
+ Name="VCALinkTool"\r
+ />\r
+ <Tool\r
+ Name="VCXDCMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCBscMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCFxCopTool"\r
+ />\r
+ <Tool\r
+ Name="VCPostBuildEventTool"\r
+ />\r
+ </Configuration>\r
+ </Configurations>\r
+ <References>\r
+ </References>\r
+ <Files>\r
+ <Filter\r
+ Name="Source Files"\r
+ Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"\r
+ >\r
+ <File\r
+ RelativePath=".\ResizableComboBox.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\ResizableComboLBox.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\ResizableDialog.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\ResizableFormView.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\ResizableFrame.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\ResizableGrip.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\ResizableLayout.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\ResizableMDIChild.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\ResizableMDIFrame.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\ResizableMinMax.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\ResizableMsgSupport.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\ResizablePage.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\ResizablePageEx.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\ResizableSheet.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\ResizableSheetEx.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\ResizableSheetState.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\ResizableSplitterWnd.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\ResizableState.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\ResizableVersion.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\ResizableWndState.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\StdAfx.cpp"\r
+ >\r
+ <FileConfiguration\r
+ Name="Release|Win32"\r
+ >\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ UsePrecompiledHeader="1"\r
+ />\r
+ </FileConfiguration>\r
+ <FileConfiguration\r
+ Name="Debug|Win32"\r
+ >\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ UsePrecompiledHeader="1"\r
+ />\r
+ </FileConfiguration>\r
+ <FileConfiguration\r
+ Name="Release|x64"\r
+ >\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ UsePrecompiledHeader="1"\r
+ />\r
+ </FileConfiguration>\r
+ <FileConfiguration\r
+ Name="Debug|x64"\r
+ >\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ UsePrecompiledHeader="1"\r
+ />\r
+ </FileConfiguration>\r
+ </File>\r
+ </Filter>\r
+ <Filter\r
+ Name="Header Files"\r
+ Filter="h;hpp;hxx;hm;inl"\r
+ >\r
+ <File\r
+ RelativePath=".\ResizableComboBox.h"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\ResizableComboLBox.h"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\ResizableDialog.h"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\ResizableFormView.h"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\ResizableFrame.h"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\ResizableGrip.h"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\ResizableLayout.h"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\ResizableMDIChild.h"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\ResizableMDIFrame.h"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\ResizableMinMax.h"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\ResizableMsgSupport.h"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\ResizableMsgSupport.inl"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\ResizablePage.h"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\ResizablePageEx.h"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\ResizableSheet.h"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\ResizableSheetEx.h"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\ResizableSheetState.h"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\ResizableSplitterWnd.h"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\ResizableState.h"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\ResizableVersion.h"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\ResizableWndState.h"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\StdAfx.h"\r
+ >\r
+ </File>\r
+ </Filter>\r
+ <File\r
+ RelativePath=".\Artistic-License.txt"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\ChangeLog"\r
+ >\r
+ </File>\r
+ </Files>\r
+ <Globals>\r
+ <Global\r
+ Name="DevPartner_IsInstrumented"\r
+ Value="0"\r
+ />\r
+ </Globals>\r
+</VisualStudioProject>\r
--- /dev/null
+// ResizableMDIChild.cpp : implementation file\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// This file is part of ResizableLib\r
+// http://sourceforge.net/projects/resizablelib\r
+//\r
+// Copyright (C) 2000-2004 by Paolo Messina\r
+// http://www.geocities.com/ppescher - mailto:ppescher@hotmail.com\r
+//\r
+// The contents of this file are subject to the Artistic License (the "License").\r
+// You may not use this file except in compliance with the License. \r
+// You may obtain a copy of the License at:\r
+// http://www.opensource.org/licenses/artistic-license.html\r
+//\r
+// If you find this code useful, credits would be nice!\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+#include "stdafx.h"\r
+#include "ResizableMDIChild.h"\r
+\r
+#ifdef _DEBUG\r
+#define new DEBUG_NEW\r
+#undef THIS_FILE\r
+static char THIS_FILE[] = __FILE__;\r
+#endif\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+// CResizableMDIChild\r
+\r
+IMPLEMENT_DYNCREATE(CResizableMDIChild, CMDIChildWnd)\r
+\r
+CResizableMDIChild::CResizableMDIChild()\r
+{\r
+ m_bEnableSaveRestore = FALSE;\r
+}\r
+\r
+CResizableMDIChild::~CResizableMDIChild()\r
+{\r
+}\r
+\r
+\r
+BEGIN_MESSAGE_MAP(CResizableMDIChild, CMDIChildWnd)\r
+ //{{AFX_MSG_MAP(CResizableMDIChild)\r
+ ON_WM_GETMINMAXINFO()\r
+ ON_WM_SIZE()\r
+ ON_WM_DESTROY()\r
+ ON_WM_NCCREATE()\r
+ //}}AFX_MSG_MAP\r
+END_MESSAGE_MAP()\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+// CResizableMDIChild message handlers\r
+\r
+void CResizableMDIChild::OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI) \r
+{\r
+ // MDI should call default implementation\r
+ CMDIChildWnd::OnGetMinMaxInfo(lpMMI);\r
+\r
+ MinMaxInfo(lpMMI);\r
+\r
+ CWnd* pView = GetDlgItem(AFX_IDW_PANE_FIRST);//GetActiveView();\r
+ if (pView != NULL)\r
+ ChainMinMaxInfo(lpMMI, this, pView);\r
+}\r
+\r
+void CResizableMDIChild::OnSize(UINT nType, int cx, int cy) \r
+{\r
+ CMDIChildWnd::OnSize(nType, cx, cy);\r
+\r
+/* Why was this necessary???\r
+\r
+ // make sure the MDI parent frame doesn't clip\r
+ // this child window when it is maximized\r
+ if (nType == SIZE_MAXIMIZED)\r
+ {\r
+ CMDIFrameWnd* pFrame = GetMDIFrame();\r
+\r
+ CRect rect;\r
+ pFrame->GetWindowRect(rect);\r
+ pFrame->MoveWindow(rect);\r
+ }\r
+/*/\r
+}\r
+\r
+// NOTE: this must be called after setting the layout\r
+// to have the view and its controls displayed properly\r
+BOOL CResizableMDIChild::EnableSaveRestore(LPCTSTR pszSection, BOOL bRectOnly)\r
+{\r
+ m_sSection = pszSection;\r
+\r
+ m_bEnableSaveRestore = TRUE;\r
+ m_bRectOnly = bRectOnly;\r
+\r
+ // restore immediately\r
+ return LoadWindowRect(pszSection, bRectOnly);\r
+}\r
+\r
+void CResizableMDIChild::OnDestroy() \r
+{\r
+ if (m_bEnableSaveRestore)\r
+ SaveWindowRect(m_sSection, m_bRectOnly);\r
+\r
+ CMDIChildWnd::OnDestroy();\r
+}\r
+\r
+\r
+LRESULT CResizableMDIChild::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) \r
+{\r
+ if (message != WM_NCCALCSIZE || wParam == 0)\r
+ return CMDIChildWnd::WindowProc(message, wParam, lParam);\r
+\r
+ // specifying valid rects needs controls already anchored\r
+ LRESULT lResult = 0;\r
+ HandleNcCalcSize(FALSE, (LPNCCALCSIZE_PARAMS)lParam, lResult);\r
+ lResult = CMDIChildWnd::WindowProc(message, wParam, lParam);\r
+ HandleNcCalcSize(TRUE, (LPNCCALCSIZE_PARAMS)lParam, lResult);\r
+ return lResult;\r
+}\r
+\r
+BOOL CResizableMDIChild::OnNcCreate(LPCREATESTRUCT lpCreateStruct) \r
+{\r
+ if (!CMDIChildWnd::OnNcCreate(lpCreateStruct))\r
+ return FALSE;\r
+ ModifyStyle(0, WS_CLIPCHILDREN);\r
+ return TRUE;\r
+}\r
--- /dev/null
+#if !defined(AFX_RESIZABLEMDICHILD_H__INCLUDED_)\r
+#define AFX_RESIZABLEMDICHILD_H__INCLUDED_\r
+\r
+#if _MSC_VER > 1000\r
+#pragma once\r
+#endif // _MSC_VER > 1000\r
+// ResizableMDIChild.h : header file\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// This file is part of ResizableLib\r
+// http://sourceforge.net/projects/resizablelib\r
+//\r
+// Copyright (C) 2000-2004 by Paolo Messina\r
+// http://www.geocities.com/ppescher - mailto:ppescher@hotmail.com\r
+//\r
+// The contents of this file are subject to the Artistic License (the "License").\r
+// You may not use this file except in compliance with the License. \r
+// You may obtain a copy of the License at:\r
+// http://www.opensource.org/licenses/artistic-license.html\r
+//\r
+// If you find this code useful, credits would be nice!\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+#include "ResizableMinMax.h"\r
+#include "ResizableWndState.h"\r
+#include "ResizableLayout.h"\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+// CResizableMDIChild frame\r
+\r
+class CResizableMDIChild : public CMDIChildWnd, public CResizableMinMax,\r
+ public CResizableWndState, public CResizableLayout\r
+{\r
+ DECLARE_DYNCREATE(CResizableMDIChild)\r
+protected:\r
+ CResizableMDIChild(); // protected constructor used by dynamic creation\r
+\r
+// Attributes\r
+public:\r
+\r
+// Operations\r
+public:\r
+\r
+// Overrides\r
+ // ClassWizard generated virtual function overrides\r
+ //{{AFX_VIRTUAL(CResizableMDIChild)\r
+ protected:\r
+ virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);\r
+ //}}AFX_VIRTUAL\r
+\r
+// Implementation\r
+protected:\r
+ virtual ~CResizableMDIChild();\r
+\r
+ BOOL EnableSaveRestore(LPCTSTR pszSection, BOOL bRectOnly = FALSE);\r
+\r
+ virtual CWnd* GetResizableWnd() const\r
+ {\r
+ // make the layout know its parent window\r
+ return CWnd::FromHandle(m_hWnd);\r
+ };\r
+\r
+private:\r
+ // flags\r
+ BOOL m_bEnableSaveRestore;\r
+ BOOL m_bRectOnly;\r
+\r
+ // internal status\r
+ CString m_sSection; // section name (identifies a parent window)\r
+\r
+protected:\r
+ // Generated message map functions\r
+ //{{AFX_MSG(CResizableMDIChild)\r
+ afx_msg void OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI);\r
+ afx_msg void OnSize(UINT nType, int cx, int cy);\r
+ afx_msg void OnDestroy();\r
+ afx_msg BOOL OnNcCreate(LPCREATESTRUCT lpCreateStruct);\r
+ //}}AFX_MSG\r
+ DECLARE_MESSAGE_MAP()\r
+};\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+//{{AFX_INSERT_LOCATION}}\r
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.\r
+\r
+#endif // !defined(AFX_RESIZABLEMDICHILD_H__INCLUDED_)\r
--- /dev/null
+// ResizableMDIFrame.cpp : implementation file\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// This file is part of ResizableLib\r
+// http://sourceforge.net/projects/resizablelib\r
+//\r
+// Copyright (C) 2000-2004 by Paolo Messina\r
+// http://www.geocities.com/ppescher - mailto:ppescher@hotmail.com\r
+//\r
+// The contents of this file are subject to the Artistic License (the "License").\r
+// You may not use this file except in compliance with the License. \r
+// You may obtain a copy of the License at:\r
+// http://www.opensource.org/licenses/artistic-license.html\r
+//\r
+// If you find this code useful, credits would be nice!\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+#include "stdafx.h"\r
+#include "ResizableMDIFrame.h"\r
+\r
+#ifdef _DEBUG\r
+#define new DEBUG_NEW\r
+#undef THIS_FILE\r
+static char THIS_FILE[] = __FILE__;\r
+#endif\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+// CResizableMDIFrame\r
+\r
+IMPLEMENT_DYNCREATE(CResizableMDIFrame, CMDIFrameWnd)\r
+\r
+CResizableMDIFrame::CResizableMDIFrame()\r
+{\r
+ m_bEnableSaveRestore = FALSE;\r
+}\r
+\r
+CResizableMDIFrame::~CResizableMDIFrame()\r
+{\r
+}\r
+\r
+\r
+BEGIN_MESSAGE_MAP(CResizableMDIFrame, CMDIFrameWnd)\r
+ //{{AFX_MSG_MAP(CResizableMDIFrame)\r
+ ON_WM_GETMINMAXINFO()\r
+ ON_WM_DESTROY()\r
+ ON_WM_NCCREATE()\r
+ ON_WM_WINDOWPOSCHANGING()\r
+ //}}AFX_MSG_MAP\r
+END_MESSAGE_MAP()\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+// CResizableMDIFrame message handlers\r
+\r
+void CResizableMDIFrame::OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI) \r
+{\r
+ // MDI should call default implementation\r
+ CMDIFrameWnd::OnGetMinMaxInfo(lpMMI);\r
+\r
+ MinMaxInfo(lpMMI);\r
+\r
+ BOOL bMaximized = FALSE;\r
+ CMDIChildWnd* pChild = MDIGetActive(&bMaximized);\r
+ if (pChild != NULL && bMaximized)\r
+ ChainMinMaxInfo(lpMMI, this, pChild);\r
+}\r
+\r
+// NOTE: this must be called after setting the layout\r
+// to have the view and its controls displayed properly\r
+BOOL CResizableMDIFrame::EnableSaveRestore(LPCTSTR pszSection, BOOL bRectOnly)\r
+{\r
+ m_sSection = pszSection;\r
+\r
+ m_bEnableSaveRestore = TRUE;\r
+ m_bRectOnly = bRectOnly;\r
+\r
+ // restore immediately\r
+ return LoadWindowRect(pszSection, bRectOnly);\r
+}\r
+\r
+void CResizableMDIFrame::OnDestroy() \r
+{\r
+ if (m_bEnableSaveRestore)\r
+ SaveWindowRect(m_sSection, m_bRectOnly);\r
+\r
+ CMDIFrameWnd::OnDestroy();\r
+}\r
+\r
+BOOL CResizableMDIFrame::OnNcCreate(LPCREATESTRUCT lpCreateStruct) \r
+{\r
+ if (!CMDIFrameWnd::OnNcCreate(lpCreateStruct))\r
+ return FALSE;\r
+\r
+ MakeResizable(lpCreateStruct);\r
+ \r
+ return TRUE;\r
+}\r
+\r
+LRESULT CResizableMDIFrame::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) \r
+{\r
+ if (message != WM_NCCALCSIZE || wParam == 0)\r
+ return CMDIFrameWnd::WindowProc(message, wParam, lParam);\r
+\r
+ // specifying valid rects needs controls already anchored\r
+ LRESULT lResult = 0;\r
+ HandleNcCalcSize(FALSE, (LPNCCALCSIZE_PARAMS)lParam, lResult);\r
+ lResult = CMDIFrameWnd::WindowProc(message, wParam, lParam);\r
+ HandleNcCalcSize(TRUE, (LPNCCALCSIZE_PARAMS)lParam, lResult);\r
+ return lResult;\r
+}\r
+\r
+void CResizableMDIFrame::OnWindowPosChanging(WINDOWPOS FAR* lpwndpos) \r
+{\r
+ CMDIFrameWnd::OnWindowPosChanging(lpwndpos);\r
+\r
+ // since this window class doesn't have the style CS_HREDRAW|CS_VREDRAW\r
+ // the client area is not invalidated during a resize operation and\r
+ // this prevents the system from using WM_NCCALCSIZE to validate rects\r
+ Invalidate();\r
+}\r
--- /dev/null
+// ResizableMDIFrame.h : header file\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// This file is part of ResizableLib\r
+// http://sourceforge.net/projects/resizablelib\r
+//\r
+// Copyright (C) 2000-2004 by Paolo Messina\r
+// http://www.geocities.com/ppescher - mailto:ppescher@hotmail.com\r
+//\r
+// The contents of this file are subject to the Artistic License (the "License").\r
+// You may not use this file except in compliance with the License. \r
+// You may obtain a copy of the License at:\r
+// http://www.opensource.org/licenses/artistic-license.html\r
+//\r
+// If you find this code useful, credits would be nice!\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+#if !defined(AFX_RESIZABLEMDIFRAME_H__INCLUDED_)\r
+#define AFX_RESIZABLEMDIFRAME_H__INCLUDED_\r
+\r
+#if _MSC_VER > 1000\r
+#pragma once\r
+#endif // _MSC_VER > 1000\r
+\r
+#include "ResizableMinMax.h"\r
+#include "ResizableWndState.h"\r
+#include "ResizableLayout.h"\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+// CResizableMDIFrame frame\r
+\r
+class CResizableMDIFrame : public CMDIFrameWnd, public CResizableMinMax,\r
+ public CResizableWndState, public CResizableLayout\r
+{\r
+ DECLARE_DYNCREATE(CResizableMDIFrame)\r
+protected:\r
+ CResizableMDIFrame(); // protected constructor used by dynamic creation\r
+\r
+// Attributes\r
+protected:\r
+\r
+// Operations\r
+public:\r
+\r
+// Overrides\r
+ // ClassWizard generated virtual function overrides\r
+ //{{AFX_VIRTUAL(CResizableMDIFrame)\r
+ protected:\r
+ virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);\r
+ //}}AFX_VIRTUAL\r
+\r
+// Implementation\r
+protected:\r
+ virtual ~CResizableMDIFrame();\r
+\r
+ BOOL EnableSaveRestore(LPCTSTR pszSection, BOOL bRectOnly = FALSE);\r
+\r
+ virtual CWnd* GetResizableWnd() const\r
+ {\r
+ // make the layout know its parent window\r
+ return CWnd::FromHandle(m_hWnd);\r
+ };\r
+\r
+private:\r
+ // flags\r
+ BOOL m_bEnableSaveRestore;\r
+ BOOL m_bRectOnly;\r
+\r
+ // internal status\r
+ CString m_sSection; // section name (identifies a parent window)\r
+\r
+protected:\r
+ // Generated message map functions\r
+ //{{AFX_MSG(CResizableMDIFrame)\r
+ afx_msg void OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI);\r
+ afx_msg void OnDestroy();\r
+ afx_msg BOOL OnNcCreate(LPCREATESTRUCT lpCreateStruct);\r
+ afx_msg void OnWindowPosChanging(WINDOWPOS FAR* lpwndpos);\r
+ //}}AFX_MSG\r
+ DECLARE_MESSAGE_MAP()\r
+};\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+//{{AFX_INSERT_LOCATION}}\r
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.\r
+\r
+#endif // !defined(AFX_RESIZABLEMDIFRAME_H__INCLUDED_)\r
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// This file is part of ResizableLib\r
+// http://sourceforge.net/projects/resizablelib\r
+//\r
+// Copyright (C) 2000-2004 by Paolo Messina\r
+// http://www.geocities.com/ppescher - mailto:ppescher@hotmail.com\r
+//\r
+// The contents of this file are subject to the Artistic License (the "License").\r
+// You may not use this file except in compliance with the License. \r
+// You may obtain a copy of the License at:\r
+// http://www.opensource.org/licenses/artistic-license.html\r
+//\r
+// If you find this code useful, credits would be nice!\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+/*!\r
+ * @file\r
+ * @brief Implementation of the CResizableMinMax class.\r
+ */\r
+\r
+#include "stdafx.h"\r
+#include "ResizableMinMax.h"\r
+\r
+#ifdef _DEBUG\r
+#undef THIS_FILE\r
+static char THIS_FILE[]=__FILE__;\r
+#define new DEBUG_NEW\r
+#endif\r
+\r
+//////////////////////////////////////////////////////////////////////\r
+// Construction/Destruction\r
+//////////////////////////////////////////////////////////////////////\r
+\r
+CResizableMinMax::CResizableMinMax()\r
+{\r
+ m_bUseMinTrack = FALSE;\r
+ m_bUseMaxTrack = FALSE;\r
+ m_bUseMaxRect = FALSE;\r
+}\r
+\r
+CResizableMinMax::~CResizableMinMax()\r
+{\r
+\r
+}\r
+\r
+void CResizableMinMax::MinMaxInfo(LPMINMAXINFO lpMMI)\r
+{\r
+ if (m_bUseMinTrack)\r
+ lpMMI->ptMinTrackSize = m_ptMinTrackSize;\r
+\r
+ if (m_bUseMaxTrack)\r
+ lpMMI->ptMaxTrackSize = m_ptMaxTrackSize;\r
+\r
+ if (m_bUseMaxRect)\r
+ {\r
+ lpMMI->ptMaxPosition = m_ptMaxPos;\r
+ lpMMI->ptMaxSize = m_ptMaxSize;\r
+ }\r
+}\r
+\r
+void CResizableMinMax::ChainMinMaxInfo(LPMINMAXINFO lpMMI, CWnd* pParentFrame, CWnd* pWnd)\r
+{\r
+ // get the extra size from child to parent\r
+ CRect rectClient, rectWnd;\r
+ if ((pParentFrame->GetStyle() & WS_CHILD) && pParentFrame->IsZoomed())\r
+ pParentFrame->GetClientRect(rectWnd);\r
+ else\r
+ pParentFrame->GetWindowRect(rectWnd);\r
+ pParentFrame->RepositionBars(0, 0xFFFF,\r
+ AFX_IDW_PANE_FIRST, CWnd::reposQuery, rectClient);\r
+ CSize sizeExtra = rectWnd.Size() - rectClient.Size();\r
+\r
+ ChainMinMaxInfo(lpMMI, pWnd->GetSafeHwnd(), sizeExtra);\r
+}\r
+\r
+void CResizableMinMax::ChainMinMaxInfo(LPMINMAXINFO lpMMI, HWND hWndChild, CSize sizeExtra)\r
+{\r
+ // ask the child window for track size\r
+ MINMAXINFO mmiChild = *lpMMI;\r
+ ::SendMessage(hWndChild, WM_GETMINMAXINFO, 0, (LPARAM)&mmiChild);\r
+ BOOL bRetMax = (lpMMI->ptMaxTrackSize.x != mmiChild.ptMaxTrackSize.x\r
+ || lpMMI->ptMaxTrackSize.y != mmiChild.ptMaxTrackSize.y);\r
+ BOOL bRetMin = (lpMMI->ptMinTrackSize.x != mmiChild.ptMinTrackSize.x\r
+ || lpMMI->ptMinTrackSize.y != mmiChild.ptMinTrackSize.y);\r
+\r
+ // add static extra size\r
+ mmiChild.ptMaxTrackSize = sizeExtra + mmiChild.ptMaxTrackSize;\r
+ mmiChild.ptMinTrackSize = sizeExtra + mmiChild.ptMinTrackSize;\r
+\r
+ // min size is the largest\r
+ if (bRetMin)\r
+ {\r
+ lpMMI->ptMinTrackSize.x = __max(lpMMI->ptMinTrackSize.x,\r
+ mmiChild.ptMinTrackSize.x);\r
+ lpMMI->ptMinTrackSize.y = __max(lpMMI->ptMinTrackSize.y,\r
+ mmiChild.ptMinTrackSize.y);\r
+ }\r
+ // max size is the shortest\r
+ if (bRetMax)\r
+ {\r
+ lpMMI->ptMaxTrackSize.x = __min(lpMMI->ptMaxTrackSize.x,\r
+ mmiChild.ptMaxTrackSize.x);\r
+ lpMMI->ptMaxTrackSize.y = __min(lpMMI->ptMaxTrackSize.y,\r
+ mmiChild.ptMaxTrackSize.y);\r
+ }\r
+}\r
+\r
+BOOL CResizableMinMax::CalcSizeExtra(HWND /*hWndChild*/, CSize /*sizeChild*/, CSize& /*sizeExtra*/)\r
+{\r
+ // should be overridden if you use ChainMinMaxInfoCB\r
+ ASSERT(FALSE);\r
+ return FALSE;\r
+}\r
+\r
+void CResizableMinMax::ChainMinMaxInfoCB(LPMINMAXINFO lpMMI, HWND hWndChild)\r
+{\r
+ // ask the child window for track size\r
+ MINMAXINFO mmiChild = *lpMMI;\r
+ ::SendMessage(hWndChild, WM_GETMINMAXINFO, 0, (LPARAM)&mmiChild);\r
+ BOOL bRetMax = (lpMMI->ptMaxTrackSize.x != mmiChild.ptMaxTrackSize.x\r
+ || lpMMI->ptMaxTrackSize.y != mmiChild.ptMaxTrackSize.y);\r
+ BOOL bRetMin = (lpMMI->ptMinTrackSize.x != mmiChild.ptMinTrackSize.x\r
+ || lpMMI->ptMinTrackSize.y != mmiChild.ptMinTrackSize.y);\r
+\r
+ // use a callback to determine extra size\r
+ CSize sizeExtra(0, 0);\r
+ bRetMax = bRetMax && CalcSizeExtra(hWndChild, mmiChild.ptMaxTrackSize, sizeExtra);\r
+ mmiChild.ptMaxTrackSize = sizeExtra + mmiChild.ptMaxTrackSize;\r
+ bRetMin = bRetMin && CalcSizeExtra(hWndChild, mmiChild.ptMinTrackSize, sizeExtra);\r
+ mmiChild.ptMinTrackSize = sizeExtra + mmiChild.ptMinTrackSize;\r
+\r
+ // min size is the largest\r
+ if (bRetMin)\r
+ {\r
+ lpMMI->ptMinTrackSize.x = __max(lpMMI->ptMinTrackSize.x,\r
+ mmiChild.ptMinTrackSize.x);\r
+ lpMMI->ptMinTrackSize.y = __max(lpMMI->ptMinTrackSize.y,\r
+ mmiChild.ptMinTrackSize.y);\r
+ }\r
+ // max size is the shortest\r
+ if (bRetMax)\r
+ {\r
+ lpMMI->ptMaxTrackSize.x = __min(lpMMI->ptMaxTrackSize.x,\r
+ mmiChild.ptMaxTrackSize.x);\r
+ lpMMI->ptMaxTrackSize.y = __min(lpMMI->ptMaxTrackSize.y,\r
+ mmiChild.ptMaxTrackSize.y);\r
+ }\r
+}\r
+\r
+void CResizableMinMax::SetMaximizedRect(const CRect& rc)\r
+{\r
+ m_bUseMaxRect = TRUE;\r
+\r
+ m_ptMaxPos = rc.TopLeft();\r
+ m_ptMaxSize.x = rc.Width();\r
+ m_ptMaxSize.y = rc.Height();\r
+}\r
+\r
+void CResizableMinMax::ResetMaximizedRect()\r
+{\r
+ m_bUseMaxRect = FALSE;\r
+}\r
+\r
+void CResizableMinMax::SetMinTrackSize(const CSize& size)\r
+{\r
+ m_bUseMinTrack = TRUE;\r
+\r
+ m_ptMinTrackSize.x = size.cx;\r
+ m_ptMinTrackSize.y = size.cy;\r
+}\r
+\r
+void CResizableMinMax::ResetMinTrackSize()\r
+{\r
+ m_bUseMinTrack = FALSE;\r
+}\r
+\r
+void CResizableMinMax::SetMaxTrackSize(const CSize& size)\r
+{\r
+ m_bUseMaxTrack = TRUE;\r
+\r
+ m_ptMaxTrackSize.x = size.cx;\r
+ m_ptMaxTrackSize.y = size.cy;\r
+}\r
+\r
+void CResizableMinMax::ResetMaxTrackSize()\r
+{\r
+ m_bUseMaxTrack = FALSE;\r
+}\r
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// This file is part of ResizableLib\r
+// http://sourceforge.net/projects/resizablelib\r
+//\r
+// Copyright (C) 2000-2004 by Paolo Messina\r
+// http://www.geocities.com/ppescher - mailto:ppescher@hotmail.com\r
+//\r
+// The contents of this file are subject to the Artistic License (the "License").\r
+// You may not use this file except in compliance with the License. \r
+// You may obtain a copy of the License at:\r
+// http://www.opensource.org/licenses/artistic-license.html\r
+//\r
+// If you find this code useful, credits would be nice!\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+/*!\r
+ * @file\r
+ * @brief Interface for the CResizableMinMax class.\r
+ */\r
+\r
+#if !defined(AFX_RESIZABLEMINMAX_H__INCLUDED_)\r
+#define AFX_RESIZABLEMINMAX_H__INCLUDED_\r
+\r
+#if _MSC_VER > 1000\r
+#pragma once\r
+#endif // _MSC_VER > 1000\r
+\r
+/*! @addtogroup CoreComponents\r
+ * @{\r
+ */\r
+\r
+//! @brief brief_description\r
+/*!\r
+ * long_description\r
+ */\r
+class CResizableMinMax\r
+{\r
+// Attributes\r
+private:\r
+ // flags\r
+ BOOL m_bUseMaxTrack;\r
+ BOOL m_bUseMinTrack;\r
+ BOOL m_bUseMaxRect;\r
+\r
+ POINT m_ptMinTrackSize; // min tracking size\r
+ POINT m_ptMaxTrackSize; // max tracking size\r
+ POINT m_ptMaxPos; // maximized position\r
+ POINT m_ptMaxSize; // maximized size\r
+\r
+public:\r
+ CResizableMinMax();\r
+ virtual ~CResizableMinMax();\r
+\r
+protected:\r
+ void MinMaxInfo(LPMINMAXINFO lpMMI);\r
+ void ChainMinMaxInfo(LPMINMAXINFO lpMMI, CWnd* pParentFrame, CWnd* pWnd);\r
+\r
+ void ChainMinMaxInfo(LPMINMAXINFO lpMMI, HWND hWndChild, CSize sizeExtra);\r
+ \r
+ void ChainMinMaxInfo(LPMINMAXINFO lpMMI, CWnd* pParentWnd, UINT nID, CSize sizeExtra)\r
+ {\r
+ ChainMinMaxInfo(lpMMI,\r
+ ::GetDlgItem(pParentWnd->GetSafeHwnd(), nID), sizeExtra);\r
+ }\r
+\r
+ void ChainMinMaxInfoCB(LPMINMAXINFO lpMMI, HWND hWndChild);\r
+ virtual BOOL CalcSizeExtra(HWND hWndChild, CSize sizeChild, CSize& sizeExtra);\r
+\r
+ void SetMaximizedRect(const CRect& rc); // set window rect when maximized\r
+ void ResetMaximizedRect(); // reset to default maximized rect\r
+ void SetMinTrackSize(const CSize& size); // set minimum tracking size\r
+ void ResetMinTrackSize(); // reset to default minimum tracking size\r
+ void SetMaxTrackSize(const CSize& size); // set maximum tracking size\r
+ void ResetMaxTrackSize(); // reset to default maximum tracking size\r
+};\r
+\r
+// @}\r
+#endif // !defined(AFX_RESIZABLEMINMAX_H__INCLUDED_)\r
--- /dev/null
+// ResizableMsgSupport.cpp: support messages for custom resizable wnds\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// Copyright (C) 2000-2002 by Paolo Messina\r
+// (http://www.geocities.com/ppescher - ppescher@yahoo.com)\r
+//\r
+// The contents of this file are subject to the Artistic License (the "License").\r
+// You may not use this file except in compliance with the License. \r
+// You may obtain a copy of the License at:\r
+// http://www.opensource.org/licenses/artistic-license.html\r
+//\r
+// If you find this code useful, credits would be nice!\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+#include "stdafx.h"\r
+#include "ResizableMsgSupport.h"\r
+\r
+#ifdef _DEBUG\r
+#define new DEBUG_NEW\r
+#undef THIS_FILE\r
+static char THIS_FILE[] = __FILE__;\r
+#endif\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+// Registered message to communicate with the library\r
+\r
+// static intializer must be called before user code\r
+#pragma warning(disable:4073)\r
+#pragma init_seg(lib)\r
+\r
+const UINT WMU_RESIZESUPPORT = ::RegisterWindowMessage(TEXT("WMU_RESIZESUPPORT"));\r
+\r
--- /dev/null
+// ResizableMsgSupport.h: some declarations to support custom resizable wnds\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// Copyright (C) 2000-2002 by Paolo Messina\r
+// (http://www.geocities.com/ppescher - ppescher@yahoo.com)\r
+//\r
+// The contents of this file are subject to the Artistic License (the "License").\r
+// You may not use this file except in compliance with the License. \r
+// You may obtain a copy of the License at:\r
+// http://www.opensource.org/licenses/artistic-license.html\r
+//\r
+// If you find this code useful, credits would be nice!\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+#if !defined(AFX_RESIZABLEMSGSUPPORT_H__INCLUDED_)\r
+#define AFX_RESIZABLEMSGSUPPORT_H__INCLUDED_\r
+\r
+#if _MSC_VER > 1000\r
+#pragma once\r
+#endif // _MSC_VER > 1000\r
+\r
+typedef struct tagRESIZEPROPERTIES\r
+{\r
+ // wether to ask for resizing properties every time\r
+ BOOL bAskClipping;\r
+ BOOL bAskRefresh;\r
+ // otherwise, use the cached properties\r
+ BOOL bCachedLikesClipping;\r
+ BOOL bCachedNeedsRefresh;\r
+\r
+ // initialize with valid data\r
+ tagRESIZEPROPERTIES() : bAskClipping(TRUE), bAskRefresh(TRUE) {}\r
+\r
+} RESIZEPROPERTIES, *PRESIZEPROPERTIES, *LPRESIZEPROPERTIES;\r
+\r
+\r
+typedef struct tagCLIPPINGPROPERTY\r
+{\r
+ BOOL bLikesClipping;\r
+\r
+ // initialize with valid data\r
+ tagCLIPPINGPROPERTY() : bLikesClipping(FALSE) {}\r
+\r
+} CLIPPINGPROPERTY, *PCLIPPINGPROPERTY, *LPCLIPPINGPROPERTY;\r
+\r
+\r
+typedef struct tagREFRESHPROPERTY\r
+{\r
+ BOOL bNeedsRefresh;\r
+ RECT rcOld;\r
+ RECT rcNew;\r
+\r
+ // initialize with valid data\r
+ tagREFRESHPROPERTY() : bNeedsRefresh(TRUE) {}\r
+\r
+} REFRESHPROPERTY, *PREFRESHPROPERTY, *LPREFRESHPROPERTY;\r
+\r
+\r
+// registered message to communicate with the library\r
+extern const UINT WMU_RESIZESUPPORT;\r
+\r
+// if the message is implemented the returned value must be non-zero\r
+// the default window procedure returns zero for unhandled messages\r
+\r
+// wParam is one of the following RSZSUP_* values, lParam as specified\r
+enum ResizeSupport\r
+{\r
+ RSZSUP_QUERYPROPERTIES = 101, // lParam = LPRESIZEPROPERTIES\r
+ RSZSUP_LIKESCLIPPING = 102, // lParam = LPCLIPPINGPROPERTY\r
+ RSZSUP_NEEDSREFRESH = 103, // lParam = LPREFRESHPROPERTY\r
+ RSZSUP_SHEETPAGEEXHACK = 104, // lParam = HWND (source prop.page)\r
+};\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+// utility functions\r
+\r
+inline BOOL Send_QueryProperties(HWND hWnd, LPRESIZEPROPERTIES pResizeProperties)\r
+{\r
+ return (0 != SendMessage(hWnd, WMU_RESIZESUPPORT,\r
+ RSZSUP_QUERYPROPERTIES, (LPARAM)pResizeProperties));\r
+}\r
+\r
+inline BOOL Send_LikesClipping(HWND hWnd, LPCLIPPINGPROPERTY pClippingProperty)\r
+{\r
+ return (0 != SendMessage(hWnd, WMU_RESIZESUPPORT,\r
+ RSZSUP_LIKESCLIPPING, (LPARAM)pClippingProperty));\r
+}\r
+\r
+inline BOOL Send_NeedsRefresh(HWND hWnd, LPREFRESHPROPERTY pRefreshProperty)\r
+{\r
+ return (0 != SendMessage(hWnd, WMU_RESIZESUPPORT,\r
+ RSZSUP_NEEDSREFRESH, (LPARAM)pRefreshProperty));\r
+}\r
+\r
+inline void Post_SheetPageExHack(HWND hWndSheet, HWND hWndPage)\r
+{\r
+ PostMessage(hWndSheet, WMU_RESIZESUPPORT,\r
+ RSZSUP_SHEETPAGEEXHACK, (LPARAM)hWndPage);\r
+}\r
+\r
+#endif // !defined(AFX_RESIZABLEMSGSUPPORT_H__INCLUDED_)\r
--- /dev/null
+// ResizablePage.cpp : implementation file\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// This file is part of ResizableLib\r
+// http://sourceforge.net/projects/resizablelib\r
+//\r
+// Copyright (C) 2000-2004 by Paolo Messina\r
+// http://www.geocities.com/ppescher - mailto:ppescher@hotmail.com\r
+//\r
+// The contents of this file are subject to the Artistic License (the "License").\r
+// You may not use this file except in compliance with the License. \r
+// You may obtain a copy of the License at:\r
+// http://www.opensource.org/licenses/artistic-license.html\r
+//\r
+// If you find this code useful, credits would be nice!\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+#include "stdafx.h"\r
+#include "ResizablePage.h"\r
+\r
+#ifdef _DEBUG\r
+#define new DEBUG_NEW\r
+#undef THIS_FILE\r
+static char THIS_FILE[] = __FILE__;\r
+#endif\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+// CResizablePage\r
+\r
+IMPLEMENT_DYNCREATE(CResizablePage, CPropertyPage)\r
+\r
+CResizablePage::CResizablePage()\r
+{\r
+}\r
+\r
+CResizablePage::CResizablePage(UINT nIDTemplate, UINT nIDCaption)\r
+ : CPropertyPage(nIDTemplate, nIDCaption)\r
+{\r
+}\r
+\r
+CResizablePage::CResizablePage(LPCTSTR lpszTemplateName, UINT nIDCaption)\r
+ : CPropertyPage(lpszTemplateName, nIDCaption)\r
+{\r
+}\r
+\r
+CResizablePage::~CResizablePage()\r
+{\r
+}\r
+\r
+\r
+BEGIN_MESSAGE_MAP(CResizablePage, CPropertyPage)\r
+ //{{AFX_MSG_MAP(CResizablePage)\r
+ ON_WM_SIZE()\r
+ ON_WM_ERASEBKGND()\r
+ ON_WM_GETMINMAXINFO()\r
+ ON_WM_DESTROY()\r
+ //}}AFX_MSG_MAP\r
+END_MESSAGE_MAP()\r
+\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+// CResizablePage message handlers\r
+\r
+void CResizablePage::OnSize(UINT nType, int cx, int cy) \r
+{\r
+ CWnd::OnSize(nType, cx, cy);\r
+ \r
+ ArrangeLayout();\r
+}\r
+\r
+BOOL CResizablePage::OnEraseBkgnd(CDC* pDC) \r
+{\r
+ ClipChildren(pDC, FALSE);\r
+\r
+ BOOL bRet = CPropertyPage::OnEraseBkgnd(pDC);\r
+\r
+ ClipChildren(pDC, TRUE);\r
+\r
+ return bRet;\r
+}\r
+\r
+void CResizablePage::OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI) \r
+{\r
+ MinMaxInfo(lpMMI);\r
+}\r
+\r
+BOOL CResizablePage::OnInitDialog() \r
+{\r
+ CPropertyPage::OnInitDialog();\r
+ \r
+ // set the initial size as the min track size\r
+ CRect rc;\r
+ GetWindowRect(&rc);\r
+ SetMinTrackSize(rc.Size());\r
+\r
+ return TRUE; // return TRUE unless you set the focus to a control\r
+ // EXCEPTION: OCX Property Pages should return FALSE\r
+}\r
+\r
+void CResizablePage::OnDestroy() \r
+{\r
+ // remove child windows\r
+ RemoveAllAnchors();\r
+\r
+ CPropertyPage::OnDestroy();\r
+}\r
+\r
+LRESULT CResizablePage::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) \r
+{\r
+ if (message != WM_NCCALCSIZE || wParam == 0)\r
+ return CPropertyPage::WindowProc(message, wParam, lParam);\r
+\r
+ LRESULT lResult = 0;\r
+ HandleNcCalcSize(FALSE, (LPNCCALCSIZE_PARAMS)lParam, lResult);\r
+ lResult = CPropertyPage::WindowProc(message, wParam, lParam);\r
+ HandleNcCalcSize(TRUE, (LPNCCALCSIZE_PARAMS)lParam, lResult);\r
+ return lResult;\r
+}\r
--- /dev/null
+#if !defined(AFX_RESIZABLEPAGE_H__INCLUDED_)\r
+#define AFX_RESIZABLEPAGE_H__INCLUDED_\r
+\r
+#if _MSC_VER > 1000\r
+#pragma once\r
+#endif // _MSC_VER > 1000\r
+\r
+// ResizablePage.h : header file\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// This file is part of ResizableLib\r
+// http://sourceforge.net/projects/resizablelib\r
+//\r
+// Copyright (C) 2000-2004 by Paolo Messina\r
+// http://www.geocities.com/ppescher - mailto:ppescher@hotmail.com\r
+//\r
+// The contents of this file are subject to the Artistic License (the "License").\r
+// You may not use this file except in compliance with the License. \r
+// You may obtain a copy of the License at:\r
+// http://www.opensource.org/licenses/artistic-license.html\r
+//\r
+// If you find this code useful, credits would be nice!\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+#include "ResizableLayout.h"\r
+#include "ResizableMinMax.h"\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+// CResizablePage window\r
+\r
+class CResizablePage : public CPropertyPage, public CResizableLayout,\r
+ public CResizableMinMax\r
+{\r
+ DECLARE_DYNCREATE(CResizablePage)\r
+\r
+// Construction\r
+public:\r
+ CResizablePage();\r
+ CResizablePage(UINT nIDTemplate, UINT nIDCaption = 0);\r
+ CResizablePage(LPCTSTR lpszTemplateName, UINT nIDCaption = 0);\r
+\r
+// Attributes\r
+public:\r
+\r
+// Operations\r
+public:\r
+\r
+// Overrides\r
+ // ClassWizard generated virtual function overrides\r
+ //{{AFX_VIRTUAL(CResizablePage)\r
+ protected:\r
+ virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);\r
+ //}}AFX_VIRTUAL\r
+\r
+// Implementation\r
+public:\r
+ virtual ~CResizablePage();\r
+\r
+// callable from derived classes\r
+protected:\r
+\r
+ virtual CWnd* GetResizableWnd() const\r
+ {\r
+ // make the layout know its parent window\r
+ return CWnd::FromHandle(m_hWnd);\r
+ };\r
+\r
+// Generated message map functions\r
+protected:\r
+ //{{AFX_MSG(CResizablePage)\r
+ afx_msg void OnSize(UINT nType, int cx, int cy);\r
+ afx_msg BOOL OnEraseBkgnd(CDC* pDC);\r
+ afx_msg void OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI);\r
+ virtual BOOL OnInitDialog();\r
+ afx_msg void OnDestroy();\r
+ //}}AFX_MSG\r
+ DECLARE_MESSAGE_MAP()\r
+};\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+//{{AFX_INSERT_LOCATION}}\r
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.\r
+\r
+#endif // !defined(AFX_RESIZABLEPAGE_H__INCLUDED_)\r
--- /dev/null
+// ResizablePageEx.cpp : implementation file\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// This file is part of ResizableLib\r
+// http://sourceforge.net/projects/resizablelib\r
+//\r
+// Copyright (C) 2000-2004 by Paolo Messina\r
+// http://www.geocities.com/ppescher - mailto:ppescher@hotmail.com\r
+//\r
+// The contents of this file are subject to the Artistic License (the "License").\r
+// You may not use this file except in compliance with the License. \r
+// You may obtain a copy of the License at:\r
+// http://www.opensource.org/licenses/artistic-license.html\r
+//\r
+// If you find this code useful, credits would be nice!\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+#include "stdafx.h"\r
+#include "ResizablePageEx.h"\r
+\r
+#ifdef _DEBUG\r
+#define new DEBUG_NEW\r
+#undef THIS_FILE\r
+static char THIS_FILE[] = __FILE__;\r
+#endif\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+// CResizablePageEx\r
+\r
+IMPLEMENT_DYNCREATE(CResizablePageEx, CPropertyPageEx)\r
+\r
+CResizablePageEx::CResizablePageEx()\r
+{\r
+}\r
+\r
+CResizablePageEx::CResizablePageEx(UINT nIDTemplate, UINT nIDCaption, UINT nIDHeaderTitle, UINT nIDHeaderSubTitle)\r
+ : CPropertyPageEx(nIDTemplate, nIDCaption, nIDHeaderTitle, nIDHeaderSubTitle)\r
+{\r
+}\r
+\r
+CResizablePageEx::CResizablePageEx(LPCTSTR lpszTemplateName, UINT nIDCaption, UINT nIDHeaderTitle, UINT nIDHeaderSubTitle)\r
+ : CPropertyPageEx(lpszTemplateName, nIDCaption, nIDHeaderTitle, nIDHeaderSubTitle)\r
+{\r
+}\r
+\r
+CResizablePageEx::~CResizablePageEx()\r
+{\r
+}\r
+\r
+\r
+BEGIN_MESSAGE_MAP(CResizablePageEx, CPropertyPageEx)\r
+ //{{AFX_MSG_MAP(CResizablePageEx)\r
+ ON_WM_SIZE()\r
+ ON_WM_ERASEBKGND()\r
+ ON_WM_GETMINMAXINFO()\r
+ ON_WM_DESTROY()\r
+ ON_WM_CTLCOLOR()\r
+ //}}AFX_MSG_MAP\r
+END_MESSAGE_MAP()\r
+\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+// CResizablePageEx message handlers\r
+\r
+void CResizablePageEx::OnSize(UINT nType, int cx, int cy) \r
+{\r
+ CWnd::OnSize(nType, cx, cy);\r
+ \r
+ ArrangeLayout();\r
+\r
+ if (m_psp.dwFlags & PSP_HIDEHEADER)\r
+ Invalidate();\r
+}\r
+\r
+BOOL CResizablePageEx::OnEraseBkgnd(CDC* pDC) \r
+{\r
+ ClipChildren(pDC, FALSE);\r
+\r
+ BOOL bRet = CPropertyPageEx::OnEraseBkgnd(pDC);\r
+\r
+ ClipChildren(pDC, TRUE);\r
+\r
+ return bRet;\r
+}\r
+\r
+void CResizablePageEx::OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI) \r
+{\r
+ MinMaxInfo(lpMMI);\r
+}\r
+\r
+BOOL CResizablePageEx::OnInitDialog() \r
+{\r
+ CPropertyPageEx::OnInitDialog();\r
+ \r
+ // set the initial size as the min track size\r
+ CRect rc;\r
+ GetWindowRect(&rc);\r
+ SetMinTrackSize(rc.Size());\r
+\r
+ // HACK: temporarily abandon subclassing\r
+ // CAUSE: system subclasses this window after this message\r
+ // ISSUE: our WindowProc is not the first to be called\r
+ // and we miss some painting related messages\r
+ if (Attach(UnsubclassWindow()))\r
+ {\r
+ CWnd* pParent = GetParent();\r
+ pParent->LockWindowUpdate();\r
+ Post_SheetPageExHack(pParent->GetSafeHwnd(), m_hWnd);\r
+ }\r
+\r
+ return TRUE; // return TRUE unless you set the focus to a control\r
+ // EXCEPTION: OCX Property Pages should return FALSE\r
+}\r
+\r
+void CResizablePageEx::OnDestroy() \r
+{\r
+ // remove child windows\r
+ RemoveAllAnchors();\r
+\r
+ CPropertyPageEx::OnDestroy();\r
+}\r
+\r
+HBRUSH CResizablePageEx::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) \r
+{\r
+ // NOTE: this message couldn't be catched without the above hack\r
+\r
+ HBRUSH hbr = CPropertyPageEx::OnCtlColor(pDC, pWnd, nCtlColor);\r
+ if (hbr && (m_psp.dwFlags & PSP_HIDEHEADER))\r
+ {\r
+ // reposition origin of background brush\r
+ // used for transparent effect on page controls\r
+ // (needed with double-buffering and XP themes)\r
+ CRect rect;\r
+ pWnd->GetWindowRect(rect);\r
+ pWnd->SendMessage(WM_NCCALCSIZE, FALSE, (LPARAM)&rect);\r
+ ScreenToClient(rect);\r
+ CPoint pt(-rect.TopLeft());\r
+ HDC hDC = pDC->GetSafeHdc();\r
+ ::LPtoDP(hDC, &pt, 1);\r
+ ::UnrealizeObject(hbr);\r
+ ::SetBrushOrgEx(hDC, pt.x, pt.y, NULL);\r
+ }\r
+ return hbr;\r
+}\r
+\r
+LRESULT CResizablePageEx::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) \r
+{\r
+ if (message != WM_NCCALCSIZE || wParam == 0)\r
+ return CPropertyPageEx::WindowProc(message, wParam, lParam);\r
+\r
+ LRESULT lResult = 0;\r
+ HandleNcCalcSize(FALSE, (LPNCCALCSIZE_PARAMS)lParam, lResult);\r
+ lResult = CPropertyPageEx::WindowProc(message, wParam, lParam);\r
+ HandleNcCalcSize(TRUE, (LPNCCALCSIZE_PARAMS)lParam, lResult);\r
+ return lResult;\r
+}\r
--- /dev/null
+#if !defined(AFX_RESIZABLEPAGEEX_H__INCLUDED_)\r
+#define AFX_RESIZABLEPAGEEX_H__INCLUDED_\r
+\r
+#if _MSC_VER > 1000\r
+#pragma once\r
+#endif // _MSC_VER > 1000\r
+\r
+// ResizablePageEx.h : header file\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// This file is part of ResizableLib\r
+// http://sourceforge.net/projects/resizablelib\r
+//\r
+// Copyright (C) 2000-2004 by Paolo Messina\r
+// http://www.geocities.com/ppescher - mailto:ppescher@hotmail.com\r
+//\r
+// The contents of this file are subject to the Artistic License (the "License").\r
+// You may not use this file except in compliance with the License. \r
+// You may obtain a copy of the License at:\r
+// http://www.opensource.org/licenses/artistic-license.html\r
+//\r
+// If you find this code useful, credits would be nice!\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+#include "ResizableLayout.h"\r
+#include "ResizableMinMax.h"\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+// CResizablePageEx window\r
+\r
+class CResizablePageEx : public CPropertyPageEx, public CResizableLayout,\r
+ public CResizableMinMax\r
+{\r
+ DECLARE_DYNCREATE(CResizablePageEx)\r
+\r
+// Construction\r
+public:\r
+ CResizablePageEx();\r
+ CResizablePageEx(UINT nIDTemplate, UINT nIDCaption = 0, UINT nIDHeaderTitle = 0, UINT nIDHeaderSubTitle = 0);\r
+ CResizablePageEx(LPCTSTR lpszTemplateName, UINT nIDCaption = 0, UINT nIDHeaderTitle = 0, UINT nIDHeaderSubTitle = 0);\r
+\r
+// Attributes\r
+public:\r
+\r
+// Operations\r
+public:\r
+\r
+// Overrides\r
+ // ClassWizard generated virtual function overrides\r
+ //{{AFX_VIRTUAL(CResizablePageEx)\r
+ protected:\r
+ virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);\r
+ //}}AFX_VIRTUAL\r
+\r
+// Implementation\r
+public:\r
+ virtual ~CResizablePageEx();\r
+\r
+// callable from derived classes\r
+protected:\r
+\r
+ virtual CWnd* GetResizableWnd() const\r
+ {\r
+ // make the layout know its parent window\r
+ return CWnd::FromHandle(m_hWnd);\r
+ };\r
+\r
+// Generated message map functions\r
+protected:\r
+ //{{AFX_MSG(CResizablePageEx)\r
+ afx_msg void OnSize(UINT nType, int cx, int cy);\r
+ afx_msg BOOL OnEraseBkgnd(CDC* pDC);\r
+ afx_msg void OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI);\r
+ virtual BOOL OnInitDialog();\r
+ afx_msg void OnDestroy();\r
+ afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);\r
+ //}}AFX_MSG\r
+ DECLARE_MESSAGE_MAP()\r
+};\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+//{{AFX_INSERT_LOCATION}}\r
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.\r
+\r
+#endif // !defined(AFX_RESIZABLEPAGEEX_H__INCLUDED_)\r
--- /dev/null
+// ResizableSheet.cpp : implementation file\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// This file is part of ResizableLib\r
+// http://sourceforge.net/projects/resizablelib\r
+//\r
+// Copyright (C) 2000-2004 by Paolo Messina\r
+// http://www.geocities.com/ppescher - mailto:ppescher@hotmail.com\r
+//\r
+// The contents of this file are subject to the Artistic License (the "License").\r
+// You may not use this file except in compliance with the License. \r
+// You may obtain a copy of the License at:\r
+// http://www.opensource.org/licenses/artistic-license.html\r
+//\r
+// If you find this code useful, credits would be nice!\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+#include "stdafx.h"\r
+#include "ResizableSheet.h"\r
+\r
+#ifdef _DEBUG\r
+#define new DEBUG_NEW\r
+#undef THIS_FILE\r
+static char THIS_FILE[] = __FILE__;\r
+#endif\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+// CResizableSheet\r
+\r
+IMPLEMENT_DYNAMIC(CResizableSheet, CPropertySheet)\r
+\r
+inline void CResizableSheet::PrivateConstruct()\r
+{\r
+ m_bEnableSaveRestore = FALSE;\r
+ m_bSavePage = FALSE;\r
+ m_dwGripTempState = 1;\r
+ m_bLayoutDone = FALSE;\r
+}\r
+\r
+inline BOOL CResizableSheet::IsWizard() const\r
+{\r
+ return (m_psh.dwFlags & PSH_WIZARD);\r
+}\r
+\r
+CResizableSheet::CResizableSheet()\r
+{\r
+ PrivateConstruct();\r
+}\r
+\r
+CResizableSheet::CResizableSheet(UINT nIDCaption, CWnd *pParentWnd, UINT iSelectPage)\r
+ : CPropertySheet(nIDCaption, pParentWnd, iSelectPage)\r
+{\r
+ PrivateConstruct();\r
+}\r
+\r
+CResizableSheet::CResizableSheet(LPCTSTR pszCaption, CWnd *pParentWnd, UINT iSelectPage)\r
+ : CPropertySheet(pszCaption, pParentWnd, iSelectPage)\r
+{\r
+ PrivateConstruct();\r
+}\r
+\r
+CResizableSheet::~CResizableSheet()\r
+{\r
+}\r
+\r
+BEGIN_MESSAGE_MAP(CResizableSheet, CPropertySheet)\r
+ //{{AFX_MSG_MAP(CResizableSheet)\r
+ ON_WM_GETMINMAXINFO()\r
+ ON_WM_SIZE()\r
+ ON_WM_DESTROY()\r
+ ON_WM_ERASEBKGND()\r
+ ON_WM_NCCREATE()\r
+ //}}AFX_MSG_MAP\r
+ ON_NOTIFY_REFLECT_EX(PSN_SETACTIVE, OnPageChanging)\r
+END_MESSAGE_MAP()\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+// CResizableSheet message handlers\r
+\r
+BOOL CResizableSheet::OnNcCreate(LPCREATESTRUCT lpCreateStruct) \r
+{\r
+ if (!CPropertySheet::OnNcCreate(lpCreateStruct))\r
+ return FALSE;\r
+\r
+ // child dialogs don't want resizable border or size grip,\r
+ // nor they can handle the min/max size constraints\r
+ BOOL bChild = lpCreateStruct->style & WS_CHILD;\r
+\r
+ // create and init the size-grip\r
+ if (!CreateSizeGrip(!bChild))\r
+ return FALSE;\r
+\r
+ MakeResizable(lpCreateStruct);\r
+ \r
+ return TRUE;\r
+}\r
+\r
+BOOL CResizableSheet::OnInitDialog() \r
+{\r
+ BOOL bResult = CPropertySheet::OnInitDialog();\r
+\r
+ // set the initial size as the min track size\r
+ CRect rc;\r
+ GetWindowRect(&rc);\r
+ SetMinTrackSize(rc.Size());\r
+\r
+ // initialize layout\r
+ PresetLayout();\r
+ m_bLayoutDone = TRUE;\r
+\r
+ return bResult;\r
+}\r
+\r
+void CResizableSheet::OnDestroy() \r
+{\r
+ if (m_bEnableSaveRestore)\r
+ {\r
+ SaveWindowRect(m_sSection, m_bRectOnly);\r
+ if (m_bSavePage)\r
+ SavePage(m_sSection);\r
+ }\r
+\r
+ RemoveAllAnchors();\r
+\r
+ CPropertySheet::OnDestroy();\r
+}\r
+\r
+// maps an index to a button ID and vice-versa\r
+static UINT _propButtons[] =\r
+{\r
+ IDOK, IDCANCEL, ID_APPLY_NOW, IDHELP,\r
+ ID_WIZBACK, ID_WIZNEXT, ID_WIZFINISH\r
+};\r
+const int _propButtonsCount = sizeof(_propButtons)/sizeof(UINT);\r
+\r
+// horizontal line in wizard mode\r
+#define ID_WIZLINE ID_WIZFINISH+1\r
+\r
+void CResizableSheet::PresetLayout()\r
+{\r
+ // set the initial size as the min track size\r
+ CRect rc;\r
+ GetWindowRect(&rc);\r
+ SetMinTrackSize(rc.Size());\r
+\r
+ if (GetStyle() & WS_CHILD)\r
+ {\r
+ GetClientRect(&rc);\r
+ GetTabControl()->MoveWindow(&rc);\r
+ }\r
+\r
+ if (IsWizard()) // wizard mode\r
+ {\r
+ // hide tab control\r
+ GetTabControl()->ShowWindow(SW_HIDE);\r
+\r
+ AddAnchor(ID_WIZLINE, BOTTOM_LEFT, BOTTOM_RIGHT);\r
+ }\r
+ else // tab mode\r
+ {\r
+ AddAnchor(AFX_IDC_TAB_CONTROL, TOP_LEFT, BOTTOM_RIGHT);\r
+ }\r
+\r
+ // add a callback for active page (which can change at run-time)\r
+ m_nCallbackID = AddAnchorCallback();\r
+\r
+ // use *total* parent size to have correct margins\r
+ CRect rectPage, rectSheet;\r
+ GetTotalClientRect(&rectSheet);\r
+\r
+ GetActivePage()->GetWindowRect(&rectPage);\r
+ ::MapWindowPoints(NULL, m_hWnd, (LPPOINT)&rectPage, 2);\r
+\r
+ // pre-calculate margins\r
+ m_sizePageTL = rectPage.TopLeft() - rectSheet.TopLeft();\r
+ m_sizePageBR = rectPage.BottomRight() - rectSheet.BottomRight();\r
+\r
+ // add all possible buttons, if they exist\r
+ for (int i = 0; i < _propButtonsCount; i++)\r
+ {\r
+ if (NULL != GetDlgItem(_propButtons[i]))\r
+ AddAnchor(_propButtons[i], BOTTOM_RIGHT);\r
+ }\r
+\r
+ // prevent flickering\r
+ GetTabControl()->ModifyStyle(0, WS_CLIPSIBLINGS);\r
+}\r
+\r
+BOOL CResizableSheet::ArrangeLayoutCallback(LAYOUTINFO &layout) const\r
+{\r
+ if (layout.nCallbackID != m_nCallbackID) // we only added 1 callback\r
+ return CResizableLayout::ArrangeLayoutCallback(layout);\r
+\r
+ // set layout info for active page\r
+ layout.hWnd = (HWND)::SendMessage(m_hWnd, PSM_GETCURRENTPAGEHWND, 0, 0);\r
+ if (!::IsWindow(layout.hWnd))\r
+ return FALSE;\r
+\r
+ // set margins\r
+ if (IsWizard()) // wizard mode\r
+ {\r
+ // use pre-calculated margins\r
+ layout.marginTopLeft = m_sizePageTL;\r
+ layout.marginBottomRight = m_sizePageBR;\r
+ }\r
+ else // tab mode\r
+ {\r
+ CTabCtrl* pTab = GetTabControl();\r
+ ASSERT(pTab != NULL);\r
+\r
+ // get tab position after resizing and calc page rect\r
+ CRect rectPage, rectSheet;\r
+ GetTotalClientRect(&rectSheet);\r
+\r
+ if (!GetAnchorPosition(pTab->m_hWnd, rectSheet, rectPage))\r
+ return FALSE; // no page yet\r
+\r
+ // temporarily resize the tab control to calc page size\r
+ CRect rectSave;\r
+ pTab->GetWindowRect(rectSave);\r
+ ::MapWindowPoints(NULL, m_hWnd, (LPPOINT)&rectSave, 2);\r
+ pTab->SetRedraw(FALSE);\r
+ pTab->MoveWindow(rectPage, FALSE);\r
+ pTab->AdjustRect(FALSE, &rectPage);\r
+ pTab->MoveWindow(rectSave, FALSE);\r
+ pTab->SetRedraw(TRUE);\r
+\r
+ // set margins\r
+ layout.marginTopLeft = rectPage.TopLeft() - rectSheet.TopLeft();\r
+ layout.marginBottomRight = rectPage.BottomRight() - rectSheet.BottomRight();\r
+ }\r
+\r
+ // set anchor types\r
+ layout.anchorTopLeft = TOP_LEFT;\r
+ layout.anchorBottomRight = BOTTOM_RIGHT;\r
+\r
+ // use this layout info\r
+ return TRUE;\r
+}\r
+\r
+void CResizableSheet::OnSize(UINT nType, int cx, int cy) \r
+{\r
+ CWnd::OnSize(nType, cx, cy);\r
+ \r
+ if (nType == SIZE_MAXHIDE || nType == SIZE_MAXSHOW)\r
+ return; // arrangement not needed\r
+\r
+ if (nType == SIZE_MAXIMIZED)\r
+ HideSizeGrip(&m_dwGripTempState);\r
+ else\r
+ ShowSizeGrip(&m_dwGripTempState);\r
+\r
+ // update grip and layout\r
+ UpdateSizeGrip();\r
+ ArrangeLayout();\r
+}\r
+\r
+BOOL CResizableSheet::OnPageChanging(NMHDR* /*pNotifyStruct*/, LRESULT* /*pResult*/)\r
+{\r
+ // update new wizard page\r
+ // active page changes after this notification\r
+ PostMessage(WM_SIZE);\r
+\r
+ return FALSE; // continue routing\r
+}\r
+\r
+BOOL CResizableSheet::OnEraseBkgnd(CDC* pDC) \r
+{\r
+ ClipChildren(pDC, FALSE);\r
+\r
+ BOOL bRet = CPropertySheet::OnEraseBkgnd(pDC);\r
+\r
+ ClipChildren(pDC, TRUE);\r
+\r
+ return bRet;\r
+}\r
+\r
+BOOL CResizableSheet::CalcSizeExtra(HWND /*hWndChild*/, CSize sizeChild, CSize &sizeExtra)\r
+{\r
+ CTabCtrl* pTab = GetTabControl();\r
+ if (!pTab)\r
+ return FALSE;\r
+\r
+ // get margins of tabcontrol\r
+ CRect rectMargins;\r
+ if (!GetAnchorMargins(pTab->m_hWnd, sizeChild, rectMargins))\r
+ return FALSE;\r
+\r
+ // get margin caused by tabcontrol\r
+ CRect rectTabMargins(0,0,0,0);\r
+\r
+ // get tab position after resizing and calc page rect\r
+ CRect rectPage, rectSheet;\r
+ GetTotalClientRect(&rectSheet);\r
+\r
+ if (!GetAnchorPosition(pTab->m_hWnd, rectSheet, rectPage))\r
+ return FALSE; // no page yet\r
+\r
+ // temporarily resize the tab control to calc page size\r
+ CRect rectSave;\r
+ pTab->GetWindowRect(rectSave);\r
+ ::MapWindowPoints(NULL, m_hWnd, (LPPOINT)&rectSave, 2);\r
+ pTab->SetRedraw(FALSE);\r
+ pTab->MoveWindow(rectPage, FALSE);\r
+ pTab->AdjustRect(TRUE, &rectTabMargins);\r
+ pTab->MoveWindow(rectSave, FALSE);\r
+ pTab->SetRedraw(TRUE);\r
+\r
+ // add non-client size\r
+ ::AdjustWindowRectEx(&rectTabMargins, GetStyle(), !(GetStyle() & WS_CHILD) &&\r
+ ::IsMenu(GetMenu()->GetSafeHmenu()), GetExStyle());\r
+\r
+ // compute extra size\r
+ sizeExtra = rectMargins.TopLeft() + rectMargins.BottomRight() +\r
+ rectTabMargins.Size();\r
+ return TRUE;\r
+}\r
+\r
+void CResizableSheet::OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI) \r
+{\r
+ MinMaxInfo(lpMMI);\r
+\r
+ CTabCtrl* pTab = GetTabControl();\r
+ if (!pTab)\r
+ return;\r
+\r
+ int nCount = GetPageCount();\r
+ for (int idx = 0; idx < nCount; ++idx)\r
+ {\r
+ if (IsWizard()) // wizard mode\r
+ {\r
+ // use pre-calculated margins\r
+ CRect rectExtra(-CPoint(m_sizePageTL), -CPoint(m_sizePageBR));\r
+ // add non-client size\r
+ ::AdjustWindowRectEx(&rectExtra, GetStyle(), !(GetStyle() & WS_CHILD) &&\r
+ ::IsMenu(GetMenu()->GetSafeHmenu()), GetExStyle());\r
+ ChainMinMaxInfo(lpMMI, *GetPage(idx), rectExtra.Size());\r
+ }\r
+ else // tab mode\r
+ {\r
+ ChainMinMaxInfoCB(lpMMI, *GetPage(idx));\r
+ }\r
+ }\r
+}\r
+\r
+// protected members\r
+\r
+int CResizableSheet::GetMinWidth()\r
+{\r
+ CWnd* pWnd = NULL;\r
+ CRect rectWnd, rectSheet;\r
+ GetTotalClientRect(&rectSheet);\r
+\r
+ int max = 0, min = rectSheet.Width();\r
+ // search for leftmost and rightmost button margins\r
+ for (int i = 0; i < 7; i++)\r
+ {\r
+ pWnd = GetDlgItem(_propButtons[i]);\r
+ // exclude not present or hidden buttons\r
+ if (pWnd == NULL || !(pWnd->GetStyle() & WS_VISIBLE))\r
+ continue;\r
+\r
+ // left position is relative to the right border\r
+ // of the parent window (negative value)\r
+ pWnd->GetWindowRect(&rectWnd);\r
+ ::MapWindowPoints(NULL, m_hWnd, (LPPOINT)&rectWnd, 2);\r
+ int left = rectSheet.right - rectWnd.left;\r
+ int right = rectSheet.right - rectWnd.right;\r
+\r
+ if (left > max)\r
+ max = left;\r
+ if (right < min)\r
+ min = right;\r
+ }\r
+\r
+ // sizing border width\r
+ int border = GetSystemMetrics(SM_CXSIZEFRAME);\r
+ \r
+ // compute total width\r
+ return max + min + 2*border;\r
+}\r
+\r
+\r
+// NOTE: this must be called after all the other settings\r
+// to have the window and its controls displayed properly\r
+void CResizableSheet::EnableSaveRestore(LPCTSTR pszSection, BOOL bRectOnly, BOOL bWithPage)\r
+{\r
+ m_sSection = pszSection;\r
+ m_bSavePage = bWithPage;\r
+\r
+ m_bEnableSaveRestore = TRUE;\r
+ m_bRectOnly = bRectOnly;\r
+\r
+ // restore immediately\r
+ LoadWindowRect(pszSection, bRectOnly);\r
+ {\r
+ LoadPage(pszSection);\r
+ ArrangeLayout(); // needs refresh\r
+ }\r
+}\r
+\r
+void CResizableSheet::RefreshLayout()\r
+{\r
+ SendMessage(WM_SIZE);\r
+}\r
+\r
+LRESULT CResizableSheet::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) \r
+{\r
+ if (message != WM_NCCALCSIZE || wParam == 0 || !m_bLayoutDone)\r
+ return CPropertySheet::WindowProc(message, wParam, lParam);\r
+\r
+ // specifying valid rects needs controls already anchored\r
+ LRESULT lResult = 0;\r
+ HandleNcCalcSize(FALSE, (LPNCCALCSIZE_PARAMS)lParam, lResult);\r
+ lResult = CPropertySheet::WindowProc(message, wParam, lParam);\r
+ HandleNcCalcSize(TRUE, (LPNCCALCSIZE_PARAMS)lParam, lResult);\r
+ return lResult;\r
+}\r
--- /dev/null
+#if !defined(AFX_RESIZABLESHEET_H__INCLUDED_)\r
+#define AFX_RESIZABLESHEET_H__INCLUDED_\r
+\r
+#if _MSC_VER > 1000\r
+#pragma once\r
+#endif // _MSC_VER > 1000\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// This file is part of ResizableLib\r
+// http://sourceforge.net/projects/resizablelib\r
+//\r
+// Copyright (C) 2000-2004 by Paolo Messina\r
+// http://www.geocities.com/ppescher - mailto:ppescher@hotmail.com\r
+//\r
+// The contents of this file are subject to the Artistic License (the "License").\r
+// You may not use this file except in compliance with the License. \r
+// You may obtain a copy of the License at:\r
+// http://www.opensource.org/licenses/artistic-license.html\r
+//\r
+// If you find this code useful, credits would be nice!\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+#include "ResizableLayout.h"\r
+#include "ResizableGrip.h"\r
+#include "ResizableMinMax.h"\r
+#include "ResizableSheetState.h"\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+// ResizableSheet.h : header file\r
+//\r
+\r
+class CResizableSheet : public CPropertySheet, public CResizableLayout,\r
+ public CResizableGrip, public CResizableMinMax,\r
+ public CResizableSheetState\r
+{\r
+ DECLARE_DYNAMIC(CResizableSheet)\r
+\r
+// Construction\r
+public:\r
+ CResizableSheet();\r
+ CResizableSheet(UINT nIDCaption, CWnd *pParentWnd = NULL, UINT iSelectPage = 0);\r
+ CResizableSheet(LPCTSTR pszCaption, CWnd *pParentWnd = NULL, UINT iSelectPage = 0);\r
+\r
+// Attributes\r
+private:\r
+ // support for temporarily hiding the grip\r
+ DWORD m_dwGripTempState;\r
+\r
+ // flags\r
+ BOOL m_bEnableSaveRestore;\r
+ BOOL m_bRectOnly;\r
+ BOOL m_bSavePage;\r
+\r
+ // layout vars\r
+ UINT_PTR m_nCallbackID;\r
+ CSize m_sizePageTL, m_sizePageBR;\r
+ BOOL m_bLayoutDone;\r
+\r
+ // internal status\r
+ CString m_sSection; // section name (identifies a parent window)\r
+\r
+// Operations\r
+public:\r
+\r
+// Overrides\r
+ // ClassWizard generated virtual function overrides\r
+ //{{AFX_VIRTUAL(CResizableSheet)\r
+ public:\r
+ virtual BOOL OnInitDialog();\r
+ protected:\r
+ virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);\r
+ //}}AFX_VIRTUAL\r
+ protected:\r
+\r
+// Implementation\r
+public:\r
+ virtual ~CResizableSheet();\r
+\r
+// used internally\r
+private:\r
+ void PrivateConstruct();\r
+\r
+ BOOL IsWizard() const;\r
+\r
+// callable from derived classes\r
+protected:\r
+ void PresetLayout();\r
+ void RefreshLayout();\r
+\r
+ // section to use in app's profile\r
+ void EnableSaveRestore(LPCTSTR pszSection, BOOL bRectOnly = FALSE,\r
+ BOOL bWithPage = FALSE);\r
+ int GetMinWidth(); // minimum width to display all buttons\r
+\r
+\r
+ virtual CWnd* GetResizableWnd() const\r
+ {\r
+ // make the layout know its parent window\r
+ return CWnd::FromHandle(m_hWnd);\r
+ };\r
+\r
+// Generated message map functions\r
+protected:\r
+ virtual BOOL CalcSizeExtra(HWND hWndChild, CSize sizeChild, CSize& sizeExtra);\r
+ virtual BOOL ArrangeLayoutCallback(LAYOUTINFO& layout) const;\r
+ //{{AFX_MSG(CResizableSheet)\r
+ afx_msg void OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI);\r
+ afx_msg void OnSize(UINT nType, int cx, int cy);\r
+ afx_msg void OnDestroy();\r
+ afx_msg BOOL OnEraseBkgnd(CDC* pDC);\r
+ afx_msg BOOL OnNcCreate(LPCREATESTRUCT lpCreateStruct);\r
+ //}}AFX_MSG\r
+ afx_msg BOOL OnPageChanging(NMHDR* pNotifyStruct, LRESULT* pResult);\r
+ DECLARE_MESSAGE_MAP()\r
+};\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+#endif // AFX_RESIZABLESHEET_H__INCLUDED_\r
--- /dev/null
+// ResizableSheetEx.cpp : implementation file\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// This file is part of ResizableLib\r
+// http://sourceforge.net/projects/resizablelib\r
+//\r
+// Copyright (C) 2000-2004 by Paolo Messina\r
+// http://www.geocities.com/ppescher - mailto:ppescher@hotmail.com\r
+//\r
+// The contents of this file are subject to the Artistic License (the "License").\r
+// You may not use this file except in compliance with the License. \r
+// You may obtain a copy of the License at:\r
+// http://www.opensource.org/licenses/artistic-license.html\r
+//\r
+// If you find this code useful, credits would be nice!\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+#include "stdafx.h"\r
+#include "ResizableSheetEx.h"\r
+\r
+#ifdef _DEBUG\r
+#define new DEBUG_NEW\r
+#undef THIS_FILE\r
+static char THIS_FILE[] = __FILE__;\r
+#endif\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+// CResizableSheetEx\r
+\r
+IMPLEMENT_DYNAMIC(CResizableSheetEx, CPropertySheetEx)\r
+\r
+inline void CResizableSheetEx::PrivateConstruct()\r
+{\r
+ m_bEnableSaveRestore = FALSE;\r
+ m_bSavePage = FALSE;\r
+ m_dwGripTempState = 1;\r
+ m_bLayoutDone = FALSE;\r
+}\r
+\r
+inline BOOL CResizableSheetEx::IsWizard() const\r
+{\r
+ return (m_psh.dwFlags & PSH_WIZARD);\r
+}\r
+\r
+inline BOOL CResizableSheetEx::IsWizard97() const\r
+{\r
+ return (m_psh.dwFlags & (PSH_IE4WIZARD97 | PSH_IE5WIZARD97));\r
+}\r
+\r
+CResizableSheetEx::CResizableSheetEx()\r
+{\r
+ PrivateConstruct();\r
+}\r
+\r
+CResizableSheetEx::CResizableSheetEx(UINT nIDCaption, CWnd* pParentWnd,\r
+ UINT iSelectPage, HBITMAP hbmWatermark, HPALETTE hpalWatermark,\r
+ HBITMAP hbmHeader)\r
+: CPropertySheetEx(nIDCaption, pParentWnd, iSelectPage,\r
+ hbmWatermark, hpalWatermark, hbmHeader)\r
+{\r
+ PrivateConstruct();\r
+}\r
+\r
+CResizableSheetEx::CResizableSheetEx(LPCTSTR pszCaption, CWnd* pParentWnd,\r
+ UINT iSelectPage, HBITMAP hbmWatermark, HPALETTE hpalWatermark,\r
+ HBITMAP hbmHeader)\r
+: CPropertySheetEx(pszCaption, pParentWnd, iSelectPage,\r
+ hbmWatermark, hpalWatermark, hbmHeader)\r
+{\r
+ PrivateConstruct();\r
+}\r
+\r
+\r
+CResizableSheetEx::~CResizableSheetEx()\r
+{\r
+}\r
+\r
+BEGIN_MESSAGE_MAP(CResizableSheetEx, CPropertySheetEx)\r
+ //{{AFX_MSG_MAP(CResizableSheetEx)\r
+ ON_WM_GETMINMAXINFO()\r
+ ON_WM_SIZE()\r
+ ON_WM_DESTROY()\r
+ ON_WM_ERASEBKGND()\r
+ ON_WM_NCCREATE()\r
+ //}}AFX_MSG_MAP\r
+ ON_NOTIFY_REFLECT_EX(PSN_SETACTIVE, OnPageChanging)\r
+ ON_REGISTERED_MESSAGE(WMU_RESIZESUPPORT, OnResizeSupport)\r
+END_MESSAGE_MAP()\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+// CResizableSheetEx message handlers\r
+\r
+BOOL CResizableSheetEx::OnNcCreate(LPCREATESTRUCT lpCreateStruct) \r
+{\r
+ if (!CPropertySheetEx::OnNcCreate(lpCreateStruct))\r
+ return FALSE;\r
+\r
+ // child dialogs don't want resizable border or size grip,\r
+ // nor they can handle the min/max size constraints\r
+ BOOL bChild = lpCreateStruct->style & WS_CHILD;\r
+\r
+ // create and init the size-grip\r
+ if (!CreateSizeGrip(!bChild))\r
+ return FALSE;\r
+\r
+ MakeResizable(lpCreateStruct);\r
+ \r
+ return TRUE;\r
+}\r
+\r
+BOOL CResizableSheetEx::OnInitDialog() \r
+{\r
+ BOOL bResult = CPropertySheetEx::OnInitDialog();\r
+ \r
+ // set the initial size as the min track size\r
+ CRect rc;\r
+ GetWindowRect(&rc);\r
+ SetMinTrackSize(rc.Size());\r
+\r
+ // initialize layout\r
+ PresetLayout();\r
+ m_bLayoutDone = TRUE;\r
+\r
+ return bResult;\r
+}\r
+\r
+LRESULT CResizableSheetEx::OnResizeSupport(WPARAM wParam, LPARAM lParam)\r
+{\r
+ switch (wParam)\r
+ {\r
+ case RSZSUP_SHEETPAGEEXHACK:\r
+ {\r
+ // a window object must be still associated to the page handle\r
+ // but MFC subclassing has been turned off to allow the system\r
+ // to subclass it first, so we can catch all the messages\r
+ CWnd* pWnd = CWnd::FromHandlePermanent((HWND)lParam);\r
+ if (pWnd == NULL)\r
+ return 0;\r
+\r
+ // suclass the window again and refresh page and sheet\r
+ pWnd->SubclassWindow(pWnd->Detach());\r
+ RefreshLayout();\r
+ pWnd->SendMessage(WM_SIZE);\r
+ Invalidate();\r
+ UnlockWindowUpdate();\r
+\r
+ if (pWnd->IsWindowVisible())\r
+ {\r
+ // send lost PSN_SETACTIVE notification message\r
+ CPropertyPage* pPage = DYNAMIC_DOWNCAST(CPropertyPage, pWnd);\r
+ if (pPage != NULL)\r
+ SetActivePage(pPage);\r
+ }\r
+ }\r
+ break;\r
+\r
+ default:\r
+ return FALSE;\r
+ }\r
+ return TRUE;\r
+}\r
+\r
+void CResizableSheetEx::OnDestroy() \r
+{\r
+ if (m_bEnableSaveRestore)\r
+ {\r
+ SaveWindowRect(m_sSection, m_bRectOnly);\r
+ if (m_bSavePage)\r
+ SavePage(m_sSection);\r
+ }\r
+\r
+ RemoveAllAnchors();\r
+\r
+ CPropertySheetEx::OnDestroy();\r
+}\r
+\r
+// maps an index to a button ID and vice-versa\r
+static UINT _propButtons[] =\r
+{\r
+ IDOK, IDCANCEL, ID_APPLY_NOW, IDHELP,\r
+ ID_WIZBACK, ID_WIZNEXT, ID_WIZFINISH\r
+};\r
+const int _propButtonsCount = sizeof(_propButtons)/sizeof(UINT);\r
+\r
+// horizontal line in wizard mode\r
+#define ID_WIZLINE ID_WIZFINISH+1\r
+#define ID_WIZLINEHDR ID_WIZFINISH+2\r
+\r
+void CResizableSheetEx::PresetLayout()\r
+{\r
+ if (IsWizard() || IsWizard97()) // wizard mode\r
+ {\r
+ // hide tab control\r
+ GetTabControl()->ShowWindow(SW_HIDE);\r
+\r
+ AddAnchor(ID_WIZLINE, BOTTOM_LEFT, BOTTOM_RIGHT);\r
+\r
+ if (IsWizard97()) // add header line for wizard97 dialogs\r
+ AddAnchor(ID_WIZLINEHDR, TOP_LEFT, TOP_RIGHT);\r
+ }\r
+ else // tab mode\r
+ {\r
+ AddAnchor(AFX_IDC_TAB_CONTROL, TOP_LEFT, BOTTOM_RIGHT);\r
+ }\r
+\r
+ // add a callback for active page (which can change at run-time)\r
+ m_nCallbackID = AddAnchorCallback();\r
+\r
+ // use *total* parent size to have correct margins\r
+ CRect rectPage, rectSheet;\r
+ GetTotalClientRect(&rectSheet);\r
+\r
+ GetActivePage()->GetWindowRect(&rectPage);\r
+ ::MapWindowPoints(NULL, m_hWnd, (LPPOINT)&rectPage, 2);\r
+\r
+ // pre-calculate margins\r
+ m_sizePageTL = rectPage.TopLeft() - rectSheet.TopLeft();\r
+ m_sizePageBR = rectPage.BottomRight() - rectSheet.BottomRight();\r
+\r
+ // add all possible buttons, if they exist\r
+ for (int i = 0; i < _propButtonsCount; i++)\r
+ {\r
+ if (NULL != GetDlgItem(_propButtons[i]))\r
+ AddAnchor(_propButtons[i], BOTTOM_RIGHT);\r
+ }\r
+}\r
+\r
+BOOL CResizableSheetEx::ArrangeLayoutCallback(LAYOUTINFO &layout) const\r
+{\r
+ if (layout.nCallbackID != m_nCallbackID) // we only added 1 callback\r
+ return CResizableLayout::ArrangeLayoutCallback(layout);\r
+\r
+ // set layout info for active page\r
+ layout.hWnd = (HWND)::SendMessage(GetSafeHwnd(), PSM_GETCURRENTPAGEHWND, 0, 0);\r
+ if (!::IsWindow(layout.hWnd))\r
+ return FALSE;\r
+\r
+ // set margins\r
+ if (IsWizard()) // wizard mode\r
+ {\r
+ // use pre-calculated margins\r
+ layout.marginTopLeft = m_sizePageTL;\r
+ layout.marginBottomRight = m_sizePageBR;\r
+ }\r
+ else if (IsWizard97()) // wizard 97\r
+ {\r
+ // use pre-calculated margins\r
+ layout.marginTopLeft = m_sizePageTL;\r
+ layout.marginBottomRight = m_sizePageBR;\r
+\r
+ if (!(GetActivePage()->m_psp.dwFlags & PSP_HIDEHEADER))\r
+ {\r
+ // add header vertical offset\r
+ CRect rectLine, rectSheet;\r
+ GetTotalClientRect(&rectSheet);\r
+ GetAnchorPosition(ID_WIZLINEHDR, rectSheet, rectLine);\r
+\r
+ layout.marginTopLeft.cy = rectLine.bottom;\r
+ }\r
+ }\r
+ else // tab mode\r
+ {\r
+ CTabCtrl* pTab = GetTabControl();\r
+ ASSERT(pTab != NULL);\r
+\r
+ // get tab position after resizing and calc page rect\r
+ CRect rectPage, rectSheet;\r
+ GetTotalClientRect(&rectSheet);\r
+\r
+ if (!GetAnchorPosition(pTab->m_hWnd, rectSheet, rectPage))\r
+ return FALSE; // no page yet\r
+\r
+ // temporarily resize the tab control to calc page size\r
+ CRect rectSave;\r
+ pTab->GetWindowRect(rectSave);\r
+ ::MapWindowPoints(NULL, m_hWnd, (LPPOINT)&rectSave, 2);\r
+ pTab->SetRedraw(FALSE);\r
+ pTab->MoveWindow(rectPage, FALSE);\r
+ pTab->AdjustRect(FALSE, &rectPage);\r
+ pTab->MoveWindow(rectSave, FALSE);\r
+ pTab->SetRedraw(TRUE);\r
+\r
+ // set margins\r
+ layout.marginTopLeft = rectPage.TopLeft() - rectSheet.TopLeft();\r
+ layout.marginBottomRight = rectPage.BottomRight() - rectSheet.BottomRight();\r
+ }\r
+\r
+ // set anchor types\r
+ layout.anchorTopLeft = TOP_LEFT;\r
+ layout.anchorBottomRight = BOTTOM_RIGHT;\r
+\r
+ // use this layout info\r
+ return TRUE;\r
+}\r
+\r
+void CResizableSheetEx::OnSize(UINT nType, int cx, int cy) \r
+{\r
+ CWnd::OnSize(nType, cx, cy);\r
+ \r
+ if (nType == SIZE_MAXHIDE || nType == SIZE_MAXSHOW)\r
+ return; // arrangement not needed\r
+\r
+ if (nType == SIZE_MAXIMIZED)\r
+ HideSizeGrip(&m_dwGripTempState);\r
+ else\r
+ ShowSizeGrip(&m_dwGripTempState);\r
+\r
+ // update grip and layout\r
+ UpdateSizeGrip();\r
+ ArrangeLayout();\r
+\r
+ if (IsWizard97())\r
+ {\r
+ // refresh header area\r
+ CRect rect;\r
+ GetHeaderRect(rect);\r
+ InvalidateRect(rect, FALSE);\r
+ }\r
+}\r
+\r
+BOOL CResizableSheetEx::OnPageChanging(NMHDR* /*pNotifyStruct*/, LRESULT* /*pResult*/)\r
+{\r
+ // update new wizard page\r
+ // active page changes after this notification\r
+ PostMessage(WM_SIZE);\r
+\r
+ return FALSE; // continue routing\r
+}\r
+\r
+BOOL CResizableSheetEx::OnEraseBkgnd(CDC* pDC) \r
+{\r
+ if (ClipChildren(pDC, FALSE))\r
+ {\r
+ // when clipping, remove header from clipping area\r
+ if (IsWizard97())\r
+ {\r
+ // clip header area out\r
+ CRect rect;\r
+ GetHeaderRect(rect);\r
+ pDC->ExcludeClipRect(rect);\r
+ }\r
+ }\r
+\r
+ BOOL bRet = CPropertySheetEx::OnEraseBkgnd(pDC);\r
+\r
+ ClipChildren(pDC, TRUE);\r
+\r
+ return bRet;\r
+}\r
+\r
+BOOL CResizableSheetEx::CalcSizeExtra(HWND /*hWndChild*/, CSize sizeChild, CSize &sizeExtra)\r
+{\r
+ CTabCtrl* pTab = GetTabControl();\r
+ if (!pTab)\r
+ return FALSE;\r
+\r
+ // get margins of tabcontrol\r
+ CRect rectMargins;\r
+ if (!GetAnchorMargins(pTab->m_hWnd, sizeChild, rectMargins))\r
+ return FALSE;\r
+\r
+ // get margin caused by tabcontrol\r
+ CRect rectTabMargins(0,0,0,0);\r
+\r
+ // get tab position after resizing and calc page rect\r
+ CRect rectPage, rectSheet;\r
+ GetTotalClientRect(&rectSheet);\r
+\r
+ if (!GetAnchorPosition(pTab->m_hWnd, rectSheet, rectPage))\r
+ return FALSE; // no page yet\r
+\r
+ // temporarily resize the tab control to calc page size\r
+ CRect rectSave;\r
+ pTab->GetWindowRect(rectSave);\r
+ ::MapWindowPoints(NULL, m_hWnd, (LPPOINT)&rectSave, 2);\r
+ pTab->SetRedraw(FALSE);\r
+ pTab->MoveWindow(rectPage, FALSE);\r
+ pTab->AdjustRect(TRUE, &rectTabMargins);\r
+ pTab->MoveWindow(rectSave, FALSE);\r
+ pTab->SetRedraw(TRUE);\r
+\r
+ // add non-client size\r
+ ::AdjustWindowRectEx(&rectTabMargins, GetStyle(), !(GetStyle() & WS_CHILD) &&\r
+ ::IsMenu(GetMenu()->GetSafeHmenu()), GetExStyle());\r
+\r
+ // compute extra size\r
+ sizeExtra = rectMargins.TopLeft() + rectMargins.BottomRight() +\r
+ rectTabMargins.Size();\r
+ return TRUE;\r
+}\r
+\r
+void CResizableSheetEx::OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI) \r
+{\r
+ MinMaxInfo(lpMMI);\r
+\r
+ CTabCtrl* pTab = GetTabControl();\r
+ if (!pTab)\r
+ return;\r
+\r
+ int nCount = GetPageCount();\r
+ for (int idx = 0; idx < nCount; ++idx)\r
+ {\r
+ if (IsWizard()) // wizard mode\r
+ {\r
+ // use pre-calculated margins\r
+ CRect rectExtra(-CPoint(m_sizePageTL), -CPoint(m_sizePageBR));\r
+ // add non-client size\r
+ ::AdjustWindowRectEx(&rectExtra, GetStyle(), !(GetStyle() & WS_CHILD) &&\r
+ ::IsMenu(GetMenu()->GetSafeHmenu()), GetExStyle());\r
+ ChainMinMaxInfo(lpMMI, *GetPage(idx), rectExtra.Size());\r
+ }\r
+ else if (IsWizard97()) // wizard 97\r
+ {\r
+ // use pre-calculated margins\r
+ CRect rectExtra(-CPoint(m_sizePageTL), -CPoint(m_sizePageBR));\r
+\r
+ if (!(GetPage(idx)->m_psp.dwFlags & PSP_HIDEHEADER))\r
+ {\r
+ // add header vertical offset\r
+ CRect rectLine, rectSheet;\r
+ GetTotalClientRect(&rectSheet);\r
+ GetAnchorPosition(ID_WIZLINEHDR, rectSheet, rectLine);\r
+\r
+ rectExtra.top = -rectLine.bottom;\r
+ }\r
+ // add non-client size\r
+ ::AdjustWindowRectEx(&rectExtra, GetStyle(), !(GetStyle() & WS_CHILD) &&\r
+ ::IsMenu(GetMenu()->GetSafeHmenu()), GetExStyle());\r
+ ChainMinMaxInfo(lpMMI, *GetPage(idx), rectExtra.Size());\r
+ }\r
+ else // tab mode\r
+ {\r
+ ChainMinMaxInfoCB(lpMMI, *GetPage(idx));\r
+ }\r
+ }\r
+}\r
+\r
+// protected members\r
+\r
+void CResizableSheetEx::GetHeaderRect(LPRECT lpRect)\r
+{\r
+ CWnd* pWizLineHdr = GetDlgItem(ID_WIZLINEHDR);\r
+ if (pWizLineHdr != NULL && pWizLineHdr->IsWindowVisible())\r
+ {\r
+ pWizLineHdr->GetWindowRect(lpRect);\r
+ ::MapWindowPoints(NULL, m_hWnd, (LPPOINT)lpRect, 2);\r
+ LONG bottom = lpRect->top;\r
+ GetClientRect(lpRect);\r
+ lpRect->bottom = bottom;\r
+ }\r
+ else\r
+ ::SetRectEmpty(lpRect);\r
+}\r
+\r
+int CResizableSheetEx::GetMinWidth()\r
+{\r
+ CWnd* pWnd = NULL;\r
+ CRect rectWnd, rectSheet;\r
+ GetTotalClientRect(&rectSheet);\r
+\r
+ int max = 0, min = rectSheet.Width();\r
+ // search for leftmost and rightmost button margins\r
+ for (int i = 0; i < 7; i++)\r
+ {\r
+ pWnd = GetDlgItem(_propButtons[i]);\r
+ // exclude not present or hidden buttons\r
+ if (pWnd == NULL || !(pWnd->GetStyle() & WS_VISIBLE))\r
+ continue;\r
+\r
+ // left position is relative to the right border\r
+ // of the parent window (negative value)\r
+ pWnd->GetWindowRect(&rectWnd);\r
+ ::MapWindowPoints(NULL, m_hWnd, (LPPOINT)&rectWnd, 2);\r
+ int left = rectSheet.right - rectWnd.left;\r
+ int right = rectSheet.right - rectWnd.right;\r
+ \r
+ if (left > max)\r
+ max = left;\r
+ if (right < min)\r
+ min = right;\r
+ }\r
+\r
+ // sizing border width\r
+ int border = GetSystemMetrics(SM_CXSIZEFRAME);\r
+ \r
+ // compute total width\r
+ return max + min + 2*border;\r
+}\r
+\r
+// NOTE: this must be called after all the other settings\r
+// to have the window and its controls displayed properly\r
+void CResizableSheetEx::EnableSaveRestore(LPCTSTR pszSection, BOOL bRectOnly, BOOL bWithPage)\r
+{\r
+ m_sSection = pszSection;\r
+ m_bSavePage = bWithPage;\r
+\r
+ m_bEnableSaveRestore = TRUE;\r
+ m_bRectOnly = bRectOnly;\r
+\r
+ // restore immediately\r
+ LoadWindowRect(pszSection, bRectOnly);\r
+ if (bWithPage)\r
+ {\r
+ LoadPage(pszSection);\r
+ ArrangeLayout(); // needs refresh\r
+ }\r
+}\r
+\r
+void CResizableSheetEx::RefreshLayout()\r
+{\r
+ SendMessage(WM_SIZE);\r
+}\r
+\r
+LRESULT CResizableSheetEx::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) \r
+{\r
+ if (message != WM_NCCALCSIZE || wParam == 0 || !m_bLayoutDone)\r
+ return CPropertySheetEx::WindowProc(message, wParam, lParam);\r
+\r
+ // specifying valid rects needs controls already anchored\r
+ LRESULT lResult = 0;\r
+ HandleNcCalcSize(FALSE, (LPNCCALCSIZE_PARAMS)lParam, lResult);\r
+ lResult = CPropertySheetEx::WindowProc(message, wParam, lParam);\r
+ HandleNcCalcSize(TRUE, (LPNCCALCSIZE_PARAMS)lParam, lResult);\r
+ return lResult;\r
+}\r
--- /dev/null
+#if !defined(AFX_RESIZABLESHEETEX_H__INCLUDED_)\r
+#define AFX_RESIZABLESHEETEX_H__INCLUDED_\r
+\r
+#if _MSC_VER > 1000\r
+#pragma once\r
+#endif // _MSC_VER > 1000\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// This file is part of ResizableLib\r
+// http://sourceforge.net/projects/resizablelib\r
+//\r
+// Copyright (C) 2000-2004 by Paolo Messina\r
+// http://www.geocities.com/ppescher - mailto:ppescher@hotmail.com\r
+//\r
+// The contents of this file are subject to the Artistic License (the "License").\r
+// You may not use this file except in compliance with the License. \r
+// You may obtain a copy of the License at:\r
+// http://www.opensource.org/licenses/artistic-license.html\r
+//\r
+// If you find this code useful, credits would be nice!\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+#include "ResizableLayout.h"\r
+#include "ResizableGrip.h"\r
+#include "ResizableMinMax.h"\r
+#include "ResizableSheetState.h"\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+// ResizableSheetEx.h : header file\r
+//\r
+\r
+class CResizableSheetEx : public CPropertySheetEx, public CResizableLayout,\r
+ public CResizableGrip, public CResizableMinMax,\r
+ public CResizableSheetState\r
+{\r
+ DECLARE_DYNAMIC(CResizableSheetEx)\r
+\r
+// Construction\r
+public:\r
+ CResizableSheetEx();\r
+ CResizableSheetEx(UINT nIDCaption, CWnd* pParentWnd = NULL, UINT iSelectPage = 0,\r
+ HBITMAP hbmWatermark = NULL, HPALETTE hpalWatermark = NULL, HBITMAP hbmHeader = NULL);\r
+ CResizableSheetEx(LPCTSTR pszCaption, CWnd* pParentWnd = NULL, UINT iSelectPage = 0,\r
+ HBITMAP hbmWatermark = NULL, HPALETTE hpalWatermark = NULL, HBITMAP hbmHeader = NULL);\r
+\r
+// Attributes\r
+private:\r
+ // support for temporarily hiding the grip\r
+ DWORD m_dwGripTempState;\r
+\r
+ // flags\r
+ BOOL m_bEnableSaveRestore;\r
+ BOOL m_bRectOnly;\r
+ BOOL m_bSavePage;\r
+\r
+ // layout vars\r
+ UINT_PTR m_nCallbackID;\r
+ CSize m_sizePageTL, m_sizePageBR;\r
+ BOOL m_bLayoutDone;\r
+\r
+ // internal status\r
+ CString m_sSection; // section name (identifies a parent window)\r
+\r
+// Operations\r
+public:\r
+ enum\r
+ {\r
+ PSH_IE4WIZARD97 = 0x00002000,\r
+ PSH_IE5WIZARD97 = 0x01000000,\r
+ };\r
+\r
+// Overrides\r
+ // ClassWizard generated virtual function overrides\r
+ //{{AFX_VIRTUAL(CResizableSheetEx)\r
+ public:\r
+ virtual BOOL OnInitDialog();\r
+ protected:\r
+ virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);\r
+ //}}AFX_VIRTUAL\r
+\r
+// Implementation\r
+public:\r
+ virtual ~CResizableSheetEx();\r
+\r
+// used internally\r
+private:\r
+ void PrivateConstruct();\r
+\r
+ BOOL IsWizard() const;\r
+ BOOL IsWizard97() const;\r
+\r
+// callable from derived classes\r
+protected:\r
+ void RefreshLayout();\r
+ void PresetLayout();\r
+\r
+ // section to use in app's profile\r
+ void EnableSaveRestore(LPCTSTR pszSection, BOOL bRectOnly = FALSE,\r
+ BOOL bWithPage = FALSE);\r
+ int GetMinWidth(); // minimum width to display all buttons\r
+\r
+\r
+ virtual CWnd* GetResizableWnd() const\r
+ {\r
+ // make the layout know its parent window\r
+ return CWnd::FromHandle(m_hWnd);\r
+ };\r
+\r
+// Generated message map functions\r
+protected:\r
+ void GetHeaderRect(LPRECT lpRect);\r
+ virtual BOOL CalcSizeExtra(HWND hWndChild, CSize sizeChild, CSize& sizeExtra);\r
+ virtual BOOL ArrangeLayoutCallback(LAYOUTINFO& layout) const;\r
+ //{{AFX_MSG(CResizableSheetEx)\r
+ afx_msg void OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI);\r
+ afx_msg void OnSize(UINT nType, int cx, int cy);\r
+ afx_msg void OnDestroy();\r
+ afx_msg BOOL OnEraseBkgnd(CDC* pDC);\r
+ afx_msg BOOL OnNcCreate(LPCREATESTRUCT lpCreateStruct);\r
+ //}}AFX_MSG\r
+ afx_msg BOOL OnPageChanging(NMHDR* pNotifyStruct, LRESULT* pResult);\r
+ afx_msg LRESULT OnResizeSupport(WPARAM wParam, LPARAM lParam);\r
+ DECLARE_MESSAGE_MAP()\r
+};\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+#endif // AFX_RESIZABLESHEETEX_H__INCLUDED_\r
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// This file is part of ResizableLib\r
+// http://sourceforge.net/projects/resizablelib\r
+//\r
+// Copyright (C) 2000-2004 by Paolo Messina\r
+// http://www.geocities.com/ppescher - mailto:ppescher@hotmail.com\r
+//\r
+// The contents of this file are subject to the Artistic License (the "License").\r
+// You may not use this file except in compliance with the License. \r
+// You may obtain a copy of the License at:\r
+// http://www.opensource.org/licenses/artistic-license.html\r
+//\r
+// If you find this code useful, credits would be nice!\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+/*!\r
+ * @file\r
+ * @brief Implementation of the CResizableSheetState class.\r
+ */\r
+\r
+#include "stdafx.h"\r
+#include "ResizableSheetState.h"\r
+\r
+//////////////////////////////////////////////////////////////////////\r
+// Construction/Destruction\r
+//////////////////////////////////////////////////////////////////////\r
+\r
+CResizableSheetState::CResizableSheetState()\r
+{\r
+\r
+}\r
+\r
+CResizableSheetState::~CResizableSheetState()\r
+{\r
+\r
+}\r
+\r
+// used to save/restore active page\r
+// either in the registry or a private .INI file\r
+// depending on your application settings\r
+\r
+#define ACTIVEPAGE_ENT _T("ActivePage")\r
+\r
+/*!\r
+ * This function saves the current property sheet active page using the base\r
+ * class persist method.\r
+ * @sa CResizableState::WriteState\r
+ * \r
+ * @param pszName String that identifies stored settings\r
+ * \r
+ * @return Returns @a TRUE if successful, @a FALSE otherwise\r
+ */\r
+BOOL CResizableSheetState::SavePage(LPCTSTR pszName)\r
+{\r
+ // saves active page index, or the initial page if problems\r
+ // cannot use GetActivePage, because it always fails\r
+\r
+ CPropertySheet* pSheet = DYNAMIC_DOWNCAST(CPropertySheet, GetResizableWnd());\r
+ if (pSheet == NULL)\r
+ return FALSE;\r
+\r
+ int page = pSheet->m_psh.nStartPage;\r
+ CTabCtrl *pTab = pSheet->GetTabControl();\r
+ if (pTab != NULL) \r
+ page = pTab->GetCurSel();\r
+ if (page < 0)\r
+ page = pSheet->m_psh.nStartPage;\r
+\r
+ CString data, id;\r
+ _itot(page, data.GetBuffer(10), 10);\r
+ id = CString(pszName) + ACTIVEPAGE_ENT;\r
+ return WriteState(id, data);\r
+}\r
+\r
+/*!\r
+ * This function loads the active page using the base class persist method.\r
+ * @sa CResizableState::ReadState\r
+ * \r
+ * @param pszName String that identifies stored settings\r
+ * \r
+ * @return Returns @a TRUE if successful, @a FALSE otherwise\r
+ */\r
+BOOL CResizableSheetState::LoadPage(LPCTSTR pszName)\r
+{\r
+ // restore active page, zero (the first) if not found\r
+\r
+ CString data, id;\r
+ id = CString(pszName) + ACTIVEPAGE_ENT;\r
+ if (!ReadState(id, data))\r
+ return FALSE;\r
+ \r
+ int page = _ttoi(data);\r
+ CPropertySheet* pSheet = DYNAMIC_DOWNCAST(CPropertySheet, GetResizableWnd());\r
+ if (pSheet != NULL)\r
+ return pSheet->SetActivePage(page);\r
+ return FALSE;\r
+}\r
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// This file is part of ResizableLib\r
+// http://sourceforge.net/projects/resizablelib\r
+//\r
+// Copyright (C) 2000-2004 by Paolo Messina\r
+// http://www.geocities.com/ppescher - mailto:ppescher@hotmail.com\r
+//\r
+// The contents of this file are subject to the Artistic License (the "License").\r
+// You may not use this file except in compliance with the License. \r
+// You may obtain a copy of the License at:\r
+// http://www.opensource.org/licenses/artistic-license.html\r
+//\r
+// If you find this code useful, credits would be nice!\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+/*!\r
+ * @file\r
+ * @brief Interface for the CResizableSheetState class.\r
+ */\r
+\r
+#if !defined(AFX_RESIZABLESHEETSTATE_H__INCLUDED_)\r
+#define AFX_RESIZABLESHEETSTATE_H__INCLUDED_\r
+\r
+#if _MSC_VER > 1000\r
+#pragma once\r
+#endif // _MSC_VER > 1000\r
+\r
+#include "ResizableWndState.h"\r
+\r
+/*! @addtogroup CoreComponents\r
+ * @{\r
+ */\r
+\r
+//! @brief Persists active page in property sheets or wizard dialogs\r
+/*!\r
+ * Derive from this class when you want to persist the active page\r
+ * in property sheets or wizard dialogs.\r
+ * This class is used in the provided resizable counterparts of\r
+ * the standard MFC property sheet classes.\r
+ */\r
+class CResizableSheetState : public CResizableWndState \r
+{\r
+protected:\r
+\r
+ //! @brief Load and set the active property page \r
+ BOOL LoadPage(LPCTSTR pszName);\r
+\r
+ //! @brief Save the current active property page \r
+ BOOL SavePage(LPCTSTR pszName);\r
+\r
+ //! @brief Override to provide the parent window\r
+ virtual CWnd* GetResizableWnd() const = 0;\r
+\r
+public:\r
+ CResizableSheetState();\r
+ virtual ~CResizableSheetState();\r
+};\r
+\r
+// @}\r
+#endif // !defined(AFX_RESIZABLESHEETSTATE_H__INCLUDED_)\r
--- /dev/null
+// ResizableSplitterWnd.cpp : implementation file\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// This file is part of ResizableLib\r
+// http://sourceforge.net/projects/resizablelib\r
+//\r
+// Copyright (C) 2000-2004 by Paolo Messina\r
+// http://www.geocities.com/ppescher - mailto:ppescher@hotmail.com\r
+//\r
+// The contents of this file are subject to the Artistic License (the "License").\r
+// You may not use this file except in compliance with the License. \r
+// You may obtain a copy of the License at:\r
+// http://www.opensource.org/licenses/artistic-license.html\r
+//\r
+// If you find this code useful, credits would be nice!\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+#include "stdafx.h"\r
+#include "ResizableSplitterWnd.h"\r
+\r
+#ifdef _DEBUG\r
+#define new DEBUG_NEW\r
+#undef THIS_FILE\r
+static char THIS_FILE[] = __FILE__;\r
+#endif\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+// CResizableSplitterWnd\r
+\r
+IMPLEMENT_DYNAMIC(CResizableSplitterWnd, CSplitterWnd)\r
+\r
+CResizableSplitterWnd::CResizableSplitterWnd()\r
+{\r
+}\r
+\r
+CResizableSplitterWnd::~CResizableSplitterWnd()\r
+{\r
+}\r
+\r
+BEGIN_MESSAGE_MAP(CResizableSplitterWnd, CSplitterWnd)\r
+ //{{AFX_MSG_MAP(CResizableSplitterWnd)\r
+ ON_WM_GETMINMAXINFO()\r
+ //}}AFX_MSG_MAP\r
+END_MESSAGE_MAP()\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+// CResizableSplitterWnd message handlers\r
+\r
+void CResizableSplitterWnd::OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI) \r
+{\r
+ if ((GetStyle() & SPLS_DYNAMIC_SPLIT) &&\r
+ GetRowCount() == 1 && GetColumnCount() == 1)\r
+ {\r
+ CWnd* pPane = GetActivePane();\r
+ if (pPane != NULL)\r
+ {\r
+ // get the extra size from child to parent\r
+ CRect rectClient, rectWnd;\r
+ GetWindowRect(rectWnd);\r
+ pPane->GetWindowRect(rectClient);\r
+ CSize sizeExtra = rectWnd.Size() - rectClient.Size();\r
+\r
+ ChainMinMaxInfo(lpMMI, pPane->m_hWnd, sizeExtra);\r
+ }\r
+ }\r
+ else if (!(GetStyle() & SPLS_DYNAMIC_SPLIT))\r
+ {\r
+ ASSERT(m_nCols > 0 && m_nRows > 0);\r
+\r
+ CSize sizeMin(0,0), sizeMax(0,0);\r
+ for (int col = 0; col < m_nCols; ++col)\r
+ {\r
+ // calc min and max width for each column\r
+ int min = 0;\r
+ int max = LONG_MAX;\r
+ for (int row = 0; row < m_nRows; ++row)\r
+ {\r
+ CWnd* pWnd = GetPane(row, col);\r
+ // ask the child window for track size\r
+ MINMAXINFO mmiChild = *lpMMI;\r
+ mmiChild.ptMinTrackSize.x = 0;\r
+ mmiChild.ptMaxTrackSize.x = LONG_MAX;\r
+ ::SendMessage(pWnd->GetSafeHwnd(), WM_GETMINMAXINFO, 0, (LPARAM)&mmiChild);\r
+ max = __min(max, mmiChild.ptMaxTrackSize.x);\r
+ min = __max(min, mmiChild.ptMinTrackSize.x);\r
+ }\r
+ // sum all column widths\r
+ if (sizeMax.cx == LONG_MAX || max == LONG_MAX)\r
+ sizeMax.cx = LONG_MAX;\r
+ else\r
+ sizeMax.cx += max + m_cxSplitterGap;\r
+ sizeMin.cx += min + m_cxSplitterGap;\r
+ }\r
+ for (int row = 0; row < m_nRows; ++row)\r
+ {\r
+ // calc min and max height for each row\r
+ int min = 0;\r
+ int max = LONG_MAX;\r
+ for (int col = 0; col < m_nCols; ++col)\r
+ {\r
+ CWnd* pWnd = GetPane(row, col);\r
+ // ask the child window for track size\r
+ MINMAXINFO mmiChild = *lpMMI;\r
+ mmiChild.ptMinTrackSize.y = 0;\r
+ mmiChild.ptMaxTrackSize.y = LONG_MAX;\r
+ ::SendMessage(pWnd->GetSafeHwnd(), WM_GETMINMAXINFO, 0, (LPARAM)&mmiChild);\r
+ max = __min(max, mmiChild.ptMaxTrackSize.y);\r
+ min = __max(min, mmiChild.ptMinTrackSize.y);\r
+ }\r
+ // sum all row heights\r
+ if (sizeMax.cy == LONG_MAX || max == LONG_MAX)\r
+ sizeMax.cy = LONG_MAX;\r
+ else\r
+ sizeMax.cy += max + m_cySplitterGap;\r
+ sizeMin.cy += min + m_cySplitterGap;\r
+ }\r
+ // adjust total size: add the client border and\r
+ // we counted one splitter more than necessary\r
+ sizeMax.cx += 2*m_cxBorder - m_cxSplitterGap;\r
+ sizeMax.cy += 2*m_cyBorder - m_cySplitterGap;\r
+ sizeMin.cx += 2*m_cxBorder - m_cxSplitterGap;\r
+ sizeMin.cy += 2*m_cyBorder - m_cySplitterGap;\r
+ // add non-client size\r
+ CRect rectExtra(0,0,0,0);\r
+ ::AdjustWindowRectEx(&rectExtra, GetStyle(), !(GetStyle() & WS_CHILD) &&\r
+ ::IsMenu(GetMenu()->GetSafeHmenu()), GetExStyle());\r
+ sizeMax += rectExtra.Size();\r
+ sizeMin += rectExtra.Size();\r
+ // set minmax info\r
+ lpMMI->ptMinTrackSize.x = __max(lpMMI->ptMinTrackSize.x, sizeMin.cx);\r
+ lpMMI->ptMinTrackSize.y = __max(lpMMI->ptMinTrackSize.y, sizeMin.cy);\r
+ lpMMI->ptMaxTrackSize.x = __min(lpMMI->ptMaxTrackSize.x, sizeMax.cx);\r
+ lpMMI->ptMaxTrackSize.y = __min(lpMMI->ptMaxTrackSize.y, sizeMax.cy);\r
+ }\r
+}\r
--- /dev/null
+// ResizableSplitterWnd.h : header file\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// This file is part of ResizableLib\r
+// http://sourceforge.net/projects/resizablelib\r
+//\r
+// Copyright (C) 2000-2004 by Paolo Messina\r
+// http://www.geocities.com/ppescher - mailto:ppescher@hotmail.com\r
+//\r
+// The contents of this file are subject to the Artistic License (the "License").\r
+// You may not use this file except in compliance with the License. \r
+// You may obtain a copy of the License at:\r
+// http://www.opensource.org/licenses/artistic-license.html\r
+//\r
+// If you find this code useful, credits would be nice!\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+#if !defined(AFX_RESIZABLESPLITTERWND_H__INCLUDED_)\r
+#define AFX_RESIZABLESPLITTERWND_H__INCLUDED_\r
+\r
+#if _MSC_VER > 1000\r
+#pragma once\r
+#endif // _MSC_VER > 1000\r
+\r
+#include "ResizableMinMax.h"\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+// CResizableSplitterWnd frame with splitter\r
+\r
+class CResizableSplitterWnd : public CSplitterWnd, public CResizableMinMax\r
+{\r
+ DECLARE_DYNAMIC(CResizableSplitterWnd)\r
+\r
+// Construction\r
+public:\r
+ CResizableSplitterWnd();\r
+\r
+// Attributes\r
+public:\r
+\r
+// Operations\r
+public:\r
+\r
+// Overrides\r
+ // ClassWizard generated virtual function overrides\r
+ //{{AFX_VIRTUAL(CResizableSplitterWnd)\r
+ protected:\r
+ //}}AFX_VIRTUAL\r
+\r
+// Implementation\r
+public:\r
+ virtual ~CResizableSplitterWnd();\r
+\r
+ // Generated message map functions\r
+ //{{AFX_MSG(CResizableSplitterWnd)\r
+ afx_msg void OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI);\r
+ //}}AFX_MSG\r
+ DECLARE_MESSAGE_MAP()\r
+};\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+//{{AFX_INSERT_LOCATION}}\r
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.\r
+\r
+#endif // !defined(AFX_RESIZABLESPLITTERWND_H__INCLUDED_)\r
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// This file is part of ResizableLib\r
+// http://sourceforge.net/projects/resizablelib\r
+//\r
+// Copyright (C) 2000-2004 by Paolo Messina\r
+// http://www.geocities.com/ppescher - mailto:ppescher@hotmail.com\r
+//\r
+// The contents of this file are subject to the Artistic License (the "License").\r
+// You may not use this file except in compliance with the License. \r
+// You may obtain a copy of the License at:\r
+// http://www.opensource.org/licenses/artistic-license.html\r
+//\r
+// If you find this code useful, credits would be nice!\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+/*!\r
+ * @file\r
+ * @brief Implementation of the CResizableState class.\r
+ */\r
+\r
+#include "stdafx.h"\r
+#include "ResizableState.h"\r
+\r
+#ifdef _DEBUG\r
+#undef THIS_FILE\r
+static char THIS_FILE[]=__FILE__;\r
+#define new DEBUG_NEW\r
+#endif\r
+\r
+//////////////////////////////////////////////////////////////////////\r
+// Construction/Destruction\r
+//////////////////////////////////////////////////////////////////////\r
+\r
+CResizableState::CResizableState()\r
+{\r
+ m_sStorePath = m_sDefaultStorePath;\r
+}\r
+\r
+CResizableState::~CResizableState()\r
+{\r
+\r
+}\r
+\r
+// static intializer must be called before user code\r
+#pragma warning(disable:4073)\r
+#pragma init_seg(lib)\r
+CString CResizableState::m_sDefaultStorePath(_T("ResizableState"));\r
+\r
+/*!\r
+ * Static function to set the default path used to store state information.\r
+ * This path is used to initialize all the instances of this class.\r
+ * @sa GetDefaultStateStore GetStateStore SetStateStore\r
+ * \r
+ * @param szPath String that specifies the new path to be set\r
+ */\r
+void CResizableState::SetDefaultStateStore(LPCTSTR szPath)\r
+{\r
+ m_sDefaultStorePath = szPath;\r
+}\r
+\r
+/*!\r
+ * Static function to retrieve the default path used to store state\r
+ * information.\r
+ * This path is used to initialize all the instances of this class.\r
+ * @sa SetDefaultStateStore GetStateStore SetStateStore\r
+ * \r
+ * @return The return value is a string that specifies the current path\r
+ */\r
+LPCTSTR CResizableState::GetDefaultStateStore()\r
+{\r
+ return m_sDefaultStorePath;\r
+}\r
+\r
+/*!\r
+ * This function sets the path used to store state information by\r
+ * the current instance of the class.\r
+ * @sa GetStateStore GetDefaultStateStore SetDefaultStateStore\r
+ * \r
+ * @param szPath String that specifies the new path to be set\r
+ */\r
+void CResizableState::SetStateStore(LPCTSTR szPath)\r
+{\r
+ m_sStorePath = szPath;\r
+}\r
+\r
+/*!\r
+ * This function retrieves the path used to store state information by\r
+ * the current instance of the class.\r
+ * @sa SetStateStore GetDefaultStateStore SetDefaultStateStore\r
+ * \r
+ * @return The return value is a string that specifies the current path\r
+ */\r
+LPCTSTR CResizableState::GetStateStore()\r
+{\r
+ return m_sStorePath;\r
+}\r
+\r
+/*!\r
+ * This function writes state information and associates it with some\r
+ * identification text for later retrieval.\r
+ * The base implementation uses the application profile to persist state\r
+ * information, but this function can be overridden to implement\r
+ * different methods.\r
+ * \r
+ * @param szId String that identifies the stored settings\r
+ * @param szState String that represents the state information to store\r
+ * \r
+ * @return The return value is @a TRUE if settings have been successfully\r
+ * stored, @a FALSE otherwise.\r
+ */\r
+BOOL CResizableState::WriteState(LPCTSTR szId, LPCTSTR szState)\r
+{\r
+ return AfxGetApp()->WriteProfileString(GetStateStore(), szId, szState);\r
+}\r
+\r
+/*!\r
+ * This function reads state information previously associated with some\r
+ * identification text.\r
+ * The base implementation uses the application profile to persist state\r
+ * information, but this function can be overridden to implement\r
+ * different methods.\r
+ * \r
+ * @param szId String that identifies the stored settings\r
+ * @param rsState String to be filled with the retrieved state information\r
+ * \r
+ * @return The return value is @a TRUE if settings have been successfully\r
+ * retrieved, @a FALSE otherwise.\r
+ */\r
+BOOL CResizableState::ReadState(LPCTSTR szId, CString &rsState)\r
+{\r
+ rsState = AfxGetApp()->GetProfileString(GetStateStore(), szId);\r
+ return !rsState.IsEmpty();\r
+}\r
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// This file is part of ResizableLib\r
+// http://sourceforge.net/projects/resizablelib\r
+//\r
+// Copyright (C) 2000-2004 by Paolo Messina\r
+// http://www.geocities.com/ppescher - mailto:ppescher@hotmail.com\r
+//\r
+// The contents of this file are subject to the Artistic License (the "License").\r
+// You may not use this file except in compliance with the License. \r
+// You may obtain a copy of the License at:\r
+// http://www.opensource.org/licenses/artistic-license.html\r
+//\r
+// If you find this code useful, credits would be nice!\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+/*!\r
+ * @file\r
+ * @brief Interface for the CResizableState class.\r
+ */\r
+\r
+#if !defined(AFX_RESIZABLESTATE_H__INCLUDED_)\r
+#define AFX_RESIZABLESTATE_H__INCLUDED_\r
+\r
+#if _MSC_VER > 1000\r
+#pragma once\r
+#endif // _MSC_VER > 1000\r
+\r
+/*! @addtogroup CoreComponents\r
+ * @{\r
+ */\r
+\r
+//! @brief Provides basic persisting capabilities\r
+/*!\r
+ * Derive from this class to persist user interface settings, or anything\r
+ * suitable. The base implementation uses the application profile, which can\r
+ * be set to either the Registry or an INI File. Other storing methods\r
+ * can be implemented in derived classes.\r
+ */\r
+class CResizableState \r
+{\r
+ static CString m_sDefaultStorePath;\r
+ CString m_sStorePath;\r
+\r
+protected:\r
+ \r
+ //! @brief Get default path where state is stored\r
+ static LPCTSTR GetDefaultStateStore();\r
+ \r
+ //! @brief Set default path where state is stored\r
+ static void SetDefaultStateStore(LPCTSTR szPath);\r
+\r
+ //! @brief Get current path where state is stored\r
+ LPCTSTR GetStateStore();\r
+ \r
+ //! @brief Set current path where state is stored\r
+ void SetStateStore(LPCTSTR szPath);\r
+\r
+ //! @name Overridables\r
+ //@{\r
+ \r
+ //! @brief Read state information\r
+ virtual BOOL ReadState(LPCTSTR szId, CString& rsState);\r
+ \r
+ //! @brief Write state information\r
+ virtual BOOL WriteState(LPCTSTR szId, LPCTSTR szState);\r
+\r
+ //@}\r
+\r
+public:\r
+ CResizableState();\r
+ virtual ~CResizableState();\r
+};\r
+\r
+// @}\r
+#endif // !defined(AFX_RESIZABLESTATE_H__INCLUDED_)\r
--- /dev/null
+// ResizableVersion.cpp: implementation of the CResizableVersion class.\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// This file is part of ResizableLib\r
+// http://sourceforge.net/projects/resizablelib\r
+//\r
+// Copyright (C) 2000-2004 by Paolo Messina\r
+// http://www.geocities.com/ppescher - mailto:ppescher@hotmail.com\r
+//\r
+// The contents of this file are subject to the Artistic License (the "License").\r
+// You may not use this file except in compliance with the License. \r
+// You may obtain a copy of the License at:\r
+// http://www.opensource.org/licenses/artistic-license.html\r
+//\r
+// If you find this code useful, credits would be nice!\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+#include "stdafx.h"\r
+#include "ResizableVersion.h"\r
+\r
+//////////////////////////////////////////////////////////////////////\r
+// Static initializer object (with macros to hide in ClassView)\r
+\r
+// static intializer must be called before user code\r
+#pragma warning(disable:4073)\r
+#pragma init_seg(lib)\r
+\r
+#ifdef _UNDEFINED_\r
+#define BEGIN_HIDDEN {\r
+#define END_HIDDEN }\r
+#else\r
+#define BEGIN_HIDDEN\r
+#define END_HIDDEN\r
+#endif\r
+\r
+BEGIN_HIDDEN\r
+struct _VersionInitializer\r
+{\r
+ _VersionInitializer()\r
+ {\r
+ InitRealVersions();\r
+ };\r
+};\r
+END_HIDDEN\r
+\r
+// The one and only version-check object\r
+static _VersionInitializer g_version;\r
+\r
+//////////////////////////////////////////////////////////////////////\r
+// Private implementation\r
+\r
+// DLL Version support\r
+#include <shlwapi.h>\r
+\r
+static DLLVERSIONINFO g_dviCommCtrls;\r
+static OSVERSIONINFOEX g_osviWindows;\r
+\r
+static void CheckOsVersion()\r
+{\r
+ // Try calling GetVersionEx using the OSVERSIONINFOEX structure.\r
+ SecureZeroMemory(&g_osviWindows, sizeof(OSVERSIONINFOEX));\r
+ g_osviWindows.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);\r
+ if (GetVersionEx((LPOSVERSIONINFO)&g_osviWindows))\r
+ return;\r
+ \r
+ // If that fails, try using the OSVERSIONINFO structure.\r
+ g_osviWindows.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);\r
+ if (GetVersionEx((LPOSVERSIONINFO)&g_osviWindows))\r
+ return;\r
+\r
+ // When all the above fails, set values for the worst case\r
+ g_osviWindows.dwMajorVersion = 4;\r
+ g_osviWindows.dwMinorVersion = 0;\r
+ g_osviWindows.dwBuildNumber = 0;\r
+ g_osviWindows.dwPlatformId = VER_PLATFORM_WIN32_WINDOWS;\r
+ g_osviWindows.szCSDVersion[0] = TEXT('\0');\r
+}\r
+\r
+static void CheckCommCtrlsVersion()\r
+{\r
+ // Check Common Controls version\r
+ SecureZeroMemory(&g_dviCommCtrls, sizeof(DLLVERSIONINFO));\r
+ HMODULE hMod = ::LoadLibrary(_T("comctl32.dll"));\r
+ if (hMod != NULL)\r
+ {\r
+ // Get the version function\r
+ DLLGETVERSIONPROC pfnDllGetVersion;\r
+ pfnDllGetVersion = (DLLGETVERSIONPROC)GetProcAddress(hMod, "DllGetVersion");\r
+\r
+ if (pfnDllGetVersion != NULL)\r
+ {\r
+ // Obtain version information\r
+ g_dviCommCtrls.cbSize = sizeof(DLLVERSIONINFO);\r
+ if (SUCCEEDED(pfnDllGetVersion(&g_dviCommCtrls)))\r
+ {\r
+ ::FreeLibrary(hMod);\r
+ return;\r
+ }\r
+ }\r
+\r
+ ::FreeLibrary(hMod);\r
+ }\r
+\r
+ // Set values for the worst case\r
+ g_dviCommCtrls.dwMajorVersion = 4;\r
+ g_dviCommCtrls.dwMinorVersion = 0;\r
+ g_dviCommCtrls.dwBuildNumber = 0;\r
+ g_dviCommCtrls.dwPlatformID = DLLVER_PLATFORM_WINDOWS;\r
+}\r
+\r
+\r
+//////////////////////////////////////////////////////////////////////\r
+// Exported global symbols\r
+\r
+DWORD realWINVER = 0;\r
+\r
+#ifdef _WIN32_WINDOWS\r
+DWORD real_WIN32_WINDOWS = 0;\r
+#endif\r
+\r
+#ifdef _WIN32_WINNT\r
+DWORD real_WIN32_WINNT = 0;\r
+#endif\r
+\r
+#ifdef _WIN32_IE\r
+DWORD real_WIN32_IE = 0;\r
+#endif\r
+\r
+// macro to convert version numbers to hex format\r
+#define CNV_OS_VER(x) ((BYTE)(((BYTE)(x) / 10 * 16) | ((BYTE)(x) % 10)))\r
+\r
+void InitRealVersions()\r
+{\r
+ CheckCommCtrlsVersion();\r
+ CheckOsVersion();\r
+\r
+ // set real version values\r
+\r
+ realWINVER = MAKEWORD(CNV_OS_VER(g_osviWindows.dwMinorVersion),\r
+ CNV_OS_VER(g_osviWindows.dwMajorVersion));\r
+\r
+#ifdef _WIN32_WINDOWS\r
+ if (g_osviWindows.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)\r
+ real_WIN32_WINDOWS = realWINVER;\r
+ else\r
+ real_WIN32_WINDOWS = 0;\r
+#endif\r
+\r
+#ifdef _WIN32_WINNT\r
+ if (g_osviWindows.dwPlatformId == VER_PLATFORM_WIN32_NT)\r
+ real_WIN32_WINNT = realWINVER;\r
+ else\r
+ real_WIN32_WINNT = 0;\r
+#endif\r
+\r
+#ifdef _WIN32_IE\r
+ switch (g_dviCommCtrls.dwMajorVersion)\r
+ {\r
+ case 4:\r
+ switch (g_dviCommCtrls.dwMinorVersion)\r
+ {\r
+ case 70:\r
+ real_WIN32_IE = 0x0300;\r
+ break;\r
+ case 71:\r
+ real_WIN32_IE = 0x0400;\r
+ break;\r
+ case 72:\r
+ real_WIN32_IE = 0x0401;\r
+ break;\r
+ default:\r
+ real_WIN32_IE = 0x0200;\r
+ }\r
+ break;\r
+ case 5:\r
+ if (g_dviCommCtrls.dwMinorVersion > 80)\r
+ real_WIN32_IE = 0x0501;\r
+ else\r
+ real_WIN32_IE = 0x0500;\r
+ break;\r
+ case 6:\r
+ real_WIN32_IE = 0x0600; // includes checks for 0x0560 (IE6)\r
+ break;\r
+ default:\r
+ real_WIN32_IE = 0;\r
+ }\r
+#endif\r
+}\r
--- /dev/null
+// ResizableVersion.h: interface for the CResizableVersion class.\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// This file is part of ResizableLib\r
+// http://sourceforge.net/projects/resizablelib\r
+//\r
+// Copyright (C) 2000-2004 by Paolo Messina\r
+// http://www.geocities.com/ppescher - mailto:ppescher@hotmail.com\r
+//\r
+// The contents of this file are subject to the Artistic License (the "License").\r
+// You may not use this file except in compliance with the License. \r
+// You may obtain a copy of the License at:\r
+// http://www.opensource.org/licenses/artistic-license.html\r
+//\r
+// If you find this code useful, credits would be nice!\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+#if !defined(AFX_RESIZABLEVERSION_H__INCLUDED_)\r
+#define AFX_RESIZABLEVERSION_H__INCLUDED_\r
+\r
+#if _MSC_VER > 1000\r
+#pragma once\r
+#endif // _MSC_VER > 1000\r
+\r
+// global variables that hold actual version numbers\r
+// retrieved and adapted at run-time to be equivalent\r
+// to preprocessor macros that set the target platform\r
+\r
+extern DWORD realWINVER;\r
+\r
+#ifdef _WIN32_WINDOWS\r
+extern DWORD real_WIN32_WINDOWS;\r
+#endif\r
+\r
+#ifdef _WIN32_WINNT\r
+extern DWORD real_WIN32_WINNT;\r
+#endif\r
+\r
+#ifdef _WIN32_IE\r
+extern DWORD real_WIN32_IE;\r
+#endif\r
+\r
+// called automatically by a static initializer\r
+// (if not appropriate can be called later)\r
+// to setup global version numbers\r
+\r
+void InitRealVersions();\r
+\r
+\r
+#endif // !defined(AFX_RESIZABLEVERSION_H__INCLUDED_)\r
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// This file is part of ResizableLib\r
+// http://sourceforge.net/projects/resizablelib\r
+//\r
+// Copyright (C) 2000-2004,2008 by Paolo Messina\r
+// http://www.geocities.com/ppescher - mailto:ppescher@hotmail.com\r
+//\r
+// The contents of this file are subject to the Artistic License (the "License").\r
+// You may not use this file except in compliance with the License. \r
+// You may obtain a copy of the License at:\r
+// http://www.opensource.org/licenses/artistic-license.html\r
+//\r
+// If you find this code useful, credits would be nice!\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+/*!\r
+ * @file\r
+ * @brief Implementation of the CResizableWndState class.\r
+ */\r
+\r
+#include "stdafx.h"\r
+#include "ResizableWndState.h"\r
+\r
+//////////////////////////////////////////////////////////////////////\r
+// Construction/Destruction\r
+//////////////////////////////////////////////////////////////////////\r
+\r
+CResizableWndState::CResizableWndState()\r
+{\r
+\r
+}\r
+\r
+CResizableWndState::~CResizableWndState()\r
+{\r
+\r
+}\r
+\r
+// used to save/restore window's size and position\r
+// either in the registry or a private .INI file\r
+// depending on your application settings\r
+\r
+#define PLACEMENT_ENT _T("WindowPlacement")\r
+#define PLACEMENT_FMT _T("%d,%d,%d,%d,%d,%d,%d,%d")\r
+\r
+/*!\r
+ * This function saves the current window position and size using the base\r
+ * class persist method. Minimized and maximized state is also optionally\r
+ * preserved.\r
+ * @sa CResizableState::WriteState\r
+ * @note Window coordinates are in the form used by the system functions\r
+ * GetWindowPlacement and SetWindowPlacement.\r
+ * \r
+ * @param pszName String that identifies stored settings\r
+ * @param bRectOnly Flag that specifies wether to ignore min/max state\r
+ * \r
+ * @return Returns @a TRUE if successful, @a FALSE otherwise\r
+ */\r
+BOOL CResizableWndState::SaveWindowRect(LPCTSTR pszName, BOOL bRectOnly)\r
+{\r
+ CString data, id;\r
+ WINDOWPLACEMENT wp;\r
+\r
+ SecureZeroMemory(&wp, sizeof(WINDOWPLACEMENT));\r
+ wp.length = sizeof(WINDOWPLACEMENT);\r
+ if (!GetResizableWnd()->GetWindowPlacement(&wp))\r
+ return FALSE;\r
+ \r
+ // use workspace coordinates\r
+ RECT& rc = wp.rcNormalPosition;\r
+\r
+ if (bRectOnly) // save size/pos only (normal state)\r
+ {\r
+ data.Format(PLACEMENT_FMT, rc.left, rc.top,\r
+ rc.right, rc.bottom, SW_SHOWNORMAL, 0, 0, 0);\r
+ }\r
+ else // save also min/max state\r
+ {\r
+ data.Format(PLACEMENT_FMT, rc.left, rc.top,\r
+ rc.right, rc.bottom, wp.showCmd, wp.flags,\r
+ wp.ptMinPosition.x, wp.ptMinPosition.y);\r
+ }\r
+\r
+ id = CString(pszName) + PLACEMENT_ENT;\r
+ return WriteState(id, data);\r
+}\r
+\r
+/*!\r
+ * This function loads and set the current window position and size using\r
+ * the base class persist method. Minimized and maximized state is also\r
+ * optionally preserved.\r
+ * @sa CResizableState::WriteState\r
+ * @note Window coordinates are in the form used by the system functions\r
+ * GetWindowPlacement and SetWindowPlacement.\r
+ * \r
+ * @param pszName String that identifies stored settings\r
+ * @param bRectOnly Flag that specifies wether to ignore min/max state\r
+ * \r
+ * @return Returns @a TRUE if successful, @a FALSE otherwise\r
+ */\r
+BOOL CResizableWndState::LoadWindowRect(LPCTSTR pszName, BOOL bRectOnly)\r
+{\r
+ CString data, id;\r
+ WINDOWPLACEMENT wp;\r
+\r
+ id = CString(pszName) + PLACEMENT_ENT;\r
+ if (!ReadState(id, data)) // never saved before\r
+ return FALSE;\r
+ \r
+ SecureZeroMemory(&wp, sizeof(WINDOWPLACEMENT));\r
+ wp.length = sizeof(WINDOWPLACEMENT);\r
+ if (!GetResizableWnd()->GetWindowPlacement(&wp))\r
+ return FALSE;\r
+\r
+ // use workspace coordinates\r
+ RECT& rc = wp.rcNormalPosition;\r
+\r
+ if (_stscanf(data, PLACEMENT_FMT, &rc.left, &rc.top,\r
+ &rc.right, &rc.bottom, &wp.showCmd, &wp.flags,\r
+ &wp.ptMinPosition.x, &wp.ptMinPosition.y) == 8)\r
+ {\r
+ if (bRectOnly) // restore size/pos only\r
+ {\r
+ wp.showCmd = SW_SHOWNORMAL;\r
+ wp.flags = 0;\r
+ return GetResizableWnd()->SetWindowPlacement(&wp);\r
+ }\r
+ else // restore also max state\r
+ {\r
+ if (wp.showCmd == SW_SHOWMINIMIZED)\r
+ wp.showCmd = SW_SHOWNORMAL;\r
+ return GetResizableWnd()->SetWindowPlacement(&wp);\r
+ }\r
+ }\r
+ return FALSE;\r
+}\r
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// This file is part of ResizableLib\r
+// http://sourceforge.net/projects/resizablelib\r
+//\r
+// Copyright (C) 2000-2004 by Paolo Messina\r
+// http://www.geocities.com/ppescher - mailto:ppescher@hotmail.com\r
+//\r
+// The contents of this file are subject to the Artistic License (the "License").\r
+// You may not use this file except in compliance with the License. \r
+// You may obtain a copy of the License at:\r
+// http://www.opensource.org/licenses/artistic-license.html\r
+//\r
+// If you find this code useful, credits would be nice!\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+/*!\r
+ * @file\r
+ * @brief Interface for the CResizableWndState class.\r
+ */\r
+\r
+#if !defined(AFX_RESIZABLEWNDSTATE_H__INCLUDED_)\r
+#define AFX_RESIZABLEWNDSTATE_H__INCLUDED_\r
+\r
+#if _MSC_VER > 1000\r
+#pragma once\r
+#endif // _MSC_VER > 1000\r
+\r
+#include "ResizableState.h"\r
+\r
+/*! @addtogroup CoreComponents\r
+ * @{\r
+ */\r
+\r
+//! @brief Persists window position, size and state\r
+/*!\r
+ * Derive from this class when you want to persist the size, position and\r
+ * minimized/maximized state of top level windows.\r
+ * This class is used in the provided resizable counterparts of\r
+ * the standard MFC window and dialog classes.\r
+ */\r
+class CResizableWndState : public CResizableState \r
+{\r
+protected:\r
+\r
+ //! @brief Load and set the window position and size\r
+ BOOL LoadWindowRect(LPCTSTR pszName, BOOL bRectOnly);\r
+\r
+ //! @brief Save the current window position and size\r
+ BOOL SaveWindowRect(LPCTSTR pszName, BOOL bRectOnly);\r
+\r
+ //! @brief Override to provide the parent window\r
+ virtual CWnd* GetResizableWnd() const = 0;\r
+\r
+public:\r
+ CResizableWndState();\r
+ virtual ~CResizableWndState();\r
+};\r
+\r
+// @}\r
+#endif // !defined(AFX_RESIZABLEWNDSTATE_H__INCLUDED_)\r
--- /dev/null
+// stdafx.cpp : source file that includes just the standard includes\r
+// ResizableLib.pch will be the pre-compiled header\r
+// stdafx.obj will contain the pre-compiled type information\r
+\r
+#include "stdafx.h"\r
+\r
--- /dev/null
+// stdafx.h : include file for standard system include files, or project\r
+// specific include files that are used frequently, but are changed infrequently\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// This file is part of ResizableLib\r
+// http://sourceforge.net/projects/resizablelib\r
+//\r
+// Copyright (C) 2000-2004 by Paolo Messina\r
+// http://www.geocities.com/ppescher - mailto:ppescher@hotmail.com\r
+//\r
+// The contents of this file are subject to the Artistic License (the "License").\r
+// You may not use this file except in compliance with the License. \r
+// You may obtain a copy of the License at:\r
+// http://www.opensource.org/licenses/artistic-license.html\r
+//\r
+// If you find this code useful, credits would be nice!\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+#if !defined(AFX_RESIZABLESTDAFX_H__INCLUDED_)\r
+#define AFX_RESIZABLESTDAFX_H__INCLUDED_\r
+\r
+#if _MSC_VER > 1000\r
+#pragma once\r
+#endif // _MSC_VER > 1000\r
+\r
+// Set max target Windows platform\r
+#define WINVER 0x0501\r
+#define _WIN32_WINNT 0x0501\r
+\r
+// Use target Common Controls version for compatibility\r
+// with CPropertyPageEx, CPropertySheetEx\r
+#define _WIN32_IE 0x0500\r
+\r
+// let us be spared from a flood of deprecation warnings.\r
+#define _CRT_NONSTDC_NO_DEPRECATE 1\r
+#define _CRT_SECURE_NO_DEPRECATE 1\r
+#define _SECURE_SCL_DEPRECATE 0\r
+#define _HAS_ITERATOR_DEBUGGING 0\r
+\r
+#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers\r
+\r
+#include <afxwin.h> // MFC core and standard components\r
+#include <afxext.h> // MFC extensions\r
+#include <afxcmn.h> // MFC support for Windows Common Controls\r
+#include <WinSock2.h>\r
+#include <Ws2tcpip.h>\r
+#include <Wspiapi.h>\r
+\r
+#ifndef WS_EX_LAYOUTRTL\r
+#pragma message("Please update your Windows header files, get the latest SDK")\r
+#pragma message("WinUser.h is out of date!")\r
+\r
+#define WS_EX_LAYOUTRTL 0x00400000\r
+#endif\r
+\r
+#ifndef WC_BUTTON\r
+#pragma message("Please update your Windows header files, get the latest SDK")\r
+#pragma message("CommCtrl.h is out of date!")\r
+\r
+#define WC_BUTTON TEXT("Button")\r
+#define WC_STATIC TEXT("Static")\r
+#define WC_EDIT TEXT("Edit")\r
+#define WC_LISTBOX TEXT("ListBox")\r
+#define WC_COMBOBOX TEXT("ComboBox")\r
+#define WC_SCROLLBAR TEXT("ScrollBar")\r
+#endif\r
+\r
+#define RSZLIB_NO_XP_DOUBLE_BUFFER\r
+\r
+//{{AFX_INSERT_LOCATION}}\r
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.\r
+\r
+#endif // !defined(AFX_RESIZABLESTDAFX_H__INCLUDED_)\r