oleview: Improved interface handling in idl viewer.
[wine/wine-kai.git] / programs / oleview / typelib.c
blobf9b8d28ab405db25c9aa6f7b4ef81d14c806b313
1 /*
2 * OleView (typelib.c)
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
21 #include "main.h"
23 #include "wine/debug.h"
25 WINE_DEFAULT_DEBUG_CHANNEL(oleview);
27 TYPELIB typelib;
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)
104 HTREEITEM hCur;
105 TVITEM tvi;
107 memset(&tvi, 0, sizeof(&tvi));
109 hCur = TreeView_GetChild(typelib.hTree, hParent);
110 if(!hCur) return;
114 tvi.hItem = hCur;
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)
125 int i;
126 BSTR bstrData;
127 HRESULT hRes;
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);\
136 break
137 VTADDTOSTR(VT_BOOL);
138 VTADDTOSTR(VT_UI1);
139 VTADDTOSTR(VT_UI2);
140 VTADDTOSTR(VT_UI4);
141 VTADDTOSTR(VT_UI8);
142 VTADDTOSTR(VT_UINT);
143 VTADDTOSTR(VT_I1);
144 VTADDTOSTR(VT_I2);
145 VTADDTOSTR(VT_I4);
146 VTADDTOSTR(VT_I8);
147 VTADDTOSTR(VT_R4);
148 VTADDTOSTR(VT_INT);
149 VTADDTOSTR(VT_BSTR);
150 VTADDTOSTR(VT_CY);
151 VTADDTOSTR(VT_VARIANT);
152 VTADDTOSTR(VT_VOID);
153 VTADDTOSTR(VT_ERROR);
154 VTADDTOSTR(VT_LPSTR);
155 VTADDTOSTR(VT_LPWSTR);
156 case VT_CARRAY:
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);
163 break;
164 case VT_PTR:
165 CreateTypeInfo(wszAddTo, wszAddAfter, *U(tdesc).lptdesc, pTypeInfo);
166 AddToStrW(wszAddTo, wszAsterix);
167 break;
168 case VT_USERDEFINED:
169 hRes = ITypeInfo_GetRefTypeInfo(pTypeInfo,
170 U(tdesc).hreftype, &pRefTypeInfo);
171 if(SUCCEEDED(hRes))
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);
180 break;
181 default:
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)
189 int i;
190 TVINSERTSTRUCT tvis;
191 VARDESC *pVarDesc;
192 BSTR bstrName;
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);
224 return 0;
227 int EnumFuncs(ITypeInfo *pTypeInfo, int cFuncs, HTREEITEM hParent)
229 int i;
230 TVINSERTSTRUCT tvis;
231 FUNCDESC *pFuncDesc;
232 BSTR bstrName;
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);
253 return 0;
256 int EnumImplTypes(ITypeInfo *pTypeInfo, int cImplTypes, HTREEITEM hParent)
258 int i;
259 TVINSERTSTRUCT tvis;
260 ITypeInfo *pRefTypeInfo;
261 HREFTYPE hRefType;
262 TYPEATTR *pTypeAttr;
263 BSTR bstrName;
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)))
283 continue;
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);
301 return 0;
304 void CreateInterfaceInfo(ITypeInfo *pTypeInfo, int cImplTypes, WCHAR *wszName,
305 WCHAR *wszHelpString, unsigned long ulHelpContext, TYPEATTR *pTypeAttr,
306 TYPELIB_DATA *pTLData)
308 ITypeInfo *pRefTypeInfo;
309 HREFTYPE hRefType;
310 BSTR bstrName;
311 WCHAR wszGuid[MAX_LOAD_STRING];
312 WCHAR wszHelpContext[MAX_LOAD_STRING];
313 BOOL bFirst;
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);
353 if(wszHelpString)
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);
364 if(ulHelpContext)
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)
376 bFirst = TRUE;
377 AddToTLDataStrW(pTLData, wszComa);
378 AddToTLDataStrW(pTLData, wszNewLine);
379 #define ENUM_FLAGS(x) if(pTypeAttr->wTypeFlags & x)\
381 if(!bFirst)\
383 AddToTLDataStrW(pTLData, wszComa);\
384 AddToTLDataStrW(pTLData, wszNewLine);\
386 bFirst = FALSE;\
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);
411 if(cImplTypes)
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,
419 NULL, NULL, NULL);
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)
436 TVINSERTSTRUCT tvis;
437 ITypeLib *pTypeLib;
438 TLIBATTR *pTLibAttr;
439 ITypeInfo *pTypeInfo, *pRefTypeInfo;
440 HREFTYPE hRefType;
441 TYPEATTR *pTypeAttr;
442 INT count, i;
443 unsigned long ulHelpContext;
444 BSTR bstrName;
445 BSTR bstrData;
446 WCHAR wszText[MAX_LOAD_STRING];
447 WCHAR wszAfter[MAX_LOAD_STRING];
448 HRESULT hRes;
449 HTREEITEM hParent;
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);
492 return 1;
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)
553 case TKIND_ENUM:
554 AddToStrW(wszText, wszTKIND_ENUM);
555 AddToStrW(wszText, bstrName);
556 break;
557 case TKIND_RECORD:
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,
566 wszCloseBrackets3);
567 AddToStrW(((TYPELIB_DATA*)(U(tvis).item.lParam))->wszInsertAfter,
568 wszSpace);
569 AddToStrW(((TYPELIB_DATA*)(U(tvis).item.lParam))->wszInsertAfter,
570 bstrName);
571 AddToStrW(((TYPELIB_DATA*)(U(tvis).item.lParam))->wszInsertAfter,
572 wszSemicolon);
573 AddToStrW(((TYPELIB_DATA*)(U(tvis).item.lParam))->wszInsertAfter,
574 wszNewLine);
576 AddToStrW(wszText, wszTKIND_RECORD);
577 AddToStrW(wszText, bstrName);
578 break;
579 case TKIND_MODULE:
580 AddToStrW(wszText, wszTKIND_MODULE);
581 AddToStrW(wszText, bstrName);
582 break;
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);
590 break;
591 case TKIND_COCLASS:
592 AddToStrW(wszText, wszTKIND_COCLASS);
593 AddToStrW(wszText, bstrName);
594 break;
595 case TKIND_UNION:
596 AddToStrW(wszText, wszTKIND_UNION);
597 AddToStrW(wszText, bstrName);
598 break;
599 case TKIND_DISPATCH:
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);
624 break;
625 case TKIND_ALIAS:
626 AddToStrW(wszText, wszTKIND_ALIAS);
627 CreateTypeInfo(wszText, wszAfter, pTypeAttr->tdescAlias, pTypeInfo);
628 AddToStrW(wszText, wszSpace);
629 AddToStrW(wszText, bstrName);
630 AddToStrW(wszText, wszAfter);
631 break;
632 default:
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);
653 return 0;
656 void UpdateData(HTREEITEM item)
658 TVITEM tvi;
660 memset(&tvi, 0, sizeof(TVITEM));
661 tvi.mask = TVIF_PARAM;
662 tvi.hItem = item;
664 SendMessage(typelib.hTree, TVM_GETITEM, 0, (LPARAM)&tvi);
665 if(!tvi.lParam)
667 SetWindowText(typelib.hEdit, wszSpace);
668 return;
671 SetWindowText(typelib.hEdit, ((TYPELIB_DATA*)tvi.lParam)->idl);
674 void TypeLibResizeChild(void)
676 RECT client, stat;
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)
691 BOOL vis;
693 switch(wParam)
695 case IDM_STATUSBAR:
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();
701 break;
702 case IDM_CLOSE:
703 DestroyWindow(hWnd);
704 break;
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)
720 HTREEITEM cur, del;
721 TVITEM tvi;
723 tvi.mask = TVIF_PARAM;
724 cur = TreeView_GetChild(typelib.hTree, TVI_ROOT);
726 while(TRUE)
728 del = cur;
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);
734 tvi.hItem = del;
735 SendMessage(typelib.hTree, TVM_GETITEM, 0, (LPARAM)&tvi);
736 if(tvi.lParam)
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);
744 if(!cur) break;
748 LRESULT CALLBACK TypeLibProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
750 switch(uMsg)
752 case WM_CREATE:
754 if(!CreatePanedWindow(hWnd, &typelib.hPaneWnd, globals.hMainInst))
755 DestroyWindow(hWnd);
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);
769 break;
771 case WM_COMMAND:
772 TypeLibMenuCommand(LOWORD(wParam), hWnd);
773 case WM_MENUSELECT:
774 UpdateTypeLibStatusBar(LOWORD(wParam));
775 break;
776 case WM_SETFOCUS:
777 SetFocus(typelib.hTree);
778 break;
779 case WM_SIZE:
780 if(wParam == SIZE_MINIMIZED) break;
781 TypeLibResizeChild();
782 break;
783 case WM_DESTROY:
784 EmptyTLTree();
785 break;
786 default:
787 return DefWindowProc(hWnd, uMsg, wParam, lParam);
789 return 0;
792 BOOL TypeLibRegisterClass(void)
794 WNDCLASS wcc;
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))
803 return FALSE;
805 return TRUE;
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);
814 else
816 TVITEM tvi;
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();
834 return TRUE;