共享一份模拟MFC和WTL对Windows窗口框架代码 有兴趣者请跟帖
medie 2005-06-08 04:41:11 ////////////////////////////////////////////////////////////////////////////
// W32Wnd.h
//==========================================================================
// Created by 苦丁茶 (2004-10-01)
//
// 功能: 模拟MFC和WTL对Windows窗口框架的封装,提供消息映射机制。
// 参考资料:MFC、WTL消息映射机制
// 消息映射用法举例:
// BEGIN_MESSAGE(W32Button, W32Wnd)
// ON_MESSAGE(WM_LBUTTONDOWN, OnLButtonDown)
// ON_MESSAGE(WM_LBUTTONUP, OnLButtonUP)
// ON_MESSAGE(WM_ERASEBKGND, OnEraseBkgnd)
// END_MESSAGE()
// LRESULT OnEraseBkgnd(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
// {
// return 0;
// }
// 具体用法请参考W32Button.h所实现的支持自画Button类。
//==========================================================================
#if !defined(AFX_W32WND_H__INCLUDED_)
#define AFX_W32WND_H__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
class W32Wnd
{
public:
HWND m_hWnd;
~W32Wnd()
{
if (m_pSuper)
{
UnsubclassWindow();
}
m_hWnd = NULL;
}
W32Wnd()
: m_hWnd(NULL)
, m_pSuper(NULL)
{
}
HWND Create(HWND hWndParent, RECT& rcPos, LPCTSTR lpstrWndClass, LPCTSTR szWindowName = NULL,
DWORD dwStyle = 0, DWORD dwExStyle = 0,
UINT nID = 0, LPVOID lpCreateParam = NULL)
{
HWND hWnd = ::CreateWindowEx(dwExStyle, lpstrWndClass, szWindowName,
dwStyle, rcPos.left, rcPos.top, rcPos.right - rcPos.left,
rcPos.bottom - rcPos.top, hWndParent, (HMENU)nID,
::GetModuleHandle(NULL), lpCreateParam);
SubclassWindow(hWnd);
return hWnd;
}
BOOL SubclassWindow(HWND hWnd)
{
// assert(NULL == m_hWnd);
::SetWindowLong(hWnd, GWL_USERDATA, (LONG)this);
m_pSuper = (WNDPROC)::SetWindowLong(hWnd, GWL_WNDPROC, (LONG)((WNDPROC)W32DefWindowProc));
m_hWnd = hWnd;
return TRUE;
}
HWND UnsubclassWindow()
{
if (::IsWindow(m_hWnd))
{
::SetWindowLong(m_hWnd, GWL_WNDPROC, (LONG)((WNDPROC)m_pSuper));
}
HWND hWnd = m_hWnd;
m_hWnd = NULL;
m_pSuper = NULL;
return hWnd;
}
BOOL ModifyStyle(DWORD dwRemove, DWORD dwAdd, UINT nFlags = 0 )
{
DWORD dwStyle = ::GetWindowLong(m_hWnd, GWL_STYLE);
DWORD dwNewStyle = (dwStyle & ~dwRemove) | dwAdd;
if (dwStyle == dwNewStyle)
return FALSE;
::SetWindowLong(m_hWnd, GWL_STYLE, dwNewStyle);
if (nFlags != 0)
{
::SetWindowPos(hWnd, NULL, 0, 0, 0, 0,
SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | nFlags);
}
return TRUE;
}
BOOL ModifyStyleEx(DWORD dwRemove, DWORD dwAdd, UINT nFlags = 0 )
{
DWORD dwStyle = ::GetWindowLong(m_hWnd, GWL_EXSTYLE);
DWORD dwNewStyle = (dwStyle & ~dwRemove) | dwAdd;
if (dwStyle == dwNewStyle)
return FALSE;
::SetWindowLong(m_hWnd, GWL_EXSTYLE, dwNewStyle);
if (nFlags != 0)
{
::SetWindowPos(hWnd, NULL, 0, 0, 0, 0,
SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | nFlags);
}
return TRUE;
}
protected:
static LRESULT W32DefWindowProc(
HWND hWnd, // handle to window
UINT Msg, // message identifier
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
)
{
W32Wnd * pWnd = (W32Wnd *)::GetWindowLong(hWnd, GWL_USERDATA);
if (pWnd)
{
return pWnd->W32DefWindowProc(Msg, wParam, lParam);
}
return 0;
}
LRESULT W32DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
LRESULT lRes = 0;
BOOL bRet = ProcessWindowMessage(m_hWnd, message, wParam, lParam, lRes, 0);
if (bRet)
{
return bRet;
}
return m_pSuper(m_hWnd, message, wParam, lParam);
}
virtual BOOL ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& lResult, DWORD dwMsgMapID = 0)
{
return FALSE;
}
WNDPROC m_pSuper;
WNDPROC m_pParentSuper;
};