WEB开发网
开发学院软件开发VC 关于如何换肤、子类化的解决方案 阅读

关于如何换肤、子类化的解决方案

 2010-06-23 20:40:47 来源:WEB开发网   
核心提示:我写了一个简化的CWnd类来解决重复子类化问题和简化窗口过程,不过它不支持对自己的重复子类化(即只能用于没有被子类化的或者被CWnd子类化的HWND),关于如何换肤、子类化的解决方案(5),因为不想弄得和MessageMap那样复杂,所以功能也有限:须手工转化WPARAM和LPARAM、消息处理无法继承、不支持多线程,

我写了一个简化的CWnd类来解决重复子类化问题和简化窗口过程,不过它不支持对自己的重复子类化(即只能用于没有被子类化的或者被CWnd子类化的HWND)。

因为不想弄得和MessageMap那样复杂,所以功能也有限:须手工转化WPARAM和LPARAM、消息处理无法继承、不支持多线程。使用很简单:CWndNew* pWnd = new CWndNew;
pWnd->SubclassWindow(hWnd);

用完了,记得释放处理:

pWnd->UnsubclassWindow();
delete pWnd;

如果要进行功能扩充(继承),就改写那几个虚函数:

class CWndNew
{
public:
   CWndNew();
   virtual ~CWndNew();
   bool SubclassWindow(HWND hWnd);
   void UnsubclassWindow();

protected: // virtual
   virtual LRESULT WindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam);
   virtual void PresubclassWindow(){};
   virtual void PostunsubclassWindow(){};

protected:
   LRESULT PrevWindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam);
   HWND m_hWnd;

private:
   WNDPROC m_oldProc;
   static map m_map;
  static LRESULT CALLBACK StaticWindowProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam);
};
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
map CWndNew::m_map;
CWndNew::CWndNew()
{
   m_hWnd = NULL;
}
CWndNew::~CWndNew()
{
   ASSERT(m_hWnd == NULL);
}
bool CWndNew::SubclassWindow(HWND hWnd)
{
   m_map[hWnd] = this;
   ASSERT(m_hWnd == NULL);
   m_hWnd = hWnd;

   //允许派生类在子类化之前做一些初始化.
   PresubclassWindow();
   m_oldProc = (WNDPROC) GetWindowLong(hWnd, GWL_WNDPROC);
   ASSERT(m_oldProc != 0);
   SetWindowLong(hWnd, GWL_WNDPROC, (LONG) StaticWindowProc);
   return true;
}
void CWndNew::UnsubclassWindow()
{
   SetWindowLong(m_hWnd, GWL_WNDPROC, (LONG)m_oldProc);
   PostunsubclassWindow();
   m_map.erase(m_hWnd);
   m_hWnd = NULL;
}
LRESULT CALLBACK CWndNew::StaticWindowProc(HWND hWnd,
          UINT uMsg,
          WPARAM wParam,
          LPARAM lParam)
{
   CWndNew* pWnd = m_map[hWnd];
   ASSERT(pWnd != NULL);
   return pWnd->WindowProc(uMsg, wParam, lParam);
}
LRESULT CWndNew::PrevWindowProc(UINT uMsg,
       WPARAM wParam,
       LPARAM lParam)
{
   return CallWindowProc(m_oldProc, m_hWnd, uMsg, wParam, lParam);
}
LRESULT CWndNew::WindowProc(UINT uMsg,
       WPARAM wParam,
       LPARAM lParam)
{
   return PrevWindowProc(uMsg, wParam, lParam);
}

上一页  1 2 3 4 5 6  下一页

Tags:关于 如何 子类

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接