4 * Copyright 2006 Piotr Caban
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.
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.
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
24 static const WCHAR wszCLSID
[] = { 'C','L','S','I','D','\\','\0' };
25 static const WCHAR wszInProcServer32
[] =
26 { 'I','n','P','r','o','c','S','e','r','v','e','r','3','2','\0' };
27 static const WCHAR wszOle32dll
[] = { 'o','l','e','3','2','.','d','l','l','\0' };
28 static const WCHAR wszOleAut32dll
[] =
29 { 'o','l','e','a','u','t','3','2','.','d','l','l','\0' };
30 static const WCHAR wszImplementedCategories
[] =
31 { 'I','m','p','l','e','m','e','n','t','e','d',' ',
32 'C','a','t','e','g','o','r','i','e','s','\0' };
33 static const WCHAR wszAppID
[] = { 'A','p','p','I','D','\\','\0' };
34 static const WCHAR wszTypeLib
[] = { 'T','y','p','e','L','i','b','\\','\0' };
35 static const WCHAR wszInterface
[] = { 'I','n','t','e','r','f','a','c','e','\\','\0' };
36 static const WCHAR wszComponentCategories
[] = { 'C','o','m','p','o','n','e','n','t',
37 ' ','C','a','t','e','g','o','r','i','e','s','\\','\0' };
39 LPARAM
CreateITEM_INFO(INT flag
, const WCHAR
*info
, const WCHAR
*clsid
)
43 reg
= HeapAlloc(GetProcessHeap(), 0, sizeof(ITEM_INFO
));
44 memset(reg
, 0, sizeof(ITEM_INFO
));
47 lstrcpyW(reg
->info
, info
);
48 if(clsid
) lstrcpyW(reg
->clsid
, clsid
);
53 void CreateInst(HTREEITEM item
, WCHAR
*wszMachineName
)
58 WCHAR wszTitle
[MAX_LOAD_STRING
];
59 WCHAR wszMessage
[MAX_LOAD_STRING
];
60 WCHAR wszFlagName
[MAX_LOAD_STRING
];
61 WCHAR wszTreeName
[MAX_LOAD_STRING
];
62 WCHAR wszRegPath
[MAX_LOAD_STRING
];
63 const WCHAR wszFormat
[] = { '\n','%','s',' ','(','$','%','x',')','\n','\0' };
65 COSERVERINFO remoteInfo
;
70 memset(&tvi
, 0, sizeof(TVITEM
));
73 tvi
.cchTextMax
= MAX_LOAD_STRING
;
74 tvi
.pszText
= wszTreeName
;
76 memset(&tvis
, 0, sizeof(TVINSERTSTRUCT
));
77 tvis
.item
.mask
= TVIF_TEXT
|TVIF_PARAM
;
78 tvis
.item
.cchTextMax
= MAX_LOAD_STRING
;
79 tvis
.hInsertAfter
= (HTREEITEM
)TVI_FIRST
;
80 tvis
.item
.pszText
= tvi
.pszText
;
82 tvis
.hInsertAfter
= TVI_LAST
;
84 SendMessage(globals
.hTree
, TVM_GETITEM
, 0, (LPARAM
)&tvi
);
86 if(!tvi
.lParam
|| ((ITEM_INFO
*)tvi
.lParam
)->loaded
87 || !(((ITEM_INFO
*)tvi
.lParam
)->cFlag
&SHOWALL
)) return;
89 if(FAILED(CLSIDFromString(((ITEM_INFO
*)tvi
.lParam
)->clsid
, &clsid
))) return;
93 remoteInfo
.dwReserved1
= 0;
94 remoteInfo
.dwReserved2
= 0;
95 remoteInfo
.pAuthInfo
= NULL
;
96 remoteInfo
.pwszName
= wszMachineName
;
98 qi
.pIID
= &IID_IUnknown
;
100 CoCreateInstanceEx(&clsid
, NULL
, globals
.dwClsCtx
|CLSCTX_REMOTE_SERVER
,
101 &remoteInfo
, 1, &qi
);
105 else hRes
= CoCreateInstance(&clsid
, NULL
, globals
.dwClsCtx
,
106 &IID_IUnknown
, (void **)&obj
);
110 LoadString(globals
.hMainInst
, IDS_CGCOFAIL
, wszMessage
,
111 sizeof(WCHAR
[MAX_LOAD_STRING
]));
112 LoadString(globals
.hMainInst
, IDS_ABOUT
, wszTitle
,
113 sizeof(WCHAR
[MAX_LOAD_STRING
]));
115 #define CASE_ERR(i) case i: \
116 MultiByteToWideChar(CP_ACP, 0, #i, -1, wszFlagName, MAX_LOAD_STRING); \
121 CASE_ERR(REGDB_E_CLASSNOTREG
);
122 CASE_ERR(E_NOINTERFACE
);
123 CASE_ERR(REGDB_E_READREGDB
);
124 CASE_ERR(REGDB_E_KEYMISSING
);
125 CASE_ERR(CO_E_DLLNOTFOUND
);
126 CASE_ERR(CO_E_APPNOTFOUND
);
127 CASE_ERR(E_ACCESSDENIED
);
128 CASE_ERR(CO_E_ERRORINDLL
);
129 CASE_ERR(CO_E_APPDIDNTREG
);
130 CASE_ERR(CLASS_E_CLASSNOTAVAILABLE
);
132 LoadString(globals
.hMainInst
, IDS_ERROR_UNKN
, wszFlagName
, MAX_LOAD_STRING
);
135 wsprintfW(&wszMessage
[lstrlenW(wszMessage
)], wszFormat
,
136 wszFlagName
, (unsigned)hRes
);
137 MessageBox(globals
.hMainWnd
, wszMessage
, wszTitle
, MB_OK
|MB_ICONEXCLAMATION
);
141 ((ITEM_INFO
*)tvi
.lParam
)->loaded
= 1;
142 ((ITEM_INFO
*)tvi
.lParam
)->pU
= obj
;
144 tvi
.mask
= TVIF_STATE
;
145 tvi
.state
= TVIS_BOLD
;
146 tvi
.stateMask
= TVIS_BOLD
;
147 SendMessage(globals
.hTree
, TVM_SETITEM
, 0, (LPARAM
)&tvi
);
149 tvi
.mask
= TVIF_TEXT
;
150 hCur
= TreeView_GetChild(globals
.hTree
, tree
.hI
);
155 SendMessage(globals
.hTree
, TVM_GETITEM
, 0, (LPARAM
)&tvi
);
159 hCur
= TreeView_GetNextSibling(globals
.hTree
, hCur
);
163 CLSIDFromString(((ITEM_INFO
*)tvi
.lParam
)->clsid
, &clsid
);
164 hRes
= IUnknown_QueryInterface(obj
, &clsid
, (void *)&unk
);
168 IUnknown_Release(unk
);
170 lstrcpyW(wszRegPath
, wszInterface
);
171 lstrcpyW(&wszRegPath
[lstrlenW(wszRegPath
)], ((ITEM_INFO
*)tvi
.lParam
)->clsid
);
172 tvis
.item
.lParam
= CreateITEM_INFO(REGTOP
|INTERFACE
|REGPATH
,
173 wszRegPath
, ((ITEM_INFO
*)tvi
.lParam
)->clsid
);
174 SendMessage(globals
.hTree
, TVM_INSERTITEM
, 0, (LPARAM
)&tvis
);
176 hCur
= TreeView_GetNextSibling(globals
.hTree
, hCur
);
180 RefreshDetails(item
);
183 void ReleaseInst(HTREEITEM item
)
189 memset(&tvi
, 0, sizeof(TVITEM
));
191 SendMessage(globals
.hTree
, TVM_GETITEM
, 0, (LPARAM
)&tvi
);
193 if(!tvi
.lParam
) return;
195 pU
= ((ITEM_INFO
*)tvi
.lParam
)->pU
;
197 if(pU
) IUnknown_Release(pU
);
198 ((ITEM_INFO
*)tvi
.lParam
)->loaded
= 0;
200 SendMessage(globals
.hTree
, TVM_EXPAND
, TVE_COLLAPSE
, (LPARAM
)item
);
202 cur
= TreeView_GetChild(globals
.hTree
, item
);
205 SendMessage(globals
.hTree
, TVM_DELETEITEM
, 0, (LPARAM
)cur
);
206 cur
= TreeView_GetChild(globals
.hTree
, item
);
209 tvi
.mask
= TVIF_CHILDREN
|TVIF_STATE
;
211 tvi
.stateMask
= TVIS_BOLD
;
213 SendMessage(globals
.hTree
, TVM_SETITEM
, 0, (LPARAM
)&tvi
);
216 BOOL
CreateRegPath(HTREEITEM item
, WCHAR
*buffer
, int bufSize
)
222 memset(buffer
, 0, sizeof(WCHAR
[bufSize
]));
223 memset(&tvi
, 0, sizeof(TVITEM
));
226 SendMessage(globals
.hTree
, TVM_GETITEM
, 0, (LPARAM
)&tvi
);
227 ret
= (tvi
.lParam
&& ((ITEM_INFO
*)tvi
.lParam
)->cFlag
& REGPATH
);
231 SendMessage(globals
.hTree
, TVM_GETITEM
, 0, (LPARAM
)&tvi
);
233 if(tvi
.lParam
&& (((ITEM_INFO
*)tvi
.lParam
)->cFlag
& (REGPATH
|REGTOP
)))
235 bufLen
= lstrlenW(((ITEM_INFO
*)tvi
.lParam
)->info
);
236 memmove(&buffer
[bufLen
], buffer
, sizeof(WCHAR
[bufSize
-bufLen
]));
237 memcpy(buffer
, ((ITEM_INFO
*)tvi
.lParam
)->info
, sizeof(WCHAR
[bufLen
]));
240 if(tvi
.lParam
&& ((ITEM_INFO
*)tvi
.lParam
)->cFlag
& REGTOP
) break;
242 if(!tvi
.lParam
) return FALSE
;
244 tvi
.hItem
= TreeView_GetParent(globals
.hTree
, tvi
.hItem
);
249 void AddCOMandAll(void)
254 HKEY hKey
, hCurKey
, hInfo
;
255 WCHAR valName
[MAX_LOAD_STRING
];
256 WCHAR buffer
[MAX_LOAD_STRING
];
257 WCHAR wszComp
[MAX_LOAD_STRING
];
261 memset(&tvi
, 0, sizeof(TVITEM
));
262 tvis
.item
.mask
= TVIF_TEXT
|TVIF_PARAM
|TVIF_CHILDREN
;
263 tvis
.item
.cchTextMax
= MAX_LOAD_STRING
;
264 tvis
.item
.cChildren
= 1;
265 tvis
.hInsertAfter
= (HTREEITEM
)TVI_FIRST
;
267 if(RegOpenKey(HKEY_CLASSES_ROOT
, wszCLSID
, &hKey
) != ERROR_SUCCESS
) return;
273 if(RegEnumKey(hKey
, i
, valName
, -1) != ERROR_SUCCESS
) break;
275 if(RegOpenKey(hKey
, valName
, &hCurKey
) != ERROR_SUCCESS
) continue;
277 lenBuffer
= sizeof(WCHAR
[MAX_LOAD_STRING
]);
278 tvis
.hParent
= tree
.hAO
;
280 if(RegOpenKey(hCurKey
, wszInProcServer32
, &hInfo
) == ERROR_SUCCESS
)
282 if(RegQueryValue(hInfo
, NULL
, buffer
, &lenBuffer
) == ERROR_SUCCESS
284 if(!memcmp(buffer
, wszOle32dll
, sizeof(WCHAR
[9]))
285 ||!memcmp(buffer
, wszOleAut32dll
, sizeof(WCHAR
[12])))
286 tvis
.hParent
= tree
.hCLO
;
291 lenBuffer
= sizeof(WCHAR
[MAX_LOAD_STRING
]);
293 if(RegQueryValue(hCurKey
, NULL
, buffer
, &lenBuffer
) == ERROR_SUCCESS
&& *buffer
)
294 tvis
.item
.pszText
= buffer
;
295 else tvis
.item
.pszText
= valName
;
297 tvis
.item
.lParam
= CreateITEM_INFO(REGPATH
|SHOWALL
, valName
, valName
);
298 if(tvis
.hParent
) SendMessage(globals
.hTree
, TVM_INSERTITEM
, 0, (LPARAM
)&tvis
);
300 if(RegOpenKey(hCurKey
, wszImplementedCategories
, &hInfo
) == ERROR_SUCCESS
)
302 if(RegEnumKey(hInfo
, 0, wszComp
, -1) != ERROR_SUCCESS
) break;
306 if(tree
.hGBCC
) curSearch
= TreeView_GetChild(globals
.hTree
, tree
.hGBCC
);
307 else curSearch
= TreeView_GetChild(globals
.hTree
, TVI_ROOT
);
311 tvi
.hItem
= curSearch
;
312 SendMessage(globals
.hTree
, TVM_GETITEM
, 0, (LPARAM
)&tvi
);
314 if(tvi
.lParam
&& !lstrcmpW(((ITEM_INFO
*)tvi
.lParam
)->info
, wszComp
))
316 tvis
.hParent
= curSearch
;
318 memmove(&valName
[6], valName
, sizeof(WCHAR
[MAX_LOAD_STRING
-6]));
319 memmove(valName
, wszCLSID
, sizeof(WCHAR
[6]));
320 tvis
.item
.lParam
= CreateITEM_INFO(REGTOP
|REGPATH
|SHOWALL
,
321 valName
, &valName
[6]);
323 SendMessage(globals
.hTree
, TVM_INSERTITEM
, 0, (LPARAM
)&tvis
);
326 curSearch
= TreeView_GetNextSibling(globals
.hTree
, curSearch
);
329 RegCloseKey(hCurKey
);
333 SendMessage(globals
.hTree
, TVM_SORTCHILDREN
, FALSE
, (LPARAM
)tree
.hCLO
);
334 SendMessage(globals
.hTree
, TVM_SORTCHILDREN
, FALSE
, (LPARAM
)tree
.hAO
);
337 void AddApplicationID(void)
341 WCHAR valName
[MAX_LOAD_STRING
];
342 WCHAR buffer
[MAX_LOAD_STRING
];
346 tvis
.item
.mask
= TVIF_TEXT
|TVIF_PARAM
;
347 tvis
.item
.cchTextMax
= MAX_LOAD_STRING
;
348 tvis
.hInsertAfter
= (HTREEITEM
)TVI_FIRST
;
349 tvis
.hParent
= tree
.hAID
;
351 if(RegOpenKey(HKEY_CLASSES_ROOT
, wszAppID
, &hKey
) != ERROR_SUCCESS
) return;
357 if(RegEnumKey(hKey
, i
, valName
, -1) != ERROR_SUCCESS
) break;
359 if(RegOpenKey(hKey
, valName
, &hCurKey
) != ERROR_SUCCESS
) continue;
361 lenBuffer
= sizeof(WCHAR
[MAX_LOAD_STRING
]);
363 if(RegQueryValue(hCurKey
, NULL
, buffer
, &lenBuffer
) == ERROR_SUCCESS
&& *buffer
)
364 tvis
.item
.pszText
= buffer
;
365 else tvis
.item
.pszText
= valName
;
367 RegCloseKey(hCurKey
);
369 tvis
.item
.lParam
= CreateITEM_INFO(REGPATH
, valName
, valName
);
370 SendMessage(globals
.hTree
, TVM_INSERTITEM
, 0, (LPARAM
)&tvis
);
374 SendMessage(globals
.hTree
, TVM_SORTCHILDREN
, FALSE
, (LPARAM
)tree
.hAID
);
377 void AddTypeLib(void)
380 HKEY hKey
, hCurKey
, hInfoKey
;
381 WCHAR valName
[MAX_LOAD_STRING
];
382 WCHAR valParent
[MAX_LOAD_STRING
];
383 WCHAR buffer
[MAX_LOAD_STRING
];
384 WCHAR wszVer
[MAX_LOAD_STRING
];
385 const WCHAR wszFormat
[] = { ' ','(','%','s',' ','%','s',')','\0' };
386 const WCHAR wszFormat2
[] = { '%','s','\\','%','s','\0' };
390 tvis
.item
.mask
= TVIF_TEXT
|TVIF_PARAM
;
391 tvis
.item
.cchTextMax
= MAX_LOAD_STRING
;
392 tvis
.hInsertAfter
= (HTREEITEM
)TVI_FIRST
;
393 tvis
.hParent
= tree
.hTL
;
395 if(RegOpenKey(HKEY_CLASSES_ROOT
, wszTypeLib
, &hKey
) != ERROR_SUCCESS
) return;
401 if(RegEnumKey(hKey
, i
, valParent
, -1) != ERROR_SUCCESS
) break;
403 if(RegOpenKey(hKey
, valParent
, &hCurKey
) != ERROR_SUCCESS
) continue;
410 if(RegEnumKey(hCurKey
, j
, valName
, -1) != ERROR_SUCCESS
) break;
412 if(RegOpenKey(hCurKey
, valName
, &hInfoKey
) != ERROR_SUCCESS
) continue;
414 lenBuffer
= sizeof(WCHAR
[MAX_LOAD_STRING
]);
416 if(RegQueryValue(hInfoKey
, NULL
, buffer
, &lenBuffer
) == ERROR_SUCCESS
419 LoadString(globals
.hMainInst
, IDS_TL_VER
, wszVer
,
420 sizeof(WCHAR
[MAX_LOAD_STRING
]));
422 wsprintfW(&buffer
[lstrlenW(buffer
)], wszFormat
, wszVer
, valName
);
423 tvis
.item
.pszText
= buffer
;
425 else tvis
.item
.pszText
= valName
;
427 RegCloseKey(hInfoKey
);
429 wsprintfW(wszVer
, wszFormat2
, valParent
, valName
);
430 tvis
.item
.lParam
= CreateITEM_INFO(REGPATH
, wszVer
, valParent
);
432 SendMessage(globals
.hTree
, TVM_INSERTITEM
, 0, (LPARAM
)&tvis
);
434 RegCloseKey(hCurKey
);
439 SendMessage(globals
.hTree
, TVM_SORTCHILDREN
, FALSE
, (LPARAM
)tree
.hTL
);
442 void AddInterfaces(void)
446 WCHAR valName
[MAX_LOAD_STRING
];
447 WCHAR buffer
[MAX_LOAD_STRING
];
451 tvis
.item
.mask
= TVIF_TEXT
|TVIF_PARAM
;
452 tvis
.item
.cchTextMax
= MAX_LOAD_STRING
;
453 tvis
.hInsertAfter
= (HTREEITEM
)TVI_FIRST
;
454 tvis
.hParent
= tree
.hI
;
456 if(RegOpenKey(HKEY_CLASSES_ROOT
, wszInterface
, &hKey
) != ERROR_SUCCESS
) return;
462 if(RegEnumKey(hKey
, i
, valName
, -1) != ERROR_SUCCESS
) break;
464 if(RegOpenKey(hKey
, valName
, &hCurKey
) != ERROR_SUCCESS
) continue;
466 lenBuffer
= sizeof(WCHAR
[MAX_LOAD_STRING
]);
468 if(RegQueryValue(hCurKey
, NULL
, buffer
, &lenBuffer
) == ERROR_SUCCESS
&& *buffer
)
469 tvis
.item
.pszText
= buffer
;
470 else tvis
.item
.pszText
= valName
;
472 RegCloseKey(hCurKey
);
474 tvis
.item
.lParam
= CreateITEM_INFO(REGPATH
|INTERFACE
, valName
, valName
);
475 SendMessage(globals
.hTree
, TVM_INSERTITEM
, 0, (LPARAM
)&tvis
);
480 SendMessage(globals
.hTree
, TVM_SORTCHILDREN
, FALSE
, (LPARAM
)tree
.hI
);
483 void AddComponentCategories(void)
487 WCHAR valName
[MAX_LOAD_STRING
];
488 WCHAR buffer
[MAX_LOAD_STRING
];
493 tvis
.item
.mask
= TVIF_TEXT
|TVIF_PARAM
|TVIF_CHILDREN
;
494 tvis
.item
.cchTextMax
= MAX_LOAD_STRING
;
495 tvis
.hInsertAfter
= (HTREEITEM
)TVI_FIRST
;
496 if(tree
.hGBCC
) tvis
.hParent
= tree
.hGBCC
;
497 else tvis
.hParent
= TVI_ROOT
;
498 tvis
.item
.cChildren
= 1;
500 if(RegOpenKey(HKEY_CLASSES_ROOT
, wszComponentCategories
, &hKey
) != ERROR_SUCCESS
)
507 if(RegEnumKey(hKey
, i
, valName
, -1) != ERROR_SUCCESS
) break;
509 if(RegOpenKey(hKey
, valName
, &hCurKey
) != ERROR_SUCCESS
) continue;
511 lenBuffer
= sizeof(WCHAR
[MAX_LOAD_STRING
]);
512 lenBufferHlp
= sizeof(WCHAR
[MAX_LOAD_STRING
]);
514 if(RegQueryValue(hCurKey
, NULL
, buffer
, &lenBuffer
) == ERROR_SUCCESS
&& *buffer
)
515 tvis
.item
.pszText
= buffer
;
516 else if(RegEnumValue(hCurKey
, 0, NULL
, NULL
, NULL
, NULL
,
517 (LPBYTE
)buffer
, &lenBufferHlp
) == ERROR_SUCCESS
&& *buffer
)
518 tvis
.item
.pszText
= buffer
;
521 RegCloseKey(hCurKey
);
523 tvis
.item
.lParam
= CreateITEM_INFO(REGTOP
, valName
, valName
);
524 SendMessage(globals
.hTree
, TVM_INSERTITEM
, 0, (LPARAM
)&tvis
);
529 SendMessage(globals
.hTree
, TVM_SORTCHILDREN
, FALSE
, (LPARAM
)tree
.hGBCC
);
532 void AddBaseEntries(void)
535 WCHAR name
[MAX_LOAD_STRING
];
537 tvis
.item
.mask
= TVIF_TEXT
|TVIF_CHILDREN
|TVIF_PARAM
;
538 /* FIXME add TVIF_IMAGE */
539 tvis
.item
.pszText
= name
;
540 tvis
.item
.cchTextMax
= MAX_LOAD_STRING
;
541 tvis
.item
.cChildren
= 1;
542 tvis
.hInsertAfter
= (HTREEITEM
)TVI_FIRST
;
543 tvis
.hParent
= TVI_ROOT
;
545 LoadString(globals
.hMainInst
, IDS_TREE_I
, tvis
.item
.pszText
,
546 sizeof(WCHAR
[MAX_LOAD_STRING
]));
547 tvis
.item
.lParam
= CreateITEM_INFO(REGTOP
, wszInterface
, NULL
);
548 tree
.hI
= TreeView_InsertItem(globals
.hTree
, &tvis
);
550 LoadString(globals
.hMainInst
, IDS_TREE_TL
, tvis
.item
.pszText
,
551 sizeof(WCHAR
[MAX_LOAD_STRING
]));
552 tvis
.item
.lParam
= CreateITEM_INFO(REGTOP
, wszTypeLib
, NULL
);
553 tree
.hTL
= TreeView_InsertItem(globals
.hTree
, &tvis
);
555 LoadString(globals
.hMainInst
, IDS_TREE_AID
, tvis
.item
.pszText
,
556 sizeof(WCHAR
[MAX_LOAD_STRING
]));
557 tvis
.item
.lParam
= CreateITEM_INFO(REGTOP
|REGPATH
, wszAppID
, NULL
);
558 tree
.hAID
= TreeView_InsertItem(globals
.hTree
, &tvis
);
560 LoadString(globals
.hMainInst
, IDS_TREE_OC
, tvis
.item
.pszText
,
561 sizeof(WCHAR
[MAX_LOAD_STRING
]));
562 tvis
.item
.lParam
= (LPARAM
)NULL
;
563 tree
.hOC
= TreeView_InsertItem(globals
.hTree
, &tvis
);
566 tvis
.hParent
= tree
.hOC
;
567 LoadString(globals
.hMainInst
, IDS_TREE_AO
, tvis
.item
.pszText
,
568 sizeof(WCHAR
[MAX_LOAD_STRING
]));
569 tvis
.item
.lParam
= CreateITEM_INFO(REGTOP
, wszCLSID
, NULL
);
570 tree
.hAO
= TreeView_InsertItem(globals
.hTree
, &tvis
);
572 LoadString(globals
.hMainInst
, IDS_TREE_CLO
, tvis
.item
.pszText
,
573 sizeof(WCHAR
[MAX_LOAD_STRING
]));
574 tree
.hCLO
= TreeView_InsertItem(globals
.hTree
, &tvis
);
576 LoadString(globals
.hMainInst
, IDS_TREE_O1O
, tvis
.item
.pszText
,
577 sizeof(WCHAR
[MAX_LOAD_STRING
]));
578 tvis
.item
.lParam
= (LPARAM
)NULL
;
579 tree
.hO1O
= TreeView_InsertItem(globals
.hTree
, &tvis
);
581 LoadString(globals
.hMainInst
, IDS_TREE_GBCC
, tvis
.item
.pszText
,
582 sizeof(WCHAR
[MAX_LOAD_STRING
]));
583 tvis
.item
.lParam
= CreateITEM_INFO(REGTOP
|REGPATH
, wszComponentCategories
, NULL
);
584 tree
.hGBCC
= TreeView_InsertItem(globals
.hTree
, &tvis
);
586 SendMessage(globals
.hTree
, TVM_EXPAND
, TVE_EXPAND
, (LPARAM
)tree
.hOC
);
594 tvi
.mask
= TVIF_PARAM
;
595 cur
= TreeView_GetChild(globals
.hTree
, TVI_ROOT
);
600 cur
= TreeView_GetChild(globals
.hTree
, del
);
602 if(!cur
) cur
= TreeView_GetNextSibling(globals
.hTree
, del
);
605 cur
= TreeView_GetPrevSibling(globals
.hTree
, del
);
606 if(!cur
) cur
= TreeView_GetParent(globals
.hTree
, del
);
609 SendMessage(globals
.hTree
, TVM_GETITEM
, 0, (LPARAM
)&tvi
);
613 if(((ITEM_INFO
*)tvi
.lParam
)->loaded
) ReleaseInst(del
);
614 HeapFree(GetProcessHeap(), 0, (ITEM_INFO
*)tvi
.lParam
);
617 SendMessage(globals
.hTree
, TVM_DELETEITEM
, 0, (LPARAM
)del
);
627 AddComponentCategories();
636 memset(&tree
, 0, sizeof(TREE
));
637 AddComponentCategories();
641 LRESULT CALLBACK
TreeProc(HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
646 globals
.hTree
= CreateWindow(WC_TREEVIEW
, NULL
,
647 WS_CHILD
|WS_VISIBLE
|TVS_HASLINES
|TVS_HASBUTTONS
|TVS_LINESATROOT
,
648 0, 0, 0, 0, hWnd
, (HMENU
)TREE_WINDOW
, globals
.hMainInst
, NULL
);
652 if((int)wParam
!= TREE_WINDOW
) break;
653 switch(((LPNMHDR
)lParam
)->code
)
655 case TVN_ITEMEXPANDING
:
656 CreateInst(((NMTREEVIEW
*)lParam
)->itemNew
.hItem
, NULL
);
659 RefreshMenu(((NMTREEVIEW
*)lParam
)->itemNew
.hItem
);
660 RefreshDetails(((NMTREEVIEW
*)lParam
)->itemNew
.hItem
);
665 MoveWindow(globals
.hTree
, 0, 0, LOWORD(lParam
), HIWORD(lParam
), TRUE
);
668 return DefWindowProc(hWnd
, uMsg
, wParam
, lParam
);
673 HWND
CreateTreeWindow(HINSTANCE hInst
)
676 const WCHAR wszTreeClass
[] = { 'T','R','E','E','\0' };
678 memset(&wct
, 0, sizeof(WNDCLASS
));
679 wct
.lpfnWndProc
= TreeProc
;
680 wct
.lpszClassName
= wszTreeClass
;
682 if(!RegisterClass(&wct
)) return NULL
;
684 return CreateWindowEx(WS_EX_CLIENTEDGE
, wszTreeClass
, NULL
, WS_CHILD
|WS_VISIBLE
,
685 0, 0, 0, 0, globals
.hPaneWnd
, NULL
, hInst
, NULL
);