设为首页 加入收藏

TOP

一个简单的子类化窗口工具类 (一)
2014-11-24 00:11:59 来源: 作者: 【 】 浏览:61
Tags:一个 简单 子类 窗口 工具

在《多标签视图类CTabView的设计实现》:http://www.2cto.com/kf/201112/113805.html 一文中,CTabView从CBasicSubClassWnd私有继承,重写其虚函数SubWindowProc,捕获WM_DRAWITEM和TTN_GETDISPINFO消息,从而实现了DrawItem和UpdateTooltipText虚函数回调机制,支持派生类的自定义处理,而CBasicSubClassWnd就是一个子类化窗口类,其原理很简单,就是挂钩替换目标窗口的消息处理过程,这里的设计实现为对于同一目标窗口,可以被多个CBasicSubClassWnd对象捕获消息,而一个CBasicSubClassWnd对象只能捕获一个目标窗口的消息,SubWindowProc返回值决定了消息是否被传递到下个CBasicSubClassWnd对象或原窗口过程处理,TRUE表示允许消息被传递,否则,反之。CBasicSubClassWnd类基于api + stl实现,简单易用,但不尽完善,比如没考虑支持不同进程间的窗口捕获、类的线程安全性等,这些东西都有待于进一步的解决。下面直接看看它的实现代码

1//basic_subclasswnd.h
2
3#ifndef _BASIC_SUBCLASSWND_H
4#define _BASIC_SUBCLASSWND_H
5
6#include
7#include
8
9class CBasicSubClassWnd
10{
11 friend class CBasicWndInfo;
12
13public:
14 CBasicSubClassWnd();
15 void Hook(HWND hWnd);
16 void Unhook();
17
18protected:
19 virtual BOOL SubWindowProc(UINT msg,WPARAM wParam,LPARAM lParam);
20
21private:
22 HWND m_hWnd;
23};
24
25class CBasicWndInfo
26{
27 typedef std::list CBasicSubClassWndList;
28 friend class CBasicSubClassWnd;
29
30private:
31 CBasicWndInfo(HWND hWnd);
32 void Add(CBasicSubClassWnd* pHandler);
33 void Remove(CBasicSubClassWnd* pHandler);
34 void RemoveAll();
35
36 typedef std::map CBasicSubClassWndMap;
37 typedef CBasicSubClassWndMap::iterator MapIter;
38
39 static CBasicSubClassWndMap& GetHookMap();
40 static LRESULT HookWndProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam);
41
42 CBasicSubClassWndList m_list_scw;
43 WNDPROC m_oldWndProc;
44 HWND m_hWnd;
45};
46
47#endif
48
49//basic_subclasswnd.cpp
50#include "stdafx.h"
51#include "basic_subclasswnd.h"
52using namespace std;
53
54CBasicSubClassWnd::CBasicSubClassWnd()
55:m_hWnd(NULL)
56{
57}
58
59void CBasicSubClassWnd::Hook(HWND hWnd)
60{
61 assert(hWnd);
62 if (m_hWnd&&m_hWnd!=hWnd)
63 Unhook();
64 m_hWnd = hWnd;
65
66 CBasicWndInfo::MapIter iter = CBasicWndInfo::GetHookMap().find(hWnd);
67 if (iter==CBasicWndInfo::GetHookMap().end())
68 {
69 iter = CBasicWndInfo::GetHookMap().insert(make_pair(hWnd,CBasicWndInfo(hWnd))).first;
70 }
71 iter->second.Add(this);
72}
73
74void CBasicSubClassWnd::Unhook()
75{
76 assert(m_hWnd);
77
78 CBasicWndInfo::MapIter iter = CBasicWndInfo::GetHookMap().find(m_hWnd);
79 if (iter==CBasicWndInfo::GetHookMap().end())
80 return;
81 iter->second.Remove(this);
82}
83
84BOOL CBasicSubClassWnd::SubWindowProc(UINT msg,WPARAM wParam,LPARAM lParam)
85{
86 return TRUE;
87}
88
89//////////////////////////////////////////////////////////////////////////////////////////////
90CBasicWndInfo::CBasicWndInfo(HWND hWnd)
91:m_oldWndProc(NULL)
92,m_hWnd(hWnd)
93{
94}
95
96void CBasicWndInfo::Add(CBasicSubClassWnd* pHandler)
97{
98 if (NULL==m_oldWndProc)
99 {
100 m_oldWndProc = (WNDPROC)SetWindowLong(m_hWnd,GWL_WNDPROC,(LONG)HookWndProc);
101 }
102 m_list_scw.push_back(pHandler);
103}
104
105void CBasicWndInfo::Remove(CBasicSubClassWnd* pHandler)
106{
107 m_list_scw.remove(pHandler);
108 if (m_list_scw.empty())
109 {
110 assert(m_hWnd);
111 SetWindowLong(m_hWnd,GWL_WNDPROC,(LON

首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇红黑树及生成超过32768随机数 下一篇双屏/多显示器截屏

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: