📄 atlwinmisc.h
字号:
#ifndef __ATLWINMISC_H__
#define __ATLWINMISC_H__
/////////////////////////////////////////////////////////////////////////////
// Misc wrappers for the Windows API
//
// Written by Bjarke Viksoe (bjarke@viksoe.dk)
// Copyright (c) 2000-2002 Bjarke Viksoe.
//
// Thanks to:
// Tim Tabor for the CResModule suggestion
// Anatoly Ivasyuk for fixing the AtlLoadHTML sz-string problem
//
// Wraps:
// SetLayeredWindowAttributes
// AnimateWindow
// DeferWindowPos
// Windows Resource API
// String types (with better localization support)
// Window Text
// LockWindowUpdate
// WM_SETREDRAW
// LoadLibrary
// GetClientRect
// GetWindowRect
// WINDOWPLACEMENT
// Windows Properties
// Ini-files (WritePrivateProfileString() etc)
// PlaySound wrapper
// MDI Commad message map
//
//
// This code may be used in compiled form in any way you desire. This
// file may be redistributed by any means PROVIDING it is
// not sold for profit without the authors written consent, and
// providing that this notice and the authors name is included.
//
// This file is provided "as is" with no expressed or implied warranty.
// The author accepts no liability if it causes any damage to you or your
// computer whatsoever. It's free, so don't hassle me about it.
//
// Beware of bugs.
//
#pragma once
#ifndef __cplusplus
#error ATL requires C++ compilation (use a .cpp suffix)
#endif
#if (_WTL_VER < 0x0700)
#error This file requires WTL version 7.0 or higher
#endif
namespace WTL
{
/////////////////////////////////////////////////////////////////////////////
// Windows Message macros
#define CHAIN_COMMANDS_HWND(hWnd) \
if(uMsg == WM_COMMAND && hWnd != NULL) \
::SendMessage(hWnd, uMsg, wParam, lParam);
#define CHAIN_CLIENT_WMAPP() \
if(uMsg >= WM_APP && m_hWndClient != NULL) \
::SendMessage(m_hWndClient, uMsg, wParam, lParam);
#define CHAIN_MDI_CHILD_WMAPP() \
if(uMsg >= WM_APP) \
{ \
HWND hWndChild = MDIGetActive(); \
if(hWndChild != NULL) \
::SendMessage(hWndChild, uMsg, wParam, lParam); \
}
/////////////////////////////////////////////////////////////////////////////
// Message Loop with Idle count
class CIdleHandlerEx
{
public:
virtual BOOL OnIdle(int nCount) = 0;
};
class CMessageLoopEx : public CMessageLoop
{
public:
CSimpleArray<CIdleHandlerEx*> m_aIdleHandler;
BOOL AddIdleHandler(CIdleHandlerEx* pIdleHandler)
{
return m_aIdleHandler.Add(pIdleHandler);
}
BOOL RemoveIdleHandler(CIdleHandlerEx* pIdleHandler)
{
return m_aIdleHandler.Remove(pIdleHandler);
}
virtual BOOL OnIdle(int nIdleCount)
{
for( int i = 0; i < m_aIdleHandler.GetSize(); i++ )
{
CIdleHandlerEx* pIdleHandler = m_aIdleHandler[i];
if( pIdleHandler != NULL ) pIdleHandler->OnIdle(nIdleCount);
}
return TRUE; // Always continue
}
};
/////////////////////////////////////////////////////////////////////////////
// Transparent window - safe usage of Win2K alpha layer window
// Platform SDK constants for layered window (Win2K and above only)
#ifndef WS_EX_LAYERED
#define WS_EX_LAYERED 0x00080000
#define LWA_COLORKEY 0x00000001
#define LWA_ALPHA 0x00000002
#endif // WS_EX_LAYERED
class CTransparentWindow : public CWindow
{
public:
CTransparentWindow(HWND hWnd = NULL) : CWindow(hWnd)
{
}
CTransparentWindow& operator=(HWND hWnd)
{
m_hWnd = hWnd;
return *this;
}
BOOL SetLayeredWindowAttributes(COLORREF crKey, BYTE bAlpha, DWORD dwFlags)
{
ATLASSERT(::IsWindow(m_hWnd));
typedef BOOL (WINAPI *PFNSETLAYEREDWINDOWATTRIBUTES)(HWND, COLORREF, BYTE, DWORD);
PFNSETLAYEREDWINDOWATTRIBUTES pfnSetLayeredWindowAttributes =
(PFNSETLAYEREDWINDOWATTRIBUTES) ::GetProcAddress( ::GetModuleHandle(_T("user32.dll")), "SetLayeredWindowAttributes");
if( pfnSetLayeredWindowAttributes == NULL ) return FALSE;
return pfnSetLayeredWindowAttributes(m_hWnd, crKey, bAlpha, dwFlags);
}
BOOL UpdateLayeredWindow(HDC hdcDst, POINT *pptDst, SIZE *psize, HDC hdcSrc, POINT *pptSrc, COLORREF crKey, BLENDFUNCTION *pblend, DWORD dwFlags)
{
ATLASSERT(::IsWindow(m_hWnd));
typedef BOOL (WINAPI *PFNUPDATELAYEREDWINDOW)(HWND, HDC, POINT*, SIZE*, HDC, POINT*, COLORREF, BLENDFUNCTION*, DWORD);
PFNUPDATELAYEREDWINDOW pfnUpdateLayeredWindow =
(PFNUPDATELAYEREDWINDOW) ::GetProcAddress( ::GetModuleHandle(_T("user32.dll")), "UpdateLayeredWindow");
if( pfnUpdateLayeredWindow == NULL ) return FALSE;
return pfnUpdateLayeredWindow(m_hWnd, hdcDst, pptDst, psize, hdcSrc, pptSrc, crKey, pblend, dwFlags);
}
};
/////////////////////////////////////////////////////////////////////////////
// CAnimateWindow
// Platform SDK constants for animate effects (Win2k and above only)
#ifndef AW_BLEND
#define AW_HOR_POSITIVE 0x00000001
#define AW_HOR_NEGATIVE 0x00000002
#define AW_VER_POSITIVE 0x00000004
#define AW_VER_NEGATIVE 0x00000008
#define AW_HIDE 0x00010000
#define AW_ACTIVATE 0x00020000
#define AW_SLIDE 0x00040000
#define AW_BLEND 0x00080000
#endif // AW_BLEND
// Wraps AnimateWindow() on Win2K
class CAnimateWindow : public CWindow
{
public:
CAnimateWindow(HWND hWnd = NULL) : CWindow(hWnd)
{
}
CAnimateWindow& operator=(HWND hWnd)
{
m_hWnd = hWnd;
return *this;
}
BOOL AnimateWindow(DWORD dwTime = 200, DWORD dwFlags = AW_BLEND|AW_ACTIVATE)
{
typedef BOOL (CALLBACK* PFNANIMATEWINDOW)(HWND,DWORD,DWORD);
if( !AtlIsOldWindows() ) {
PFNANIMATEWINDOW pfnAnimateWindow = (PFNANIMATEWINDOW)
::GetProcAddress(::GetModuleHandle(_T("user32.dll")), "AnimateWindow");
if( pfnAnimateWindow != NULL ) return pfnAnimateWindow( m_hWnd, dwTime, dwFlags );
}
return FALSE;
}
};
/////////////////////////////////////////////////////////////////////////////
// CResource
// Wraps a Windows resource.
// Use it with custom resource types other than the standard
// RT_CURSOR, RT_BITMAP etc etc.
class CResource
{
public:
HGLOBAL m_hglb;
HRSRC m_hrsrc;
bool m_bLocked;
CResource() : m_hglb(NULL), m_hrsrc(NULL), m_bLocked(false)
{
}
~CResource()
{
Release();
}
BOOL Load(_U_STRINGorID Type, _U_STRINGorID ID)
{
ATLASSERT(m_hrsrc==NULL);
ATLASSERT(m_hglb==NULL);
#if (_ATL_VER >= 0x0700)
m_hrsrc = ::FindResource(ATL::_AtlBaseModule.GetResourceInstance(), ID.m_lpstr, Type.m_lpstr);
#else
m_hrsrc = ::FindResource(_Module.GetResourceInstance(), ID.m_lpstr, Type.m_lpstr);
#endif // _ATL_VER
if( m_hrsrc == NULL ) return FALSE;
#if (_ATL_VER >= 0x0700)
m_hglb = ::LoadResource(ATL::_AtlBaseModule.GetResourceInstance(), m_hrsrc);
#else
m_hglb = ::LoadResource(_Module.GetResourceInstance(), m_hrsrc);
#endif // _ATL_VER
if( m_hglb == NULL ) {
m_hrsrc = NULL;
return FALSE;
}
return TRUE;
}
BOOL LoadEx(_U_STRINGorID Type, _U_STRINGorID ID, WORD wLanguage)
{
ATLASSERT(m_hrsrc==NULL);
ATLASSERT(m_hglb==NULL);
#if (_ATL_VER >= 0x0700)
m_hrsrc = ::FindResourceEx(ATL::_AtlBaseModule.GetResourceInstance(), ID.m_lpstr, Type.m_lpstr, wLanguage);
#else
m_hrsrc = ::FindResourceEx(_Module.GetResourceInstance(), ID.m_lpstr, Type.m_lpstr, wLanguage);
#endif // _ATL_VER
if( m_hrsrc == NULL ) return FALSE;
#if (_ATL_VER >= 0x0700)
m_hglb = ::LoadResource(ATL::_AtlBaseModule.GetResourceInstance(), m_hrsrc);
#else
m_hglb = ::LoadResource(_Module.GetResourceInstance(), m_hrsrc);
#endif // _ATL_VER
if( m_hglb == NULL ) {
m_hrsrc = NULL;
return FALSE;
}
return TRUE;
}
DWORD GetSize() const
{
ATLASSERT(m_hrsrc);
#if (_ATL_VER >= 0x0700)
return ::SizeofResource(ATL::_AtlBaseModule.GetResourceInstance(), m_hrsrc);
#else
return ::SizeofResource(_Module.GetResourceInstance(), m_hrsrc);
#endif // _ATL_VER
}
LPVOID Lock()
{
ATLASSERT(m_hrsrc);
ATLASSERT(m_hglb);
ATLASSERT(!m_bLocked);
LPVOID pVoid = ::LockResource(m_hglb);
ATLASSERT(pVoid);
m_bLocked = true;
return pVoid;
}
void Unlock()
{
ATLASSERT(m_hrsrc);
ATLASSERT(m_hglb);
ATLASSERT(m_bLocked);
m_bLocked = false;
UnlockResource(m_hglb);
}
void Release()
{
if( m_bLocked ) Unlock();
if( m_hglb != NULL ) ::FreeResource(m_hglb);
m_hglb = NULL;
m_hrsrc = NULL;
}
};
/////////////////////////////////////////////////////////////////////////////
// CResString
// Stack-based string buffer. Loads strings from the string-resource maps.
template< int nSize >
class CResString
{
public:
TCHAR m_szStr[nSize];
CResString()
{
m_szStr[0] = _T('\0');
}
CResString(UINT ID)
{
LoadString(ID);
}
inline int LoadString(UINT ID)
{
#if (_ATL_VER >= 0x0700)
return ::LoadString(ATL::_AtlBaseModule.GetResourceInstance(), ID, m_szStr, sizeof(m_szStr)/sizeof(TCHAR));
#else
return ::LoadString(_Module.GetResourceInstance(), ID, m_szStr, sizeof(m_szStr)/sizeof(TCHAR));
#endif // _ATL_VER
}
#ifdef _VA_LIST_DEFINED
int FormatString(UINT ID, ...)
{
TCHAR szFormat[nSize];
#if (_ATL_VER >= 0x0700)
int cch = ::LoadString(ATL::_AtlBaseModule.GetResourceInstance(), ID, szFormat, sizeof(szFormat)/sizeof(TCHAR));
#else
int cch = ::LoadString(_Module.GetResourceInstance(), ID, szFormat, sizeof(szFormat)/sizeof(TCHAR));
#endif // _ATL_VER
if( cch == 0 ) return 0;
va_list arglist;
va_start(arglist, ID);
cch = ::wvsprintf(m_szStr, szFormat, arglist);
va_end(arglist);
return cch;
}
#endif // _VA_LIST_DEFINED
inline int GetLength() const
{
return ::lstrlen(m_szStr);
}
operator LPCTSTR() const
{
return m_szStr;
}
};
/////////////////////////////////////////////////////////////////////////////
// CLangString
#if defined(__ATLSTR_H__) || defined(_WTL_USE_CSTRING)
class CLangString : public CString
{
public:
CLangString() { };
CLangString(const CString& s) : CString(s) { };
CLangString(const CLangString& s) : CString(s) { };
CLangString(LPCTSTR pstr) : CString(pstr) { };
CLangString(WORD wLanguage, UINT nID) { LoadString(wLanguage, nID); };
BOOL LoadString(WORD wLanguage, UINT nID)
{
// NOTE: This is a copy of the original WTL::String::LoadString() method
// but tweaked to call our _LoadString() helper instead...
// Try fixed buffer first (to avoid wasting space in the heap)
TCHAR szTemp[256];
int nCount = sizeof(szTemp) / sizeof(szTemp[0]);
int nLen = _LoadString(wLanguage, nID, szTemp, nCount);
if( nCount - nLen > CHAR_FUDGE ) {
* (CString*) this = szTemp;
return nLen > 0;
}
// Try buffer size of 512, then larger size until entire string is retrieved
int nSize = 256;
do {
nSize += 256;
LPTSTR lpstr = GetBuffer(nSize - 1);
if( lpstr == NULL ) {
nLen = 0;
break;
}
nLen = _LoadString(wLanguage, nID, lpstr, nSize);
} while( nSize - nLen <= CHAR_FUDGE );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -