gusucode.com > wince下的directui编程源码程序 > wince下的directui编程源码程序/code/UIBase.cpp
#include "StdAfx.h" #ifdef _DEBUG #ifndef _WIN32_WCE #include <shlwapi.h> #pragma comment(lib, "shlwapi.lib") #endif #endif namespace DuiLib { ///////////////////////////////////////////////////////////////////////////////////// // // void UILIB_API __Trace(LPCTSTR pstrFormat, ...) { #ifdef _DEBUG #ifndef _WIN32_WCE TCHAR szBuffer[300] = { 0 }; va_list args; va_start(args, pstrFormat); ::wvnsprintf(szBuffer, lengthof(szBuffer) - 2, pstrFormat, args); _tcscat(szBuffer, _T("\n")); va_end(args); ::OutputDebugString(szBuffer); #else va_list VAList; va_start(VAList, pstrFormat); _vtprintf(pstrFormat,VAList); va_end(VAList); #endif #endif } LPCTSTR __TraceMsg(UINT uMsg) { #define MSGDEF(x) if(uMsg==x) return _T(#x) MSGDEF(WM_SETCURSOR); #ifndef _WIN32_WCE MSGDEF(WM_NCHITTEST); MSGDEF(WM_NCPAINT); #endif MSGDEF(WM_PAINT); MSGDEF(WM_ERASEBKGND); #ifndef _WIN32_WCE MSGDEF(WM_NCMOUSEMOVE); MSGDEF(WM_MOUSEMOVE); MSGDEF(WM_MOUSELEAVE); MSGDEF(WM_MOUSEHOVER); #endif MSGDEF(WM_NOTIFY); MSGDEF(WM_COMMAND); MSGDEF(WM_MEASUREITEM); MSGDEF(WM_DRAWITEM); MSGDEF(WM_LBUTTONDOWN); MSGDEF(WM_LBUTTONUP); MSGDEF(WM_LBUTTONDBLCLK); MSGDEF(WM_RBUTTONDOWN); MSGDEF(WM_RBUTTONUP); MSGDEF(WM_RBUTTONDBLCLK); MSGDEF(WM_SETFOCUS); MSGDEF(WM_KILLFOCUS); MSGDEF(WM_MOVE); MSGDEF(WM_SIZE); #ifndef _WIN32_WCE MSGDEF(WM_SIZING); MSGDEF(WM_MOVING); MSGDEF(WM_GETMINMAXINFO); #endif MSGDEF(WM_CAPTURECHANGED); MSGDEF(WM_WINDOWPOSCHANGED); #ifndef _WIN32_WCE MSGDEF(WM_WINDOWPOSCHANGING); MSGDEF(WM_NCCALCSIZE); MSGDEF(WM_NCCREATE); MSGDEF(WM_NCDESTROY); #endif MSGDEF(WM_TIMER); MSGDEF(WM_KEYDOWN); MSGDEF(WM_KEYUP); MSGDEF(WM_CHAR); MSGDEF(WM_SYSKEYDOWN); MSGDEF(WM_SYSKEYUP); MSGDEF(WM_SYSCOMMAND); MSGDEF(WM_SYSCHAR); MSGDEF(WM_VSCROLL); MSGDEF(WM_HSCROLL); MSGDEF(WM_CHAR); MSGDEF(WM_SHOWWINDOW); #ifndef _WIN32_WCE MSGDEF(WM_PARENTNOTIFY); #endif MSGDEF(WM_CREATE); #ifndef _WIN32_WCE MSGDEF(WM_NCACTIVATE); #endif MSGDEF(WM_ACTIVATE); #ifndef _WIN32_WCE MSGDEF(WM_ACTIVATEAPP); #endif MSGDEF(WM_CLOSE); MSGDEF(WM_DESTROY); MSGDEF(WM_GETICON); MSGDEF(WM_GETTEXT); MSGDEF(WM_GETTEXTLENGTH); static TCHAR szMsg[10]; ::wsprintf(szMsg, _T("0x%04X"), uMsg); return szMsg; } ///////////////////////////////////////////////////////////////////////////////////// // // CPoint::CPoint() { x = y = 0; } CPoint::CPoint(const POINT& src) { x = src.x; y = src.y; } CPoint::CPoint(int _x, int _y) { x = _x; y = _y; } CPoint::CPoint(LPARAM lParam) { x = GET_X_LPARAM(lParam); y = GET_Y_LPARAM(lParam); } ///////////////////////////////////////////////////////////////////////////////////// // // CSize::CSize() { cx = cy = 0; } CSize::CSize(const SIZE& src) { cx = src.cx; cy = src.cy; } CSize::CSize(const RECT rc) { cx = rc.right - rc.left; cy = rc.bottom - rc.top; } CSize::CSize(int _cx, int _cy) { cx = _cx; cy = _cy; } ///////////////////////////////////////////////////////////////////////////////////// // // CRect::CRect() { left = top = right = bottom = 0; } CRect::CRect(const RECT& src) { left = src.left; top = src.top; right = src.right; bottom = src.bottom; } CRect::CRect(int iLeft, int iTop, int iRight, int iBottom) { left = iLeft; top = iTop; right = iRight; bottom = iBottom; } int CRect::GetWidth() const { return right - left; } int CRect::GetHeight() const { return bottom - top; } void CRect::Empty() { left = top = right = bottom = 0; } bool CRect::IsNull() const { return (left == 0 && right == 0 && top == 0 && bottom == 0); } void CRect::Join(const RECT& rc) { if( rc.left < left ) left = rc.left; if( rc.top < top ) top = rc.top; if( rc.right > right ) right = rc.right; if( rc.bottom > bottom ) bottom = rc.bottom; } void CRect::ResetOffset() { ::OffsetRect(this, -left, -top); } void CRect::Normalize() { if( left > right ) { int iTemp = left; left = right; right = iTemp; } if( top > bottom ) { int iTemp = top; top = bottom; bottom = iTemp; } } void CRect::Offset(int cx, int cy) { ::OffsetRect(this, cx, cy); } void CRect::Inflate(int cx, int cy) { ::InflateRect(this, cx, cy); } void CRect::Deflate(int cx, int cy) { ::InflateRect(this, -cx, -cy); } void CRect::Union(CRect& rc) { ::UnionRect(this, this, &rc); } ///////////////////////////////////////////////////////////////////////////////////// // // CStdPtrArray::CStdPtrArray(int iPreallocSize) : m_ppVoid(NULL), m_nCount(0), m_nAllocated(iPreallocSize) { ASSERT(iPreallocSize>=0); if( iPreallocSize > 0 ) m_ppVoid = static_cast<LPVOID*>(malloc(iPreallocSize * sizeof(LPVOID))); } CStdPtrArray::CStdPtrArray(const CStdPtrArray& src) : m_ppVoid(NULL), m_nCount(0), m_nAllocated(0) { for(int i=0; i<src.GetSize(); i++) Add(src.GetAt(i)); } CStdPtrArray::~CStdPtrArray() { if( m_ppVoid != NULL ) free(m_ppVoid); } void CStdPtrArray::Empty() { if( m_ppVoid != NULL ) free(m_ppVoid); m_ppVoid = NULL; m_nCount = m_nAllocated = 0; } void CStdPtrArray::Resize(int iSize) { Empty(); m_ppVoid = static_cast<LPVOID*>(malloc(iSize * sizeof(LPVOID))); ::ZeroMemory(m_ppVoid, iSize * sizeof(LPVOID)); m_nAllocated = iSize; m_nCount = iSize; } bool CStdPtrArray::IsEmpty() const { return m_nCount == 0; } bool CStdPtrArray::Add(LPVOID pData) { if( ++m_nCount >= m_nAllocated) { int nAllocated = m_nAllocated * 2; if( nAllocated == 0 ) nAllocated = 11; LPVOID* ppVoid = static_cast<LPVOID*>(realloc(m_ppVoid, nAllocated * sizeof(LPVOID))); if( ppVoid != NULL ) { m_nAllocated = nAllocated; m_ppVoid = ppVoid; } else { --m_nCount; return false; } } m_ppVoid[m_nCount - 1] = pData; return true; } bool CStdPtrArray::InsertAt(int iIndex, LPVOID pData) { if( iIndex == m_nCount ) return Add(pData); if( iIndex < 0 || iIndex > m_nCount ) return false; if( ++m_nCount >= m_nAllocated) { int nAllocated = m_nAllocated * 2; if( nAllocated == 0 ) nAllocated = 11; LPVOID* ppVoid = static_cast<LPVOID*>(realloc(m_ppVoid, nAllocated * sizeof(LPVOID))); if( ppVoid != NULL ) { m_nAllocated = nAllocated; m_ppVoid = ppVoid; } else { --m_nCount; return false; } } memmove(&m_ppVoid[iIndex + 1], &m_ppVoid[iIndex], (m_nCount - iIndex - 1) * sizeof(LPVOID)); m_ppVoid[iIndex] = pData; return true; } bool CStdPtrArray::SetAt(int iIndex, LPVOID pData) { if( iIndex < 0 || iIndex >= m_nCount ) return false; m_ppVoid[iIndex] = pData; return true; } bool CStdPtrArray::Remove(int iIndex) { if( iIndex < 0 || iIndex >= m_nCount ) return false; if( iIndex < --m_nCount ) ::CopyMemory(m_ppVoid + iIndex, m_ppVoid + iIndex + 1, (m_nCount - iIndex) * sizeof(LPVOID)); return true; } int CStdPtrArray::Find(LPVOID pData) const { for( int i = 0; i < m_nCount; i++ ) if( m_ppVoid[i] == pData ) return i; return -1; } int CStdPtrArray::GetSize() const { return m_nCount; } LPVOID* CStdPtrArray::GetData() { return m_ppVoid; } LPVOID CStdPtrArray::GetAt(int iIndex) const { if( iIndex < 0 || iIndex >= m_nCount ) return NULL; return m_ppVoid[iIndex]; } LPVOID CStdPtrArray::operator[] (int iIndex) const { ASSERT(iIndex>=0 && iIndex<m_nCount); return m_ppVoid[iIndex]; } ///////////////////////////////////////////////////////////////////////////////////// // // CStdValArray::CStdValArray(int iElementSize, int iPreallocSize /*= 0*/) : m_pVoid(NULL), m_nCount(0), m_iElementSize(iElementSize), m_nAllocated(iPreallocSize) { ASSERT(iElementSize>0); ASSERT(iPreallocSize>=0); if( iPreallocSize > 0 ) m_pVoid = static_cast<LPBYTE>(malloc(iPreallocSize * m_iElementSize)); } CStdValArray::~CStdValArray() { if( m_pVoid != NULL ) free(m_pVoid); } void CStdValArray::Empty() { m_nCount = 0; // NOTE: We keep the memory in place } bool CStdValArray::IsEmpty() const { return m_nCount == 0; } bool CStdValArray::Add(LPCVOID pData) { if( ++m_nCount >= m_nAllocated) { int nAllocated = m_nAllocated * 2; if( nAllocated == 0 ) nAllocated = 11; LPBYTE pVoid = static_cast<LPBYTE>(realloc(m_pVoid, nAllocated * m_iElementSize)); if( pVoid != NULL ) { m_nAllocated = nAllocated; m_pVoid = pVoid; } else { --m_nCount; return false; } } ::CopyMemory(m_pVoid + ((m_nCount - 1) * m_iElementSize), pData, m_iElementSize); return true; } bool CStdValArray::Remove(int iIndex) { if( iIndex < 0 || iIndex >= m_nCount ) return false; if( iIndex < --m_nCount ) ::CopyMemory(m_pVoid + (iIndex * m_iElementSize), m_pVoid + ((iIndex + 1) * m_iElementSize), (m_nCount - iIndex) * m_iElementSize); return true; } int CStdValArray::GetSize() const { return m_nCount; } LPVOID CStdValArray::GetData() { return static_cast<LPVOID>(m_pVoid); } LPVOID CStdValArray::GetAt(int iIndex) const { if( iIndex < 0 || iIndex >= m_nCount ) return NULL; return m_pVoid + (iIndex * m_iElementSize); } LPVOID CStdValArray::operator[] (int iIndex) const { ASSERT(iIndex>=0 && iIndex<m_nCount); return m_pVoid + (iIndex * m_iElementSize); } ///////////////////////////////////////////////////////////////////////////////////// // // CStdString::CStdString() : m_pstr(m_szBuffer) { m_szBuffer[0] = '\0'; } CStdString::CStdString(const TCHAR ch) : m_pstr(m_szBuffer) { m_szBuffer[0] = ch; m_szBuffer[1] = '\0'; } CStdString::CStdString(LPCTSTR lpsz, int nLen) : m_pstr(m_szBuffer) { #ifndef _WIN32_WCE ASSERT(!::IsBadStringPtr(lpsz,-1) || lpsz==NULL); #else #endif m_szBuffer[0] = '\0'; Assign(lpsz, nLen); } CStdString::CStdString(const CStdString& src) : m_pstr(m_szBuffer) { m_szBuffer[0] = '\0'; Assign(src.m_pstr); } CStdString::~CStdString() { if( m_pstr != m_szBuffer ) free(m_pstr); } int CStdString::GetLength() const { return (int) _tcslen(m_pstr); } CStdString::operator LPCTSTR() const { return m_pstr; } void CStdString::Append(LPCTSTR pstr) { int nNewLength = GetLength() + (int) _tcslen(pstr); if( nNewLength >= MAX_LOCAL_STRING_LEN ) { if( m_pstr == m_szBuffer ) { m_pstr = static_cast<LPTSTR>(malloc((nNewLength + 1) * sizeof(TCHAR))); _tcscpy(m_pstr, m_szBuffer); _tcscat(m_pstr, pstr); } else { m_pstr = static_cast<LPTSTR>(realloc(m_pstr, (nNewLength + 1) * sizeof(TCHAR))); _tcscat(m_pstr, pstr); } } else { if( m_pstr != m_szBuffer ) { free(m_pstr); m_pstr = m_szBuffer; } _tcscat(m_szBuffer, pstr); } } void CStdString::Assign(LPCTSTR pstr, int cchMax) { if( pstr == NULL ) pstr = _T(""); cchMax = (cchMax < 0 ? (int) _tcslen(pstr) : cchMax); if( cchMax < MAX_LOCAL_STRING_LEN ) { if( m_pstr != m_szBuffer ) { free(m_pstr); m_pstr = m_szBuffer; } } else if( cchMax > GetLength() || m_pstr == m_szBuffer ) { if( m_pstr == m_szBuffer ) m_pstr = NULL; m_pstr = static_cast<LPTSTR>(realloc(m_pstr, (cchMax + 1) * sizeof(TCHAR))); } _tcsncpy(m_pstr, pstr, cchMax); m_pstr[cchMax] = '\0'; } bool CStdString::IsEmpty() const { return m_pstr[0] == '\0'; } void CStdString::Empty() { if( m_pstr != m_szBuffer ) free(m_pstr); m_pstr = m_szBuffer; m_szBuffer[0] = '\0'; } LPCTSTR CStdString::GetData() { return m_pstr; } TCHAR CStdString::GetAt(int nIndex) const { return m_pstr[nIndex]; } TCHAR CStdString::operator[] (int nIndex) const { return m_pstr[nIndex]; } const CStdString& CStdString::operator=(const CStdString& src) { Assign(src); return *this; } const CStdString& CStdString::operator=(LPCTSTR lpStr) { #ifndef _WIN32_WCE ASSERT(!::IsBadStringPtr(lpStr,-1)); #endif Assign(lpStr); return *this; } #ifndef _UNICODE const CStdString& CStdString::operator=(LPCWSTR lpwStr) { ASSERT(!::IsBadStringPtrW(lpwStr,-1)); int cchStr = ((int) wcslen(lpwStr) * 2) + 1; LPSTR pstr = (LPSTR) _alloca(cchStr); if( pstr != NULL ) ::WideCharToMultiByte(::GetACP(), 0, lpwStr, -1, pstr, cchStr, NULL, NULL); Assign(pstr); return *this; } #endif // _UNICODE const CStdString& CStdString::operator=(const TCHAR ch) { Empty(); m_szBuffer[0] = ch; m_szBuffer[1] = '\0'; return *this; } CStdString CStdString::operator+(const CStdString& src) { CStdString sTemp = *this; sTemp.Append(src); return sTemp; } CStdString CStdString::operator+(LPCTSTR lpStr) { #ifndef _WIN32_WCE ASSERT(!::IsBadStringPtr(lpStr,-1)); #endif CStdString sTemp = *this; sTemp.Append(lpStr); return sTemp; } const CStdString& CStdString::operator+=(const CStdString& src) { Append(src); return *this; } const CStdString& CStdString::operator+=(LPCTSTR lpStr) { #ifndef _WIN32_WCE ASSERT(!::IsBadStringPtr(lpStr,-1)); #endif Append(lpStr); return *this; } const CStdString& CStdString::operator+=(const TCHAR ch) { TCHAR str[] = { ch, '\0' }; Append(str); return *this; } bool CStdString::operator == (LPCTSTR str) const { return (Compare(str) == 0); }; bool CStdString::operator != (LPCTSTR str) const { return (Compare(str) != 0); }; bool CStdString::operator <= (LPCTSTR str) const { return (Compare(str) <= 0); }; bool CStdString::operator < (LPCTSTR str) const { return (Compare(str) < 0); }; bool CStdString::operator >= (LPCTSTR str) const { return (Compare(str) >= 0); }; bool CStdString::operator > (LPCTSTR str) const { return (Compare(str) > 0); }; void CStdString::SetAt(int nIndex, TCHAR ch) { ASSERT(nIndex>=0 && nIndex<GetLength()); m_pstr[nIndex] = ch; } int CStdString::Compare(LPCTSTR lpsz) const { return _tcscmp(m_pstr, lpsz); } int CStdString::CompareNoCase(LPCTSTR lpsz) const { return _tcsicmp(m_pstr, lpsz); } void CStdString::MakeUpper() { _tcsupr(m_pstr); } void CStdString::MakeLower() { _tcslwr(m_pstr); } CStdString CStdString::Left(int iLength) const { if( iLength < 0 ) iLength = 0; if( iLength > GetLength() ) iLength = GetLength(); return CStdString(m_pstr, iLength); } CStdString CStdString::Mid(int iPos, int iLength) const { if( iLength < 0 ) iLength = GetLength() - iPos; if( iPos + iLength > GetLength() ) iLength = GetLength() - iPos; if( iLength <= 0 ) return CStdString(); return CStdString(m_pstr + iPos, iLength); } CStdString CStdString::Right(int iLength) const { int iPos = GetLength() - iLength; if( iPos < 0 ) { iPos = 0; iLength = GetLength(); } return CStdString(m_pstr + iPos, iLength); } int CStdString::Find(TCHAR ch, int iPos /*= 0*/) const { ASSERT(iPos>=0 && iPos<=GetLength()); if( iPos != 0 && (iPos < 0 || iPos >= GetLength()) ) return -1; LPCTSTR p = _tcschr(m_pstr + iPos, ch); if( p == NULL ) return -1; return (int)(p - m_pstr); } int CStdString::Find(LPCTSTR pstrSub, int iPos /*= 0*/) const { #ifndef _WIN32_WCE ASSERT(!::IsBadStringPtr(pstrSub,-1)); #endif ASSERT(iPos>=0 && iPos<=GetLength()); if( iPos != 0 && (iPos < 0 || iPos > GetLength()) ) return -1; LPCTSTR p = _tcsstr(m_pstr + iPos, pstrSub); if( p == NULL ) return -1; return (int)(p - m_pstr); } int CStdString::ReverseFind(TCHAR ch) const { LPCTSTR p = _tcsrchr(m_pstr, ch); if( p == NULL ) return -1; return (int)(p - m_pstr); } int CStdString::Replace(LPCTSTR pstrFrom, LPCTSTR pstrTo) { CStdString sTemp; int nCount = 0; int iPos = Find(pstrFrom); if( iPos < 0 ) return 0; int cchFrom = (int) _tcslen(pstrFrom); int cchTo = (int) _tcslen(pstrTo); while( iPos >= 0 ) { sTemp = Left(iPos); sTemp += pstrTo; sTemp += Mid(iPos + cchFrom); Assign(sTemp); iPos = Find(pstrFrom, iPos + cchTo); nCount++; } return nCount; } int CStdString::Format(LPCTSTR pstrFormat, ...) { CStdString sFormat = pstrFormat; // Do ordinary printf replacements // NOTE: Documented max-length of wvsprintf() is 1024 TCHAR szBuffer[1025] = { 0 }; va_list argList; va_start(argList, pstrFormat); int iRet = ::wvsprintf(szBuffer, sFormat, argList); va_end(argList); Assign(szBuffer); return iRet; } int CStdString::SmallFormat(LPCTSTR pstrFormat, ...) { CStdString sFormat = pstrFormat; TCHAR szBuffer[64] = { 0 }; va_list argList; va_start(argList, pstrFormat); int iRet = ::wvsprintf(szBuffer, sFormat, argList); va_end(argList); Assign(szBuffer); return iRet; } ///////////////////////////////////////////////////////////////////////////// // // static UINT HashKey(LPCTSTR Key) { UINT i = 0; SIZE_T len = _tcslen(Key); while( len-- > 0 ) i = (i << 5) + i + Key[len]; return i; } static UINT HashKey(const CStdString& Key) { return HashKey((LPCTSTR)Key); }; CStdStringPtrMap::CStdStringPtrMap(int nSize) { if( nSize < 16 ) nSize = 16; m_nBuckets = nSize; m_aT = new TITEM*[nSize]; memset(m_aT, 0, nSize * sizeof(TITEM*)); } CStdStringPtrMap::~CStdStringPtrMap() { if( m_aT ) { int len = m_nBuckets; while( len-- ) { TITEM* pItem = m_aT[len]; while( pItem ) { TITEM* pKill = pItem; pItem = pItem->pNext; delete pKill; } } delete [] m_aT; m_aT = NULL; } } void CStdStringPtrMap::Resize(int nSize) { if( m_aT ) { int len = m_nBuckets; while( len-- ) { TITEM* pItem = m_aT[len]; while( pItem ) { TITEM* pKill = pItem; pItem = pItem->pNext; delete pKill; } } delete [] m_aT; m_aT = NULL; } if( nSize < 0 ) nSize = 0; if( nSize > 0 ) { m_aT = new TITEM*[nSize]; memset(m_aT, 0, nSize * sizeof(TITEM*)); } m_nBuckets = nSize; } LPVOID CStdStringPtrMap::Find(LPCTSTR key) const { if( m_nBuckets == 0 ) return NULL; UINT slot = HashKey(key) % m_nBuckets; for( const TITEM* pItem = m_aT[slot]; pItem; pItem = pItem->pNext ) { if( pItem->Key == key ) { return pItem->Data; } } return NULL; } bool CStdStringPtrMap::Insert(LPCTSTR key, LPVOID pData) { if( m_nBuckets == 0 ) return false; if( Find(key) ) return false; // Add first in bucket UINT slot = HashKey(key) % m_nBuckets; TITEM* pItem = new TITEM; pItem->Key = key; pItem->Data = pData; pItem->pNext = m_aT[slot]; m_aT[slot] = pItem; return true; } LPVOID CStdStringPtrMap::Set(LPCTSTR key, LPVOID pData) { if( m_nBuckets == 0 ) return pData; UINT slot = HashKey(key) % m_nBuckets; // Modify existing item for( TITEM* pItem = m_aT[slot]; pItem; pItem = pItem->pNext ) { if( pItem->Key == key ) { LPVOID pOldData = pItem->Data; pItem->Data = pData; return pOldData; } } Insert(key, pData); return NULL; } bool CStdStringPtrMap::Remove(LPCTSTR key) { if( m_nBuckets == 0 ) return false; UINT slot = HashKey(key) % m_nBuckets; TITEM** ppItem = &m_aT[slot]; while( *ppItem ) { if( (*ppItem)->Key == key ) { TITEM* pKill = *ppItem; *ppItem = (*ppItem)->pNext; delete pKill; return true; } ppItem = &((*ppItem)->pNext); } return false; } int CStdStringPtrMap::GetSize() const { int nCount = 0; int len = m_nBuckets; while( len-- ) { for( const TITEM* pItem = m_aT[len]; pItem; pItem = pItem->pNext ) nCount++; } return nCount; } LPCTSTR CStdStringPtrMap::GetAt(int iIndex) const { int pos = 0; int len = m_nBuckets; while( len-- ) { for( TITEM* pItem = m_aT[len]; pItem; pItem = pItem->pNext ) { if( pos++ == iIndex ) { return pItem->Key.GetData(); } } } return NULL; } LPCTSTR CStdStringPtrMap::operator[] (int nIndex) const { return GetAt(nIndex); } ///////////////////////////////////////////////////////////////////////////////////// // // CWindowWnd::CWindowWnd() : m_hWnd(NULL), m_OldWndProc(::DefWindowProc), m_bSubclassed(false) { } HWND CWindowWnd::GetHWND() const { return m_hWnd; } UINT CWindowWnd::GetClassStyle() const { return 0; } LPCTSTR CWindowWnd::GetSuperClassName() const { return NULL; } CWindowWnd::operator HWND() const { return m_hWnd; } HWND CWindowWnd::Create(HWND hwndParent, LPCTSTR pstrName, DWORD dwStyle, DWORD dwExStyle, const RECT rc, HMENU hMenu) { return Create(hwndParent, pstrName, dwStyle, dwExStyle, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, hMenu); } HWND CWindowWnd::Create(HWND hwndParent, LPCTSTR pstrName, DWORD dwStyle, DWORD dwExStyle, int x, int y, int cx, int cy, HMENU hMenu) { if( GetSuperClassName() != NULL && !RegisterSuperclass() ) return NULL; if( GetSuperClassName() == NULL && !RegisterWindowClass() ) return NULL; m_hWnd = ::CreateWindowEx(dwExStyle, GetWindowClassName(), pstrName, dwStyle, x, y, cx, cy, hwndParent, hMenu, CPaintManagerUI::GetInstance(), this); ASSERT(m_hWnd!=NULL); return m_hWnd; } HWND CWindowWnd::Subclass(HWND hWnd) { ASSERT(::IsWindow(hWnd)); ASSERT(m_hWnd==NULL); m_OldWndProc = SubclassWindow(hWnd, __WndProc); if( m_OldWndProc == NULL ) return NULL; m_bSubclassed = true; m_hWnd = hWnd; return m_hWnd; } void CWindowWnd::Unsubclass() { ASSERT(::IsWindow(m_hWnd)); if( !::IsWindow(m_hWnd) ) return; if( !m_bSubclassed ) return; SubclassWindow(m_hWnd, m_OldWndProc); m_OldWndProc = ::DefWindowProc; m_bSubclassed = false; } void CWindowWnd::ShowWindow(bool bShow /*= true*/, bool bTakeFocus /*= false*/) { ASSERT(::IsWindow(m_hWnd)); if( !::IsWindow(m_hWnd) ) return; ::ShowWindow(m_hWnd, bShow ? (bTakeFocus ? SW_SHOWNORMAL : SW_SHOWNOACTIVATE) : SW_HIDE); } UINT CWindowWnd::ShowModal() { ASSERT(::IsWindow(m_hWnd)); UINT nRet = 0; HWND hWndParent = GetWindowOwner(m_hWnd); ::ShowWindow(m_hWnd, SW_SHOWNORMAL); ::EnableWindow(hWndParent, FALSE); MSG msg = { 0 }; while( ::IsWindow(m_hWnd) && ::GetMessage(&msg, NULL, 0, 0) ) { if( msg.message == WM_CLOSE && msg.hwnd == m_hWnd ) { nRet = msg.wParam; ::EnableWindow(hWndParent, TRUE); ::SetFocus(hWndParent); } if( !CPaintManagerUI::TranslateMessage(&msg) ) { ::TranslateMessage(&msg); ::DispatchMessage(&msg); } if( msg.message == WM_QUIT ) break; } ::EnableWindow(hWndParent, TRUE); ::SetFocus(hWndParent); if( msg.message == WM_QUIT ) ::PostQuitMessage(msg.wParam); return nRet; } void CWindowWnd::Close(UINT nRet) { ASSERT(::IsWindow(m_hWnd)); if( !::IsWindow(m_hWnd) ) return; PostMessage(WM_CLOSE, (WPARAM)nRet, 0L); } void CWindowWnd::CenterWindow() { ASSERT(::IsWindow(m_hWnd)); ASSERT((GetWindowStyle(m_hWnd)&WS_CHILD)==0); RECT rcDlg = { 0 }; ::GetWindowRect(m_hWnd, &rcDlg); RECT rcArea = { 0 }; RECT rcCenter = { 0 }; HWND hWndParent = ::GetParent(m_hWnd); HWND hWndCenter = ::GetWindowOwner(m_hWnd); ::SystemParametersInfo(SPI_GETWORKAREA, NULL, &rcArea, NULL); if( hWndCenter == NULL ) rcCenter = rcArea; else ::GetWindowRect(hWndCenter, &rcCenter); int DlgWidth = rcDlg.right - rcDlg.left; int DlgHeight = rcDlg.bottom - rcDlg.top; // Find dialog's upper left based on rcCenter int xLeft = (rcCenter.left + rcCenter.right) / 2 - DlgWidth / 2; int yTop = (rcCenter.top + rcCenter.bottom) / 2 - DlgHeight / 2; // The dialog is outside the screen, move it inside if( xLeft < rcArea.left ) xLeft = rcArea.left; else if( xLeft + DlgWidth > rcArea.right ) xLeft = rcArea.right - DlgWidth; if( yTop < rcArea.top ) yTop = rcArea.top; else if( yTop + DlgHeight > rcArea.bottom ) yTop = rcArea.bottom - DlgHeight; ::SetWindowPos(m_hWnd, NULL, xLeft, yTop, -1, -1, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); } void CWindowWnd::SetIcon(UINT nRes) { HICON hIcon = (HICON)::LoadImage(CPaintManagerUI::GetInstance(), MAKEINTRESOURCE(nRes), IMAGE_ICON, ::GetSystemMetrics(SM_CXICON), ::GetSystemMetrics(SM_CYICON), LR_DEFAULTCOLOR); ASSERT(hIcon); ::SendMessage(m_hWnd, WM_SETICON, (WPARAM) TRUE, (LPARAM) hIcon); hIcon = (HICON)::LoadImage(CPaintManagerUI::GetInstance(), MAKEINTRESOURCE(nRes), IMAGE_ICON, ::GetSystemMetrics(SM_CXSMICON), ::GetSystemMetrics(SM_CYSMICON), LR_DEFAULTCOLOR); ASSERT(hIcon); ::SendMessage(m_hWnd, WM_SETICON, (WPARAM) FALSE, (LPARAM) hIcon); } bool CWindowWnd::RegisterWindowClass() { WNDCLASS wc = { 0 }; wc.style = GetClassStyle(); wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hIcon = NULL; wc.lpfnWndProc = CWindowWnd::__WndProc; wc.hInstance = CPaintManagerUI::GetInstance(); wc.hCursor = ::LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = NULL; wc.lpszMenuName = NULL; wc.lpszClassName = GetWindowClassName(); ATOM ret = ::RegisterClass(&wc); ASSERT(ret!=NULL || ::GetLastError()==ERROR_CLASS_ALREADY_EXISTS); return ret != NULL || ::GetLastError() == ERROR_CLASS_ALREADY_EXISTS; } bool CWindowWnd::RegisterSuperclass() { // Get the class information from an existing // window so we can subclass it later on... #ifndef _WIN32_WCE WNDCLASSEX wc = { 0 }; wc.cbSize = sizeof(WNDCLASSEX); if( !::GetClassInfoEx(NULL, GetSuperClassName(), &wc) ) { if( !::GetClassInfoEx(CPaintManagerUI::GetInstance(), GetSuperClassName(), &wc) ) { ASSERT(!"Unable to locate window class"); return NULL; } } m_OldWndProc = wc.lpfnWndProc; wc.lpfnWndProc = CWindowWnd::__ControlProc; wc.hInstance = CPaintManagerUI::GetInstance(); wc.lpszClassName = GetWindowClassName(); ATOM ret = ::RegisterClassEx(&wc); #else WNDCLASS wc = { 0 }; if( !::GetClassInfo(NULL, GetSuperClassName(), &wc) ) { if( !::GetClassInfo(CPaintManagerUI::GetInstance(), GetSuperClassName(), &wc) ) { ASSERT(!"Unable to locate window class"); return NULL; } } wc.hbrBackground = (HBRUSH)::GetStockObject(WHITE_BRUSH); wc.hCursor = ::LoadCursor(NULL, IDC_ARROW); m_OldWndProc = wc.lpfnWndProc; wc.lpfnWndProc = CWindowWnd::__ControlProc; wc.hInstance = CPaintManagerUI::GetInstance(); wc.lpszClassName = GetWindowClassName(); ATOM ret = ::RegisterClass(&wc); #endif ASSERT(ret!=NULL || ::GetLastError()==ERROR_CLASS_ALREADY_EXISTS); return ret != NULL || ::GetLastError() == ERROR_CLASS_ALREADY_EXISTS; } LRESULT CALLBACK CWindowWnd::__WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { CWindowWnd* pThis = NULL; #ifndef _WIN32_WCE if( uMsg == WM_NCCREATE ) { LPCREATESTRUCT lpcs = reinterpret_cast<LPCREATESTRUCT>(lParam); pThis = static_cast<CWindowWnd*>(lpcs->lpCreateParams); pThis->m_hWnd = hWnd; ::SetWindowLongPtr(hWnd, GWLP_USERDATA, reinterpret_cast<LPARAM>(pThis)); } else { pThis = reinterpret_cast<CWindowWnd*>(::GetWindowLongPtr(hWnd, GWLP_USERDATA)); if( uMsg == WM_NCDESTROY && pThis != NULL ) { LRESULT lRes = ::CallWindowProc(pThis->m_OldWndProc, hWnd, uMsg, wParam, lParam); ::SetWindowLongPtr(pThis->m_hWnd, GWLP_USERDATA, 0L); if( pThis->m_bSubclassed ) pThis->Unsubclass(); pThis->m_hWnd = NULL; pThis->OnFinalMessage(hWnd); return lRes; } } #else if( uMsg == WM_CREATE ) { LPCREATESTRUCT lpcs = reinterpret_cast<LPCREATESTRUCT>(lParam); pThis = static_cast<CWindowWnd*>(lpcs->lpCreateParams); pThis->m_hWnd = hWnd; ::SetWindowLong(hWnd, GWL_USERDATA, reinterpret_cast<LPARAM>(pThis)); } else { pThis = reinterpret_cast<CWindowWnd*>(::GetWindowLong(hWnd, GWL_USERDATA)); if( uMsg == WM_DESTROY && pThis != NULL ) { LRESULT lRes = ::CallWindowProc(pThis->m_OldWndProc, hWnd, uMsg, wParam, lParam); ::SetWindowLong(pThis->m_hWnd, GWL_USERDATA, 0L); if( pThis->m_bSubclassed ) pThis->Unsubclass(); pThis->m_hWnd = NULL; pThis->OnFinalMessage(hWnd); return lRes; } } #endif if( pThis != NULL ) { return pThis->HandleMessage(uMsg, wParam, lParam); } else { return ::DefWindowProc(hWnd, uMsg, wParam, lParam); } } LRESULT CALLBACK CWindowWnd::__ControlProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { CWindowWnd* pThis = NULL; #ifndef _WIN32_WCE if( uMsg == WM_NCCREATE ) { LPCREATESTRUCT lpcs = reinterpret_cast<LPCREATESTRUCT>(lParam); pThis = static_cast<CWindowWnd*>(lpcs->lpCreateParams); ::SetProp(hWnd, _T("WndX"), (HANDLE) pThis); pThis->m_hWnd = hWnd; } else { pThis = reinterpret_cast<CWindowWnd*>(::GetProp(hWnd, _T("WndX"))); if( uMsg == WM_NCDESTROY && pThis != NULL ) { LRESULT lRes = ::CallWindowProc(pThis->m_OldWndProc, hWnd, uMsg, wParam, lParam); if( pThis->m_bSubclassed ) pThis->Unsubclass(); ::SetProp(hWnd, _T("WndX"), NULL); pThis->m_hWnd = NULL; pThis->OnFinalMessage(hWnd); return lRes; } } #else if( uMsg == WM_CREATE ) { LPCREATESTRUCT lpcs = reinterpret_cast<LPCREATESTRUCT>(lParam); pThis = static_cast<CWindowWnd*>(lpcs->lpCreateParams); ::SetProp(hWnd, _T("WndX"), (HANDLE) pThis); pThis->m_hWnd = hWnd; } else { pThis = reinterpret_cast<CWindowWnd*>(::GetProp(hWnd, _T("WndX"))); if( uMsg == WM_DESTROY && pThis != NULL ) { LRESULT lRes = ::CallWindowProc(pThis->m_OldWndProc, hWnd, uMsg, wParam, lParam); if( pThis->m_bSubclassed ) pThis->Unsubclass(); ::SetProp(hWnd, _T("WndX"), NULL); pThis->m_hWnd = NULL; pThis->OnFinalMessage(hWnd); return lRes; } } #endif if( pThis != NULL ) { return pThis->HandleMessage(uMsg, wParam, lParam); } else { return ::DefWindowProc(hWnd, uMsg, wParam, lParam); } } LRESULT CWindowWnd::SendMessage(UINT uMsg, WPARAM wParam /*= 0*/, LPARAM lParam /*= 0*/) { ASSERT(::IsWindow(m_hWnd)); return ::SendMessage(m_hWnd, uMsg, wParam, lParam); } LRESULT CWindowWnd::PostMessage(UINT uMsg, WPARAM wParam /*= 0*/, LPARAM lParam /*= 0*/) { ASSERT(::IsWindow(m_hWnd)); return ::PostMessage(m_hWnd, uMsg, wParam, lParam); } void CWindowWnd::ResizeClient(int cx /*= -1*/, int cy /*= -1*/) { ASSERT(::IsWindow(m_hWnd)); RECT rc = { 0 }; if( !::GetClientRect(m_hWnd, &rc) ) return; if( cx != -1 ) rc.right = cx; if( cy != -1 ) rc.bottom = cy; #ifndef _WIN32_WCE if( !::AdjustWindowRectEx(&rc, GetWindowStyle(m_hWnd), (!(GetWindowStyle(m_hWnd) & WS_CHILD) && (::GetMenu(m_hWnd) != NULL)), GetWindowExStyle(m_hWnd)) ) return; #else if( !::AdjustWindowRectEx(&rc, GetWindowStyle(m_hWnd), (!(GetWindowStyle(m_hWnd) & WS_CHILD)), GetWindowExStyle(m_hWnd)) ) return; #endif ::SetWindowPos(m_hWnd, NULL, 0, 0, rc.right - rc.left, rc.bottom - rc.top, SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE); } LRESULT CWindowWnd::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) { return ::CallWindowProc(m_OldWndProc, m_hWnd, uMsg, wParam, lParam); } void CWindowWnd::OnFinalMessage(HWND /*hWnd*/) { } ///////////////////////////////////////////////////////////////////////////////////// // // CWaitCursor::CWaitCursor() { m_hOrigCursor = ::SetCursor(::LoadCursor(NULL, IDC_WAIT)); } CWaitCursor::~CWaitCursor() { ::SetCursor(m_hOrigCursor); } } // namespace DuiLib