--- /dev/null
+// Win32++ Version 7.3\r
+// Released: 30th November 2011\r
+//\r
+// David Nash\r
+// url: https://sourceforge.net/projects/win32-framework\r
+//\r
+//\r
+// Copyright (c) 2005-2011 David Nash\r
+//\r
+// Permission is hereby granted, free of charge, to\r
+// any person obtaining a copy of this software and\r
+// associated documentation files (the "Software"),\r
+// to deal in the Software without restriction, including\r
+// without limitation the rights to use, copy, modify,\r
+// merge, publish, distribute, sublicense, and/or sell\r
+// copies of the Software, and to permit persons to whom\r
+// the Software is furnished to do so, subject to the\r
+// following conditions:\r
+//\r
+// The above copyright notice and this permission notice\r
+// shall be included in all copies or substantial portions\r
+// of the Software.\r
+//\r
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF\r
+// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED\r
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\r
+// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT\r
+// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR\r
+// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
+// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE\r
+// OR OTHER DEALINGS IN THE SOFTWARE.\r
+//\r
+////////////////////////////////////////////////////////\r
+\r
+#ifndef _WIN32XX_WINUTILS_H_\r
+#define _WIN32XX_WINUTILS_H_\r
+\r
+\r
+// define useful macros from WindowsX.h\r
+#ifndef GET_X_LPARAM\r
+ #define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp))\r
+#endif\r
+#ifndef GET_Y_LPARAM\r
+ #define GET_Y_LPARAM(lp) ((int)(short)HIWORD(lp))\r
+#endif\r
+\r
+// Define our own MIN and MAX macros\r
+// this avoids inconsistencies with Dev-C++ and other compilers, and\r
+// avoids conflicts between typical min/max macros and std::min/std::max\r
+#define MAX(a,b) (((a) > (b)) ? (a) : (b))\r
+#define MIN(a,b) (((a) < (b)) ? (a) : (b))\r
+\r
+\r
+namespace Win32xx\r
+{\r
+ // Forward declarations\r
+ class CPoint;\r
+ class CRect;\r
+ CWinApp* GetApp();\r
+ void TRACE(LPCTSTR str);\r
+\r
+\r
+ /////////////////////////////////////////\r
+ // Definition of the CSize class\r
+ // This class can be used to replace the SIZE structure\r
+ class CSize : public SIZE\r
+ {\r
+ public:\r
+ CSize() { cx = 0; cy = 0; }\r
+ CSize(int CX, int CY) { cx = CX; cy = CY; }\r
+ CSize(SIZE sz) { cx = sz.cx; cy = sz.cy; }\r
+ CSize(POINT pt) { cx = pt.x; cy = pt.y; }\r
+ CSize(DWORD dw) { cx = (short)LOWORD(dw); cy = (short)HIWORD(dw); }\r
+ void SetSize(int CX, int CY) { cx = CX; cy = CY; }\r
+\r
+ // Operators\r
+ operator LPSIZE() { return this; }\r
+ BOOL operator == (SIZE sz) const { return (cx == sz.cx && cy == sz.cy); }\r
+ BOOL operator != (SIZE sz) const { return (cx != sz.cx || cy != sz.cy); }\r
+ void operator += (SIZE sz) { cx += sz.cx; cy += sz.cy; }\r
+ void operator -= (SIZE sz) { cx -= sz.cx; cy -= sz.cy; }\r
+\r
+ // Operators returning CSize\r
+ CSize operator - () const { return CSize (-cx, -cy); }\r
+ CSize operator + (SIZE sz) const { return CSize (cx + sz.cx, cy + sz.cy); }\r
+ CSize operator - (SIZE sz) const { return CSize (cx - sz.cx, cy - sz.cy); }\r
+\r
+ // Operators returning CPoint\r
+ CPoint operator + (POINT point) const;\r
+ CPoint operator - (POINT point) const;\r
+\r
+ // Operators returning CRect\r
+ CRect operator + (RECT rc) const;\r
+ CRect operator - (RECT rc) const;\r
+ };\r
+\r
+\r
+ /////////////////////////////////////////\r
+ // Definition of the CPoint class\r
+ // This class can be used to replace the POINT structure\r
+ class CPoint : public POINT\r
+ {\r
+ public:\r
+ CPoint() { x = 0; y = 0; }\r
+ CPoint(int X, int Y) { x = X; y = Y; }\r
+ CPoint(POINT pt) { x = pt.x ; y = pt.y; }\r
+ CPoint(POINTS pts) { x = pts.x; y = pts.y; }\r
+ CPoint(SIZE sz) { x = sz.cx; y = sz.cy; }\r
+ CPoint(DWORD dw) { x = (short) LOWORD(dw); y = (short) HIWORD(dw); }\r
+\r
+ void Offset(int dx, int dy) { x += dx; y += dy; }\r
+ void Offset(POINT pt) { x += pt.x; y += pt.y; }\r
+ void Offset(SIZE sz) { x += sz.cx; y += sz.cy; }\r
+ void SetPoint(int X, int Y) { x = X; y = Y; }\r
+\r
+ // Operators\r
+ operator LPPOINT() { return this; }\r
+ BOOL operator == (POINT pt) const { return ((x == pt.x) && (y == pt.y)); }\r
+ BOOL operator != (POINT pt) const { return ((x != pt.x) || (y != pt.y)); }\r
+ void operator += (SIZE sz) { x += sz.cx; y += sz.cy; }\r
+ void operator -= (SIZE sz) { x -= sz.cx; y -= sz.cy; }\r
+ void operator += (POINT pt) { x += pt.x; y += pt.y; }\r
+ void operator -= (POINT pt) { x -= pt.x; y -= pt.y; }\r
+\r
+ // Operators returning CPoint\r
+ CPoint operator - () const { return CPoint(-x, -y); }\r
+ CPoint operator + (SIZE sz) const { return CPoint(x + sz.cx, y + sz.cy); }\r
+ CPoint operator - (SIZE sz) const { return CPoint(x - sz.cx, y - sz.cy); }\r
+ CPoint operator + (POINT pt) const { return CPoint(x + pt.x, y + pt.y); }\r
+ CPoint operator - (POINT pt) const { return CPoint(x - pt.x, y - pt.y); }\r
+\r
+ // Operators returning CRect\r
+ CRect operator + (RECT rc) const;\r
+ CRect operator - (RECT rc) const;\r
+ };\r
+\r
+\r
+ /////////////////////////////////////////\r
+ // Definition of the CRect class\r
+ // This class can be used to replace the RECT structure.\r
+ class CRect : public RECT\r
+ {\r
+ public:\r
+ CRect() { left = top = right = bottom = 0; }\r
+ CRect(int l, int t, int r, int b) { left = l; top = t; right = r; bottom = b; }\r
+ CRect(RECT rc) { left = rc.left; top = rc.top; right = rc.right; bottom = rc.bottom; }\r
+ CRect(POINT pt, SIZE sz) { right = (left = pt.x) + sz.cx; bottom = (top = pt.y) + sz.cy; }\r
+ CRect(POINT topLeft, POINT bottomRight) { left = topLeft.x; top = topLeft.y; right = bottomRight.x; bottom = bottomRight.y; }\r
+\r
+ BOOL CopyRect(RECT rc) { return ::CopyRect(this, &rc); }\r
+ BOOL DeflateRect(int x, int y) { return ::InflateRect(this, -x, -y); }\r
+ BOOL DeflateRect(SIZE size) { return ::InflateRect(this, -size.cx, -size.cy); }\r
+ BOOL DeflateRect(RECT rc) { return ::InflateRect(this, rc.left - rc.right, rc.top - rc.bottom); }\r
+ BOOL DeflateRect(int l, int t, int r, int b){ return ::InflateRect(this, l - r, t - b); }\r
+ BOOL EqualRect(RECT rc) const { return ::EqualRect(&rc, this); }\r
+ BOOL InflateRect(int dx, int dy) { return ::InflateRect(this, dx, dy); }\r
+ BOOL InflateRect(SIZE sz) { return ::InflateRect(this, sz.cx, sz.cy); }\r
+ BOOL InflateRect(RECT rc) { return ::InflateRect(this, rc.right - rc.left, rc.bottom - rc.top); }\r
+ BOOL InflateRect(int l, int t, int r, int b){ return ::InflateRect(this, r - l, b - t); }\r
+ BOOL IntersectRect(RECT rc1, RECT rc2) { return ::IntersectRect(this, &rc1, &rc2); }\r
+ BOOL IsRectEmpty() const { return ::IsRectEmpty(this);}\r
+ BOOL IsRectNull() const { return (left == 0 && right == 0 && top == 0 && bottom == 0); }\r
+ CRect MulDiv(int nMult, int nDiv) const { return CRect ((left * nMult) / nDiv, (top * nMult) / nDiv,\r
+ (right * nMult) / nDiv, (bottom * nMult) / nDiv); }\r
+ void NormalizeRect() { int nTemp; if (left > right) { nTemp = left; left = right; right = nTemp; }\r
+ if (top > bottom) { nTemp = top; top = bottom; bottom = nTemp; } }\r
+ BOOL OffsetRect(int dx, int dy) { return ::OffsetRect(this, dx, dy); }\r
+ BOOL OffsetRect(POINT pt) { return ::OffsetRect(this, pt.x, pt.y); }\r
+ BOOL OffsetRect(SIZE size) { return ::OffsetRect(this, size.cx, size.cy); }\r
+ BOOL PtInRect(POINT pt) const { return ::PtInRect(this, pt); }\r
+ BOOL SetRect(int l, int t, int r, int b) { return ::SetRect(this, l, t, r, b); }\r
+ BOOL SetRect(POINT TopLeft, POINT BtmRight) { return ::SetRect(this, TopLeft.x, TopLeft.y, BtmRight.x, BtmRight.y); }\r
+ BOOL SetRectEmpty() { return ::SetRectEmpty(this); }\r
+ BOOL SubtractRect(RECT rc1, RECT rc2) { return ::SubtractRect(this, &rc1, &rc2); }\r
+ BOOL UnionRect(RECT rc1, RECT rc2) { return ::UnionRect(this, &rc1, &rc2); }\r
+\r
+ // Reposition rectangle\r
+ void MoveToX (int x) { right = Width() + x; left = x; }\r
+ void MoveToY (int y) { bottom = Height() + y; top = y; }\r
+ void MoveToXY (int x, int y) { MoveToX(x); MoveToY(y); }\r
+ void MoveToXY (POINT pt) { MoveToX (pt.x); MoveToY (pt.y); }\r
+\r
+ // Attributes\r
+ int Height() const { return bottom - top; }\r
+ int Width() const { return right - left; }\r
+ CSize Size() const { return CSize(Width(), Height()); }\r
+ CPoint CenterPoint() const { return CPoint((left + right) / 2, (top + bottom) / 2); }\r
+ CPoint TopLeft() const { return CPoint(left, top); }\r
+ CPoint BottomRight() const { return CPoint(right, bottom); }\r
+\r
+ // operators\r
+ operator LPRECT() { return this; }\r
+ BOOL operator == (RECT rc) const { return ::EqualRect(this, &rc); }\r
+ BOOL operator != (RECT rc) const { return !::EqualRect(this, &rc); }\r
+ void operator += (POINT pt) { ::OffsetRect(this, pt.x, pt.y); }\r
+ void operator += (SIZE size) { ::OffsetRect(this, size.cx, size.cy); }\r
+ void operator += (RECT rc) { ::InflateRect(this, rc.right - rc.left, rc.bottom - rc.top); }\r
+ void operator -= (RECT rc) { ::InflateRect(this, rc.left - rc.right, rc.top - rc.bottom); }\r
+ void operator -= (POINT pt) { ::OffsetRect(this, -pt.x, -pt.y); }\r
+ void operator -= (SIZE sz) { ::OffsetRect(this, -sz.cx, -sz.cy); }\r
+ void operator &= (RECT rc) { ::IntersectRect(this, this, &rc); }\r
+ void operator |= (RECT rc) { ::UnionRect(this, this, &rc); }\r
+\r
+ // Operators returning CRect\r
+ CRect operator + (POINT pt) const { CRect rc(*this); ::OffsetRect(&rc, pt.x, pt.y); return rc; }\r
+ CRect operator - (POINT pt) const { CRect rc(*this); ::OffsetRect(&rc, -pt.x, -pt.y); return rc; }\r
+ CRect operator + (SIZE sz) const { CRect rc(*this); ::OffsetRect(&rc, sz.cx, sz.cy); return rc; }\r
+ CRect operator - (SIZE sz) const { CRect rc(*this); ::OffsetRect(&rc, -sz.cx, -sz.cy); return rc; }\r
+ CRect operator + (RECT rc) const { CRect rc1(*this); rc1.InflateRect(rc); return rc1; }\r
+ CRect operator - (RECT rc) const { CRect rc1(*this); rc1.DeflateRect(rc); return rc1; }\r
+ CRect operator & (RECT rc) const { CRect rc1; ::IntersectRect(&rc1, this, &rc); return rc1; }\r
+ CRect operator | (RECT rc) const { CRect rc1; ::UnionRect(&rc1, this, &rc); return rc1; }\r
+ };\r
+\r
+ // CSize member function definitions\r
+ inline CPoint CSize::operator + (POINT pt) const { return CPoint(pt) + *this; }\r
+ inline CPoint CSize::operator - (POINT pt) const { return CPoint(pt) - *this; }\r
+ inline CRect CSize::operator + (RECT rc) const { return CRect(rc) + *this; }\r
+ inline CRect CSize::operator - (RECT rc) const { return CRect(rc) - *this; }\r
+\r
+ // CPoint member function definitions\r
+ inline CRect CPoint::operator + (RECT rc) const { return CRect(rc) + *this; }\r
+ inline CRect CPoint::operator - (RECT rc) const { return CRect(rc) - *this; }\r
+\r
+\r
+ ////////////////////////////////////////////////////////\r
+ // Classes and functions (typedefs) for text conversions\r
+ //\r
+ // This section defines the following text conversions:\r
+ // A2BSTR ANSI to BSTR\r
+ // A2OLE ANSI to OLE\r
+ // A2T ANSI to TCHAR\r
+ // A2W ANSI to WCHAR\r
+ // OLE2A OLE to ANSI\r
+ // OLE2T OLE to TCHAR\r
+ // OLE2W OLE to WCHAR\r
+ // T2A TCHAR to ANSI\r
+ // T2BSTR TCHAR to BSTR\r
+ // T2OLE TCHAR to OLE\r
+ // T2W TCHAR to WCHAR\r
+ // W2A WCHAR to ANSI\r
+ // W2BSTR WCHAR to BSTR\r
+ // W2OLE WCHAR to OLE\r
+ // W2T WCHAR to TCHAR\r
+\r
+ // About different character and string types:\r
+ // ------------------------------------------\r
+ // char (or CHAR) character types are ANSI (8 bits).\r
+ // wchar_t (or WCHAR) character types are Unicode (16 bits).\r
+ // TCHAR characters are Unicode if the _UNICODE macro is defined, otherwise they are ANSI.\r
+ // BSTR (Basic String) is a type of string used in Visual Basic and COM programming.\r
+ // OLE is the same as WCHAR. It is used in Visual Basic and COM programming.\r
+\r
+\r
+ // Forward declarations of our classes. They are defined later.\r
+ class CA2A;\r
+ class CA2W;\r
+ class CW2A;\r
+ class CW2W;\r
+ class CA2BSTR;\r
+ class CW2BSTR;\r
+\r
+ // typedefs for the well known text conversions\r
+ typedef CA2W A2W;\r
+ typedef CW2A W2A;\r
+ typedef CW2BSTR W2BSTR;\r
+ typedef CA2BSTR A2BSTR;\r
+ typedef CW2A BSTR2A;\r
+ typedef CW2W BSTR2W;\r
+\r
+#ifdef _UNICODE\r
+ typedef CA2W A2T;\r
+ typedef CW2A T2A;\r
+ typedef CW2W T2W;\r
+ typedef CW2W W2T;\r
+ typedef CW2BSTR T2BSTR;\r
+ typedef BSTR2W BSTR2T;\r
+#else\r
+ typedef CA2A A2T;\r
+ typedef CA2A T2A;\r
+ typedef CA2W T2W;\r
+ typedef CW2A W2T;\r
+ typedef CA2BSTR T2BSTR;\r
+ typedef BSTR2A BSTR2T;\r
+#endif\r
+\r
+ typedef A2W A2OLE;\r
+ typedef T2W T2OLE;\r
+ typedef CW2W W2OLE;\r
+ typedef W2A OLE2A;\r
+ typedef W2T OLE2T;\r
+ typedef CW2W OLE2W;\r
+\r
+ class CA2W\r
+ {\r
+ public:\r
+ CA2W(LPCSTR pStr) : m_pStr(pStr)\r
+ {\r
+ if (pStr)\r
+ {\r
+ // Resize the vector and assign null WCHAR to each element\r
+ int length = (int)strlen(pStr)+1;\r
+ m_vWideArray.assign(length, L'\0');\r
+\r
+ // Fill our vector with the converted WCHAR array\r
+ MultiByteToWideChar(CP_ACP, 0, pStr, -1, &m_vWideArray[0], length);\r
+ }\r
+ }\r
+ ~CA2W() {}\r
+ operator LPCWSTR() { return m_pStr? &m_vWideArray[0] : NULL; }\r
+ operator LPOLESTR() { return m_pStr? (LPOLESTR)&m_vWideArray[0] : (LPOLESTR)NULL; }\r
+\r
+ private:\r
+ CA2W(const CA2W&);\r
+ CA2W& operator= (const CA2W&);\r
+ std::vector<wchar_t> m_vWideArray;\r
+ LPCSTR m_pStr;\r
+ };\r
+\r
+ class CW2A\r
+ {\r
+ public:\r
+ CW2A(LPCWSTR pWStr) : m_pWStr(pWStr)\r
+ {\r
+ // Resize the vector and assign null char to each element\r
+ int length = (int)wcslen(pWStr)+1;\r
+ m_vAnsiArray.assign(length, '\0');\r
+\r
+ // Fill our vector with the converted char array\r
+ WideCharToMultiByte(CP_ACP, 0, pWStr, -1, &m_vAnsiArray[0], length, NULL,NULL);\r
+ }\r
+\r
+ ~CW2A() {}\r
+ operator LPCSTR() { return m_pWStr? &m_vAnsiArray[0] : NULL; }\r
+\r
+ private:\r
+ CW2A(const CW2A&);\r
+ CW2A& operator= (const CW2A&);\r
+ std::vector<char> m_vAnsiArray;\r
+ LPCWSTR m_pWStr;\r
+ };\r
+\r
+ class CW2W\r
+ {\r
+ public:\r
+ CW2W(LPCWSTR pWStr) : m_pWStr(pWStr) {}\r
+ operator LPCWSTR() { return (LPWSTR)m_pWStr; }\r
+ operator LPOLESTR() { return (LPOLESTR)m_pWStr; }\r
+\r
+ private:\r
+ CW2W(const CW2W&);\r
+ CW2W& operator= (const CW2W&);\r
+\r
+ LPCWSTR m_pWStr;\r
+ };\r
+\r
+ class CA2A\r
+ {\r
+ public:\r
+ CA2A(LPCSTR pStr) : m_pStr(pStr) {}\r
+ operator LPCSTR() { return (LPSTR)m_pStr; }\r
+\r
+ private:\r
+ CA2A(const CA2A&);\r
+ CA2A& operator= (const CA2A&);\r
+\r
+ LPCSTR m_pStr;\r
+ };\r
+\r
+ class CW2BSTR\r
+ {\r
+ public:\r
+ CW2BSTR(LPCWSTR pWStr) { m_bstrString = ::SysAllocString(pWStr); }\r
+ ~CW2BSTR() { ::SysFreeString(m_bstrString); }\r
+ operator BSTR() { return m_bstrString;}\r
+\r
+ private:\r
+ CW2BSTR(const CW2BSTR&);\r
+ CW2BSTR& operator= (const CW2BSTR&);\r
+ BSTR m_bstrString;\r
+ };\r
+\r
+ class CA2BSTR\r
+ {\r
+ public:\r
+ CA2BSTR(LPCSTR pStr) { m_bstrString = ::SysAllocString(A2W(pStr)); }\r
+ ~CA2BSTR() { ::SysFreeString(m_bstrString); }\r
+ operator BSTR() { return m_bstrString;}\r
+\r
+ private:\r
+ CA2BSTR(const CA2BSTR&);\r
+ CA2BSTR& operator= (const CA2BSTR&);\r
+ BSTR m_bstrString;\r
+ };\r
+\r
+\r
+ ////////////////////////////////////////\r
+ // Global Functions\r
+ //\r
+\r
+ inline CWnd* FromHandle(HWND hWnd)\r
+ // Returns the CWnd object associated with the window handle\r
+ {\r
+ assert( GetApp() );\r
+ CWnd* pWnd = hWnd? GetApp()->GetCWndFromMap(hWnd) : 0;\r
+ if ( hWnd != NULL && pWnd == 0 )\r
+ {\r
+ GetApp()->AddTmpWnd(hWnd);\r
+ pWnd = GetApp()->GetCWndFromMap(hWnd);\r
+ ::PostMessage(hWnd, UWM_CLEANUPTEMPS, 0, 0);\r
+ }\r
+\r
+ return pWnd;\r
+ }\r
+\r
+ \r
+ inline CWinApp* GetApp()\r
+ // Returns a pointer to the CWinApp derrived class\r
+ {\r
+ return CWinApp::SetnGetThis();\r
+ }\r
+\r
+ inline CPoint GetCursorPos()\r
+ {\r
+ CPoint pt;\r
+ ::GetCursorPos(&pt);\r
+ return pt;\r
+ }\r
+\r
+ inline HBITMAP LoadBitmap (LPCTSTR lpszName)\r
+ {\r
+ assert(GetApp());\r
+\r
+ HBITMAP hBitmap = (HBITMAP)::LoadImage (GetApp()->GetResourceHandle(), lpszName, IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR);\r
+ return hBitmap;\r
+ }\r
+\r
+ inline HBITMAP LoadBitmap (int nID)\r
+ {\r
+ return LoadBitmap(MAKEINTRESOURCE(nID));\r
+ }\r
+\r
+\r
+ inline void TRACE(LPCTSTR str)\r
+ // TRACE sends a string to the debug/output pane, or an external debugger\r
+ {\r
+ #ifdef _DEBUG\r
+ OutputDebugString(str);\r
+ #else\r
+ UNREFERENCED_PARAMETER(str); // no-op\r
+ #endif\r
+ }\r
+\r
+ #ifndef _WIN32_WCE // for Win32/64 operating systems, not WinCE\r
+\r
+ inline int GetWinVersion()\r
+ {\r
+ DWORD dwVersion = GetVersion();\r
+ int Platform = (dwVersion < 0x80000000)? 2:1;\r
+ int MajorVer = LOBYTE(LOWORD(dwVersion));\r
+ int MinorVer = HIBYTE(LOWORD(dwVersion));\r
+\r
+ int nVersion = 1000*Platform + 100*MajorVer + MinorVer;\r
+\r
+ // Return values and window versions:\r
+ // 1400 Windows 95\r
+ // 1410 Windows 98\r
+ // 1490 Windows ME\r
+ // 2400 Windows NT\r
+ // 2500 Windows 2000\r
+ // 2501 Windows XP\r
+ // 2502 Windows Server 2003\r
+ // 2600 Windows Vista and Windows Server 2008\r
+ // 2601 Windows 7\r
+\r
+ return nVersion;\r
+ }\r
+\r
+ inline int GetComCtlVersion()\r
+ {\r
+ // Load the Common Controls DLL\r
+ HMODULE hComCtl = ::LoadLibraryA("COMCTL32.DLL");\r
+ if (!hComCtl)\r
+ return 0;\r
+\r
+ int ComCtlVer = 400;\r
+\r
+ if (::GetProcAddress(hComCtl, "InitCommonControlsEx"))\r
+ {\r
+ // InitCommonControlsEx is unique to 4.7 and later\r
+ ComCtlVer = 470;\r
+\r
+ if (::GetProcAddress(hComCtl, "DllGetVersion"))\r
+ {\r
+ typedef HRESULT CALLBACK DLLGETVERSION(DLLVERSIONINFO*);\r
+ DLLGETVERSION* pfnDLLGetVersion = NULL;\r
+\r
+ pfnDLLGetVersion = (DLLGETVERSION*)::GetProcAddress(hComCtl, "DllGetVersion");\r
+ if(pfnDLLGetVersion)\r
+ {\r
+ DLLVERSIONINFO dvi;\r
+ dvi.cbSize = sizeof dvi;\r
+ if(NOERROR == pfnDLLGetVersion(&dvi))\r
+ {\r
+ DWORD dwVerMajor = dvi.dwMajorVersion;\r
+ DWORD dwVerMinor = dvi.dwMinorVersion;\r
+ ComCtlVer = 100 * dwVerMajor + dwVerMinor;\r
+ }\r
+ }\r
+ }\r
+ else if (::GetProcAddress(hComCtl, "InitializeFlatSB"))\r
+ ComCtlVer = 471; // InitializeFlatSB is unique to version 4.71\r
+ }\r
+\r
+ ::FreeLibrary(hComCtl);\r
+\r
+ // return values and DLL versions\r
+ // 400 dll ver 4.00 Windows 95/Windows NT 4.0\r
+ // 470 dll ver 4.70 Internet Explorer 3.x\r
+ // 471 dll ver 4.71 Internet Explorer 4.0\r
+ // 472 dll ver 4.72 Internet Explorer 4.01 and Windows 98\r
+ // 580 dll ver 5.80 Internet Explorer 5\r
+ // 581 dll ver 5.81 Windows 2000 and Windows ME\r
+ // 582 dll ver 5.82 Windows XP or Vista without XP themes\r
+ // 600 dll ver 6.00 Windows XP with XP themes\r
+ // 610 dll ver 6.10 Windows Vista with XP themes\r
+ // 616 dll ver 6.16 Windows Vista SP1 or Windows 7 with XP themes\r
+\r
+ return ComCtlVer;\r
+ }\r
+\r
+ inline UINT GetSizeofMenuItemInfo()\r
+ {\r
+ UINT uSize = sizeof(MENUITEMINFO);\r
+ // For Win95 and NT, cbSize needs to be 44\r
+ if (1400 == (GetWinVersion()) || (2400 == GetWinVersion()))\r
+ uSize = 44;\r
+\r
+ return uSize;\r
+ }\r
+\r
+ inline UINT GetSizeofNonClientMetrics()\r
+ {\r
+ // This function correctly determines the sizeof NONCLIENTMETRICS\r
+ UINT uSize = sizeof (NONCLIENTMETRICS);\r
+\r
+ #if (WINVER >= 0x0600)\r
+ if (GetWinVersion() < 2600 && (uSize > 500)) // Is OS version less than Vista\r
+ uSize -= sizeof(int); // Adjust size back to correct value\r
+ #endif\r
+\r
+ return uSize;\r
+ }\r
+\r
+ \r
+\r
+ // A global function to report the state of the left mouse button\r
+ inline BOOL IsLeftButtonDown()\r
+ {\r
+ SHORT state;\r
+ if (GetSystemMetrics(SM_SWAPBUTTON))\r
+ // Mouse buttons are swapped\r
+ state = GetAsyncKeyState(VK_RBUTTON);\r
+ else\r
+ // Mouse buttons are not swapped\r
+ state = GetAsyncKeyState(VK_LBUTTON);\r
+\r
+ // returns true if the left mouse button is down\r
+ return (state & 0x8000);\r
+ }\r
+\r
+ inline BOOL IsAeroThemed()\r
+ {\r
+ BOOL bIsAeroThemed = FALSE;\r
+\r
+ // Test if Windows version is XP or greater\r
+ if (GetWinVersion() >= 2501)\r
+ {\r
+ HMODULE hMod = ::LoadLibrary(_T("uxtheme.dll"));\r
+ if(hMod)\r
+ {\r
+ // Declare pointers to IsCompositionActive function\r
+ FARPROC pIsCompositionActive = ::GetProcAddress(hMod, "IsCompositionActive");\r
+\r
+ if(pIsCompositionActive)\r
+ {\r
+ if(pIsCompositionActive())\r
+ {\r
+ bIsAeroThemed = TRUE;\r
+ }\r
+ }\r
+ ::FreeLibrary(hMod);\r
+ }\r
+ }\r
+\r
+ return bIsAeroThemed;\r
+ }\r
+\r
+ inline BOOL IsXPThemed()\r
+ {\r
+ BOOL bIsXPThemed = FALSE;\r
+\r
+ // Test if Windows version is XP or greater\r
+ if (GetWinVersion() >= 2501)\r
+ {\r
+ HMODULE hMod = ::LoadLibrary(_T("uxtheme.dll"));\r
+ if(hMod)\r
+ {\r
+ // Declare pointers to functions\r
+ FARPROC pIsAppThemed = ::GetProcAddress(hMod, "IsAppThemed");\r
+ FARPROC pIsThemeActive = ::GetProcAddress(hMod, "IsThemeActive");\r
+\r
+ if(pIsAppThemed && pIsThemeActive)\r
+ {\r
+ if(pIsAppThemed() && pIsThemeActive())\r
+ {\r
+ // Test if ComCtl32 dll used is version 6 or later\r
+ bIsXPThemed = (GetComCtlVersion() >= 600);\r
+ }\r
+ }\r
+ ::FreeLibrary(hMod);\r
+ }\r
+ }\r
+\r
+ return bIsXPThemed;\r
+ }\r
+\r
+ #endif // #ifndef _WIN32_WCE\r
+\r
+ // Required for WinCE\r
+ #ifndef lstrcpyn\r
+ inline LPTSTR lstrcpyn(LPTSTR lpstrDest, LPCTSTR lpstrSrc, int nLength)\r
+ {\r
+ if(NULL == lpstrDest || NULL == lpstrSrc || nLength <= 0)\r
+ return NULL;\r
+ int nLen = MIN((int)lstrlen(lpstrSrc), nLength - 1);\r
+ LPTSTR lpstrRet = (LPTSTR)memcpy(lpstrDest, lpstrSrc, nLen * sizeof(TCHAR));\r
+ lpstrDest[nLen] = _T('\0');\r
+ return lpstrRet;\r
+ }\r
+ #endif // !lstrcpyn\r
+\r
+}\r
+\r
+\r
+#endif // _WIN32XX_WINUTILS_H_\r