Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/programs/oleview/tree.c
4389 views
1
/*
2
* OleView (tree.c)
3
*
4
* Copyright 2006 Piotr Caban
5
*
6
* This library is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU Lesser General Public
8
* License as published by the Free Software Foundation; either
9
* version 2.1 of the License, or (at your option) any later version.
10
*
11
* This library is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
* Lesser General Public License for more details.
15
*
16
* You should have received a copy of the GNU Lesser General Public
17
* License along with this library; if not, write to the Free Software
18
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19
*/
20
21
#include "main.h"
22
23
TREE tree;
24
25
static LPARAM CreateITEM_INFO(INT flag, const WCHAR *info, const WCHAR *clsid, const WCHAR *path)
26
{
27
ITEM_INFO *reg;
28
29
reg = calloc(1, sizeof(ITEM_INFO));
30
31
reg->cFlag = flag;
32
lstrcpyW(reg->info, info);
33
if(clsid) lstrcpyW(reg->clsid, clsid);
34
if(path) lstrcpyW(reg->path, path);
35
36
return (LPARAM)reg;
37
}
38
39
void CreateInst(HTREEITEM item, WCHAR *wszMachineName)
40
{
41
TVITEMW tvi;
42
HTREEITEM hCur;
43
TVINSERTSTRUCTW tvis;
44
WCHAR wszTitle[MAX_LOAD_STRING];
45
WCHAR wszMessage[MAX_LOAD_STRING];
46
WCHAR wszFlagName[MAX_LOAD_STRING];
47
WCHAR wszTreeName[MAX_LOAD_STRING];
48
WCHAR wszRegPath[MAX_LOAD_STRING];
49
CLSID clsid;
50
COSERVERINFO remoteInfo;
51
MULTI_QI qi;
52
IUnknown *obj, *unk;
53
HRESULT hRes;
54
55
memset(&tvi, 0, sizeof(TVITEMW));
56
tvi.mask = TVIF_TEXT;
57
tvi.hItem = item;
58
tvi.cchTextMax = MAX_LOAD_STRING;
59
tvi.pszText = wszTreeName;
60
61
memset(&tvis, 0, sizeof(TVINSERTSTRUCTW));
62
tvis.item.mask = TVIF_TEXT|TVIF_PARAM;
63
tvis.item.cchTextMax = MAX_LOAD_STRING;
64
tvis.hInsertAfter = TVI_FIRST;
65
tvis.item.pszText = tvi.pszText;
66
tvis.hParent = item;
67
tvis.hInsertAfter = TVI_LAST;
68
69
if (!SendMessageW(globals.hTree, TVM_GETITEMW, 0, (LPARAM)&tvi)) return;
70
71
if(!tvi.lParam || ((ITEM_INFO *)tvi.lParam)->loaded
72
|| !(((ITEM_INFO *)tvi.lParam)->cFlag&SHOWALL)) return;
73
74
if(FAILED(CLSIDFromString(((ITEM_INFO *)tvi.lParam)->clsid, &clsid))) return;
75
76
if(wszMachineName)
77
{
78
remoteInfo.dwReserved1 = 0;
79
remoteInfo.dwReserved2 = 0;
80
remoteInfo.pAuthInfo = NULL;
81
remoteInfo.pwszName = wszMachineName;
82
83
qi.pIID = &IID_IUnknown;
84
85
CoCreateInstanceEx(&clsid, NULL, globals.dwClsCtx|CLSCTX_REMOTE_SERVER,
86
&remoteInfo, 1, &qi);
87
hRes = qi.hr;
88
obj = qi.pItf;
89
}
90
else hRes = CoCreateInstance(&clsid, NULL, globals.dwClsCtx,
91
&IID_IUnknown, (void **)&obj);
92
93
if(FAILED(hRes))
94
{
95
LoadStringW(globals.hMainInst, IDS_CGCOFAIL, wszMessage, ARRAY_SIZE(wszMessage));
96
LoadStringW(globals.hMainInst, IDS_ABOUT, wszTitle, ARRAY_SIZE(wszTitle));
97
98
#define CASE_ERR(i) case i: \
99
MultiByteToWideChar(CP_ACP, 0, #i, -1, wszFlagName, MAX_LOAD_STRING); \
100
break
101
102
switch(hRes)
103
{
104
CASE_ERR(REGDB_E_CLASSNOTREG);
105
CASE_ERR(E_NOINTERFACE);
106
CASE_ERR(REGDB_E_READREGDB);
107
CASE_ERR(REGDB_E_KEYMISSING);
108
CASE_ERR(CO_E_DLLNOTFOUND);
109
CASE_ERR(CO_E_APPNOTFOUND);
110
CASE_ERR(E_ACCESSDENIED);
111
CASE_ERR(CO_E_ERRORINDLL);
112
CASE_ERR(CO_E_APPDIDNTREG);
113
CASE_ERR(CLASS_E_CLASSNOTAVAILABLE);
114
default:
115
LoadStringW(globals.hMainInst, IDS_ERROR_UNKN, wszFlagName, ARRAY_SIZE(wszFlagName));
116
}
117
118
wsprintfW(&wszMessage[lstrlenW(wszMessage)], L"\n%s ($%x)\n", wszFlagName, (unsigned)hRes);
119
MessageBoxW(globals.hMainWnd, wszMessage, wszTitle, MB_OK|MB_ICONEXCLAMATION);
120
return;
121
}
122
123
((ITEM_INFO *)tvi.lParam)->loaded = 1;
124
((ITEM_INFO *)tvi.lParam)->pU = obj;
125
126
tvi.mask = TVIF_STATE;
127
tvi.state = TVIS_BOLD;
128
tvi.stateMask = TVIS_BOLD;
129
SendMessageW(globals.hTree, TVM_SETITEMW, 0, (LPARAM)&tvi);
130
131
tvi.mask = TVIF_TEXT;
132
hCur = (HTREEITEM)SendMessageW(globals.hTree, TVM_GETNEXTITEM,
133
TVGN_CHILD, (LPARAM)tree.hI);
134
135
while(hCur)
136
{
137
tvi.hItem = hCur;
138
if(!SendMessageW(globals.hTree, TVM_GETITEMW, 0, (LPARAM)&tvi) || !tvi.lParam)
139
{
140
hCur = (HTREEITEM)SendMessageW(globals.hTree, TVM_GETNEXTITEM,
141
TVGN_NEXT, (LPARAM)hCur);
142
continue;
143
}
144
145
CLSIDFromString(((ITEM_INFO *)tvi.lParam)->clsid, &clsid);
146
hRes = IUnknown_QueryInterface(obj, &clsid, (void *)&unk);
147
148
if(SUCCEEDED(hRes))
149
{
150
IUnknown_Release(unk);
151
152
lstrcpyW(wszRegPath, L"Interface\\");
153
lstrcpyW(&wszRegPath[lstrlenW(wszRegPath)], ((ITEM_INFO *)tvi.lParam)->clsid);
154
tvis.item.lParam = CreateITEM_INFO(REGTOP|INTERFACE|REGPATH,
155
wszRegPath, ((ITEM_INFO *)tvi.lParam)->clsid, NULL);
156
SendMessageW(globals.hTree, TVM_INSERTITEMW, 0, (LPARAM)&tvis);
157
}
158
hCur = (HTREEITEM)SendMessageW(globals.hTree, TVM_GETNEXTITEM,
159
TVGN_NEXT, (LPARAM)hCur);
160
}
161
162
RefreshMenu(item);
163
RefreshDetails(item);
164
}
165
166
void ReleaseInst(HTREEITEM item)
167
{
168
TVITEMW tvi;
169
HTREEITEM cur;
170
IUnknown *pU;
171
172
memset(&tvi, 0, sizeof(TVITEMW));
173
tvi.hItem = item;
174
if(!SendMessageW(globals.hTree, TVM_GETITEMW, 0, (LPARAM)&tvi) || !tvi.lParam) return;
175
176
pU = ((ITEM_INFO *)tvi.lParam)->pU;
177
178
if(pU) IUnknown_Release(pU);
179
((ITEM_INFO *)tvi.lParam)->loaded = 0;
180
181
SendMessageW(globals.hTree, TVM_EXPAND, TVE_COLLAPSE, (LPARAM)item);
182
183
cur = (HTREEITEM)SendMessageW(globals.hTree, TVM_GETNEXTITEM,
184
TVGN_CHILD, (LPARAM)item);
185
while(cur)
186
{
187
SendMessageW(globals.hTree, TVM_DELETEITEM, 0, (LPARAM)cur);
188
cur = (HTREEITEM)SendMessageW(globals.hTree, TVM_GETNEXTITEM,
189
TVGN_CHILD, (LPARAM)item);
190
}
191
192
tvi.mask = TVIF_CHILDREN|TVIF_STATE;
193
tvi.state = 0;
194
tvi.stateMask = TVIS_BOLD;
195
tvi.cChildren = 1;
196
SendMessageW(globals.hTree, TVM_SETITEMW, 0, (LPARAM)&tvi);
197
}
198
199
BOOL CreateRegPath(HTREEITEM item, WCHAR *buffer, int bufSize)
200
{
201
TVITEMW tvi;
202
int bufLen;
203
BOOL ret = FALSE;
204
205
memset(buffer, 0, bufSize * sizeof(WCHAR));
206
memset(&tvi, 0, sizeof(TVITEMW));
207
tvi.hItem = item;
208
209
if (SendMessageW(globals.hTree, TVM_GETITEMW, 0, (LPARAM)&tvi))
210
ret = (tvi.lParam && ((ITEM_INFO *)tvi.lParam)->cFlag & REGPATH);
211
212
while(TRUE)
213
{
214
if(!SendMessageW(globals.hTree, TVM_GETITEMW, 0, (LPARAM)&tvi)) break;
215
216
if(tvi.lParam && (((ITEM_INFO *)tvi.lParam)->cFlag & (REGPATH|REGTOP)))
217
{
218
bufLen = lstrlenW(((ITEM_INFO *)tvi.lParam)->info);
219
memmove(&buffer[bufLen], buffer, (bufSize - bufLen) * sizeof(WCHAR));
220
memcpy(buffer, ((ITEM_INFO *)tvi.lParam)->info, bufLen * sizeof(WCHAR));
221
}
222
223
if(tvi.lParam && ((ITEM_INFO *)tvi.lParam)->cFlag & REGTOP) break;
224
225
if(!tvi.lParam) return FALSE;
226
227
tvi.hItem = (HTREEITEM)SendMessageW(globals.hTree, TVM_GETNEXTITEM,
228
TVGN_PARENT, (LPARAM)tvi.hItem);
229
}
230
return ret;
231
}
232
233
static void AddCOMandAll(void)
234
{
235
TVINSERTSTRUCTW tvis;
236
TVITEMW tvi;
237
HTREEITEM curSearch;
238
HKEY hKey, hCurKey, hInfo;
239
WCHAR valName[MAX_LOAD_STRING];
240
WCHAR buffer[MAX_LOAD_STRING];
241
WCHAR wszComp[MAX_LOAD_STRING];
242
LONG lenBuffer;
243
int i=-1;
244
245
memset(&tvi, 0, sizeof(TVITEMW));
246
tvis.item.mask = TVIF_TEXT|TVIF_PARAM|TVIF_CHILDREN;
247
tvis.item.cchTextMax = MAX_LOAD_STRING;
248
tvis.item.cChildren = 1;
249
tvis.hInsertAfter = TVI_FIRST;
250
251
if(RegOpenKeyW(HKEY_CLASSES_ROOT, L"CLSID", &hKey) != ERROR_SUCCESS) return;
252
253
while(TRUE)
254
{
255
i++;
256
257
if(RegEnumKeyW(hKey, i, valName, ARRAY_SIZE(valName)) != ERROR_SUCCESS) break;
258
259
if(RegOpenKeyW(hKey, valName, &hCurKey) != ERROR_SUCCESS) continue;
260
261
lenBuffer = sizeof(WCHAR[MAX_LOAD_STRING]);
262
tvis.hParent = tree.hAO;
263
264
if(RegOpenKeyW(hCurKey, L"InProcServer32", &hInfo) == ERROR_SUCCESS)
265
{
266
if(RegQueryValueW(hInfo, NULL, buffer, &lenBuffer) == ERROR_SUCCESS
267
&& *buffer)
268
if(!wcsncmp(buffer, L"ole32.dll", 9) ||
269
!wcsncmp(buffer, L"oleaut32.dll", 12))
270
tvis.hParent = tree.hCLO;
271
272
RegCloseKey(hInfo);
273
}
274
275
lenBuffer = sizeof(WCHAR[MAX_LOAD_STRING]);
276
277
if(RegQueryValueW(hCurKey, NULL, buffer, &lenBuffer) == ERROR_SUCCESS && *buffer)
278
tvis.item.pszText = buffer;
279
else tvis.item.pszText = valName;
280
281
tvis.item.lParam = CreateITEM_INFO(REGPATH|SHOWALL, valName, valName, NULL);
282
if(tvis.hParent) SendMessageW(globals.hTree, TVM_INSERTITEMW, 0, (LPARAM)&tvis);
283
284
if(RegOpenKeyW(hCurKey, L"Implemented Categories", &hInfo) == ERROR_SUCCESS)
285
{
286
if(RegEnumKeyW(hInfo, 0, wszComp, ARRAY_SIZE(wszComp)) != ERROR_SUCCESS) break;
287
288
RegCloseKey(hInfo);
289
290
if(tree.hGBCC) curSearch = (HTREEITEM)SendMessageW(globals.hTree,
291
TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)tree.hGBCC);
292
else curSearch = (HTREEITEM)SendMessageW(globals.hTree,
293
TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)TVI_ROOT);
294
295
while(curSearch)
296
{
297
tvi.hItem = curSearch;
298
if(!SendMessageW(globals.hTree, TVM_GETITEMW, 0, (LPARAM)&tvi)) break;
299
300
if(tvi.lParam && !lstrcmpW(((ITEM_INFO *)tvi.lParam)->info, wszComp))
301
{
302
tvis.hParent = curSearch;
303
304
memmove(&valName[6], valName, sizeof(WCHAR[MAX_LOAD_STRING-6]));
305
memmove(valName, L"CLSID\\", sizeof(WCHAR[6]));
306
tvis.item.lParam = CreateITEM_INFO(REGTOP|REGPATH|SHOWALL,
307
valName, &valName[6], NULL);
308
309
SendMessageW(globals.hTree, TVM_INSERTITEMW, 0, (LPARAM)&tvis);
310
break;
311
}
312
curSearch = (HTREEITEM)SendMessageW(globals.hTree,
313
TVM_GETNEXTITEM, TVGN_NEXT, (LPARAM)curSearch);
314
}
315
}
316
RegCloseKey(hCurKey);
317
}
318
RegCloseKey(hKey);
319
320
SendMessageW(globals.hTree, TVM_SORTCHILDREN, FALSE, (LPARAM)tree.hCLO);
321
SendMessageW(globals.hTree, TVM_SORTCHILDREN, FALSE, (LPARAM)tree.hAO);
322
}
323
324
static void AddApplicationID(void)
325
{
326
TVINSERTSTRUCTW tvis;
327
HKEY hKey, hCurKey;
328
WCHAR valName[MAX_LOAD_STRING];
329
WCHAR buffer[MAX_LOAD_STRING];
330
LONG lenBuffer;
331
int i=-1;
332
333
tvis.item.mask = TVIF_TEXT|TVIF_PARAM;
334
tvis.item.cchTextMax = MAX_LOAD_STRING;
335
tvis.hInsertAfter = TVI_FIRST;
336
tvis.hParent = tree.hAID;
337
338
if(RegOpenKeyW(HKEY_CLASSES_ROOT, L"AppID", &hKey) != ERROR_SUCCESS) return;
339
340
while(TRUE)
341
{
342
i++;
343
344
if(RegEnumKeyW(hKey, i, valName, ARRAY_SIZE(valName)) != ERROR_SUCCESS) break;
345
346
if(RegOpenKeyW(hKey, valName, &hCurKey) != ERROR_SUCCESS) continue;
347
348
lenBuffer = sizeof(WCHAR[MAX_LOAD_STRING]);
349
350
if(RegQueryValueW(hCurKey, NULL, buffer, &lenBuffer) == ERROR_SUCCESS && *buffer)
351
tvis.item.pszText = buffer;
352
else tvis.item.pszText = valName;
353
354
RegCloseKey(hCurKey);
355
356
tvis.item.lParam = CreateITEM_INFO(REGPATH, valName, valName, NULL);
357
SendMessageW(globals.hTree, TVM_INSERTITEMW, 0, (LPARAM)&tvis);
358
}
359
RegCloseKey(hKey);
360
361
SendMessageW(globals.hTree, TVM_SORTCHILDREN, FALSE, (LPARAM)tree.hAID);
362
}
363
364
static void AddTypeLib(void)
365
{
366
TVINSERTSTRUCTW tvis;
367
HKEY hKey, hCurKey, hInfoKey, hPath;
368
WCHAR valName[MAX_LOAD_STRING];
369
WCHAR valParent[MAX_LOAD_STRING];
370
WCHAR buffer[MAX_LOAD_STRING];
371
WCHAR wszVer[MAX_LOAD_STRING];
372
WCHAR wszPath[MAX_LOAD_STRING];
373
LONG lenBuffer;
374
int i=-1, j;
375
376
tvis.item.mask = TVIF_TEXT|TVIF_PARAM;
377
tvis.item.cchTextMax = MAX_LOAD_STRING;
378
tvis.hInsertAfter = TVI_FIRST;
379
tvis.hParent = tree.hTL;
380
381
if(RegOpenKeyW(HKEY_CLASSES_ROOT, L"TypeLib", &hKey) != ERROR_SUCCESS) return;
382
383
while(TRUE)
384
{
385
i++;
386
387
if(RegEnumKeyW(hKey, i, valParent, ARRAY_SIZE(valParent)) != ERROR_SUCCESS) break;
388
389
if(RegOpenKeyW(hKey, valParent, &hCurKey) != ERROR_SUCCESS) continue;
390
391
j = -1;
392
while(TRUE)
393
{
394
j++;
395
396
if(RegEnumKeyW(hCurKey, j, valName, ARRAY_SIZE(valName)) != ERROR_SUCCESS) break;
397
398
if(RegOpenKeyW(hCurKey, valName, &hInfoKey) != ERROR_SUCCESS) continue;
399
400
lenBuffer = sizeof(WCHAR[MAX_LOAD_STRING]);
401
402
if(RegQueryValueW(hInfoKey, NULL, buffer, &lenBuffer) == ERROR_SUCCESS
403
&& *buffer)
404
{
405
LoadStringW(globals.hMainInst, IDS_TL_VER, wszVer, ARRAY_SIZE(wszVer));
406
407
wsprintfW(&buffer[lstrlenW(buffer)], L" (%s %s)", wszVer, valName);
408
tvis.item.pszText = buffer;
409
410
lenBuffer = MAX_LOAD_STRING;
411
RegOpenKeyW(hInfoKey, L"0\\win32", &hPath);
412
RegQueryValueW(hPath, NULL, wszPath, &lenBuffer);
413
RegCloseKey(hPath);
414
}
415
else tvis.item.pszText = valName;
416
417
RegCloseKey(hInfoKey);
418
419
wsprintfW(wszVer, L"%s\\%s", valParent, valName);
420
tvis.item.lParam = CreateITEM_INFO(REGPATH, wszVer, valParent, wszPath);
421
422
SendMessageW(globals.hTree, TVM_INSERTITEMW, 0, (LPARAM)&tvis);
423
}
424
RegCloseKey(hCurKey);
425
}
426
427
RegCloseKey(hKey);
428
429
SendMessageW(globals.hTree, TVM_SORTCHILDREN, FALSE, (LPARAM)tree.hTL);
430
}
431
432
static void AddInterfaces(void)
433
{
434
TVINSERTSTRUCTW tvis;
435
HKEY hKey, hCurKey;
436
WCHAR valName[MAX_LOAD_STRING];
437
WCHAR buffer[MAX_LOAD_STRING];
438
LONG lenBuffer;
439
int i=-1;
440
441
tvis.item.mask = TVIF_TEXT|TVIF_PARAM;
442
tvis.item.cchTextMax = MAX_LOAD_STRING;
443
tvis.hInsertAfter = TVI_FIRST;
444
tvis.hParent = tree.hI;
445
446
if(RegOpenKeyW(HKEY_CLASSES_ROOT, L"Interface", &hKey) != ERROR_SUCCESS) return;
447
448
while(TRUE)
449
{
450
i++;
451
452
if(RegEnumKeyW(hKey, i, valName, ARRAY_SIZE(valName)) != ERROR_SUCCESS) break;
453
454
if(RegOpenKeyW(hKey, valName, &hCurKey) != ERROR_SUCCESS) continue;
455
456
lenBuffer = sizeof(WCHAR[MAX_LOAD_STRING]);
457
458
if(RegQueryValueW(hCurKey, NULL, buffer, &lenBuffer) == ERROR_SUCCESS && *buffer)
459
tvis.item.pszText = buffer;
460
else tvis.item.pszText = valName;
461
462
RegCloseKey(hCurKey);
463
464
tvis.item.lParam = CreateITEM_INFO(REGPATH|INTERFACE, valName, valName, NULL);
465
SendMessageW(globals.hTree, TVM_INSERTITEMW, 0, (LPARAM)&tvis);
466
}
467
468
RegCloseKey(hKey);
469
470
SendMessageW(globals.hTree, TVM_SORTCHILDREN, FALSE, (LPARAM)tree.hI);
471
}
472
473
static void AddComponentCategories(void)
474
{
475
TVINSERTSTRUCTW tvis;
476
HKEY hKey, hCurKey;
477
WCHAR keyName[MAX_LOAD_STRING];
478
WCHAR valName[MAX_LOAD_STRING];
479
WCHAR buffer[MAX_LOAD_STRING];
480
LONG lenBuffer;
481
DWORD lenBufferHlp;
482
DWORD lenValName;
483
int i=-1;
484
485
tvis.item.mask = TVIF_TEXT|TVIF_PARAM|TVIF_CHILDREN;
486
tvis.item.cchTextMax = MAX_LOAD_STRING;
487
tvis.hInsertAfter = TVI_FIRST;
488
if(tree.hGBCC) tvis.hParent = tree.hGBCC;
489
else tvis.hParent = TVI_ROOT;
490
tvis.item.cChildren = 1;
491
492
if(RegOpenKeyW(HKEY_CLASSES_ROOT, L"Component Categories", &hKey) != ERROR_SUCCESS)
493
return;
494
495
while(TRUE)
496
{
497
i++;
498
499
if(RegEnumKeyW(hKey, i, keyName, ARRAY_SIZE(keyName)) != ERROR_SUCCESS) break;
500
501
if(RegOpenKeyW(hKey, keyName, &hCurKey) != ERROR_SUCCESS) continue;
502
503
lenBuffer = sizeof(WCHAR[MAX_LOAD_STRING]);
504
lenBufferHlp = sizeof(WCHAR[MAX_LOAD_STRING]);
505
lenValName = sizeof(WCHAR[MAX_LOAD_STRING]);
506
507
if(RegQueryValueW(hCurKey, NULL, buffer, &lenBuffer) == ERROR_SUCCESS && *buffer)
508
tvis.item.pszText = buffer;
509
else if(RegEnumValueW(hCurKey, 0, valName, &lenValName, NULL, NULL,
510
(LPBYTE)buffer, &lenBufferHlp) == ERROR_SUCCESS && *buffer)
511
tvis.item.pszText = buffer;
512
else continue;
513
514
RegCloseKey(hCurKey);
515
516
tvis.item.lParam = CreateITEM_INFO(REGTOP, keyName, keyName, NULL);
517
SendMessageW(globals.hTree, TVM_INSERTITEMW, 0, (LPARAM)&tvis);
518
}
519
520
RegCloseKey(hKey);
521
522
SendMessageW(globals.hTree, TVM_SORTCHILDREN, FALSE, (LPARAM)tree.hGBCC);
523
}
524
525
static void AddBaseEntries(void)
526
{
527
TVINSERTSTRUCTW tvis;
528
WCHAR name[MAX_LOAD_STRING];
529
530
tvis.item.mask = TVIF_TEXT|TVIF_CHILDREN|TVIF_PARAM;
531
/* FIXME add TVIF_IMAGE */
532
tvis.item.pszText = name;
533
tvis.item.cchTextMax = MAX_LOAD_STRING;
534
tvis.item.cChildren = 1;
535
tvis.hInsertAfter = TVI_FIRST;
536
tvis.hParent = TVI_ROOT;
537
538
LoadStringW(globals.hMainInst, IDS_TREE_I, tvis.item.pszText,
539
MAX_LOAD_STRING);
540
tvis.item.lParam = CreateITEM_INFO(REGTOP, L"Interface\\", NULL, NULL);
541
tree.hI = TreeView_InsertItemW(globals.hTree, &tvis);
542
543
LoadStringW(globals.hMainInst, IDS_TREE_TL, tvis.item.pszText,
544
MAX_LOAD_STRING);
545
tvis.item.lParam = CreateITEM_INFO(REGTOP, L"TypeLib\\", NULL, NULL);
546
tree.hTL = TreeView_InsertItemW(globals.hTree, &tvis);
547
548
LoadStringW(globals.hMainInst, IDS_TREE_AID, tvis.item.pszText,
549
MAX_LOAD_STRING);
550
tvis.item.lParam = CreateITEM_INFO(REGTOP|REGPATH, L"AppID\\", NULL, NULL);
551
tree.hAID = TreeView_InsertItemW(globals.hTree, &tvis);
552
553
LoadStringW(globals.hMainInst, IDS_TREE_OC, tvis.item.pszText,
554
MAX_LOAD_STRING);
555
tvis.item.lParam = 0;
556
tree.hOC = TreeView_InsertItemW(globals.hTree, &tvis);
557
558
559
tvis.hParent = tree.hOC;
560
LoadStringW(globals.hMainInst, IDS_TREE_AO, tvis.item.pszText,
561
MAX_LOAD_STRING);
562
tvis.item.lParam = CreateITEM_INFO(REGTOP, L"CLSID\\", NULL, NULL);
563
tree.hAO = TreeView_InsertItemW(globals.hTree, &tvis);
564
565
LoadStringW(globals.hMainInst, IDS_TREE_CLO, tvis.item.pszText,
566
MAX_LOAD_STRING);
567
tree.hCLO = TreeView_InsertItemW(globals.hTree, &tvis);
568
569
LoadStringW(globals.hMainInst, IDS_TREE_O1O, tvis.item.pszText,
570
MAX_LOAD_STRING);
571
tvis.item.lParam = 0;
572
tree.hO1O = TreeView_InsertItemW(globals.hTree, &tvis);
573
574
LoadStringW(globals.hMainInst, IDS_TREE_GBCC, tvis.item.pszText,
575
MAX_LOAD_STRING);
576
tvis.item.lParam = CreateITEM_INFO(REGTOP|REGPATH, L"Component Categories\\", NULL, NULL);
577
tree.hGBCC = TreeView_InsertItemW(globals.hTree, &tvis);
578
579
SendMessageW(globals.hTree, TVM_EXPAND, TVE_EXPAND, (LPARAM)tree.hOC);
580
}
581
582
void EmptyTree(void)
583
{
584
SendMessageW(globals.hTree, TVM_DELETEITEM, 0, (LPARAM)TVI_ROOT);
585
}
586
587
void AddTreeEx(void)
588
{
589
AddBaseEntries();
590
AddComponentCategories();
591
AddCOMandAll();
592
AddApplicationID();
593
AddTypeLib();
594
AddInterfaces();
595
}
596
597
void AddTree(void)
598
{
599
memset(&tree, 0, sizeof(TREE));
600
AddComponentCategories();
601
AddCOMandAll();
602
}
603
604
static LRESULT CALLBACK TreeProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
605
{
606
switch(uMsg)
607
{
608
case WM_CREATE:
609
globals.hTree = CreateWindowW(WC_TREEVIEWW, NULL,
610
WS_CHILD|WS_VISIBLE|TVS_HASLINES|TVS_HASBUTTONS|TVS_LINESATROOT,
611
0, 0, 0, 0, hWnd, (HMENU)TREE_WINDOW, globals.hMainInst, NULL);
612
AddTreeEx();
613
break;
614
case WM_NOTIFY:
615
if((int)wParam != TREE_WINDOW) break;
616
switch(((LPNMHDR)lParam)->code)
617
{
618
case TVN_ITEMEXPANDINGW:
619
CreateInst(((NMTREEVIEWW *)lParam)->itemNew.hItem, NULL);
620
break;
621
case TVN_SELCHANGEDW:
622
RefreshMenu(((NMTREEVIEWW *)lParam)->itemNew.hItem);
623
RefreshDetails(((NMTREEVIEWW *)lParam)->itemNew.hItem);
624
break;
625
case TVN_DELETEITEMW:
626
{
627
NMTREEVIEWW *nm = (NMTREEVIEWW*)lParam;
628
ITEM_INFO *info = (ITEM_INFO*)nm->itemOld.lParam;
629
630
if (info)
631
{
632
if (info->loaded)
633
ReleaseInst(nm->itemOld.hItem);
634
free(info);
635
}
636
break;
637
}
638
}
639
break;
640
case WM_SIZE:
641
MoveWindow(globals.hTree, 0, 0, LOWORD(lParam), HIWORD(lParam), TRUE);
642
break;
643
default:
644
return DefWindowProcW(hWnd, uMsg, wParam, lParam);
645
}
646
return 0;
647
}
648
649
HWND CreateTreeWindow(HINSTANCE hInst)
650
{
651
WNDCLASSW wct;
652
653
memset(&wct, 0, sizeof(WNDCLASSW));
654
wct.lpfnWndProc = TreeProc;
655
wct.lpszClassName = L"TREE";
656
wct.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
657
wct.hCursor = LoadCursorW(0, (LPCWSTR)IDC_ARROW);
658
659
if(!RegisterClassW(&wct)) return NULL;
660
661
return CreateWindowExW(WS_EX_CLIENTEDGE, L"TREE", NULL, WS_CHILD|WS_VISIBLE,
662
0, 0, 0, 0, globals.hPaneWnd, NULL, hInst, NULL);
663
}
664
665