📄 mtlwin.h
字号:
#ifndef __MTLWIN_H__
#define __MTLWIN_H__
////////////////////////////////////////////////////////////////////////////
// MTL Version 0.10
// Copyright (C) 2001 MB<mb2@geocities.co.jp>
// All rights unreserved.
//
// This file is a part of Mb Template Library.
// The code and information is *NOT* provided "as-is" without
// warranty of any kind, either expressed or implied.
//
// Mtlwin.h: Last updated: February 12, 2001
////////////////////////////////////////////////////////////////////////////
#pragma once
#define _MTL_TRANSLATE_PASS 0x00
#define _MTL_TRANSLATE_HANDLE 0x01
#define _MTL_TRANSLATE_WANT 0x02
namespace WTL
{
////////////////////////////////////////////////////////////////////////////
// Easy macros
#define HANDLE_MESSAGE(msg) \
if(uMsg == msg) \
{ \
bHandled = TRUE; \
return TRUE; \
}
#define DEFWINDOWPROC_MESSAGE(msg) \
if(uMsg == msg) \
{ \
return DefWindowProc(uMsg, wParam, lParam); \
}
// System global window message
#define DECLARE_REGISTERED_MESSAGE(message) \
static UINT GetRegistered##message() \
{ \
static UINT uRegisterd##message = 0; \
if (uRegisterd##message == 0) { \
uRegisterd##message = ::RegisterWindowMessage(_T(#message)); \
} \
ATLASSERT(uRegisterd##message != 0); \
return uRegisterd##message; \
}
#define GET_REGISTERED_MESSAGE(message) \
GetRegistered##message()
// WTL sucks
#define DECLARE_FRAME_WND_MENU(menu) \
HWND CreateEx(HWND hWndParent, _U_RECT rect = NULL, LPCTSTR lpcstrWindowName = NULL, DWORD dwStyle = 0, DWORD dwExStyle = 0, LPVOID lpCreateParam = NULL) \
{ \
TCHAR szWindowName[256]; \
szWindowName[0] = 0; \
if(lpcstrWindowName == NULL) \
{ \
::LoadString(_Module.GetResourceInstance(), GetWndClassInfo().m_uCommonResourceID, szWindowName, 256); \
lpcstrWindowName = szWindowName; \
} \
HWND hWnd = Create(hWndParent, rect, lpcstrWindowName, dwStyle, dwExStyle, menu, lpCreateParam); \
if(hWnd != NULL) \
m_hAccel = ::LoadAccelerators(_Module.GetResourceInstance(), MAKEINTRESOURCE(GetWndClassInfo().m_uCommonResourceID)); \
return hWnd; \
}
inline CString MtlGetWindowClassName(HWND hWnd)
{
CString strClassNameOfHwnd;
int nLen = 255;
int nRetLen = ::GetClassName(hWnd, strClassNameOfHwnd.GetBufferSetLength(nLen), nLen + 1);
strClassNameOfHwnd.ReleaseBuffer();
return strClassNameOfHwnd;
}
// Antithesis to MFC
inline bool MtlIsKindOf(HWND hWnd, const CString& strClassName)
{
CString strClassNameOfHwnd;
int nLen = strClassName.GetLength();
int nRetLen = ::GetClassName(hWnd, strClassNameOfHwnd.GetBufferSetLength(nLen), nLen + 1);
strClassNameOfHwnd.ReleaseBuffer();
if (nRetLen < nLen)
return false;
return (strClassNameOfHwnd == strClassName);
}
#define MTLASSERT_KINDOF(window_class_name, object) \
ATLASSERT(MtlIsKindOf(object, window_class_name))
////////////////////////////////////////////////////////////////////////////
// Window message functions
inline CString MtlGetWindowText(HWND hWnd)
{
CString strText;
int nLen = ::GetWindowTextLength(hWnd);
int nRetLen = ::GetWindowText(hWnd, strText.GetBufferSetLength(nLen), nLen + 1);
strText.ReleaseBuffer();
if(nRetLen < nLen)
return CString();
return strText;
}
inline void MtlSetWindowText(HWND hWndCtrl, LPCTSTR lpszNew)
{// MFC6::AfxSetWindowText
int nNewLen = lstrlen(lpszNew);
TCHAR szOld[256];
// fast check to see if text really changes (reduces flash in controls)
if (nNewLen > _countof(szOld) ||
::GetWindowText(hWndCtrl, szOld, _countof(szOld)) != nNewLen ||
lstrcmp(szOld, lpszNew) != 0)
{
// change it
::SetWindowText(hWndCtrl, lpszNew);
}
}
// Fatal bug fixed by JOBBY, thanks!
int MtlGetLBTextFixed(HWND hWndCombo, int nIndex, CString& strText)
{
CComboBox combo(hWndCombo);
ATLASSERT(combo.IsWindow());
int nRet = combo.GetLBText(nIndex, strText.GetBufferSetLength( combo.GetLBTextLen(nIndex)*2 ));
strText.ReleaseBuffer();
return nRet;
}
// scary...
int MtlListBoxGetText(HWND hWndBox, int nIndex, CString& strText)
{
CListBox box(hWndBox);
ATLASSERT(box.IsWindow());
int nRet = box.GetText(nIndex, strText.GetBufferSetLength( box.GetTextLen(nIndex)*2 ));
strText.ReleaseBuffer();
return nRet;
}
inline BOOL MtlSendCommand(HWND hWnd, WORD wID)
{
return (BOOL)::SendMessage(hWnd, WM_COMMAND, MAKEWPARAM(wID, 0), 0);
}
inline void MtlPostCommand(HWND hWnd, WORD wID)
{
::PostMessage(hWnd, WM_COMMAND, MAKEWPARAM(wID, 0), 0);
}
// MDI client window wrapper class
class CMDIClientWindow : public CMDIWindow
{
public:
CMDIClientWindow(HWND hWnd)
{
m_hWndMDIClient = hWnd;
}
};
// Locking redraw
class CLockRedraw
{
public:
CWindow m_wnd;
CLockRedraw(HWND hWnd) : m_wnd(hWnd)
{
if (m_wnd.m_hWnd) {
m_wnd.SetRedraw(FALSE);
}
}
~CLockRedraw()
{
if (m_wnd.m_hWnd) {
m_wnd.SetRedraw(TRUE);
m_wnd.Invalidate();
m_wnd.UpdateWindow();
}
}
};
class CLockRedrawMDIClient
{
public:
CWindow m_wndMDIClient;
CLockRedrawMDIClient(HWND hWnd) : m_wndMDIClient(hWnd)
{
m_wndMDIClient.ShowWindow(SW_HIDE);
}
~CLockRedrawMDIClient()
{
m_wndMDIClient.ShowWindow(SW_SHOW);
}
};
struct CPostCommand
{
WORD m_wID;
WORD m_wNotifyCode;
CPostCommand(WORD wID, WORD wNotifyCode = 0) : m_wID(wID), m_wNotifyCode(wNotifyCode) { }
void operator()(HWND hWnd)
{
::PostMessage(hWnd, WM_COMMAND, MAKEWPARAM(m_wID, m_wNotifyCode), 0);
}
};
struct CSendCommand
{
WORD m_wID;
WORD m_wNotifyCode;
BOOL m_bResult;
CSendCommand(WORD wID, WORD wNotifyCode = 0) : m_wID(wID), m_wNotifyCode(wNotifyCode), m_bResult(FALSE) { }
void operator()(HWND hWnd)
{
m_bResult = (BOOL)::SendMessage(hWnd, WM_COMMAND, MAKEWPARAM(m_wID, m_wNotifyCode), 0);
}
};
bool MtlIsFamily(HWND hWnd1, HWND hWnd2)
{
if (hWnd1 == NULL || hWnd2 == NULL)
return false;
if (hWnd1 == hWnd2)
return true;
CWindow wnd1(hWnd1);
CWindow wnd2(hWnd2);
return wnd1.GetTopLevelParent() == wnd2.GetTopLevelParent();
}
void MtlSetForegroundWindow(HWND hWnd)
{
::SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSENDCHANGING|SWP_NOSIZE);
::SetWindowPos(hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSENDCHANGING|SWP_NOSIZE);
}
bool MtlIsApplicationActive(HWND hWnd)
{
ATLASSERT(::IsWindow(hWnd));
CWindow wndFrame = CWindow(hWnd).GetTopLevelParent();
CVersional<WINDOWPLACEMENT> wndpl; wndFrame.GetWindowPlacement(&wndpl);
if (wndpl.showCmd == SW_SHOWMINIMIZED)
return false;
CWindow wndFore = ::GetForegroundWindow();
if (wndFore.m_hWnd == NULL)
return false;
CWindow wndForeParent = wndFore.GetTopLevelParent();
return wndFrame.m_hWnd == wndForeParent.m_hWnd;
}
template <class T>
class CTrackMouseLeave
{
public:
bool m_bTrackMouseLeave;
CTrackMouseLeave() : m_bTrackMouseLeave(false)
{
}
// Overridables
void OnTrackMouseMove(UINT nFlags, CPoint pt)
{
}
void OnTrackMouseLeave()
{
}
// Message map and handlers
BEGIN_MSG_MAP(CTrackMouseLeave<T>)
MESSAGE_HANDLER(WM_MOUSEMOVE, OnMouseMove)
MESSAGE_HANDLER(WM_MOUSELEAVE, OnMouseLeave)
END_MSG_MAP()
LRESULT OnMouseMove(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
bHandled = FALSE;
_StartTrackMouseLeave();
T* pT = static_cast<T*>(this);
POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
pT->OnTrackMouseMove((UINT)wParam, pt);
return 1;
}
LRESULT OnMouseLeave(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
bHandled = FALSE;
_LastTrackMouseLeave();
T* pT = static_cast<T*>(this);
pT->OnTrackMouseLeave();
return 0;
}
BOOL _StartTrackMouseLeave()
{
T* pT = static_cast<T*>(this);
if (m_bTrackMouseLeave)
return FALSE;
TRACKMOUSEEVENT tme;
tme.cbSize = sizeof(tme);
tme.dwFlags = TME_LEAVE;
tme.hwndTrack = pT->m_hWnd;
m_bTrackMouseLeave = true;
return ::_TrackMouseEvent(&tme);
}
void _LastTrackMouseLeave()
{
m_bTrackMouseLeave = false;
}
};
template <class T>
class CFrameWndFixWrongActiveMessageHandler
{
public:
BEGIN_MSG_MAP(CFrameWndFixWrongActiveMessageHandler<T>)
MSG_WM_ACTIVATE(OnActivate)
// MSG_WM_NCACTIVATE(OnNcActivate)
// MSG_WM_ENABLE(OnEnable)
END_MSG_MAP()
// Overridables
void OnFrameActivate(bool bActive)
{
}
void OnFrameWrongInactivate()
{
}
void OnActivate(UINT nState, BOOL bMinimized, HWND hWndOther)
{
// SetMsgHandled(FALSE);
T* pT = static_cast<T*>(this);
pT->DefWindowProc();
// if (nState == WA_INACTIVE) {
// if (pT->IsChild(hWndOther) || hWndOther == NULL) {
// pT->OnFrameWrongInactivate();
// return;
// }
// }
pT->OnFrameActivate(nState != WA_INACTIVE);
/*
// get top level frame unless this is a child window
// determine if window should be active or not
HWND hWndTopLevel = (pT->GetStyle() & WS_CHILD) ? pT->m_hWnd : pT->GetTopLevelParent();
ATLASSERT(::IsWindow(hWndTopLevel));
HWND hWndActive = (nState == WA_INACTIVE ? hWndOther : pT->m_hWnd);
m_bStayActive = (hWndTopLevel == hWndActive || CWindow(hWndTopLevel).IsChild(hWndActive));
*/
}
BOOL OnNcActivate(BOOL bActive)
{
ATLTRACE(_T("CFrameWndFixWrongActiveMessageHandler:OnNcActivate(%d)\n"), m_bStayActive);
T* pT = static_cast<T*>(this);
// stay active if WF_STAYACTIVE bit is on
// if (m_bStayActive)
// bActive = TRUE;
// but do not stay active if the window is disabled
if (!pT->IsWindowEnabled())
bActive = FALSE;
// do not call the base class because it will call Default()
// and we may have changed bActive.
return (BOOL)pT->DefWindowProc(WM_NCACTIVATE, bActive, 0L);
}
void OnEnable(BOOL bEnable)
{
T* pT = static_cast<T*>(this);
if (bEnable && m_bStayActive) {
// Work around for MAPI support. This makes sure the main window
// remains disabled even when the mail system is booting.
pT->EnableWindow(FALSE);
::SetFocus(NULL);
return;
}
// only for top-level (and non-owned) windows
if (pT->GetParent() != NULL)
return;
}
};
// OnIdle not called while Flush prugin running
// and WM_TIMER associated with HWND will not be sent.
class CCriticalIdleTimer
{
public:
static UINT s_nTimerID;
static HWND s_hWndMainFrame;
static WORD s_wCmdID;
static void InstallCriticalIdleTimer(HWND hWndMainFrame, WORD wCmdID)
{
s_hWndMainFrame = hWndMainFrame;
s_wCmdID = wCmdID;
if (s_nTimerID == 0)
s_nTimerID = ::SetTimer(NULL, 0, 800, _FocusCheckerTimerProc);
}
static void UninstallCriticalIdleTimer()
{
if (s_nTimerID != 0) {
::KillTimer(NULL, s_nTimerID);
s_nTimerID = 0;
}
}
static VOID CALLBACK _FocusCheckerTimerProc(HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime)
{
_FocusChecker();
}
static void _FocusChecker()
{
MtlSendCommand(s_hWndMainFrame, s_wCmdID);
}
};
__declspec(selectany) UINT CCriticalIdleTimer::s_nTimerID = 0;
__declspec(selectany) HWND CCriticalIdleTimer::s_hWndMainFrame = NULL;
__declspec(selectany) WORD CCriticalIdleTimer::s_wCmdID = 0;
#define NM_ON 0xffa6 // (NM_FIRST-90)
#define NM_OFF 0xffa5 // (NM_FIRST-91)
inline void MtlSendOnCommand(HWND hWndTarget, WORD nCmd, HWND hWndSrc = NULL)
{
::SendMessage(hWndTarget, WM_COMMAND, MAKEWPARAM(nCmd, NM_ON), (LPARAM)hWndSrc);
}
inline void MtlSendOffCommand(HWND hWndTarget, WORD nCmd, HWND hWndSrc = NULL)
{
::SendMessage(hWndTarget, WM_COMMAND, MAKEWPARAM(nCmd, NM_OFF), (LPARAM)hWndSrc);
}
inline bool MtlIsWindowCurrentProcess(HWND hWnd)
{
DWORD dwProcessId = 0;
::GetWindowThreadProcessId(hWnd, &dwProcessId);
return (::GetCurrentProcessId() == dwProcessId);
}
template <class _Function>
inline _Function MtlForEachTopLevelWindow(LPCTSTR lpszClass, LPCTSTR lpszWindow, _Function __f)
{
for (HWND hWnd = ::FindWindowEx(NULL, NULL, lpszClass, lpszWindow); hWnd != NULL;
hWnd = ::FindWindowEx(NULL, hWnd, lpszClass, lpszWindow))
{
if (!__f(hWnd))
break;
}
return __f;
}
////////////////////////////////////////////////////////////////////////////
} // namespace MTL;
#endif // __MTLWIN_H__
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -