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
23 #include "wine/debug.h"
25 WINE_DEFAULT_DEBUG_CHANNEL(oleview
);
28 static const WCHAR wszTypeLib
[] = { 'T','Y','P','E','L','I','B','\0' };
30 static const WCHAR wszFailed
[] = { '<','f','a','i','l','e','d','>','\0' };
31 static const WCHAR wszSpace
[] = { ' ','\0' };
32 static const WCHAR wszAsterix
[] = { '*','\0' };
33 static const WCHAR wszComa
[] = { ',','\0' };
34 static const WCHAR wszSemicolon
[] = { ';','\0' };
35 static const WCHAR wszNewLine
[] = { '\n','\0' };
36 static const WCHAR wszOpenBrackets1
[] = { '[','\0' };
37 static const WCHAR wszCloseBrackets1
[] = { ']','\0' };
38 static const WCHAR wszOpenBrackets2
[] = { '(','\0' };
39 static const WCHAR wszCloseBrackets2
[] = { ')','\0' };
40 static const WCHAR wszOpenBrackets3
[] = { '{','\0' };
41 static const WCHAR wszCloseBrackets3
[] = { '}','\0' };
42 static const WCHAR wszInvertedComa
[] = { '"','\0' };
43 static const WCHAR wszColon
[] = { ':','\0' };
45 static const WCHAR wszUUID
[] = { 'u','u','i','d','\0' };
46 static const WCHAR wszOdl
[] = { 'o','d','l','\0' };
48 static const WCHAR wszVT_BOOL
[]
49 = { 'V','A','R','I','A','N','T','_','B','O','O','L','\0' };
50 static const WCHAR wszVT_UI1
[]
51 = { 'u','n','s','i','g','n','e','d',' ','c','h','a','r','\0' };
52 static const WCHAR wszVT_UI2
[]
53 = { 'u','n','s','i','g','n','e','d',' ','s','h','o','r','t','\0' };
54 static const WCHAR wszVT_UI4
[]
55 = { 'u','n','s','i','g','n','e','d',' ','l','o','n','g','\0' };
56 static const WCHAR wszVT_UI8
[] = { 'u','i','n','t','6','4','\0' };
57 static const WCHAR wszVT_UINT
[]
58 = { 'u','n','s','i','g','n','e','d',' ','i','n','t','\0' };
59 static const WCHAR wszVT_I1
[] = { 'c','h','a','r','\0' };
60 static const WCHAR wszVT_I2
[] = { 's','h','o','r','t','\0' };
61 static const WCHAR wszVT_I4
[] = { 'l','o','n','g','\0' };
62 static const WCHAR wszVT_I8
[] = { 'i','n','t','6','4','\0' };
63 static const WCHAR wszVT_R4
[] = { 's','i','n','g','l','e','\0' };
64 static const WCHAR wszVT_INT
[] = { 'i','n','t','\0' };
65 static const WCHAR wszVT_BSTR
[] = { 'B','S','T','R','\0' };
66 static const WCHAR wszVT_CY
[] = { 'C','U','R','R','E','N','C','Y','\0' };
67 static const WCHAR wszVT_VARIANT
[] = { 'V','A','R','I','A','N','T','\0' };
68 static const WCHAR wszVT_VOID
[] = { 'v','o','i','d','\0' };
69 static const WCHAR wszVT_ERROR
[] = { 'S','C','O','D','E','\0' };
70 static const WCHAR wszVT_LPSTR
[] = { 'L','P','S','T','R','\0' };
71 static const WCHAR wszVT_LPWSTR
[] = { 'L','P','W','S','T','R','\0' };
73 void AddToStrW(WCHAR
*wszDest
, const WCHAR
*wszSource
)
75 lstrcpyW(&wszDest
[lstrlenW(wszDest
)], wszSource
);
78 void AddToTLDataStrW(TYPELIB_DATA
*pTLData
, const WCHAR
*wszSource
)
80 int SourceLen
= lstrlenW(wszSource
);
82 pTLData
->idl
= HeapReAlloc(GetProcessHeap(), 0, pTLData
->idl
,
83 sizeof(WCHAR
)*(pTLData
->idlLen
+SourceLen
+1));
85 memcpy(&pTLData
->idl
[pTLData
->idlLen
], wszSource
, sizeof(WCHAR
)*(SourceLen
+1));
86 pTLData
->idlLen
+= SourceLen
;
89 LPARAM
InitializeTLData(void)
91 TYPELIB_DATA
*pTLData
;
93 pTLData
= HeapAlloc(GetProcessHeap(), 0, sizeof(TYPELIB_DATA
));
95 memset(pTLData
, 0, sizeof(TYPELIB_DATA
));
96 pTLData
->idl
= HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR
));
97 pTLData
->idl
[0] = '\0';
99 return (LPARAM
)pTLData
;
102 void AddChildrenData(HTREEITEM hParent
, TYPELIB_DATA
*pData
)
107 memset(&tvi
, 0, sizeof(&tvi
));
109 hCur
= TreeView_GetChild(typelib
.hTree
, hParent
);
115 SendMessage(typelib
.hTree
, TVM_GETITEM
, 0, (LPARAM
)&tvi
);
116 if(tvi
.lParam
&& ((TYPELIB_DATA
*)(tvi
.lParam
))->idlLen
)
117 AddToTLDataStrW(pData
, ((TYPELIB_DATA
*)(tvi
.lParam
))->idl
);
118 }while((hCur
= TreeView_GetNextSibling(typelib
.hTree
, hCur
)));
120 AddToTLDataStrW(pData
, pData
->wszInsertAfter
);
123 void CreateTypeInfo(WCHAR
*wszAddTo
, WCHAR
*wszAddAfter
, TYPEDESC tdesc
, ITypeInfo
*pTypeInfo
)
128 ITypeInfo
*pRefTypeInfo
;
129 WCHAR wszBuf
[MAX_LOAD_STRING
];
130 WCHAR wszFormat
[] = { '[','%','l','u',']','\0' };
132 switch(tdesc
.vt
&VT_TYPEMASK
)
134 #define VTADDTOSTR(x) case x:\
135 AddToStrW(wszAddTo, wsz##x);\
151 VTADDTOSTR(VT_VARIANT
);
153 VTADDTOSTR(VT_ERROR
);
154 VTADDTOSTR(VT_LPSTR
);
155 VTADDTOSTR(VT_LPWSTR
);
157 for(i
=0; i
<U(tdesc
).lpadesc
->cDims
; i
++)
159 wsprintfW(wszBuf
, wszFormat
, U(tdesc
).lpadesc
->rgbounds
[i
].cElements
);
160 AddToStrW(wszAddAfter
, wszBuf
);
162 CreateTypeInfo(wszAddTo
, wszAddAfter
, U(tdesc
).lpadesc
->tdescElem
, pTypeInfo
);
165 CreateTypeInfo(wszAddTo
, wszAddAfter
, *U(tdesc
).lptdesc
, pTypeInfo
);
166 AddToStrW(wszAddTo
, wszAsterix
);
169 hRes
= ITypeInfo_GetRefTypeInfo(pTypeInfo
,
170 U(tdesc
).hreftype
, &pRefTypeInfo
);
173 ITypeInfo_GetDocumentation(pRefTypeInfo
, MEMBERID_NIL
,
174 &bstrData
, NULL
, NULL
, NULL
);
175 AddToStrW(wszAddTo
, bstrData
);
176 SysFreeString(bstrData
);
177 ITypeInfo_Release(pRefTypeInfo
);
179 else AddToStrW(wszAddTo
, wszFailed
);
182 WINE_FIXME("tdesc.vt&VT_TYPEMASK == %d not supported\n",
183 tdesc
.vt
&VT_TYPEMASK
);
187 int EnumVars(ITypeInfo
*pTypeInfo
, int cVars
, HTREEITEM hParent
)
193 WCHAR wszText
[MAX_LOAD_STRING
];
194 WCHAR wszAfter
[MAX_LOAD_STRING
];
196 U(tvis
).item
.mask
= TVIF_TEXT
|TVIF_PARAM
;
197 U(tvis
).item
.cchTextMax
= MAX_LOAD_STRING
;
198 U(tvis
).item
.pszText
= wszText
;
199 tvis
.hInsertAfter
= (HTREEITEM
)TVI_LAST
;
200 tvis
.hParent
= hParent
;
202 for(i
=0; i
<cVars
; i
++)
204 if(FAILED(ITypeInfo_GetVarDesc(pTypeInfo
, i
, &pVarDesc
))) continue;
205 if(FAILED(ITypeInfo_GetDocumentation(pTypeInfo
, pVarDesc
->memid
, &bstrName
,
206 NULL
, NULL
, NULL
))) continue;
208 memset(wszText
, 0, sizeof(wszText
));
209 memset(wszAfter
, 0, sizeof(wszAfter
));
210 CreateTypeInfo(wszText
, wszAfter
, pVarDesc
->elemdescVar
.tdesc
, pTypeInfo
);
211 AddToStrW(wszText
, wszSpace
);
212 AddToStrW(wszText
, bstrName
);
213 AddToStrW(wszText
, wszAfter
);
214 U(tvis
).item
.lParam
= InitializeTLData();
215 AddToTLDataStrW((TYPELIB_DATA
*)(U(tvis
).item
.lParam
), wszText
);
216 AddToTLDataStrW((TYPELIB_DATA
*)(U(tvis
).item
.lParam
), wszSemicolon
);
217 AddToTLDataStrW((TYPELIB_DATA
*)(U(tvis
).item
.lParam
), wszNewLine
);
219 SendMessage(typelib
.hTree
, TVM_INSERTITEM
, 0, (LPARAM
)&tvis
);
220 SysFreeString(bstrName
);
221 ITypeInfo_ReleaseVarDesc(pTypeInfo
, pVarDesc
);
227 int EnumFuncs(ITypeInfo
*pTypeInfo
, int cFuncs
, HTREEITEM hParent
)
234 U(tvis
).item
.mask
= TVIF_TEXT
;
235 tvis
.hInsertAfter
= (HTREEITEM
)TVI_LAST
;
236 tvis
.hParent
= hParent
;
238 for(i
=0; i
<cFuncs
; i
++)
240 if(FAILED(ITypeInfo_GetFuncDesc(pTypeInfo
, i
, &pFuncDesc
))) continue;
241 if(FAILED(ITypeInfo_GetDocumentation(pTypeInfo
, pFuncDesc
->memid
, &bstrName
,
242 NULL
, NULL
, NULL
))) continue;
244 U(tvis
).item
.cchTextMax
= SysStringLen(bstrName
);
245 U(tvis
).item
.pszText
= bstrName
;
246 U(tvis
).item
.lParam
= 0;
248 SendMessage(typelib
.hTree
, TVM_INSERTITEM
, 0, (LPARAM
)&tvis
);
249 SysFreeString(bstrName
);
250 ITypeInfo_ReleaseFuncDesc(pTypeInfo
, pFuncDesc
);
256 int EnumImplTypes(ITypeInfo
*pTypeInfo
, int cImplTypes
, HTREEITEM hParent
)
260 ITypeInfo
*pRefTypeInfo
;
264 WCHAR wszInheritedInterfaces
[MAX_LOAD_STRING
];
266 if(!cImplTypes
) return 0;
268 LoadString(globals
.hMainInst
, IDS_INHERITINTERFACES
, wszInheritedInterfaces
,
269 sizeof(WCHAR
[MAX_LOAD_STRING
]));
271 U(tvis
).item
.mask
= TVIF_TEXT
;
272 U(tvis
).item
.cchTextMax
= MAX_LOAD_STRING
;
273 U(tvis
).item
.pszText
= wszInheritedInterfaces
;
274 tvis
.hInsertAfter
= (HTREEITEM
)TVI_LAST
;
275 tvis
.hParent
= hParent
;
277 tvis
.hParent
= TreeView_InsertItem(typelib
.hTree
, &tvis
);
279 for(i
=0; i
<cImplTypes
; i
++)
281 if(FAILED(ITypeInfo_GetRefTypeOfImplType(pTypeInfo
, i
, &hRefType
))) continue;
282 if(FAILED(ITypeInfo_GetRefTypeInfo(pTypeInfo
, hRefType
, &pRefTypeInfo
)))
284 if(FAILED(ITypeInfo_GetDocumentation(pRefTypeInfo
, MEMBERID_NIL
, &bstrName
,
285 NULL
, NULL
, NULL
))) continue;
286 if(FAILED(ITypeInfo_GetTypeAttr(pRefTypeInfo
, &pTypeAttr
))) continue;
288 U(tvis
).item
.cchTextMax
= SysStringLen(bstrName
);
289 U(tvis
).item
.pszText
= bstrName
;
291 hParent
= TreeView_InsertItem(typelib
.hTree
, &tvis
);
292 EnumVars(pRefTypeInfo
, pTypeAttr
->cVars
, hParent
);
293 EnumFuncs(pRefTypeInfo
, pTypeAttr
->cFuncs
, hParent
);
294 EnumImplTypes(pRefTypeInfo
, pTypeAttr
->cImplTypes
, hParent
);
296 SysFreeString(bstrName
);
297 ITypeInfo_ReleaseTypeAttr(pRefTypeInfo
, pTypeAttr
);
298 ITypeInfo_Release(pRefTypeInfo
);
304 void CreateInterfaceInfo(ITypeInfo
*pTypeInfo
, int cImplTypes
, WCHAR
*wszName
,
305 WCHAR
*wszHelpString
, unsigned long ulHelpContext
, TYPEATTR
*pTypeAttr
,
306 TYPELIB_DATA
*pTLData
)
308 ITypeInfo
*pRefTypeInfo
;
311 WCHAR wszGuid
[MAX_LOAD_STRING
];
312 WCHAR wszHelpContext
[MAX_LOAD_STRING
];
315 const WCHAR wszFormat
[] = { '0','x','%','.','8','l','x','\0' };
316 const WCHAR wszInterface
[] = { 'I','n','t','e','r','f','a','c','e',' ','\0' };
317 const WCHAR wszHelpstring
[] = { 'h','e','l','p','s','t','r','i','n','g','\0' };
318 const WCHAR wszHelpcontext
[] = { 'h','e','l','p','c','o','n','t','e','x','t','\0' };
319 const WCHAR wszTYPEFLAG_FAPPOBJECT
[] = { 'a','p','p','o','b','j','e','c','t','\0' };
320 const WCHAR wszTYPEFLAG_FCANCREATE
[] = { 'c','a','n','c','r','e','a','t','e','\0' };
321 const WCHAR wszTYPEFLAG_FLICENSED
[] = { 'l','i','c','e','n','s','e','d','\0' };
322 const WCHAR wszTYPEFLAG_FPREDECLID
[] = { 'p','r','e','d','e','c','l','i','d','\0' };
323 const WCHAR wszTYPEFLAG_FHIDDEN
[] = { 'h','i','d','d','e','n','\0' };
324 const WCHAR wszTYPEFLAG_FCONTROL
[] = { 'c','o','n','t','r','o','l','\0' };
325 const WCHAR wszTYPEFLAG_FDUAL
[] = { 'd','u','a','l','\0' };
326 const WCHAR wszTYPEFLAG_FNONEXTENSIBLE
[]
327 = { 'n','o','n','e','x','t','e','n','s','i','b','l','e','\0' };
328 const WCHAR wszTYPEFLAG_FOLEAUTOMATION
[]
329 = { 'o','l','e','a','u','t','o','m','a','t','i','o','n','\0' };
330 const WCHAR wszTYPEFLAG_FRESTRICTED
[]
331 = { 'r','e','s','t','r','i','c','t','e','d','\0' };
332 const WCHAR wszTYPEFLAG_FAGGREGATABLE
[]
333 = { 'a','g','g','r','e','g','a','t','a','b','l','e','\0' };
334 const WCHAR wszTYPEFLAG_FREPLACEABLE
[]
335 = { 'r','e','p','l','a','c','a','b','l','e','\0' };
336 const WCHAR wszTYPEFLAG_FDISPATCHABLE
[]
337 = { 'd','i','s','p','a','t','c','h','a','b','l','e','\0' };
338 const WCHAR wszTYPEFLAG_FREVERSEBIND
[]
339 = { 'r','e','v','e','r','s','e','b','i','n','d','\0' };
340 const WCHAR wszTYPEFLAG_FPROXY
[] = { 'p','r','o','x','y','\0' };
342 AddToTLDataStrW(pTLData
, wszOpenBrackets1
);
343 AddToTLDataStrW(pTLData
, wszNewLine
);
344 AddToTLDataStrW(pTLData
, wszOdl
);
345 AddToTLDataStrW(pTLData
, wszComa
);
346 AddToTLDataStrW(pTLData
, wszNewLine
);
347 AddToTLDataStrW(pTLData
, wszUUID
);
348 AddToTLDataStrW(pTLData
, wszOpenBrackets2
);
349 StringFromGUID2(&(pTypeAttr
->guid
), wszGuid
, MAX_LOAD_STRING
);
350 wszGuid
[lstrlenW(wszGuid
)-1] = '\0';
351 AddToTLDataStrW(pTLData
, &wszGuid
[1]);
352 AddToTLDataStrW(pTLData
, wszCloseBrackets2
);
355 AddToTLDataStrW(pTLData
, wszComa
);
356 AddToTLDataStrW(pTLData
, wszNewLine
);
357 AddToTLDataStrW(pTLData
, wszHelpstring
);
358 AddToTLDataStrW(pTLData
, wszOpenBrackets2
);
359 AddToTLDataStrW(pTLData
, wszInvertedComa
);
360 AddToTLDataStrW(pTLData
, wszHelpString
);
361 AddToTLDataStrW(pTLData
, wszInvertedComa
);
362 AddToTLDataStrW(pTLData
, wszCloseBrackets2
);
366 AddToTLDataStrW(pTLData
, wszComa
);
367 AddToTLDataStrW(pTLData
, wszNewLine
);
368 AddToTLDataStrW(pTLData
, wszHelpcontext
);
369 AddToTLDataStrW(pTLData
, wszOpenBrackets2
);
370 wsprintfW(wszHelpContext
, wszFormat
, ulHelpContext
);
371 AddToTLDataStrW(pTLData
, wszHelpContext
);
372 AddToTLDataStrW(pTLData
, wszCloseBrackets2
);
374 if(pTypeAttr
->wTypeFlags
)
377 AddToTLDataStrW(pTLData
, wszComa
);
378 AddToTLDataStrW(pTLData
, wszNewLine
);
379 #define ENUM_FLAGS(x) if(pTypeAttr->wTypeFlags & x)\
383 AddToTLDataStrW(pTLData, wszComa);\
384 AddToTLDataStrW(pTLData, wszNewLine);\
387 AddToTLDataStrW(pTLData, wsz##x);\
389 ENUM_FLAGS(TYPEFLAG_FAPPOBJECT
);
390 ENUM_FLAGS(TYPEFLAG_FCANCREATE
);
391 ENUM_FLAGS(TYPEFLAG_FLICENSED
);
392 ENUM_FLAGS(TYPEFLAG_FPREDECLID
);
393 ENUM_FLAGS(TYPEFLAG_FHIDDEN
);
394 ENUM_FLAGS(TYPEFLAG_FCONTROL
);
395 ENUM_FLAGS(TYPEFLAG_FDUAL
);
396 ENUM_FLAGS(TYPEFLAG_FNONEXTENSIBLE
);
397 ENUM_FLAGS(TYPEFLAG_FOLEAUTOMATION
);
398 ENUM_FLAGS(TYPEFLAG_FRESTRICTED
);
399 ENUM_FLAGS(TYPEFLAG_FAGGREGATABLE
);
400 ENUM_FLAGS(TYPEFLAG_FREPLACEABLE
);
401 ENUM_FLAGS(TYPEFLAG_FDISPATCHABLE
);
402 ENUM_FLAGS(TYPEFLAG_FREVERSEBIND
);
403 ENUM_FLAGS(TYPEFLAG_FPROXY
);
405 AddToTLDataStrW(pTLData
, wszNewLine
);
406 AddToTLDataStrW(pTLData
, wszCloseBrackets1
);
407 AddToTLDataStrW(pTLData
, wszNewLine
);
408 AddToTLDataStrW(pTLData
, wszInterface
);
409 AddToTLDataStrW(pTLData
, wszName
);
410 AddToTLDataStrW(pTLData
, wszSpace
);
413 AddToTLDataStrW(pTLData
, wszColon
);
414 AddToTLDataStrW(pTLData
, wszSpace
);
416 ITypeInfo_GetRefTypeOfImplType(pTypeInfo
, 0, &hRefType
);
417 ITypeInfo_GetRefTypeInfo(pTypeInfo
, hRefType
, &pRefTypeInfo
);
418 ITypeInfo_GetDocumentation(pRefTypeInfo
, MEMBERID_NIL
, &bstrName
,
420 AddToTLDataStrW(pTLData
, bstrName
);
421 AddToTLDataStrW(pTLData
, wszSpace
);
423 SysFreeString(bstrName
);
424 ITypeInfo_Release(pRefTypeInfo
);
426 AddToTLDataStrW(pTLData
, wszOpenBrackets3
);
427 AddToTLDataStrW(pTLData
, wszNewLine
);
429 AddToStrW(pTLData
->wszInsertAfter
, wszCloseBrackets3
);
430 AddToStrW(pTLData
->wszInsertAfter
, wszSemicolon
);
431 AddToStrW(pTLData
->wszInsertAfter
, wszNewLine
);
434 int PopulateTree(void)
439 ITypeInfo
*pTypeInfo
, *pRefTypeInfo
;
443 unsigned long ulHelpContext
;
446 WCHAR wszText
[MAX_LOAD_STRING
];
447 WCHAR wszAfter
[MAX_LOAD_STRING
];
451 const WCHAR wszGeneratedInfo
[] = { '/','/',' ','G','e','n','e','r','a','t','e','d',
452 ' ','.','I','D','L',' ','f','i','l','e',' ','(','b','y',' ','t','h','e',' ',
453 'O','L','E','/','C','O','M',' ','O','b','j','e','c','t',' ',
454 'V','i','e','w','e','r',')','\n','/','/','\n','/','/',' ',
455 't','y','p','e','l','i','b',' ','f','i','l','e','n','a','m','e',':',' ','\0'};
457 const WCHAR wszFormat
[] = { '%','s',' ','(','%','s',')','\0' };
458 const WCHAR wszFormat2
[] = { 'v','e','r','s','i','o','n',
459 '(','%','l','d','.','%','l','d',')','\0' };
461 const WCHAR wszTKIND_ENUM
[] = { 't','y','p','e','d','e','f',' ','e','n','u','m',' ','\0' };
462 const WCHAR wszTKIND_RECORD
[]
463 = { 't','y','p','e','d','e','f',' ','s','t','r','u','c','t',' ','\0' };
464 const WCHAR wszTKIND_MODULE
[] = { 'm','o','d','u','l','e',' ','\0' };
465 const WCHAR wszTKIND_INTERFACE
[] = { 'i','n','t','e','r','f','a','c','e',' ','\0' };
466 const WCHAR wszTKIND_DISPATCH
[]
467 = { 'd','i','s','p','i','n','t','e','r','f','a','c','e',' ','\0' };
468 const WCHAR wszTKIND_COCLASS
[] = { 'c','o','c','l','a','s','s',' ','\0' };
469 const WCHAR wszTKIND_ALIAS
[] = { 't','y','p','e','d','e','f',' ','\0' };
470 const WCHAR wszTKIND_UNION
[]
471 = { 't','y','p','e','d','e','f',' ','u','n','i','o','n',' ','\0' };
473 const WCHAR wszHelpString
[] = { 'h','e','l','p','s','t','r','i','n','g','\0' };
474 const WCHAR wszLibrary
[] = { 'l','i','b','r','a','r','y',' ','\0' };
475 const WCHAR wszTag
[] = { 't','a','g','\0' };
477 U(tvis
).item
.mask
= TVIF_TEXT
|TVIF_PARAM
;
478 U(tvis
).item
.cchTextMax
= MAX_LOAD_STRING
;
479 U(tvis
).item
.pszText
= wszText
;
480 tvis
.hInsertAfter
= (HTREEITEM
)TVI_LAST
;
481 tvis
.hParent
= TVI_ROOT
;
483 if(FAILED((hRes
= LoadTypeLib(typelib
.wszFileName
, &pTypeLib
))))
485 WCHAR wszMessage
[MAX_LOAD_STRING
];
486 WCHAR wszError
[MAX_LOAD_STRING
];
488 LoadString(globals
.hMainInst
, IDS_ERROR_LOADTYPELIB
,
489 wszError
, sizeof(WCHAR
[MAX_LOAD_STRING
]));
490 wsprintfW(wszMessage
, wszError
, typelib
.wszFileName
, hRes
);
491 MessageBox(globals
.hMainWnd
, wszMessage
, NULL
, MB_OK
|MB_ICONEXCLAMATION
);
494 count
= ITypeLib_GetTypeInfoCount(pTypeLib
);
496 ITypeLib_GetDocumentation(pTypeLib
, -1, &bstrName
, &bstrData
, NULL
, NULL
);
497 ITypeLib_GetLibAttr(pTypeLib
, &pTLibAttr
);
499 U(tvis
).item
.lParam
= InitializeTLData();
500 AddToTLDataStrW((TYPELIB_DATA
*)(U(tvis
).item
.lParam
), wszGeneratedInfo
);
501 AddToTLDataStrW((TYPELIB_DATA
*)(U(tvis
).item
.lParam
), typelib
.wszFileName
);
502 AddToTLDataStrW((TYPELIB_DATA
*)(U(tvis
).item
.lParam
), wszNewLine
);
503 AddToTLDataStrW((TYPELIB_DATA
*)(U(tvis
).item
.lParam
), wszNewLine
);
504 AddToTLDataStrW((TYPELIB_DATA
*)(U(tvis
).item
.lParam
), wszOpenBrackets1
);
505 AddToTLDataStrW((TYPELIB_DATA
*)(U(tvis
).item
.lParam
), wszNewLine
);
506 AddToTLDataStrW((TYPELIB_DATA
*)(U(tvis
).item
.lParam
), wszUUID
);
507 AddToTLDataStrW((TYPELIB_DATA
*)(U(tvis
).item
.lParam
), wszOpenBrackets2
);
508 StringFromGUID2(&(pTLibAttr
->guid
), wszText
, MAX_LOAD_STRING
);
509 wszText
[lstrlenW(wszText
)-1] = '\0';
510 AddToTLDataStrW((TYPELIB_DATA
*)(U(tvis
).item
.lParam
), &wszText
[1]);
511 AddToTLDataStrW((TYPELIB_DATA
*)(U(tvis
).item
.lParam
), wszCloseBrackets2
);
512 AddToTLDataStrW((TYPELIB_DATA
*)(U(tvis
).item
.lParam
), wszComa
);
513 AddToTLDataStrW((TYPELIB_DATA
*)(U(tvis
).item
.lParam
), wszNewLine
);
514 wsprintfW(wszText
, wszFormat2
, pTLibAttr
->wMajorVerNum
, pTLibAttr
->wMinorVerNum
);
515 AddToTLDataStrW((TYPELIB_DATA
*)(U(tvis
).item
.lParam
), wszText
);
516 AddToTLDataStrW((TYPELIB_DATA
*)(U(tvis
).item
.lParam
), wszComa
);
517 AddToTLDataStrW((TYPELIB_DATA
*)(U(tvis
).item
.lParam
), wszNewLine
);
518 AddToTLDataStrW((TYPELIB_DATA
*)(U(tvis
).item
.lParam
), wszHelpString
);
519 AddToTLDataStrW((TYPELIB_DATA
*)(U(tvis
).item
.lParam
), wszOpenBrackets2
);
520 AddToTLDataStrW((TYPELIB_DATA
*)(U(tvis
).item
.lParam
), bstrData
);
521 AddToTLDataStrW((TYPELIB_DATA
*)(U(tvis
).item
.lParam
), wszCloseBrackets2
);
522 AddToTLDataStrW((TYPELIB_DATA
*)(U(tvis
).item
.lParam
), wszNewLine
);
523 AddToTLDataStrW((TYPELIB_DATA
*)(U(tvis
).item
.lParam
), wszCloseBrackets1
);
524 AddToTLDataStrW((TYPELIB_DATA
*)(U(tvis
).item
.lParam
), wszNewLine
);
525 AddToTLDataStrW((TYPELIB_DATA
*)(U(tvis
).item
.lParam
), wszLibrary
);
526 AddToTLDataStrW((TYPELIB_DATA
*)(U(tvis
).item
.lParam
), bstrName
);
527 AddToTLDataStrW((TYPELIB_DATA
*)(U(tvis
).item
.lParam
), wszNewLine
);
528 AddToTLDataStrW((TYPELIB_DATA
*)(U(tvis
).item
.lParam
), wszOpenBrackets3
);
529 AddToTLDataStrW((TYPELIB_DATA
*)(U(tvis
).item
.lParam
), wszNewLine
);
531 AddToStrW(((TYPELIB_DATA
*)(U(tvis
).item
.lParam
))->wszInsertAfter
, wszCloseBrackets3
);
532 AddToStrW(((TYPELIB_DATA
*)(U(tvis
).item
.lParam
))->wszInsertAfter
, wszSemicolon
);
534 wsprintfW(wszText
, wszFormat
, bstrName
, bstrData
);
535 SysFreeString(bstrName
);
536 SysFreeString(bstrData
);
537 tvis
.hParent
= (HTREEITEM
)SendMessage(typelib
.hTree
,
538 TVM_INSERTITEM
, 0, (LPARAM
)&tvis
);
540 for(i
=0; i
<count
; i
++)
542 ITypeLib_GetTypeInfo(pTypeLib
, i
, &pTypeInfo
);
544 ITypeInfo_GetDocumentation(pTypeInfo
, MEMBERID_NIL
, &bstrName
, &bstrData
,
545 &ulHelpContext
, NULL
);
546 ITypeInfo_GetTypeAttr(pTypeInfo
, &pTypeAttr
);
548 memset(wszText
, 0, sizeof(wszText
));
549 memset(wszAfter
, 0, sizeof(wszAfter
));
550 U(tvis
).item
.lParam
= InitializeTLData();
551 switch(pTypeAttr
->typekind
)
554 AddToStrW(wszText
, wszTKIND_ENUM
);
555 AddToStrW(wszText
, bstrName
);
558 AddToTLDataStrW((TYPELIB_DATA
*)(U(tvis
).item
.lParam
), wszTKIND_RECORD
);
559 AddToTLDataStrW((TYPELIB_DATA
*)(U(tvis
).item
.lParam
), wszTag
);
560 AddToTLDataStrW((TYPELIB_DATA
*)(U(tvis
).item
.lParam
), bstrName
);
561 AddToTLDataStrW((TYPELIB_DATA
*)(U(tvis
).item
.lParam
), wszSpace
);
562 AddToTLDataStrW((TYPELIB_DATA
*)(U(tvis
).item
.lParam
), wszOpenBrackets3
);
563 AddToTLDataStrW((TYPELIB_DATA
*)(U(tvis
).item
.lParam
), wszNewLine
);
565 AddToStrW(((TYPELIB_DATA
*)(U(tvis
).item
.lParam
))->wszInsertAfter
,
567 AddToStrW(((TYPELIB_DATA
*)(U(tvis
).item
.lParam
))->wszInsertAfter
,
569 AddToStrW(((TYPELIB_DATA
*)(U(tvis
).item
.lParam
))->wszInsertAfter
,
571 AddToStrW(((TYPELIB_DATA
*)(U(tvis
).item
.lParam
))->wszInsertAfter
,
573 AddToStrW(((TYPELIB_DATA
*)(U(tvis
).item
.lParam
))->wszInsertAfter
,
576 AddToStrW(wszText
, wszTKIND_RECORD
);
577 AddToStrW(wszText
, bstrName
);
580 AddToStrW(wszText
, wszTKIND_MODULE
);
581 AddToStrW(wszText
, bstrName
);
583 case TKIND_INTERFACE
:
584 CreateInterfaceInfo(pTypeInfo
, pTypeAttr
->cImplTypes
, bstrName
,
585 bstrData
, ulHelpContext
, pTypeAttr
,
586 (TYPELIB_DATA
*)(U(tvis
).item
.lParam
));
588 AddToStrW(wszText
, wszTKIND_INTERFACE
);
589 AddToStrW(wszText
, bstrName
);
592 AddToStrW(wszText
, wszTKIND_COCLASS
);
593 AddToStrW(wszText
, bstrName
);
596 AddToStrW(wszText
, wszTKIND_UNION
);
597 AddToStrW(wszText
, bstrName
);
600 AddToStrW(wszText
, wszTKIND_DISPATCH
);
601 AddToStrW(wszText
, bstrName
);
602 if(SUCCEEDED(ITypeInfo_GetRefTypeOfImplType(pTypeInfo
, -1, &hRefType
)))
604 hParent
= TreeView_InsertItem(typelib
.hTree
, &tvis
);
605 EnumImplTypes(pTypeInfo
, pTypeAttr
->cImplTypes
, hParent
);
606 memset(wszText
, 0, sizeof(wszText
));
607 U(tvis
).item
.lParam
= InitializeTLData();
609 SysFreeString(bstrName
);
610 SysFreeString(bstrData
);
612 ITypeInfo_GetRefTypeInfo(pTypeInfo
, hRefType
, &pRefTypeInfo
);
613 ITypeInfo_GetDocumentation(pRefTypeInfo
, MEMBERID_NIL
, &bstrName
,
614 &bstrData
, &ulHelpContext
, NULL
);
616 CreateInterfaceInfo(pTypeInfo
, pTypeAttr
->cImplTypes
, bstrName
,
617 bstrData
, ulHelpContext
, pTypeAttr
,
618 (TYPELIB_DATA
*)(U(tvis
).item
.lParam
));
620 AddToStrW(wszText
, wszTKIND_INTERFACE
);
621 AddToStrW(wszText
, bstrName
);
622 ITypeInfo_Release(pRefTypeInfo
);
626 AddToStrW(wszText
, wszTKIND_ALIAS
);
627 CreateTypeInfo(wszText
, wszAfter
, pTypeAttr
->tdescAlias
, pTypeInfo
);
628 AddToStrW(wszText
, wszSpace
);
629 AddToStrW(wszText
, bstrName
);
630 AddToStrW(wszText
, wszAfter
);
633 lstrcpyW(wszText
, bstrName
);
634 WINE_FIXME("pTypeAttr->typekind == %d\n not supported",
635 pTypeAttr
->typekind
);
637 hParent
= TreeView_InsertItem(typelib
.hTree
, &tvis
);
639 EnumVars(pTypeInfo
, pTypeAttr
->cVars
, hParent
);
640 EnumFuncs(pTypeInfo
, pTypeAttr
->cFuncs
, hParent
);
641 EnumImplTypes(pTypeInfo
, pTypeAttr
->cImplTypes
, hParent
);
643 AddChildrenData(hParent
, (TYPELIB_DATA
*)(U(tvis
).item
.lParam
));
645 ITypeInfo_ReleaseTypeAttr(pTypeInfo
, pTypeAttr
);
646 ITypeInfo_Release(pTypeInfo
);
647 SysFreeString(bstrName
);
648 SysFreeString(bstrData
);
650 SendMessage(typelib
.hTree
, TVM_EXPAND
, TVE_EXPAND
, (LPARAM
)tvis
.hParent
);
652 ITypeLib_Release(pTypeLib
);
656 void UpdateData(HTREEITEM item
)
660 memset(&tvi
, 0, sizeof(TVITEM
));
661 tvi
.mask
= TVIF_PARAM
;
664 SendMessage(typelib
.hTree
, TVM_GETITEM
, 0, (LPARAM
)&tvi
);
667 SetWindowText(typelib
.hEdit
, wszSpace
);
671 SetWindowText(typelib
.hEdit
, ((TYPELIB_DATA
*)tvi
.lParam
)->idl
);
674 void TypeLibResizeChild(void)
678 MoveWindow(typelib
.hStatusBar
, 0, 0, 0, 0, TRUE
);
680 if(IsWindowVisible(typelib
.hStatusBar
))
681 GetClientRect(typelib
.hStatusBar
, &stat
);
682 else stat
.bottom
= 0;
684 GetClientRect(globals
.hTypeLibWnd
, &client
);
685 MoveWindow(typelib
.hPaneWnd
, 0, 0,
686 client
.right
, client
.bottom
-stat
.bottom
, TRUE
);
689 void TypeLibMenuCommand(WPARAM wParam
, HWND hWnd
)
696 vis
= IsWindowVisible(typelib
.hStatusBar
);
697 ShowWindow(typelib
.hStatusBar
, vis
? SW_HIDE
: SW_SHOW
);
698 CheckMenuItem(GetMenu(hWnd
), LOWORD(wParam
),
699 vis
? MF_UNCHECKED
: MF_CHECKED
);
700 TypeLibResizeChild();
708 void UpdateTypeLibStatusBar(int itemID
)
710 WCHAR info
[MAX_LOAD_STRING
];
712 if(!LoadString(globals
.hMainInst
, itemID
, info
, sizeof(WCHAR
[MAX_LOAD_STRING
])))
713 LoadString(globals
.hMainInst
, IDS_READY
, info
, sizeof(WCHAR
[MAX_LOAD_STRING
]));
715 SendMessage(typelib
.hStatusBar
, SB_SETTEXT
, 0, (LPARAM
)info
);
718 void EmptyTLTree(void)
723 tvi
.mask
= TVIF_PARAM
;
724 cur
= TreeView_GetChild(typelib
.hTree
, TVI_ROOT
);
729 cur
= TreeView_GetChild(typelib
.hTree
, del
);
731 if(!cur
) cur
= TreeView_GetNextSibling(typelib
.hTree
, del
);
732 if(!cur
) cur
= TreeView_GetParent(typelib
.hTree
, del
);
735 SendMessage(typelib
.hTree
, TVM_GETITEM
, 0, (LPARAM
)&tvi
);
738 HeapFree(GetProcessHeap(), 0, ((TYPELIB_DATA
*)tvi
.lParam
)->idl
);
739 HeapFree(GetProcessHeap(), 0, (TYPELIB_DATA
*)tvi
.lParam
);
742 SendMessage(typelib
.hTree
, TVM_DELETEITEM
, 0, (LPARAM
)del
);
748 LRESULT CALLBACK
TypeLibProc(HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
754 if(!CreatePanedWindow(hWnd
, &typelib
.hPaneWnd
, globals
.hMainInst
))
756 typelib
.hTree
= CreateWindowEx(WS_EX_CLIENTEDGE
, WC_TREEVIEW
, NULL
,
757 WS_CHILD
|WS_VISIBLE
|TVS_HASLINES
|TVS_HASBUTTONS
|TVS_LINESATROOT
,
758 0, 0, 0, 0, typelib
.hPaneWnd
, (HMENU
)TYPELIB_TREE
,
759 globals
.hMainInst
, NULL
);
760 typelib
.hEdit
= CreateWindowEx(WS_EX_CLIENTEDGE
, WC_EDIT
, NULL
,
761 WS_CHILD
|WS_VISIBLE
|ES_MULTILINE
|ES_READONLY
|WS_HSCROLL
|WS_VSCROLL
,
762 0, 0, 0, 0, typelib
.hPaneWnd
, NULL
, globals
.hMainInst
, NULL
);
764 SetLeft(typelib
.hPaneWnd
, typelib
.hTree
);
765 SetRight(typelib
.hPaneWnd
, typelib
.hEdit
);
767 if(PopulateTree()) DestroyWindow(hWnd
);
768 else SetFocus(typelib
.hTree
);
772 TypeLibMenuCommand(LOWORD(wParam
), hWnd
);
774 UpdateTypeLibStatusBar(LOWORD(wParam
));
777 SetFocus(typelib
.hTree
);
780 if(wParam
== SIZE_MINIMIZED
) break;
781 TypeLibResizeChild();
787 return DefWindowProc(hWnd
, uMsg
, wParam
, lParam
);
792 BOOL
TypeLibRegisterClass(void)
796 memset(&wcc
, 0, sizeof(WNDCLASS
));
797 wcc
.lpfnWndProc
= TypeLibProc
;
798 wcc
.hbrBackground
= (HBRUSH
)(COLOR_WINDOW
+1);
799 wcc
.lpszMenuName
= MAKEINTRESOURCE(IDM_TYPELIB
);
800 wcc
.lpszClassName
= wszTypeLib
;
802 if(!RegisterClass(&wcc
))
808 BOOL
CreateTypeLibWindow(HINSTANCE hInst
, WCHAR
*wszFileName
)
810 WCHAR wszTitle
[MAX_LOAD_STRING
];
811 LoadString(hInst
, IDS_TYPELIBTITLE
, wszTitle
, sizeof(WCHAR
[MAX_LOAD_STRING
]));
813 if(wszFileName
) lstrcpyW(typelib
.wszFileName
, wszFileName
);
818 memset(&tvi
, 0, sizeof(TVITEM
));
819 tvi
.hItem
= TreeView_GetSelection(globals
.hTree
);
821 SendMessage(globals
.hTree
, TVM_GETITEM
, 0, (LPARAM
)&tvi
);
822 lstrcpyW(typelib
.wszFileName
, ((ITEM_INFO
*)tvi
.lParam
)->path
);
825 globals
.hTypeLibWnd
= CreateWindow(wszTypeLib
, wszTitle
,
826 WS_OVERLAPPEDWINDOW
|WS_VISIBLE
,
827 CW_USEDEFAULT
, CW_USEDEFAULT
, 800, 600, NULL
, NULL
, hInst
, NULL
);
828 if(!globals
.hTypeLibWnd
) return FALSE
;
830 typelib
.hStatusBar
= CreateStatusWindow(WS_VISIBLE
|WS_CHILD
,
831 (LPWSTR
)wszTitle
, globals
.hTypeLibWnd
, 0);
833 TypeLibResizeChild();