5 #include "../../Common/Allocators/SimplePooledAlloc.h"
9 // Track memory leaks on Windows to the line that new'd the memory
12 #define DEBUG_NEW new( _NORMAL_BLOCK, THIS_FILE, __LINE__ )
15 static char THIS_FILE
[] = __FILE__
;
19 CSimplePooledAlloc
< ControlTree
> gControlAlloc(20);
21 using namespace WinMenus
;
22 std::vector
< HWND
> windownames
;
23 ControlTree
*menutree
;
24 ControlTree
*dummytree
;
25 ControlTree
*stoptree
;
27 ControlTree
*WinMenus::GetWindowMenus() {
28 dummytree
= gControlAlloc
.Alloc();
29 stoptree
= gControlAlloc
.Alloc();
30 dummytree
->pointer
= NULL
;
33 dummytree
->next
= NULL
;
34 dummytree
->colour
= 8;
35 dummytree
->text
= "Control";
36 dummytree
->children
= stoptree
;
37 menutree
= buildcontroltree();
40 EnumDesktopWindows(GetThreadDesktop(GetCurrentThreadId()), WNDENUMPROC(WindowProc
), LPARAM(0));
41 return (ProcessWindows());
50 BOOL CALLBACK
WinMenus::WindowProc(HWND hwnd
, LPARAM lParam
) {
51 windownames
.push_back(hwnd
);
55 ControlTree
*WinMenus::buildcontroltree() {
56 ControlTree
*pausetree
= gControlAlloc
.Alloc();
57 ControlTree
*movetree
= gControlAlloc
.Alloc();
58 ControlTree
*deletetree
= gControlAlloc
.Alloc();
59 ControlTree
*speaktree
= gControlAlloc
.Alloc();
60 stoptree
->pointer
= (void *)1;
62 stoptree
->children
= menutree
;
63 stoptree
->text
= "Stop";
64 stoptree
->next
= pausetree
;
66 stoptree
->colour
= 242;
67 stoptree
->children
= dummytree
;
68 pausetree
->pointer
= (void *)1;
70 pausetree
->children
= menutree
;
71 pausetree
->text
= "Pause";
72 pausetree
->next
= movetree
;
74 pausetree
->colour
= 241;
75 pausetree
->children
= dummytree
;
76 movetree
->pointer
= NULL
;
78 movetree
->children
= menutree
;
79 movetree
->text
= "Move";
80 movetree
->next
= deletetree
;
81 movetree
->children
= buildmovetree(movetree
);
83 movetree
->colour
= -1;
84 deletetree
->pointer
= NULL
;
86 deletetree
->children
= builddeletetree(deletetree
);
87 deletetree
->text
= "Delete";
88 deletetree
->next
= speaktree
;
90 deletetree
->colour
= -1;
91 speaktree
->pointer
= 0;
93 speaktree
->children
= buildspeaktree(speaktree
);
94 speaktree
->text
= "Speak";
95 speaktree
->next
= NULL
;
97 speaktree
->colour
= -1;
101 ControlTree
*WinMenus::buildmovetree(ControlTree
*movetree
) {
102 ControlTree
*lefttree
= gControlAlloc
.Alloc();
103 ControlTree
*righttree
= gControlAlloc
.Alloc();
104 ControlTree
*beginningtree
= gControlAlloc
.Alloc();
105 ControlTree
*endtree
= gControlAlloc
.Alloc();
106 lefttree
->pointer
= (void *)1;
108 lefttree
->children
= lefttree
;
109 lefttree
->text
= "Previous";
110 lefttree
->next
= righttree
;
112 lefttree
->colour
= -1;
113 righttree
->pointer
= (void *)1;
114 righttree
->data
= 12;
115 righttree
->children
= lefttree
;
116 righttree
->text
= "Next";
117 righttree
->next
= beginningtree
;
119 righttree
->colour
= -1;
120 beginningtree
->pointer
= (void *)1;
121 beginningtree
->data
= 13;
122 beginningtree
->children
= lefttree
;
123 beginningtree
->text
= "Beginning";
124 beginningtree
->next
= endtree
;
125 beginningtree
->type
= 1;
126 beginningtree
->colour
= -1;
127 endtree
->pointer
= (void *)1;
129 endtree
->children
= lefttree
;
130 endtree
->text
= "End";
131 endtree
->next
= NULL
;
133 endtree
->colour
= -1;
137 ControlTree
*WinMenus::builddeletetree(ControlTree
*deletetree
) {
138 ControlTree
*forwardtree
= gControlAlloc
.Alloc();
139 ControlTree
*backwardtree
= gControlAlloc
.Alloc();
140 ControlTree
*forwardchar
= gControlAlloc
.Alloc();
141 ControlTree
*forwardword
= gControlAlloc
.Alloc();
142 ControlTree
*backwardchar
= gControlAlloc
.Alloc();
143 ControlTree
*backwardword
= gControlAlloc
.Alloc();
145 forwardtree
->pointer
= NULL
;
146 forwardtree
->data
= 0;
147 forwardtree
->next
= backwardtree
;
148 forwardtree
->children
= forwardchar
;
149 forwardtree
->text
= "Forward";
150 forwardtree
->type
= 1;
151 forwardtree
->colour
= -1;
152 backwardtree
->pointer
= NULL
;
153 backwardtree
->data
= 0;
154 backwardtree
->next
= NULL
;
155 backwardtree
->children
= backwardchar
;
156 backwardtree
->text
= "Backward";
157 backwardtree
->type
= 1;
158 backwardtree
->colour
= -1;
160 forwardchar
->pointer
= (void *)1;
161 forwardchar
->data
= 21;
162 forwardchar
->children
= forwardtree
;
163 forwardchar
->next
= forwardword
;
164 forwardchar
->text
= "Character";
165 forwardchar
->type
= 1;
166 forwardchar
->colour
= -1;
167 forwardword
->pointer
= (void *)1;
168 forwardword
->data
= 22;
169 forwardword
->children
= forwardtree
;
170 forwardword
->next
= NULL
;
171 forwardword
->text
= "Word";
172 forwardword
->type
= 1;
173 forwardword
->colour
= -1;
175 backwardchar
->pointer
= (void *)1;
176 backwardchar
->data
= 24;
177 backwardchar
->children
= forwardtree
;
178 backwardchar
->next
= backwardword
;
179 backwardchar
->text
= "Character";
180 backwardchar
->type
= 1;
181 backwardchar
->colour
= -1;
182 backwardword
->pointer
= (void *)1;
183 backwardword
->data
= 25;
184 backwardword
->children
= forwardtree
;
185 backwardword
->next
= NULL
;
186 backwardword
->text
= "Word";
187 backwardword
->type
= 1;
188 backwardword
->colour
= -1;
193 ControlTree
*WinMenus::buildspeaktree(ControlTree
*speaktree
) {
194 ControlTree
*everythingtree
= gControlAlloc
.Alloc();
195 ControlTree
*newtree
= gControlAlloc
.Alloc();
196 ControlTree
*repeattree
= gControlAlloc
.Alloc();
198 everythingtree
->pointer
= (void *)1;
199 everythingtree
->data
= 4;
200 everythingtree
->next
= newtree
;
201 everythingtree
->children
= dummytree
;
202 everythingtree
->text
= "Everything";
203 everythingtree
->type
= 1;
204 everythingtree
->colour
= -1;
205 newtree
->pointer
= (void *)1;
207 newtree
->next
= repeattree
;
208 newtree
->children
= dummytree
;
209 newtree
->text
= "New";
211 newtree
->colour
= -1;
212 repeattree
->pointer
= (void *)1;
213 repeattree
->data
= 6;
214 repeattree
->children
= dummytree
;
215 repeattree
->next
= NULL
;
216 repeattree
->text
= "Repeat";
217 repeattree
->type
= 1;
218 repeattree
->colour
= -1;
220 return everythingtree
;
225 ControlTree
*WinMenus::ProcessWindows() {
226 IAccessible
*AccessibleObject
= 0;
227 VARIANT AccessibleChild
;
228 VariantInit(&AccessibleChild
);
229 std::vector
< IAccessible
* >AccessibleWindows
;
230 ControlTree
*RootNode
;
231 RootNode
= gControlAlloc
.Alloc();
232 RootNode
->parent
= NULL
;
233 RootNode
->children
= NULL
;
234 RootNode
->next
= NULL
;
235 RootNode
->pointer
= NULL
;
238 RootNode
->text
= "Menus";
239 RootNode
->colour
= -1;
241 for(int i
= 0; i
< windownames
.size(); i
++) {
242 AccessibleObjectFromWindow(windownames
[i
], OBJID_WINDOW
, IID_IAccessible
, (void **)&AccessibleObject
);
243 if(AccessibleObject
!= 0) {
244 AddObjectToTree(AccessibleObject
, RootNode
);
250 bool WinMenus::AddObjectToTree(IAccessible
*AccessibleObject
, ControlTree
*TreeParent
) {
252 VARIANT AccessibleObjectVariant
;
257 VariantInit(&AccessibleObjectVariant
);
258 AccessibleObjectVariant
.vt
= VT_I4
;
259 AccessibleObjectVariant
.lVal
= CHILDID_SELF
;
261 BSTR ObjectName
= NULL
;
263 hr
= AccessibleObject
->get_accName(AccessibleObjectVariant
, &ObjectName
);
264 if(hr
== S_OK
&& ObjectName
!= NULL
) {
265 bstrstring
= ObjectName
;
267 else { // Nameless things are uninteresting
271 // Check if we have any children
273 ControlTree
*NewNode
= gControlAlloc
.Alloc();
274 NewNode
->parent
= TreeParent
;
275 NewNode
->children
= NULL
;
276 NewNode
->next
= NULL
;
277 NewNode
->pointer
= NULL
;
279 NewNode
->colour
= -1;
281 // We don't need to hook it into the tree yet
283 // Check how many children we have
285 AccessibleObject
->get_accChildCount(&NumChildren
);
287 if(NumChildren
> 0) { // if we have kids, recurse through them
289 IEnumVARIANT
*ParentEnum
= NULL
;
290 AccessibleObject
->QueryInterface(IID_IEnumVARIANT
, (PVOID
*) & ParentEnum
);
296 for(int i
= 1; i
<= NumChildren
; i
++) {
298 IDispatch
*ChildDispatch
= NULL
;
299 IAccessible
*ChildAccessible
= NULL
;
302 ParentEnum
->Next(1, &AccessibleObjectVariant
, &NumFetched
);
305 AccessibleObjectVariant
.vt
= VT_I4
;
306 AccessibleObjectVariant
.lVal
= i
;
309 if(AccessibleObjectVariant
.vt
== VT_I4
) {
310 HRESULT hr
= AccessibleObject
->get_accChild(AccessibleObjectVariant
, &ChildDispatch
);
313 ChildDispatch
= AccessibleObjectVariant
.pdispVal
;
316 if(ChildDispatch
!= NULL
&& int (ChildDispatch
) != 0xcccccccc) {
317 ChildDispatch
->QueryInterface(IID_IAccessible
, (void **)&ChildAccessible
);
318 ChildDispatch
->Release();
321 if(ChildAccessible
!= NULL
) {
322 if(useful
== false) {
323 useful
= AddObjectToTree(ChildAccessible
, NewNode
);
326 AddObjectToTree(ChildAccessible
, NewNode
);
333 // We have no kids - check whether we're a menu item
335 VariantInit(&ObjectRole
);
336 ObjectRole
.vt
= VT_I4
;
337 AccessibleObject
->get_accRole(AccessibleObjectVariant
, &ObjectRole
);
338 if((ObjectRole
.iVal
== ROLE_SYSTEM_MENUITEM
|| ObjectRole
.iVal
== ROLE_SYSTEM_PUSHBUTTON
) && NumChildren
== 0) {
339 NewNode
->pointer
= AccessibleObject
;
340 NewNode
->data
= CHILDID_SELF
;
345 // If no useful children, remove our node
347 if(useful
== false) {
350 else { // If we're useful, add our node to the parent
351 if(TreeParent
->children
== NULL
) {
352 TreeParent
->children
= NewNode
;
355 ControlTree
*ParentNext
;
356 ParentNext
= TreeParent
->children
;
357 while(ParentNext
->next
!= NULL
) {
358 ParentNext
= ParentNext
->next
;
360 ParentNext
->next
= NewNode
;
363 // And give it a name
364 NewNode
->text
= bstrstring
;
368 VariantClear(&AccessibleObjectVariant
);