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

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134
