⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mtlwin.h

📁 一个使用wtl写的完整的多窗口浏览器
💻 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 + -