📄 atlgdix.h
字号:
}
};
typedef CAcceleratorT<true> CAccelerator;
typedef CAcceleratorT<false> CAcceleratorHandle;
/////////////////////////////////////////////////////////////////////////////
// CLogFont
class CLogFont : public LOGFONT
{
public:
CLogFont()
{
::ZeroMemory( (LOGFONT*) this, sizeof(LOGFONT) );
}
CLogFont(const LOGFONT& lf)
{
Copy(&lf);
}
CLogFont(HFONT hFont)
{
ATLASSERT(::GetObjectType(hFont)==OBJ_FONT);
::GetObject(hFont, sizeof(LOGFONT), (LOGFONT*) this);
}
HFONT CreateFontIndirect()
{
return ::CreateFontIndirect(this);
}
void SetBold()
{
lfWeight = FW_BOLD;
}
BOOL IsBold() const
{
return lfWeight >= FW_BOLD;
}
void MakeBolder(int iScale = 1)
{
lfWeight += FW_BOLD * iScale;
}
void MakeLarger(int iScale)
{
if( lfHeight > 0 ) lfHeight += iScale; else lfHeight -= iScale;
}
void SetHeight(long PointSize, HDC hDC = NULL)
{
// For MM_TEXT mapping mode...
// NOTE: MulDiv() gives correct rounding.
lfHeight = -MulDiv(PointSize, ::GetDeviceCaps(hDC, LOGPIXELSY), 72);
}
long GetHeight(HDC hDC = NULL) const
{
// For MM_TEXT mapping mode...
// NOTE: MulDiv() gives correct rounding.
return MulDiv(-lfHeight, 72, ::GetDeviceCaps(hDC, LOGPIXELSY));
}
long GetDeciPointHeight(HDC hDC = NULL)
{
POINT ptOrg = { 0, 0 };
::DPtoLP(hDC, &ptOrg, 1);
POINT pt = { 0, 0 };
pt.y = abs(lfHeight) + ptOrg.y;
::LPtoDP(hDC,&pt,1);
return MulDiv(pt.y, 720, ::GetDeviceCaps(hDC,LOGPIXELSY)); // 72 points/inch, 10 decipoints/point
}
void SetHeightFromDeciPoint(long DeciPtHeight, HDC hDC = NULL)
{
POINT pt;
pt.y = MulDiv(::GetDeviceCaps(hDC, LOGPIXELSY), DeciPtHeight, 720); // 72 points/inch, 10 decipoints/point
::DPtoLP(hDC, &pt, 1);
POINT ptOrg = { 0, 0 };
::DPtoLP(hDC, &ptOrg, 1);
lfHeight = -abs(pt.y - ptOrg.y);
}
void SetCaptionFont()
{
NONCLIENTMETRICS ncm = { 0 };
ncm.cbSize = sizeof(ncm);
::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, 0);
Copy(&ncm.lfCaptionFont);
}
void SetMenuFont()
{
NONCLIENTMETRICS ncm = { 0 };
ncm.cbSize = sizeof(ncm);
::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, 0);
Copy(&ncm.lfMenuFont);
}
void SetStatusFont()
{
NONCLIENTMETRICS ncm = { 0 };
ncm.cbSize = sizeof(ncm);
::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, 0);
Copy(&ncm.lfStatusFont);
}
void SetMessageBoxFont()
{
NONCLIENTMETRICS ncm = { 0 };
ncm.cbSize = sizeof(ncm);
::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, 0);
Copy(&ncm.lfMessageFont);
}
void Copy(const LOGFONT* lf)
{
ATLASSERT(lf);
::CopyMemory( (LOGFONT*) this, lf, sizeof(LOGFONT) );
}
CLogFont& operator=(const CLogFont& src)
{
Copy(&src);
return *this;
}
CLogFont& operator=(const LOGFONT& src)
{
Copy(&src);
return *this;
}
CLogFont& operator=(HFONT hFont)
{
ATLASSERT(::GetObjectType(hFont)==OBJ_FONT);
::GetObject(hFont, sizeof(LOGFONT), (LOGFONT*) this);
return *this;
}
bool operator==(const LOGFONT& logfont) const
{
return( logfont.lfHeight == lfHeight &&
logfont.lfWidth == lfWidth &&
logfont.lfEscapement == lfEscapement &&
logfont.lfOrientation == lfOrientation &&
logfont.lfWeight == lfWeight &&
logfont.lfItalic == lfItalic &&
logfont.lfUnderline == lfUnderline &&
logfont.lfStrikeOut == lfStrikeOut &&
logfont.lfCharSet == lfCharSet &&
logfont.lfOutPrecision == lfOutPrecision &&
logfont.lfClipPrecision == lfClipPrecision &&
logfont.lfQuality == lfQuality &&
logfont.lfPitchAndFamily == lfPitchAndFamily &&
::lstrcmp(logfont.lfFaceName, lfFaceName) == 0 );
}
};
#endif // _WTL_VER
/////////////////////////////////////////////////////////////////////////////
// CMemDC
class CMemDC : public CDC
{
public:
CDCHandle m_dc; // Owner DC
CBitmap m_bitmap; // Offscreen bitmap
CBitmapHandle m_hOldBitmap; // Originally selected bitmap
RECT m_rc; // Rectangle of drawing area
CMemDC(HDC hDC, LPRECT pRect = NULL)
{
ATLASSERT(hDC!=NULL);
m_dc = hDC;
if( pRect != NULL ) m_rc = *pRect; else m_dc.GetClipBox(&m_rc);
CreateCompatibleDC(m_dc);
::LPtoDP(m_dc, (LPPOINT) &m_rc, sizeof(RECT) / sizeof(POINT));
m_bitmap.CreateCompatibleBitmap(m_dc, m_rc.right - m_rc.left, m_rc.bottom - m_rc.top);
m_hOldBitmap = SelectBitmap(m_bitmap);
::DPtoLP(m_dc, (LPPOINT) &m_rc, sizeof(RECT) / sizeof(POINT));
SetWindowOrg(m_rc.left, m_rc.top);
}
~CMemDC()
{
// Copy the offscreen bitmap onto the screen.
m_dc.BitBlt(m_rc.left, m_rc.top, m_rc.right - m_rc.left, m_rc.bottom - m_rc.top,
m_hDC, m_rc.left, m_rc.top, SRCCOPY);
// Swap back the original bitmap.
SelectBitmap(m_hOldBitmap);
}
};
/////////////////////////////////////////////////////////////////////////////
// COffscreenDraw
// To use it, derive from it and chain it in the message map.
template< class T >
class COffscreenDraw
{
public:
BEGIN_MSG_MAP(COffscreenDraw)
MESSAGE_HANDLER(WM_PAINT, OnPaint)
MESSAGE_HANDLER(WM_PRINTCLIENT, OnPaint)
MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground)
END_MSG_MAP()
LRESULT OnPaint(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
T* pT = static_cast<T*>(this);
if( wParam != NULL )
{
CMemDC memdc( (HDC) wParam, NULL );
pT->DoPaint(memdc.m_hDC);
}
else
{
RECT rc;
pT->GetClientRect(&rc);
CPaintDC dc(pT->m_hWnd);
CMemDC memdc(dc.m_hDC, &rc);
pT->DoPaint(memdc.m_hDC);
}
return 0;
}
LRESULT OnEraseBackground(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
return 1; // handled; no need to erase background; do it in DoPaint();
}
void DoPaint(CDCHandle dc)
{
ATLASSERT(false); // must override this
}
};
// To use it, derive from it and chain it in the message map.
template< class T >
class COffscreenDrawRect
{
public:
BEGIN_MSG_MAP(COffscreenDrawRect)
MESSAGE_HANDLER(WM_PAINT, OnPaint)
MESSAGE_HANDLER(WM_PRINTCLIENT, OnPaint)
MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground)
END_MSG_MAP()
LRESULT OnPaint(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
T* pT = static_cast<T*>(this);
if( wParam != NULL )
{
CMemDC memdc( (HDC) wParam, NULL );
pT->DoPaint(memdc.m_hDC, memdc.m_rc);
}
else
{
CPaintDC dc(pT->m_hWnd);
CMemDC memdc(dc.m_hDC, &dc.m_ps.rcPaint);
pT->DoPaint(memdc.m_hDC, dc.m_ps.rcPaint);
}
return 0;
}
LRESULT OnEraseBackground(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
return 1; // handled; no need to erase background; do it in DoPaint();
}
void DoPaint(CDCHandle dc, RECT& rcClip)
{
ATLASSERT(false); // must override this
}
};
/////////////////////////////////////////////////////////////////////////////
// CSaveDC
class CSaveDC
{
public:
HDC m_hDC;
int m_iState;
CSaveDC(HDC hDC) : m_hDC(hDC)
{
ATLASSERT(::GetObjectType(m_hDC)==OBJ_DC || ::GetObjectType(m_hDC)==OBJ_MEMDC);
m_iState = ::SaveDC(hDC);
ATLASSERT(m_iState!=0);
}
~CSaveDC()
{
Restore();
}
void Restore()
{
if( m_iState == 0 ) return;
ATLASSERT(::GetObjectType(m_hDC)==OBJ_DC || ::GetObjectType(m_hDC)==OBJ_MEMDC);
::RestoreDC(m_hDC, m_iState);
m_iState = 0;
}
};
/////////////////////////////////////////////////////////////////////////////
// CHandle
#if (_ATL_VER < 0x0700)
class CHandle
{
public:
HANDLE m_h;
CHandle(HANDLE hSrc = INVALID_HANDLE_VALUE) : m_h(hSrc)
{ }
~CHandle()
{
Close();
}
operator HANDLE() const { return m_h; };
LPHANDLE operator&()
{
ATLASSERT(!IsValid());
return &m_h;
}
CHandle& operator=(HANDLE h)
{
ATLASSERT(!IsValid());
m_h = h;
return *this;
}
bool IsValid() const { return m_h != INVALID_HANDLE_VALUE; };
void Attach(HANDLE h)
{
if( IsValid() ) ::CloseHandle(m_h);
m_h = h;
}
HANDLE Detach()
{
HANDLE h = m_h;
m_h = INVALID_HANDLE_VALUE;
return h;
}
BOOL Close()
{
BOOL bRes = FALSE;
if( m_h != INVALID_HANDLE_VALUE ) {
bRes = ::CloseHandle(m_h);
m_h = INVALID_HANDLE_VALUE;
}
return bRes;
}
BOOL Duplicate(HANDLE hSource, bool bInherit = false)
{
ATLASSERT(!IsValid());
HANDLE hOurProcess = ::GetCurrentProcess();
BOOL b = ::DuplicateHandle(hOurProcess,
hSource,
hOurProcess,
&m_h,
DUPLICATE_SAME_ACCESS,
bInherit,
DUPLICATE_SAME_ACCESS);
ATLASSERT(b);
return b;
}
};
#endif // _ATL_VER
/////////////////////////////////////////////////////////////////////////////
// Mouse Hover helper
#ifndef NOTRACKMOUSEEVENT
#ifndef WM_MOUSEENTER
#define WM_MOUSEENTER WM_USER + 253
#endif // WM_MOUSEENTER
// To use it, derive from it and chain it in the message map.
// Make sure to set bHandled to FALSE when handling WM_MOUSEMOVE or
// the WM_MOUSELEAVE message!
template< class T >
class CMouseHover
{
public:
bool m_fMouseOver; // Internal mouse-over state
bool m_fMouseForceUpdate; // Update window immediately on event
CMouseHover() :
m_fMouseOver(false),
m_fMouseForceUpdate(true)
{
}
void SetForceMouseOverUpdate(bool bForce = false)
{
m_fMouseForceUpdate = bForce;
}
BEGIN_MSG_MAP(CMouseHover)
MESSAGE_HANDLER(WM_MOUSEMOVE, OnMouseMove)
MESSAGE_HANDLER(WM_MOUSELEAVE, OnMouseLeave)
END_MSG_MAP()
LRESULT OnMouseMove(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
T* pT = static_cast<T*>(this);
if( !m_fMouseOver ) {
m_fMouseOver = true;
pT->SendMessage(WM_MOUSEENTER, wParam, lParam);
if( m_fMouseForceUpdate ) {
pT->Invalidate();
pT->UpdateWindow();
}
_StartTrackMouseLeave(pT->m_hWnd);
}
bHandled = FALSE;
return 0;
}
LRESULT OnMouseLeave(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
{
T* pT = static_cast<T*>(this);
if( m_fMouseOver ) {
m_fMouseOver = false;
if( m_fMouseForceUpdate ) {
pT->Invalidate();
pT->UpdateWindow();
}
}
bHandled = FALSE;
return 0;
}
BOOL _StartTrackMouseLeave(HWND hWnd) const
{
ATLASSERT(::IsWindow(hWnd));
TRACKMOUSEEVENT tme = { 0 };
tme.cbSize = sizeof(tme);
tme.dwFlags = TME_LEAVE;
tme.hwndTrack = hWnd;
return _TrackMouseEvent(&tme);
}
BOOL _CancelTrackMouseLeave(HWND hWnd) const
{
TRACKMOUSEEVENT tme = { 0 };
tme.cbSize = sizeof(tme);
tme.dwFlags = TME_LEAVE | TME_CANCEL;
tme.hwndTrack = hWnd;
return _TrackMouseEvent(&tme);
}
};
#endif // NOTRACKMOUSEEVENT
}; // namespace WTL
#endif // __ATLGDIX_H__
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -