kernel32: Implement GetCurrentThreadStackLimits.
[wine.git] / programs / oleview / typelib.c
blob99de87b43be23194bae5bf1bdb2f5665080ffb4f
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"
24 #include "wine/unicode.h"
26 WINE_DEFAULT_DEBUG_CHANNEL(oleview);
28 TYPELIB typelib;
29 static const WCHAR wszTypeLib[] = { 'T','Y','P','E','L','I','B','\0' };
31 static const WCHAR wszFailed[] = { '<','f','a','i','l','e','d','>','\0' };
32 static const WCHAR wszSpace[] = { ' ','\0' };
33 static const WCHAR wszAsterix[] = { '*','\0' };
34 static const WCHAR wszComa[] = { ',','\0' };
35 static const WCHAR wszEquals[] = { '=','\0' };
36 static const WCHAR wszSemicolon[] = { ';','\0' };
37 static const WCHAR wszNewLine[] = { '\n','\0' };
38 static const WCHAR wszOpenBrackets1[] = { '[','\0' };
39 static const WCHAR wszCloseBrackets1[] = { ']','\0' };
40 static const WCHAR wszOpenBrackets2[] = { '(','\0' };
41 static const WCHAR wszCloseBrackets2[] = { ')','\0' };
42 static const WCHAR wszOpenBrackets3[] = { '{','\0' };
43 static const WCHAR wszCloseBrackets3[] = { '}','\0' };
44 static const WCHAR wszInvertedComa[] = { '"','\0' };
45 static const WCHAR wszColon[] = { ':','\0' };
47 static const WCHAR wszUUID[] = { 'u','u','i','d','\0' };
48 static const WCHAR wszOdl[] = { 'o','d','l','\0' };
50 static const WCHAR wszVT_BOOL[]
51 = { 'V','A','R','I','A','N','T','_','B','O','O','L','\0' };
52 static const WCHAR wszVT_UI1[]
53 = { 'u','n','s','i','g','n','e','d',' ','c','h','a','r','\0' };
54 static const WCHAR wszVT_UI2[]
55 = { 'u','n','s','i','g','n','e','d',' ','s','h','o','r','t','\0' };
56 static const WCHAR wszVT_UI4[]
57 = { 'u','n','s','i','g','n','e','d',' ','l','o','n','g','\0' };
58 static const WCHAR wszVT_UI8[] = { 'u','i','n','t','6','4','\0' };
59 static const WCHAR wszVT_UINT[]
60 = { 'u','n','s','i','g','n','e','d',' ','i','n','t','\0' };
61 static const WCHAR wszVT_I1[] = { 'c','h','a','r','\0' };
62 static const WCHAR wszVT_I2[] = { 's','h','o','r','t','\0' };
63 static const WCHAR wszVT_I4[] = { 'l','o','n','g','\0' };
64 static const WCHAR wszVT_I8[] = { 'i','n','t','6','4','\0' };
65 static const WCHAR wszVT_R4[] = { 's','i','n','g','l','e','\0' };
66 static const WCHAR wszVT_INT[] = { 'i','n','t','\0' };
67 static const WCHAR wszVT_BSTR[] = { 'B','S','T','R','\0' };
68 static const WCHAR wszVT_CY[] = { 'C','U','R','R','E','N','C','Y','\0' };
69 static const WCHAR wszVT_VARIANT[] = { 'V','A','R','I','A','N','T','\0' };
70 static const WCHAR wszVT_VOID[] = { 'v','o','i','d','\0' };
71 static const WCHAR wszVT_ERROR[] = { 'S','C','O','D','E','\0' };
72 static const WCHAR wszVT_LPSTR[] = { 'L','P','S','T','R','\0' };
73 static const WCHAR wszVT_LPWSTR[] = { 'L','P','W','S','T','R','\0' };
74 static const WCHAR wszVT_HRESULT[] = { 'H','R','E','S','U','L','T','\0' };
75 static const WCHAR wszVT_UNKNOWN[] = { 'I','U','n','k','n','o','w','n','\0' };
76 static const WCHAR wszVT_DISPATCH[] = { 'I','D','i','s','p','a','t','c','h','\0' };
77 static const WCHAR wszVT_DATE[] = { 'D','A','T','E','\0' };
78 static const WCHAR wszVT_R8[] = { 'd','o','u','b','l','e','\0' };
79 static const WCHAR wszVT_SAFEARRAY[] = { 'S','A','F','E','A','R','R','A','Y','\0' };
81 static const WCHAR wszFormat[] = { '0','x','%','.','8','l','x','\0' };
82 static const WCHAR wszStdCall[] = { '_','s','t','d','c','a','l','l','\0' };
83 static const WCHAR wszId[] = { 'i','d','\0' };
84 static const WCHAR wszHelpstring[] = { 'h','e','l','p','s','t','r','i','n','g','\0' };
85 static const WCHAR wszPropPut[] = { 'p','r','o','p','p','u','t','\0' };
86 static const WCHAR wszPropGet[] = { 'p','r','o','p','g','e','t','\0' };
87 static const WCHAR wszPropPutRef[] = { 'p','r','o','p','p','u','t','r','e','f','\0' };
88 static const WCHAR wszPARAMFLAG_FIN[] = { 'i','n','\0' };
89 static const WCHAR wszPARAMFLAG_FOUT[] = { 'o','u','t','\0' };
90 static const WCHAR wszPARAMFLAG_FLCID[] = { 'c','i','d','\0' };
91 static const WCHAR wszPARAMFLAG_FRETVAL[] = { 'r','e','t','v','a','l','\0' };
92 static const WCHAR wszPARAMFLAG_FOPT[] = { 'o','p','t','i','o','n','a','l','\0' };
93 static const WCHAR wszPARAMFLAG_FHASCUSTDATA[]
94 = { 'h','a','s','c','u','s','t','d','a','t','a','\0' };
95 static const WCHAR wszDefaultValue[]
96 = { 'd','e','f','a','u','l','t','v','a','l','u','e','\0' };
98 static const WCHAR wszReadOnly[] = { 'r','e','a','d','o','n','l','y','\0' };
99 static const WCHAR wszConst[] = { 'c','o','n','s','t','\0' };
101 static void ShowLastError(void)
103 DWORD error = GetLastError();
104 LPWSTR lpMsgBuf;
105 WCHAR wszTitle[MAX_LOAD_STRING];
107 LoadStringW(globals.hMainInst, IDS_TYPELIBTITLE, wszTitle, ARRAY_SIZE(wszTitle));
108 FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
109 NULL, error, 0, (LPWSTR)&lpMsgBuf, 0, NULL);
110 MessageBoxW(NULL, lpMsgBuf, wszTitle, MB_OK | MB_ICONERROR);
111 LocalFree(lpMsgBuf);
112 return;
115 static void SaveIdl(WCHAR *wszFileName)
117 HTREEITEM hIDL;
118 TVITEMW tvi;
119 HANDLE hFile;
120 DWORD len, dwNumWrite;
121 char *wszIdl;
122 TYPELIB_DATA *data;
124 hIDL = (HTREEITEM)SendMessageW(typelib.hTree, TVM_GETNEXTITEM,
125 TVGN_CHILD, (LPARAM)TVI_ROOT);
127 memset(&tvi, 0, sizeof(TVITEMW));
128 tvi.hItem = hIDL;
130 SendMessageW(typelib.hTree, TVM_GETITEMW, 0, (LPARAM)&tvi);
131 data = (TYPELIB_DATA *)tvi.lParam;
133 hFile = CreateFileW(wszFileName, GENERIC_WRITE, FILE_SHARE_WRITE,
134 NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
135 if(hFile == INVALID_HANDLE_VALUE)
137 ShowLastError();
138 return;
141 len = WideCharToMultiByte( CP_UTF8, 0, data->idl, data->idlLen, NULL, 0, NULL, NULL );
142 wszIdl = HeapAlloc(GetProcessHeap(), 0, len);
143 WideCharToMultiByte( CP_UTF8, 0, data->idl, data->idlLen, wszIdl, len, NULL, NULL );
145 if(!WriteFile(hFile, wszIdl, len, &dwNumWrite, NULL))
146 ShowLastError();
148 HeapFree(GetProcessHeap(), 0, wszIdl);
149 CloseHandle(hFile);
152 static void GetSaveIdlAsPath(void)
154 OPENFILENAMEW saveidl;
155 WCHAR *pFileName;
156 WCHAR wszPath[MAX_LOAD_STRING];
157 WCHAR wszDir[MAX_LOAD_STRING];
158 static const WCHAR wszDefaultExt[] = { 'i','d','l',0 };
159 static const WCHAR wszIdlFiles[] = { '*','.','i','d','l','\0','\0' };
161 memset(&saveidl, 0, sizeof(saveidl));
163 lstrcpyW(wszDir, typelib.wszFileName);
164 pFileName = wszDir + lstrlenW(wszDir);
165 while(*pFileName != '.' && *pFileName != '\\' && *pFileName != '/'
166 && pFileName > wszDir) pFileName -= 1;
167 if(*pFileName == '.')
169 *pFileName = '\0';
170 while(*pFileName != '\\' && *pFileName != '/' && pFileName > wszDir)
171 pFileName -= 1;
173 if(*pFileName == '\\' || *pFileName == '/') pFileName += 1;
174 lstrcpyW(wszPath, pFileName);
176 GetCurrentDirectoryW(MAX_LOAD_STRING, wszDir);
178 saveidl.lStructSize = sizeof(OPENFILENAMEW);
179 saveidl.hwndOwner = globals.hTypeLibWnd;
180 saveidl.hInstance = globals.hMainInst;
181 saveidl.lpstrFilter = wszIdlFiles;
182 saveidl.lpstrFile = wszPath;
183 saveidl.nMaxFile = MAX_LOAD_STRING;
184 saveidl.lpstrInitialDir = wszDir;
185 saveidl.Flags = OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY;
186 saveidl.lpstrDefExt = wszDefaultExt;
188 if (GetSaveFileNameW(&saveidl))
189 SaveIdl(wszPath);
192 static void AddToStrW(WCHAR *wszDest, const WCHAR *wszSource)
194 lstrcpyW(&wszDest[lstrlenW(wszDest)], wszSource);
197 static void AddToTLDataStrW(TYPELIB_DATA *pTLData, const WCHAR *wszSource)
199 int SourceLen = lstrlenW(wszSource);
201 pTLData->idl = HeapReAlloc(GetProcessHeap(), 0, pTLData->idl,
202 sizeof(WCHAR)*(pTLData->idlLen+SourceLen+1));
204 memcpy(&pTLData->idl[pTLData->idlLen], wszSource, sizeof(WCHAR)*(SourceLen+1));
205 pTLData->idlLen += SourceLen;
208 static void AddToTLDataStrWithTabsW(TYPELIB_DATA *pTLData, WCHAR *wszSource)
210 int lineLen = lstrlenW(wszSource);
211 int newLinesNo = 0;
212 WCHAR *pSourcePos = wszSource;
213 WCHAR *pSourceBeg;
215 if(!lineLen) return;
216 while(*pSourcePos)
218 if(*pSourcePos == *wszNewLine) newLinesNo++;
219 pSourcePos += 1;
221 if(*(pSourcePos - 1) != *wszNewLine) newLinesNo++;
223 pTLData->idl = HeapReAlloc(GetProcessHeap(), 0, pTLData->idl,
224 sizeof(WCHAR)*(pTLData->idlLen+lineLen+4*newLinesNo+1));
226 pSourcePos = wszSource;
227 pSourceBeg = wszSource;
228 while(newLinesNo)
230 if(*pSourcePos != *wszNewLine && *pSourcePos)
232 pSourcePos += 1;
233 continue;
235 newLinesNo--;
237 if(*pSourcePos)
239 *pSourcePos = '\0';
240 lineLen = lstrlenW(pSourceBeg)+1;
241 *pSourcePos = '\n';
242 pSourcePos += 1;
244 else lineLen = lstrlenW(pSourceBeg);
246 pTLData->idl[pTLData->idlLen] = *wszSpace;
247 pTLData->idl[pTLData->idlLen+1] = *wszSpace;
248 pTLData->idl[pTLData->idlLen+2] = *wszSpace;
249 pTLData->idl[pTLData->idlLen+3] = *wszSpace;
250 memcpy(&pTLData->idl[pTLData->idlLen+4], pSourceBeg, sizeof(WCHAR)*lineLen);
251 pTLData->idlLen += lineLen + 4;
252 pTLData->idl[pTLData->idlLen] = '\0';
254 pSourceBeg = pSourcePos;
258 static TYPELIB_DATA *InitializeTLData(void)
260 TYPELIB_DATA *pTLData;
262 pTLData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(TYPELIB_DATA));
264 pTLData->idl = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR));
265 pTLData->idl[0] = '\0';
267 return pTLData;
270 static void AddSpaces(TYPELIB_DATA *pTLData, int tabSize)
272 for(; tabSize>0; tabSize--)
273 AddToTLDataStrW(pTLData, wszSpace);
276 static void AddChildrenData(HTREEITEM hParent, TYPELIB_DATA *pData)
278 HTREEITEM hCur;
279 TVITEMW tvi;
281 memset(&tvi, 0, sizeof(tvi));
283 hCur = (HTREEITEM)SendMessageW(typelib.hTree, TVM_GETNEXTITEM,
284 TVGN_CHILD, (LPARAM)hParent);
285 if(!hCur) return;
289 tvi.hItem = hCur;
290 SendMessageW(typelib.hTree, TVM_GETITEMW, 0, (LPARAM)&tvi);
291 if(tvi.lParam && ((TYPELIB_DATA *)(tvi.lParam))->idlLen)
292 AddToTLDataStrWithTabsW(pData, ((TYPELIB_DATA *)(tvi.lParam))->idl);
293 } while((hCur = (HTREEITEM)SendMessageW(typelib.hTree, TVM_GETNEXTITEM,
294 TVGN_NEXT, (LPARAM)hCur)));
297 static void CreateTypeInfo(WCHAR *wszAddTo, WCHAR *wszAddAfter, TYPEDESC tdesc, ITypeInfo *pTypeInfo)
299 int i;
300 BSTR bstrData;
301 HRESULT hRes;
302 ITypeInfo *pRefTypeInfo;
303 WCHAR wszBuf[MAX_LOAD_STRING];
304 WCHAR wszFormat[] = { '[','%','l','u',']','\0' };
306 switch(tdesc.vt&VT_TYPEMASK)
308 #define VTADDTOSTR(x) case x:\
309 AddToStrW(wszAddTo, wsz##x);\
310 break
311 VTADDTOSTR(VT_BOOL);
312 VTADDTOSTR(VT_UI1);
313 VTADDTOSTR(VT_UI2);
314 VTADDTOSTR(VT_UI4);
315 VTADDTOSTR(VT_UI8);
316 VTADDTOSTR(VT_UINT);
317 VTADDTOSTR(VT_I1);
318 VTADDTOSTR(VT_I2);
319 VTADDTOSTR(VT_I4);
320 VTADDTOSTR(VT_I8);
321 VTADDTOSTR(VT_R4);
322 VTADDTOSTR(VT_INT);
323 VTADDTOSTR(VT_BSTR);
324 VTADDTOSTR(VT_CY);
325 VTADDTOSTR(VT_VARIANT);
326 VTADDTOSTR(VT_VOID);
327 VTADDTOSTR(VT_ERROR);
328 VTADDTOSTR(VT_LPSTR);
329 VTADDTOSTR(VT_LPWSTR);
330 VTADDTOSTR(VT_HRESULT);
331 VTADDTOSTR(VT_UNKNOWN);
332 VTADDTOSTR(VT_DISPATCH);
333 VTADDTOSTR(VT_DATE);
334 VTADDTOSTR(VT_R8);
335 case VT_CARRAY:
336 for(i=0; i<U(tdesc).lpadesc->cDims; i++)
338 wsprintfW(wszBuf, wszFormat, U(tdesc).lpadesc->rgbounds[i].cElements);
339 AddToStrW(wszAddAfter, wszBuf);
341 CreateTypeInfo(wszAddTo, wszAddAfter, U(tdesc).lpadesc->tdescElem, pTypeInfo);
342 break;
343 case VT_SAFEARRAY:
344 AddToStrW(wszAddTo, wszVT_SAFEARRAY);
345 AddToStrW(wszAddTo, wszOpenBrackets2);
346 CreateTypeInfo(wszAddTo, wszAddAfter, *U(tdesc).lptdesc, pTypeInfo);
347 AddToStrW(wszAddTo, wszCloseBrackets2);
348 break;
349 case VT_PTR:
350 CreateTypeInfo(wszAddTo, wszAddAfter, *U(tdesc).lptdesc, pTypeInfo);
351 AddToStrW(wszAddTo, wszAsterix);
352 break;
353 case VT_USERDEFINED:
354 hRes = ITypeInfo_GetRefTypeInfo(pTypeInfo,
355 U(tdesc).hreftype, &pRefTypeInfo);
356 if(SUCCEEDED(hRes))
358 ITypeInfo_GetDocumentation(pRefTypeInfo, MEMBERID_NIL,
359 &bstrData, NULL, NULL, NULL);
360 AddToStrW(wszAddTo, bstrData);
361 SysFreeString(bstrData);
362 ITypeInfo_Release(pRefTypeInfo);
364 else AddToStrW(wszAddTo, wszFailed);
365 break;
366 default:
367 WINE_FIXME("tdesc.vt&VT_TYPEMASK == %d not supported\n",
368 tdesc.vt&VT_TYPEMASK);
372 static int EnumVars(ITypeInfo *pTypeInfo, int cVars, HTREEITEM hParent)
374 int i;
375 TVINSERTSTRUCTW tvis;
376 VARDESC *pVarDesc;
377 BSTR bstrName;
378 WCHAR wszText[MAX_LOAD_STRING];
379 WCHAR wszAfter[MAX_LOAD_STRING];
381 U(tvis).item.mask = TVIF_TEXT|TVIF_PARAM;
382 U(tvis).item.cchTextMax = MAX_LOAD_STRING;
383 U(tvis).item.pszText = wszText;
384 tvis.hInsertAfter = TVI_LAST;
385 tvis.hParent = hParent;
387 for(i=0; i<cVars; i++)
389 TYPELIB_DATA *tld;
391 if(FAILED(ITypeInfo_GetVarDesc(pTypeInfo, i, &pVarDesc))) continue;
392 if(FAILED(ITypeInfo_GetDocumentation(pTypeInfo, pVarDesc->memid, &bstrName,
393 NULL, NULL, NULL))) continue;
395 tld = InitializeTLData();
396 U(tvis).item.lParam = (LPARAM) tld;
397 if(pVarDesc->memid < MIN_VAR_ID)
400 AddToTLDataStrW(tld, wszOpenBrackets1);
401 AddToTLDataStrW(tld, wszId);
402 AddToTLDataStrW(tld, wszOpenBrackets2);
403 wsprintfW(wszText, wszFormat, pVarDesc->memid);
404 AddToTLDataStrW(tld, wszText);
405 memset(wszText, 0, sizeof(wszText));
406 AddToTLDataStrW(tld, wszCloseBrackets2);
408 if(pVarDesc->wVarFlags & VARFLAG_FREADONLY)
410 AddToTLDataStrW(tld, wszComa);
411 AddToTLDataStrW(tld, wszSpace);
412 AddToTLDataStrW(tld, wszReadOnly);
414 AddToTLDataStrW(tld, wszCloseBrackets1);
415 AddToTLDataStrW(tld, wszNewLine);
418 memset(wszText, 0, sizeof(wszText));
419 memset(wszAfter, 0, sizeof(wszAfter));
420 CreateTypeInfo(wszText, wszAfter, pVarDesc->elemdescVar.tdesc, pTypeInfo);
421 AddToStrW(wszText, wszSpace);
422 if (bstrName) AddToStrW(wszText, bstrName);
423 AddToStrW(wszText, wszAfter);
424 AddToTLDataStrW(tld, wszText);
425 AddToTLDataStrW(tld, wszSemicolon);
426 AddToTLDataStrW(tld, wszNewLine);
428 SendMessageW(typelib.hTree, TVM_INSERTITEMW, 0, (LPARAM)&tvis);
429 SysFreeString(bstrName);
430 ITypeInfo_ReleaseVarDesc(pTypeInfo, pVarDesc);
433 return 0;
436 static int EnumEnums(ITypeInfo *pTypeInfo, int cVars, HTREEITEM hParent)
438 int i;
439 TVINSERTSTRUCTW tvis;
440 VARDESC *pVarDesc;
441 BSTR bstrName;
442 WCHAR wszText[MAX_LOAD_STRING];
443 WCHAR wszAfter[MAX_LOAD_STRING];
445 U(tvis).item.mask = TVIF_TEXT|TVIF_PARAM;
446 U(tvis).item.cchTextMax = MAX_LOAD_STRING;
447 U(tvis).item.pszText = wszText;
448 tvis.hInsertAfter = TVI_LAST;
449 tvis.hParent = hParent;
451 for(i=0; i<cVars; i++)
453 TYPELIB_DATA *tld;
455 if(FAILED(ITypeInfo_GetVarDesc(pTypeInfo, i, &pVarDesc))) continue;
456 if(FAILED(ITypeInfo_GetDocumentation(pTypeInfo, pVarDesc->memid, &bstrName,
457 NULL, NULL, NULL))) continue;
459 tld = InitializeTLData();
460 U(tvis).item.lParam = (LPARAM) tld;
462 memset(wszText, 0, sizeof(wszText));
463 memset(wszAfter, 0, sizeof(wszAfter));
465 if (pVarDesc->varkind == VAR_CONST)
467 VARIANT var;
468 VariantInit(&var);
469 if (VariantChangeType(&var, U(*pVarDesc).lpvarValue, 0, VT_BSTR) == S_OK)
471 AddToStrW(wszText, wszConst);
472 AddToStrW(wszText, wszSpace);
473 AddToStrW(wszAfter, wszSpace);
474 AddToStrW(wszAfter, wszEquals);
475 AddToStrW(wszAfter, wszSpace);
476 AddToStrW(wszAfter, V_BSTR(&var));
480 CreateTypeInfo(wszText, wszAfter, pVarDesc->elemdescVar.tdesc, pTypeInfo);
481 AddToStrW(wszText, wszSpace);
482 AddToStrW(wszText, bstrName);
483 AddToStrW(wszText, wszAfter);
484 AddToTLDataStrW(tld, bstrName);
485 AddToTLDataStrW(tld, wszAfter);
486 if (i<cVars-1)
487 AddToTLDataStrW(tld, wszComa);
488 AddToTLDataStrW(tld, wszNewLine);
490 SendMessageW(typelib.hTree, TVM_INSERTITEMW, 0, (LPARAM)&tvis);
491 SysFreeString(bstrName);
492 ITypeInfo_ReleaseVarDesc(pTypeInfo, pVarDesc);
495 return 0;
498 static int EnumFuncs(ITypeInfo *pTypeInfo, TYPEATTR *pTypeAttr, HTREEITEM hParent)
500 int i, j;
501 int cFuncs;
502 unsigned namesNo;
503 TVINSERTSTRUCTW tvis;
504 FUNCDESC *pFuncDesc;
505 BSTR bstrName, bstrHelpString, *bstrParamNames;
506 WCHAR wszText[MAX_LOAD_STRING];
507 WCHAR wszAfter[MAX_LOAD_STRING];
508 WCHAR szRhs[] = {'r','h','s',0}; /* Right-hand side of a propput */
509 BOOL bFirst;
511 U(tvis).item.mask = TVIF_TEXT|TVIF_PARAM;
512 tvis.hInsertAfter = TVI_LAST;
513 tvis.hParent = hParent;
515 cFuncs = pTypeAttr->cFuncs;
517 i = 0;
518 if(pTypeAttr->wTypeFlags & TYPEFLAG_FDUAL) { /* skip 7 members of IDispatch */
519 cFuncs += 7;
520 i += 7;
523 for(; i<cFuncs; i++)
525 TYPELIB_DATA *tld;
527 if(FAILED(ITypeInfo_GetFuncDesc(pTypeInfo, i, &pFuncDesc))) continue;
529 if(FAILED(ITypeInfo_GetDocumentation(pTypeInfo, pFuncDesc->memid, &bstrName,
530 &bstrHelpString, NULL, NULL))) continue;
532 memset(wszText, 0, sizeof(wszText));
533 memset(wszAfter, 0, sizeof(wszAfter));
534 tld = InitializeTLData();
535 U(tvis).item.cchTextMax = SysStringLen(bstrName);
536 U(tvis).item.pszText = bstrName;
537 U(tvis).item.lParam = (LPARAM) tld;
538 bFirst = TRUE;
539 if(pFuncDesc->memid < MIN_FUNC_ID || pTypeAttr->wTypeFlags & TYPEFLAG_FDUAL)
541 AddToTLDataStrW(tld, wszOpenBrackets1);
542 bFirst = FALSE;
543 AddToTLDataStrW(tld, wszId);
544 AddToTLDataStrW(tld, wszOpenBrackets2);
545 wsprintfW(wszText, wszFormat, pFuncDesc->memid);
546 AddToTLDataStrW(tld, wszText);
547 AddToTLDataStrW(tld, wszCloseBrackets2);
548 memset(wszText, 0, sizeof(wszText));
551 CreateTypeInfo(wszText, wszAfter, pFuncDesc->elemdescFunc.tdesc, pTypeInfo);
552 switch(pFuncDesc->invkind)
554 case INVOKE_PROPERTYGET:
555 if(bFirst) AddToTLDataStrW(tld, wszOpenBrackets1);
556 else
558 AddToTLDataStrW(tld, wszComa);
559 AddToTLDataStrW(tld, wszSpace);
561 bFirst = FALSE;
562 AddToTLDataStrW(tld, wszPropGet);
563 break;
564 case INVOKE_PROPERTYPUT:
565 if(bFirst) AddToTLDataStrW(tld, wszOpenBrackets1);
566 else
568 AddToTLDataStrW(tld, wszComa);
569 AddToTLDataStrW(tld, wszSpace);
571 bFirst = FALSE;
572 AddToTLDataStrW(tld, wszPropPut);
573 break;
574 case INVOKE_PROPERTYPUTREF:
575 if(bFirst) AddToTLDataStrW(tld, wszOpenBrackets1);
576 else
578 AddToTLDataStrW(tld, wszComa);
579 AddToTLDataStrW(tld, wszSpace);
581 bFirst = FALSE;
582 AddToTLDataStrW(tld, wszPropPutRef);
583 break;
584 default:;
586 if(SysStringLen(bstrHelpString))
588 if(bFirst) AddToTLDataStrW(tld, wszOpenBrackets1);
589 else
591 AddToTLDataStrW(tld, wszComa);
592 AddToTLDataStrW(tld, wszSpace);
594 bFirst = FALSE;
595 AddToTLDataStrW(tld, wszHelpstring);
596 AddToTLDataStrW(tld, wszOpenBrackets2);
597 AddToTLDataStrW(tld, wszInvertedComa);
598 AddToTLDataStrW(tld, bstrHelpString);
599 AddToTLDataStrW(tld, wszInvertedComa);
600 AddToTLDataStrW(tld, wszCloseBrackets2);
602 if(!bFirst)
604 AddToTLDataStrW(tld, wszCloseBrackets1);
605 AddToTLDataStrW(tld, wszNewLine);
608 if(pTypeAttr->wTypeFlags & TYPEFLAG_FOLEAUTOMATION) {
609 AddToTLDataStrW(tld, wszVT_HRESULT);
610 if(strcmpW(wszText, wszVT_VOID)) pFuncDesc->cParams++;
612 else {
613 AddToTLDataStrW(tld, wszText);
614 AddToTLDataStrW(tld, wszAfter);
617 bstrParamNames = HeapAlloc(GetProcessHeap(), 0,
618 sizeof(BSTR)*(pFuncDesc->cParams+1));
619 if(FAILED(ITypeInfo_GetNames(pTypeInfo, pFuncDesc->memid, bstrParamNames,
620 pFuncDesc->cParams+1, &namesNo)))
622 HeapFree(GetProcessHeap(), 0, bstrParamNames);
623 continue;
625 SysFreeString(bstrParamNames[0]);
627 AddToTLDataStrW(tld, wszSpace);
628 if(pFuncDesc->memid >= MIN_FUNC_ID)
630 AddToTLDataStrW(tld, wszStdCall);
631 AddToTLDataStrW(tld, wszSpace);
633 if (bstrName) AddToTLDataStrW(tld, bstrName);
634 AddToTLDataStrW(tld, wszOpenBrackets2);
636 for(j=0; j<pFuncDesc->cParams; j++)
638 if(j != 0) AddToTLDataStrW(tld, wszComa);
639 if(pFuncDesc->cParams != 1)
641 AddToTLDataStrW(tld, wszNewLine);
642 AddSpaces(tld, TAB_SIZE);
644 bFirst = TRUE;
645 #define ENUM_PARAM_FLAG(x)\
646 if(U(pFuncDesc->lprgelemdescParam[j]).paramdesc.wParamFlags & x) \
648 if(bFirst) AddToTLDataStrW(tld,\
649 wszOpenBrackets1);\
650 else\
652 AddToTLDataStrW(tld, wszComa);\
653 AddToTLDataStrW(tld, wszSpace);\
655 bFirst = FALSE;\
656 AddToTLDataStrW(tld, wsz##x);\
658 ENUM_PARAM_FLAG(PARAMFLAG_FIN);
659 ENUM_PARAM_FLAG(PARAMFLAG_FOUT);
660 ENUM_PARAM_FLAG(PARAMFLAG_FLCID);
661 ENUM_PARAM_FLAG(PARAMFLAG_FRETVAL);
662 ENUM_PARAM_FLAG(PARAMFLAG_FOPT);
663 ENUM_PARAM_FLAG(PARAMFLAG_FHASCUSTDATA);
665 if(U(pFuncDesc->lprgelemdescParam[j]).paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT)
667 VARIANT var, *param=&U(pFuncDesc->lprgelemdescParam[j]).paramdesc.pparamdescex->varDefaultValue;
668 VariantInit(&var);
669 if(bFirst) AddToTLDataStrW(tld,
670 wszOpenBrackets1);
671 else
673 AddToTLDataStrW(tld, wszComa);
674 AddToTLDataStrW(tld, wszSpace);
676 bFirst = FALSE;
677 AddToTLDataStrW(tld, wszDefaultValue);
678 AddToTLDataStrW(tld, wszOpenBrackets2);
679 if (V_VT(param) == VT_BSTR)
681 AddToTLDataStrW(tld, wszInvertedComa);
682 AddToTLDataStrW(tld, V_BSTR(param));
683 AddToTLDataStrW(tld, wszInvertedComa);
684 } else if (VariantChangeType(&var, param, 0, VT_BSTR) == S_OK)
685 AddToTLDataStrW(tld, V_BSTR(&var));
686 AddToTLDataStrW(tld, wszCloseBrackets2);
689 if(!bFirst)
691 AddToTLDataStrW(tld, wszCloseBrackets1);
692 AddToTLDataStrW(tld, wszSpace);
695 memset(wszText, 0, sizeof(wszText));
696 memset(wszAfter, 0, sizeof(wszAfter));
697 CreateTypeInfo(wszText, wszAfter, pFuncDesc->lprgelemdescParam[j].tdesc,
698 pTypeInfo);
699 AddToTLDataStrW(tld, wszText);
700 AddToTLDataStrW(tld, wszAfter);
701 AddToTLDataStrW(tld, wszSpace);
702 if (j+1 < namesNo) {
703 if (bstrParamNames[j+1])
705 AddToTLDataStrW(tld, bstrParamNames[j+1]);
706 SysFreeString(bstrParamNames[j+1]);
708 } else {
709 AddToTLDataStrW(tld, szRhs);
712 AddToTLDataStrW(tld, wszCloseBrackets2);
713 AddToTLDataStrW(tld, wszSemicolon);
714 AddToTLDataStrW(tld, wszNewLine);
716 SendMessageW(typelib.hTree, TVM_INSERTITEMW, 0, (LPARAM)&tvis);
717 HeapFree(GetProcessHeap(), 0, bstrParamNames);
718 SysFreeString(bstrName);
719 SysFreeString(bstrHelpString);
720 ITypeInfo_ReleaseFuncDesc(pTypeInfo, pFuncDesc);
723 return 0;
726 static int EnumImplTypes(ITypeInfo *pTypeInfo, int cImplTypes, HTREEITEM hParent)
728 int i;
729 TVINSERTSTRUCTW tvis;
730 ITypeInfo *pRefTypeInfo;
731 HREFTYPE hRefType;
732 TYPEATTR *pTypeAttr;
733 BSTR bstrName;
734 WCHAR wszInheritedInterfaces[MAX_LOAD_STRING];
736 if(!cImplTypes) return 0;
738 LoadStringW(globals.hMainInst, IDS_INHERITINTERFACES, wszInheritedInterfaces,
739 ARRAY_SIZE(wszInheritedInterfaces));
741 U(tvis).item.mask = TVIF_TEXT;
742 U(tvis).item.cchTextMax = MAX_LOAD_STRING;
743 U(tvis).item.pszText = wszInheritedInterfaces;
744 tvis.hInsertAfter = TVI_LAST;
745 tvis.hParent = hParent;
747 tvis.hParent = TreeView_InsertItemW(typelib.hTree, &tvis);
749 for(i=0; i<cImplTypes; i++)
751 if(FAILED(ITypeInfo_GetRefTypeOfImplType(pTypeInfo, i, &hRefType))) continue;
752 if(FAILED(ITypeInfo_GetRefTypeInfo(pTypeInfo, hRefType, &pRefTypeInfo)))
753 continue;
754 if(FAILED(ITypeInfo_GetDocumentation(pRefTypeInfo, MEMBERID_NIL, &bstrName,
755 NULL, NULL, NULL)))
757 ITypeInfo_Release(pRefTypeInfo);
758 continue;
760 if(FAILED(ITypeInfo_GetTypeAttr(pRefTypeInfo, &pTypeAttr)))
762 ITypeInfo_Release(pRefTypeInfo);
763 continue;
766 U(tvis).item.cchTextMax = SysStringLen(bstrName);
767 U(tvis).item.pszText = bstrName;
769 hParent = TreeView_InsertItemW(typelib.hTree, &tvis);
770 EnumVars(pRefTypeInfo, pTypeAttr->cVars, hParent);
771 EnumFuncs(pRefTypeInfo, pTypeAttr, hParent);
772 EnumImplTypes(pRefTypeInfo, pTypeAttr->cImplTypes, hParent);
774 SysFreeString(bstrName);
775 ITypeInfo_ReleaseTypeAttr(pRefTypeInfo, pTypeAttr);
776 ITypeInfo_Release(pRefTypeInfo);
779 return 0;
782 static void EnumCoclassImplTypes(ITypeInfo *pTypeInfo,
783 int cImplTypes, TYPELIB_DATA *pTLData)
785 int i;
786 ITypeInfo *pRefTypeInfo;
787 HREFTYPE hRefType;
788 TYPEATTR *pTypeAttr;
789 BSTR bstrName;
790 BOOL bFirst;
791 INT flags;
792 const WCHAR wszTKIND_INTERFACE[] = { 'i','n','t','e','r','f','a','c','e',' ','\0' };
793 const WCHAR wszTKIND_DISPATCH[]
794 = { 'd','i','s','p','i','n','t','e','r','f','a','c','e',' ','\0' };
795 const WCHAR wszIMPLTYPEFLAG_FDEFAULT[]
796 = { 'd','e','f','a','u','l','t','\0' };
797 const WCHAR wszIMPLTYPEFLAG_FSOURCE[]
798 = { 's','o','u','r','c','e','\0' };
799 const WCHAR wszIMPLTYPEFLAG_FRESTRICTED[]
800 = { 'r','e','s','t','r','i','c','t','e','d','\0' };
802 for(i=0; i<cImplTypes; i++)
804 if(FAILED(ITypeInfo_GetRefTypeOfImplType(pTypeInfo, i, &hRefType))) continue;
805 if(FAILED(ITypeInfo_GetRefTypeInfo(pTypeInfo, hRefType, &pRefTypeInfo)))
806 continue;
807 if(FAILED(ITypeInfo_GetDocumentation(pRefTypeInfo, MEMBERID_NIL, &bstrName,
808 NULL, NULL, NULL)))
810 ITypeInfo_Release(pRefTypeInfo);
811 continue;
813 if(FAILED(ITypeInfo_GetTypeAttr(pRefTypeInfo, &pTypeAttr)))
815 ITypeInfo_Release(pRefTypeInfo);
816 continue;
819 AddSpaces(pTLData, TAB_SIZE);
820 ITypeInfo_GetImplTypeFlags(pTypeInfo, i, &flags);
821 bFirst = TRUE;
822 #define ENUM_IMPLTYPEFLAG(x)\
823 if(flags & x) \
825 if(bFirst) AddToTLDataStrW(pTLData,\
826 wszOpenBrackets1);\
827 else\
829 AddToTLDataStrW(pTLData, wszComa);\
830 AddToTLDataStrW(pTLData, wszSpace);\
832 bFirst = FALSE;\
833 AddToTLDataStrW(pTLData, wsz##x);\
835 ENUM_IMPLTYPEFLAG(IMPLTYPEFLAG_FDEFAULT);
836 ENUM_IMPLTYPEFLAG(IMPLTYPEFLAG_FSOURCE);
837 ENUM_IMPLTYPEFLAG(IMPLTYPEFLAG_FRESTRICTED);
838 if(!bFirst)
840 AddToTLDataStrW(pTLData, wszCloseBrackets1);
841 AddToTLDataStrW(pTLData, wszSpace);
844 if(pTypeAttr->typekind == TKIND_INTERFACE ||
845 (pTypeAttr->wTypeFlags & TYPEFLAG_FDUAL))
846 AddToTLDataStrW(pTLData, wszTKIND_INTERFACE);
847 else if(pTypeAttr->typekind == TKIND_DISPATCH)
848 AddToTLDataStrW(pTLData, wszTKIND_DISPATCH);
849 AddToTLDataStrW(pTLData, wszSpace);
851 AddToTLDataStrW(pTLData, bstrName);
852 AddToTLDataStrW(pTLData, wszSemicolon);
853 AddToTLDataStrW(pTLData, wszNewLine);
855 SysFreeString(bstrName);
856 ITypeInfo_ReleaseTypeAttr(pRefTypeInfo, pTypeAttr);
857 ITypeInfo_Release(pRefTypeInfo);
861 static void AddIdlData(HTREEITEM hCur, TYPELIB_DATA *pTLData)
863 TVITEMW tvi;
865 hCur = (HTREEITEM)SendMessageW(typelib.hTree, TVM_GETNEXTITEM,
866 TVGN_CHILD, (LPARAM)hCur);
867 memset(&tvi, 0, sizeof(TVITEMW));
868 tvi.mask = TVIF_PARAM;
870 while(hCur)
872 tvi.hItem = hCur;
873 SendMessageW(typelib.hTree, TVM_GETITEMW, 0, (LPARAM)&tvi);
874 if(!((TYPELIB_DATA*)(tvi.lParam))->bHide) {
875 AddToTLDataStrW(pTLData, wszNewLine);
876 AddToTLDataStrWithTabsW(pTLData, ((TYPELIB_DATA*)(tvi.lParam))->idl);
878 hCur = (HTREEITEM)SendMessageW(typelib.hTree, TVM_GETNEXTITEM,
879 TVGN_NEXT, (LPARAM)hCur);
883 static void AddPredefinitions(HTREEITEM hFirst, TYPELIB_DATA *pTLData)
885 HTREEITEM hCur;
886 TVITEMW tvi;
887 WCHAR wszText[MAX_LOAD_STRING];
888 WCHAR wszPredefinition[] = { '/','/',' ','T','L','i','b',' ',':','\n',
889 '/','/',' ','F','o','r','w','a','r','d',' ','d','e','c','l','a','r','e',' ',
890 'a','l','l',' ','t','y','p','e','s',' ','d','e','f','i','n','e','d',' ',
891 'i','n',' ','t','h','i','s',' ','t','y','p','e','l','i','b','\0' };
893 hFirst = (HTREEITEM)SendMessageW(typelib.hTree, TVM_GETNEXTITEM,
894 TVGN_CHILD, (LPARAM)hFirst);
896 AddToTLDataStrWithTabsW(pTLData, wszPredefinition);
897 AddToTLDataStrW(pTLData, wszNewLine);
899 hCur = hFirst;
900 memset(&tvi, 0, sizeof(TVITEMW));
901 tvi.mask = TVIF_TEXT|TVIF_PARAM;
902 tvi.cchTextMax = MAX_LOAD_STRING;
903 tvi.pszText = wszText;
904 while(hCur)
906 tvi.hItem = hCur;
907 SendMessageW(typelib.hTree, TVM_GETITEMW, 0, (LPARAM)&tvi);
908 if(((TYPELIB_DATA*)(tvi.lParam))->bPredefine &&
909 !((TYPELIB_DATA*)(tvi.lParam))->bHide)
911 AddToStrW(wszText, wszSemicolon);
912 AddToTLDataStrWithTabsW(pTLData, wszText);
913 AddToTLDataStrW(pTLData, wszNewLine);
915 hCur = (HTREEITEM)SendMessageW(typelib.hTree, TVM_GETNEXTITEM,
916 TVGN_NEXT, (LPARAM)hCur);
920 static void CreateInterfaceInfo(ITypeInfo *pTypeInfo, int cImplTypes, WCHAR *wszName,
921 WCHAR *wszHelpString, ULONG ulHelpContext, TYPEATTR *pTypeAttr,
922 TYPELIB_DATA *pTLData)
924 ITypeInfo *pRefTypeInfo;
925 HREFTYPE hRefType;
926 BSTR bstrName;
927 WCHAR wszGuid[MAX_LOAD_STRING];
928 WCHAR wszHelpContext[MAX_LOAD_STRING];
930 const WCHAR wszInterface[] = { 'i','n','t','e','r','f','a','c','e',' ','\0' };
931 const WCHAR wszDispinterface[]
932 = { 'd','i','s','p','i','n','t','e','r','f','a','c','e',' ','\0' };
933 const WCHAR wszHelpcontext[] = { 'h','e','l','p','c','o','n','t','e','x','t','\0' };
934 const WCHAR wszTYPEFLAG_FAPPOBJECT[] = { 'a','p','p','o','b','j','e','c','t','\0' };
935 const WCHAR wszTYPEFLAG_FCANCREATE[] = { 'c','a','n','c','r','e','a','t','e','\0' };
936 const WCHAR wszTYPEFLAG_FLICENSED[] = { 'l','i','c','e','n','s','e','d','\0' };
937 const WCHAR wszTYPEFLAG_FPREDECLID[] = { 'p','r','e','d','e','c','l','i','d','\0' };
938 const WCHAR wszTYPEFLAG_FHIDDEN[] = { 'h','i','d','d','e','n','\0' };
939 const WCHAR wszTYPEFLAG_FCONTROL[] = { 'c','o','n','t','r','o','l','\0' };
940 const WCHAR wszTYPEFLAG_FDUAL[] = { 'd','u','a','l','\0' };
941 const WCHAR wszTYPEFLAG_FNONEXTENSIBLE[]
942 = { 'n','o','n','e','x','t','e','n','s','i','b','l','e','\0' };
943 const WCHAR wszTYPEFLAG_FOLEAUTOMATION[]
944 = { 'o','l','e','a','u','t','o','m','a','t','i','o','n','\0' };
945 const WCHAR wszTYPEFLAG_FRESTRICTED[]
946 = { 'r','e','s','t','r','i','c','t','e','d','\0' };
947 const WCHAR wszTYPEFLAG_FAGGREGATABLE[]
948 = { 'a','g','g','r','e','g','a','t','a','b','l','e','\0' };
949 const WCHAR wszTYPEFLAG_FREPLACEABLE[]
950 = { 'r','e','p','l','a','c','a','b','l','e','\0' };
951 const WCHAR wszTYPEFLAG_FREVERSEBIND[]
952 = { 'r','e','v','e','r','s','e','b','i','n','d','\0' };
953 const WCHAR wszTYPEFLAG_FPROXY[] = { 'p','r','o','x','y','\0' };
955 AddToTLDataStrW(pTLData, wszOpenBrackets1);
956 AddToTLDataStrW(pTLData, wszNewLine);
957 if(pTypeAttr->typekind != TKIND_DISPATCH)
959 AddSpaces(pTLData, TAB_SIZE);
960 AddToTLDataStrW(pTLData, wszOdl);
961 AddToTLDataStrW(pTLData, wszComa);
962 AddToTLDataStrW(pTLData, wszNewLine);
964 AddSpaces(pTLData, TAB_SIZE);
965 AddToTLDataStrW(pTLData, wszUUID);
966 AddToTLDataStrW(pTLData, wszOpenBrackets2);
967 StringFromGUID2(&(pTypeAttr->guid), wszGuid, MAX_LOAD_STRING);
968 wszGuid[lstrlenW(wszGuid)-1] = '\0';
969 AddToTLDataStrW(pTLData, &wszGuid[1]);
970 AddToTLDataStrW(pTLData, wszCloseBrackets2);
971 if(wszHelpString)
973 AddToTLDataStrW(pTLData, wszComa);
974 AddToTLDataStrW(pTLData, wszNewLine);
975 AddSpaces(pTLData, TAB_SIZE);
976 AddToTLDataStrW(pTLData, wszHelpstring);
977 AddToTLDataStrW(pTLData, wszOpenBrackets2);
978 AddToTLDataStrW(pTLData, wszInvertedComa);
979 AddToTLDataStrW(pTLData, wszHelpString);
980 AddToTLDataStrW(pTLData, wszInvertedComa);
981 AddToTLDataStrW(pTLData, wszCloseBrackets2);
983 if(ulHelpContext)
985 AddToTLDataStrW(pTLData, wszComa);
986 AddToTLDataStrW(pTLData, wszNewLine);
987 AddSpaces(pTLData, TAB_SIZE);
988 AddToTLDataStrW(pTLData, wszHelpcontext);
989 AddToTLDataStrW(pTLData, wszOpenBrackets2);
990 wsprintfW(wszHelpContext, wszFormat, ulHelpContext);
991 AddToTLDataStrW(pTLData, wszHelpContext);
992 AddToTLDataStrW(pTLData, wszCloseBrackets2);
994 if(pTypeAttr->wTypeFlags)
996 #define ENUM_FLAGS(x) if(pTypeAttr->wTypeFlags & x)\
998 AddToTLDataStrW(pTLData, wszComa);\
999 AddToTLDataStrW(pTLData, wszNewLine);\
1000 AddSpaces(pTLData, TAB_SIZE);\
1001 AddToTLDataStrW(pTLData, wsz##x);\
1003 ENUM_FLAGS(TYPEFLAG_FAPPOBJECT);
1004 ENUM_FLAGS(TYPEFLAG_FCANCREATE);
1005 ENUM_FLAGS(TYPEFLAG_FLICENSED);
1006 ENUM_FLAGS(TYPEFLAG_FPREDECLID);
1007 ENUM_FLAGS(TYPEFLAG_FHIDDEN);
1008 ENUM_FLAGS(TYPEFLAG_FCONTROL);
1009 ENUM_FLAGS(TYPEFLAG_FDUAL);
1010 ENUM_FLAGS(TYPEFLAG_FNONEXTENSIBLE);
1011 ENUM_FLAGS(TYPEFLAG_FOLEAUTOMATION);
1012 ENUM_FLAGS(TYPEFLAG_FRESTRICTED);
1013 ENUM_FLAGS(TYPEFLAG_FAGGREGATABLE);
1014 ENUM_FLAGS(TYPEFLAG_FREPLACEABLE);
1015 ENUM_FLAGS(TYPEFLAG_FREVERSEBIND);
1016 ENUM_FLAGS(TYPEFLAG_FPROXY);
1018 AddToTLDataStrW(pTLData, wszNewLine);
1019 AddToTLDataStrW(pTLData, wszCloseBrackets1);
1020 AddToTLDataStrW(pTLData, wszNewLine);
1021 if(pTypeAttr->typekind != TKIND_DISPATCH) AddToTLDataStrW(pTLData, wszInterface);
1022 else AddToTLDataStrW(pTLData, wszDispinterface);
1023 AddToTLDataStrW(pTLData, wszName);
1024 AddToTLDataStrW(pTLData, wszSpace);
1025 if(cImplTypes && pTypeAttr->typekind != TKIND_DISPATCH)
1027 AddToTLDataStrW(pTLData, wszColon);
1028 AddToTLDataStrW(pTLData, wszSpace);
1030 ITypeInfo_GetRefTypeOfImplType(pTypeInfo, 0, &hRefType);
1031 if (SUCCEEDED(ITypeInfo_GetRefTypeInfo(pTypeInfo, hRefType, &pRefTypeInfo)))
1033 ITypeInfo_GetDocumentation(pRefTypeInfo, MEMBERID_NIL, &bstrName,
1034 NULL, NULL, NULL);
1035 AddToTLDataStrW(pTLData, bstrName);
1036 AddToTLDataStrW(pTLData, wszSpace);
1038 SysFreeString(bstrName);
1039 ITypeInfo_Release(pRefTypeInfo);
1041 else
1042 AddToTLDataStrW(pTLData, wszFailed);
1044 AddToTLDataStrW(pTLData, wszOpenBrackets3);
1045 AddToTLDataStrW(pTLData, wszNewLine);
1047 AddToStrW(pTLData->wszInsertAfter, wszCloseBrackets3);
1048 AddToStrW(pTLData->wszInsertAfter, wszSemicolon);
1049 AddToStrW(pTLData->wszInsertAfter, wszNewLine);
1052 static void CreateTypedefHeader(ITypeInfo *pTypeInfo,
1053 TYPEATTR *pTypeAttr, TYPELIB_DATA *pTLData)
1055 BOOL bFirst = TRUE;
1056 WCHAR wszGuid[MAX_LOAD_STRING];
1057 const WCHAR wszTypedef[] = { 't','y','p','e','d','e','f',' ','\0' };
1058 const WCHAR wszPublic[] = { 'p','u','b','l','i','c','\0' };
1060 AddToTLDataStrW(pTLData, wszTypedef);
1061 if(memcmp(&pTypeAttr->guid, &GUID_NULL, sizeof(GUID)))
1063 AddToTLDataStrW(pTLData, wszOpenBrackets1);
1064 bFirst = FALSE;
1065 AddToTLDataStrW(pTLData, wszUUID);
1066 AddToTLDataStrW(pTLData, wszOpenBrackets2);
1067 StringFromGUID2(&(pTypeAttr->guid), wszGuid, MAX_LOAD_STRING);
1068 wszGuid[lstrlenW(wszGuid)-1] = '\0';
1069 AddToTLDataStrW(pTLData, &wszGuid[1]);
1070 AddToTLDataStrW(pTLData, wszCloseBrackets2);
1072 if(pTypeAttr->typekind == TKIND_ALIAS)
1074 if(bFirst) AddToTLDataStrW(pTLData, wszOpenBrackets1);
1075 else
1077 AddToTLDataStrW(pTLData, wszComa);
1078 AddToTLDataStrW(pTLData, wszSpace);
1080 bFirst = FALSE;
1081 AddToTLDataStrW(pTLData, wszPublic);
1083 if(!bFirst)
1085 AddToTLDataStrW(pTLData, wszCloseBrackets1);
1086 AddToTLDataStrW(pTLData, wszNewLine);
1090 static void CreateCoclassHeader(ITypeInfo *pTypeInfo,
1091 TYPEATTR *pTypeAttr, TYPELIB_DATA *pTLData)
1093 WCHAR wszGuid[MAX_LOAD_STRING];
1094 BSTR bstrHelpString;
1095 const WCHAR wszNoncreatable[]
1096 = { 'n','o','n','c','r','e','a','t','a','b','l','e','\0' };
1098 AddToTLDataStrW(pTLData, wszOpenBrackets1);
1099 AddToTLDataStrW(pTLData, wszNewLine);
1101 AddSpaces(pTLData, TAB_SIZE);
1102 AddToTLDataStrW(pTLData, wszUUID);
1103 AddToTLDataStrW(pTLData, wszOpenBrackets2);
1104 StringFromGUID2(&(pTypeAttr->guid), wszGuid, MAX_LOAD_STRING);
1105 wszGuid[lstrlenW(wszGuid)-1] = '\0';
1106 AddToTLDataStrW(pTLData, &wszGuid[1]);
1107 AddToTLDataStrW(pTLData, wszCloseBrackets2);
1109 if(SUCCEEDED(ITypeInfo_GetDocumentation(pTypeInfo, MEMBERID_NIL, NULL,
1110 &bstrHelpString, NULL, NULL)))
1112 if(SysStringLen(bstrHelpString))
1114 AddToTLDataStrW(pTLData, wszComa);
1115 AddToTLDataStrW(pTLData, wszNewLine);
1116 AddSpaces(pTLData, TAB_SIZE);
1117 AddToTLDataStrW(pTLData, wszHelpstring);
1118 AddToTLDataStrW(pTLData, wszOpenBrackets2);
1119 AddToTLDataStrW(pTLData, wszInvertedComa);
1120 AddToTLDataStrW(pTLData, bstrHelpString);
1121 AddToTLDataStrW(pTLData, wszInvertedComa);
1122 AddToTLDataStrW(pTLData, wszCloseBrackets2);
1124 SysFreeString(bstrHelpString);
1127 if(!(pTypeAttr->wTypeFlags & TYPEFLAG_FCANCREATE))
1129 AddToTLDataStrW(pTLData, wszComa);
1130 AddToTLDataStrW(pTLData, wszNewLine);
1131 AddSpaces(pTLData, TAB_SIZE);
1132 AddToTLDataStrW(pTLData, wszNoncreatable);
1135 AddToTLDataStrW(pTLData, wszNewLine);
1136 AddToTLDataStrW(pTLData, wszCloseBrackets1);
1137 AddToTLDataStrW(pTLData, wszNewLine);
1140 static int PopulateTree(void)
1142 TVINSERTSTRUCTW tvis;
1143 TVITEMW tvi;
1144 ITypeLib *pTypeLib;
1145 TLIBATTR *pTLibAttr;
1146 ITypeInfo *pTypeInfo, *pRefTypeInfo;
1147 HREFTYPE hRefType;
1148 TYPEATTR *pTypeAttr;
1149 INT count, i;
1150 ULONG ulHelpContext;
1151 BSTR bstrName;
1152 BSTR bstrData;
1153 WCHAR wszText[MAX_LOAD_STRING];
1154 WCHAR wszAfter[MAX_LOAD_STRING];
1155 HRESULT hRes;
1156 HTREEITEM hParent;
1157 HTREEITEM hMain;
1158 BOOL bInsert;
1159 TYPELIB_DATA *tldDispatch;
1160 TYPELIB_DATA *tld;
1162 const WCHAR wszGeneratedInfo[] = { '/','/',' ','G','e','n','e','r','a','t','e','d',
1163 ' ','.','I','D','L',' ','f','i','l','e',' ','(','b','y',' ','t','h','e',' ',
1164 'O','L','E','/','C','O','M',' ','O','b','j','e','c','t',' ',
1165 'V','i','e','w','e','r',')','\n','/','/','\n','/','/',' ',
1166 't','y','p','e','l','i','b',' ','f','i','l','e','n','a','m','e',':',' ','\0'};
1168 const WCHAR wszFormat[] = { '%','s',' ','(','%','s',')','\0' };
1169 const WCHAR wszFormat2[] = { 'v','e','r','s','i','o','n',
1170 '(','%','l','d','.','%','l','d',')','\0' };
1172 const WCHAR wszTKIND_ENUM[] = { 't','y','p','e','d','e','f',' ','e','n','u','m',' ','\0' };
1173 const WCHAR wszTKIND_RECORD[]
1174 = { 't','y','p','e','d','e','f',' ','s','t','r','u','c','t',' ','\0' };
1175 const WCHAR wszTKIND_MODULE[] = { 'm','o','d','u','l','e',' ','\0' };
1176 const WCHAR wszTKIND_INTERFACE[] = { 'i','n','t','e','r','f','a','c','e',' ','\0' };
1177 const WCHAR wszTKIND_DISPATCH[]
1178 = { 'd','i','s','p','i','n','t','e','r','f','a','c','e',' ','\0' };
1179 const WCHAR wszTKIND_COCLASS[] = { 'c','o','c','l','a','s','s',' ','\0' };
1180 const WCHAR wszTKIND_ALIAS[] = { 't','y','p','e','d','e','f',' ','\0' };
1181 const WCHAR wszTKIND_UNION[]
1182 = { 't','y','p','e','d','e','f',' ','u','n','i','o','n',' ','\0' };
1184 const WCHAR wszLibrary[] = { 'l','i','b','r','a','r','y',' ','\0' };
1185 const WCHAR wszTag[] = { 't','a','g','\0' };
1187 WCHAR wszProperties[] = { 'p','r','o','p','e','r','t','i','e','s','\0' };
1188 WCHAR wszMethods[] = { 'm','e','t','h','o','d','s','\0' };
1190 U(tvis).item.mask = TVIF_TEXT|TVIF_PARAM;
1191 U(tvis).item.cchTextMax = MAX_LOAD_STRING;
1192 U(tvis).item.pszText = wszText;
1193 tvis.hInsertAfter = TVI_LAST;
1194 tvis.hParent = TVI_ROOT;
1196 if(FAILED((hRes = LoadTypeLib(typelib.wszFileName, &pTypeLib))))
1198 WCHAR wszMessage[MAX_LOAD_STRING];
1199 WCHAR wszError[MAX_LOAD_STRING];
1200 DWORD_PTR args[2];
1202 LoadStringW(globals.hMainInst, IDS_ERROR_LOADTYPELIB, wszError, ARRAY_SIZE(wszError));
1203 args[0] = (DWORD_PTR)typelib.wszFileName;
1204 args[1] = hRes;
1205 FormatMessageW(FORMAT_MESSAGE_FROM_STRING|FORMAT_MESSAGE_ARGUMENT_ARRAY,
1206 wszError, 0, 0, wszMessage, ARRAY_SIZE(wszMessage), (__ms_va_list*)args);
1207 MessageBoxW(globals.hMainWnd, wszMessage, NULL, MB_OK|MB_ICONEXCLAMATION);
1208 return 1;
1210 count = ITypeLib_GetTypeInfoCount(pTypeLib);
1212 ITypeLib_GetDocumentation(pTypeLib, -1, &bstrName, &bstrData, NULL, NULL);
1213 ITypeLib_GetLibAttr(pTypeLib, &pTLibAttr);
1215 tld = InitializeTLData();
1216 U(tvis).item.lParam = (LPARAM) tld;
1217 AddToTLDataStrW(tld, wszGeneratedInfo);
1218 AddToTLDataStrW(tld, typelib.wszFileName);
1219 AddToTLDataStrW(tld, wszNewLine);
1220 AddToTLDataStrW(tld, wszNewLine);
1221 AddToTLDataStrW(tld, wszOpenBrackets1);
1222 AddToTLDataStrW(tld, wszNewLine);
1223 AddSpaces(tld, TAB_SIZE);
1224 AddToTLDataStrW(tld, wszUUID);
1225 AddToTLDataStrW(tld, wszOpenBrackets2);
1226 StringFromGUID2(&(pTLibAttr->guid), wszText, MAX_LOAD_STRING);
1227 wszText[lstrlenW(wszText)-1] = '\0';
1228 AddToTLDataStrW(tld, &wszText[1]);
1229 AddToTLDataStrW(tld, wszCloseBrackets2);
1230 AddToTLDataStrW(tld, wszComa);
1231 AddToTLDataStrW(tld, wszNewLine);
1232 AddSpaces(tld, TAB_SIZE);
1233 wsprintfW(wszText, wszFormat2, pTLibAttr->wMajorVerNum, pTLibAttr->wMinorVerNum);
1234 AddToTLDataStrW(tld, wszText);
1236 if (bstrData)
1238 /* helpstring is optional */
1239 AddToTLDataStrW(tld, wszComa);
1240 AddToTLDataStrW(tld, wszNewLine);
1241 AddSpaces(tld, TAB_SIZE);
1242 AddToTLDataStrW(tld, wszHelpstring);
1243 AddToTLDataStrW(tld, wszOpenBrackets2);
1244 AddToTLDataStrW(tld, wszInvertedComa);
1245 AddToTLDataStrW(tld, bstrData);
1246 AddToTLDataStrW(tld, wszInvertedComa);
1247 AddToTLDataStrW(tld, wszCloseBrackets2);
1250 AddToTLDataStrW(tld, wszNewLine);
1251 AddToTLDataStrW(tld, wszCloseBrackets1);
1252 AddToTLDataStrW(tld, wszNewLine);
1253 AddToTLDataStrW(tld, wszLibrary);
1254 if (bstrName) AddToTLDataStrW(tld, bstrName);
1255 AddToTLDataStrW(tld, wszNewLine);
1256 AddToTLDataStrW(tld, wszOpenBrackets3);
1257 AddToTLDataStrW(tld, wszNewLine);
1259 AddToStrW(tld->wszInsertAfter, wszCloseBrackets3);
1260 AddToStrW(tld->wszInsertAfter, wszSemicolon);
1262 wsprintfW(wszText, wszFormat, bstrName, bstrData);
1263 SysFreeString(bstrName);
1264 SysFreeString(bstrData);
1265 tvis.hParent = (HTREEITEM)SendMessageW(typelib.hTree,
1266 TVM_INSERTITEMW, 0, (LPARAM)&tvis);
1268 for(i=0; i<count; i++)
1270 bInsert = TRUE;
1271 ITypeLib_GetTypeInfo(pTypeLib, i, &pTypeInfo);
1273 ITypeInfo_GetDocumentation(pTypeInfo, MEMBERID_NIL, &bstrName, &bstrData,
1274 &ulHelpContext, NULL);
1275 ITypeInfo_GetTypeAttr(pTypeInfo, &pTypeAttr);
1277 memset(wszText, 0, sizeof(wszText));
1278 memset(wszAfter, 0, sizeof(wszAfter));
1279 tld = InitializeTLData();
1280 U(tvis).item.lParam = (LPARAM)tld;
1281 switch(pTypeAttr->typekind)
1283 case TKIND_ENUM:
1284 AddToStrW(wszText, wszTKIND_ENUM);
1285 AddToStrW(wszText, bstrName);
1287 CreateTypedefHeader(pTypeInfo, pTypeAttr, tld);
1288 AddToTLDataStrW(tld, &wszTKIND_ENUM[lstrlenW(wszTKIND_ALIAS)]);
1289 AddToTLDataStrW(tld, wszOpenBrackets3);
1290 AddToTLDataStrW(tld,wszNewLine);
1291 AddToStrW(tld->wszInsertAfter, wszCloseBrackets3);
1292 AddToStrW(tld->wszInsertAfter, wszSpace);
1293 AddToStrW(tld->wszInsertAfter, bstrName);
1294 AddToStrW(tld->wszInsertAfter, wszSemicolon);
1295 AddToStrW(tld->wszInsertAfter, wszNewLine);
1297 bInsert = FALSE;
1298 hParent = TreeView_InsertItemW(typelib.hTree, &tvis);
1299 EnumEnums(pTypeInfo, pTypeAttr->cVars, hParent);
1300 AddChildrenData(hParent, tld);
1301 AddToTLDataStrW(tld, tld->wszInsertAfter);
1302 break;
1303 case TKIND_RECORD:
1304 AddToTLDataStrW(tld, wszTKIND_RECORD);
1305 AddToTLDataStrW(tld, wszTag);
1306 AddToTLDataStrW(tld, bstrName);
1307 AddToTLDataStrW(tld, wszSpace);
1308 AddToTLDataStrW(tld, wszOpenBrackets3);
1309 AddToTLDataStrW(tld, wszNewLine);
1311 AddToStrW(tld->wszInsertAfter, wszCloseBrackets3);
1312 AddToStrW(tld->wszInsertAfter, wszSpace);
1313 AddToStrW(tld->wszInsertAfter, bstrName);
1314 AddToStrW(tld->wszInsertAfter, wszSemicolon);
1315 AddToStrW(tld->wszInsertAfter, wszNewLine);
1317 AddToStrW(wszText, wszTKIND_RECORD);
1318 AddToStrW(wszText, bstrName);
1319 break;
1320 case TKIND_MODULE:
1321 AddToStrW(wszText, wszTKIND_MODULE);
1322 AddToStrW(wszText, bstrName);
1323 break;
1324 case TKIND_INTERFACE:
1325 CreateInterfaceInfo(pTypeInfo, pTypeAttr->cImplTypes, bstrName,
1326 bstrData, ulHelpContext, pTypeAttr, tld);
1327 tld->bPredefine = TRUE;
1329 AddToStrW(wszText, wszTKIND_INTERFACE);
1330 AddToStrW(wszText, bstrName);
1331 break;
1332 case TKIND_COCLASS:
1333 AddToStrW(wszText, wszTKIND_COCLASS);
1334 AddToStrW(wszText, bstrName);
1336 CreateCoclassHeader(pTypeInfo, pTypeAttr, tld);
1337 AddToTLDataStrW(tld, wszTKIND_COCLASS);
1338 AddToTLDataStrW(tld, bstrName);
1339 AddToTLDataStrW(tld, wszSpace);
1340 AddToTLDataStrW(tld, wszOpenBrackets3);
1341 AddToTLDataStrW(tld, wszNewLine);
1343 EnumCoclassImplTypes(pTypeInfo, pTypeAttr->cImplTypes, tld);
1345 AddToStrW(tld->wszInsertAfter, wszCloseBrackets3);
1346 AddToStrW(tld->wszInsertAfter, wszSemicolon);
1347 AddToStrW(tld->wszInsertAfter, wszNewLine);
1349 bInsert = FALSE;
1350 hParent = TreeView_InsertItemW(typelib.hTree, &tvis);
1351 AddToTLDataStrW(tld, tld->wszInsertAfter);
1352 break;
1353 case TKIND_UNION:
1354 AddToStrW(wszText, wszTKIND_UNION);
1355 AddToStrW(wszText, bstrName);
1356 break;
1357 case TKIND_DISPATCH:
1358 CreateInterfaceInfo(pTypeInfo, pTypeAttr->cImplTypes, bstrName,
1359 bstrData, ulHelpContext, pTypeAttr, tld);
1360 tld->bPredefine = TRUE;
1361 if(pTypeAttr->wTypeFlags & TYPEFLAG_FDUAL)
1362 tld->bHide = TRUE;
1363 AddToStrW(wszText, wszTKIND_DISPATCH);
1364 AddToStrW(wszText, bstrName);
1366 hParent = TreeView_InsertItemW(typelib.hTree, &tvis);
1367 hMain = tvis.hParent;
1368 tldDispatch = tld;
1370 lstrcpyW(wszText, wszProperties);
1371 tvis.hParent = hParent;
1372 tld = InitializeTLData();
1373 U(tvis).item.lParam = (LPARAM) tld;
1374 AddToTLDataStrW(tld, wszProperties);
1375 AddToTLDataStrW(tld, wszColon);
1376 AddToTLDataStrW(tld, wszNewLine);
1377 tvis.hParent = TreeView_InsertItemW(typelib.hTree, &tvis);
1378 EnumVars(pTypeInfo, pTypeAttr->cVars, tvis.hParent);
1379 AddChildrenData(tvis.hParent, tld);
1381 lstrcpyW(wszText, wszMethods);
1382 tvis.hParent = hParent;
1383 tld = InitializeTLData();
1384 U(tvis).item.lParam = (LPARAM) tld;
1385 AddToTLDataStrW(tld, wszMethods);
1386 AddToTLDataStrW(tld, wszColon);
1387 AddToTLDataStrW(tld, wszNewLine);
1388 tvis.hParent = TreeView_InsertItemW(typelib.hTree, &tvis);
1389 EnumFuncs(pTypeInfo, pTypeAttr, tvis.hParent);
1390 AddChildrenData(tvis.hParent, tld);
1392 EnumImplTypes(pTypeInfo, pTypeAttr->cImplTypes, hParent);
1393 AddChildrenData(hParent, tldDispatch);
1394 AddToTLDataStrW(tldDispatch, tldDispatch->wszInsertAfter);
1396 bInsert = FALSE;
1397 tvis.hParent = hMain;
1399 if(SUCCEEDED(ITypeInfo_GetRefTypeOfImplType(pTypeInfo, -1, &hRefType)))
1401 bInsert = TRUE;
1403 ITypeInfo_ReleaseTypeAttr(pTypeInfo, pTypeAttr);
1404 SysFreeString(bstrName);
1405 SysFreeString(bstrData);
1407 memset(wszText, 0, sizeof(wszText));
1408 tld = InitializeTLData();
1409 U(tvis).item.lParam = (LPARAM) tld;
1411 ITypeInfo_GetRefTypeInfo(pTypeInfo, hRefType, &pRefTypeInfo);
1412 ITypeInfo_GetDocumentation(pRefTypeInfo, MEMBERID_NIL, &bstrName,
1413 &bstrData, &ulHelpContext, NULL);
1414 ITypeInfo_GetTypeAttr(pRefTypeInfo, &pTypeAttr);
1416 CreateInterfaceInfo(pTypeInfo, pTypeAttr->cImplTypes, bstrName,
1417 bstrData, ulHelpContext, pTypeAttr, tld);
1418 tld->bPredefine = TRUE;
1420 AddToStrW(wszText, wszTKIND_INTERFACE);
1421 AddToStrW(wszText, bstrName);
1422 ITypeInfo_Release(pRefTypeInfo);
1424 break;
1425 case TKIND_ALIAS:
1426 AddToStrW(wszText, wszTKIND_ALIAS);
1427 CreateTypeInfo(wszText, wszAfter, pTypeAttr->tdescAlias, pTypeInfo);
1428 AddToStrW(wszText, wszSpace);
1429 AddToStrW(wszText, bstrName);
1430 AddToStrW(wszText, wszAfter);
1432 CreateTypedefHeader(pTypeInfo, pTypeAttr, tld);
1433 AddToTLDataStrW(tld, &wszText[lstrlenW(wszTKIND_ALIAS)]);
1434 AddToTLDataStrW(tld, wszSemicolon);
1435 AddToTLDataStrW(tld, wszNewLine);
1436 break;
1437 default:
1438 lstrcpyW(wszText, bstrName);
1439 WINE_FIXME("pTypeAttr->typekind == %d not supported\n",
1440 pTypeAttr->typekind);
1443 if(bInsert)
1445 hParent = TreeView_InsertItemW(typelib.hTree, &tvis);
1447 EnumVars(pTypeInfo, pTypeAttr->cVars, hParent);
1448 EnumFuncs(pTypeInfo, pTypeAttr, hParent);
1449 EnumImplTypes(pTypeInfo, pTypeAttr->cImplTypes, hParent);
1451 if(memcmp(bstrName, wszVT_UNKNOWN, sizeof(wszVT_UNKNOWN)))
1452 AddChildrenData(hParent, tld);
1453 AddToTLDataStrW(tld, tld->wszInsertAfter);
1456 ITypeInfo_ReleaseTypeAttr(pTypeInfo, pTypeAttr);
1457 ITypeInfo_Release(pTypeInfo);
1458 SysFreeString(bstrName);
1459 SysFreeString(bstrData);
1461 SendMessageW(typelib.hTree, TVM_EXPAND, TVE_EXPAND, (LPARAM)tvis.hParent);
1463 memset(&tvi, 0, sizeof(TVITEMW));
1464 tvi.mask = TVIF_PARAM;
1465 tvi.hItem = tvis.hParent;
1467 SendMessageW(typelib.hTree, TVM_GETITEMW, 0, (LPARAM)&tvi);
1468 AddPredefinitions(tvi.hItem, (TYPELIB_DATA*)(tvi.lParam));
1469 AddIdlData(tvi.hItem, (TYPELIB_DATA*)(tvi.lParam));
1470 AddToTLDataStrW((TYPELIB_DATA*)(tvi.lParam),
1471 ((TYPELIB_DATA*)(tvi.lParam))->wszInsertAfter);
1473 ITypeLib_Release(pTypeLib);
1474 return 0;
1477 void UpdateData(HTREEITEM item)
1479 TVITEMW tvi;
1481 memset(&tvi, 0, sizeof(TVITEMW));
1482 tvi.mask = TVIF_PARAM;
1483 tvi.hItem = item;
1485 SendMessageW(typelib.hTree, TVM_GETITEMW, 0, (LPARAM)&tvi);
1486 if(!tvi.lParam)
1488 SetWindowTextW(typelib.hEdit, wszSpace);
1489 return;
1492 SetWindowTextW(typelib.hEdit, ((TYPELIB_DATA*)tvi.lParam)->idl);
1495 static void TypeLibResizeChild(void)
1497 RECT client, stat;
1499 MoveWindow(typelib.hStatusBar, 0, 0, 0, 0, TRUE);
1501 if(IsWindowVisible(typelib.hStatusBar))
1502 GetClientRect(typelib.hStatusBar, &stat);
1503 else stat.bottom = 0;
1505 GetClientRect(globals.hTypeLibWnd, &client);
1506 MoveWindow(typelib.hPaneWnd, 0, 0,
1507 client.right, client.bottom-stat.bottom, TRUE);
1510 static void TypeLibMenuCommand(WPARAM wParam, HWND hWnd)
1512 BOOL vis;
1514 switch(wParam)
1516 case IDM_SAVEAS:
1517 GetSaveIdlAsPath();
1518 break;
1519 case IDM_STATUSBAR:
1520 vis = IsWindowVisible(typelib.hStatusBar);
1521 ShowWindow(typelib.hStatusBar, vis ? SW_HIDE : SW_SHOW);
1522 CheckMenuItem(GetMenu(hWnd), LOWORD(wParam),
1523 vis ? MF_UNCHECKED : MF_CHECKED);
1524 TypeLibResizeChild();
1525 break;
1526 case IDM_CLOSE:
1527 DestroyWindow(hWnd);
1528 break;
1532 static void UpdateTypeLibStatusBar(int itemID)
1534 WCHAR info[MAX_LOAD_STRING];
1536 if(!LoadStringW(globals.hMainInst, itemID, info, ARRAY_SIZE(info)))
1537 LoadStringW(globals.hMainInst, IDS_READY, info, ARRAY_SIZE(info));
1539 SendMessageW(typelib.hStatusBar, SB_SETTEXTW, 0, (LPARAM)info);
1542 static void EmptyTLTree(void)
1544 HTREEITEM cur, del;
1545 TVITEMW tvi;
1547 tvi.mask = TVIF_PARAM;
1548 cur = (HTREEITEM)SendMessageW(typelib.hTree, TVM_GETNEXTITEM,
1549 TVGN_CHILD, (LPARAM)TVI_ROOT);
1551 while(TRUE)
1553 del = cur;
1554 cur = (HTREEITEM)SendMessageW(typelib.hTree, TVM_GETNEXTITEM,
1555 TVGN_CHILD, (LPARAM)del);
1557 if(!cur) cur = (HTREEITEM)SendMessageW(typelib.hTree,
1558 TVM_GETNEXTITEM, TVGN_NEXT, (LPARAM)del);
1559 if(!cur) cur = (HTREEITEM)SendMessageW(typelib.hTree,
1560 TVM_GETNEXTITEM, TVGN_PARENT, (LPARAM)del);
1562 tvi.hItem = del;
1563 SendMessageW(typelib.hTree, TVM_GETITEMW, 0, (LPARAM)&tvi);
1564 if(tvi.lParam)
1566 HeapFree(GetProcessHeap(), 0, ((TYPELIB_DATA *)tvi.lParam)->idl);
1567 HeapFree(GetProcessHeap(), 0, (TYPELIB_DATA *)tvi.lParam);
1570 SendMessageW(typelib.hTree, TVM_DELETEITEM, 0, (LPARAM)del);
1572 if(!cur) break;
1576 static LRESULT CALLBACK TypeLibProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
1578 switch(uMsg)
1580 case WM_CREATE:
1582 if(!CreatePanedWindow(hWnd, &typelib.hPaneWnd, globals.hMainInst))
1583 DestroyWindow(hWnd);
1584 typelib.hTree = CreateWindowExW(WS_EX_CLIENTEDGE, WC_TREEVIEWW, NULL,
1585 WS_CHILD|WS_VISIBLE|TVS_HASLINES|TVS_HASBUTTONS|TVS_LINESATROOT,
1586 0, 0, 0, 0, typelib.hPaneWnd, (HMENU)TYPELIB_TREE,
1587 globals.hMainInst, NULL);
1588 typelib.hEdit = CreateWindowExW(WS_EX_CLIENTEDGE, WC_EDITW, NULL,
1589 WS_CHILD|WS_VISIBLE|ES_MULTILINE|ES_READONLY|WS_HSCROLL|WS_VSCROLL,
1590 0, 0, 0, 0, typelib.hPaneWnd, NULL, globals.hMainInst, NULL);
1592 SetLeft(typelib.hPaneWnd, typelib.hTree);
1593 SetRight(typelib.hPaneWnd, typelib.hEdit);
1595 if(PopulateTree()) DestroyWindow(hWnd);
1596 else SetFocus(typelib.hTree);
1597 break;
1599 case WM_COMMAND:
1600 TypeLibMenuCommand(LOWORD(wParam), hWnd);
1601 break;
1602 case WM_MENUSELECT:
1603 UpdateTypeLibStatusBar(LOWORD(wParam));
1604 break;
1605 case WM_SETFOCUS:
1606 SetFocus(typelib.hTree);
1607 break;
1608 case WM_SIZE:
1609 if(wParam == SIZE_MINIMIZED) break;
1610 TypeLibResizeChild();
1611 break;
1612 case WM_DESTROY:
1613 EmptyTLTree();
1614 break;
1615 default:
1616 return DefWindowProcW(hWnd, uMsg, wParam, lParam);
1618 return 0;
1621 BOOL TypeLibRegisterClassW(void)
1623 WNDCLASSW wcc;
1625 memset(&wcc, 0, sizeof(WNDCLASSW));
1626 wcc.lpfnWndProc = TypeLibProc;
1627 wcc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
1628 wcc.hCursor = LoadCursorW(0, (LPCWSTR)IDC_ARROW);
1629 wcc.lpszMenuName = MAKEINTRESOURCEW(IDM_TYPELIB);
1630 wcc.lpszClassName = wszTypeLib;
1632 if(!RegisterClassW(&wcc))
1633 return FALSE;
1635 return TRUE;
1638 BOOL CreateTypeLibWindow(HINSTANCE hInst, WCHAR *wszFileName)
1640 WCHAR wszTitle[MAX_LOAD_STRING];
1641 LoadStringW(hInst, IDS_TYPELIBTITLE, wszTitle, ARRAY_SIZE(wszTitle));
1643 if(wszFileName) lstrcpyW(typelib.wszFileName, wszFileName);
1644 else
1646 TVITEMW tvi;
1648 memset(&tvi, 0, sizeof(TVITEMW));
1649 tvi.hItem = (HTREEITEM)SendMessageW(globals.hTree, TVM_GETNEXTITEM,
1650 TVGN_CARET, 0);
1652 SendMessageW(globals.hTree, TVM_GETITEMW, 0, (LPARAM)&tvi);
1653 lstrcpyW(typelib.wszFileName, ((ITEM_INFO*)tvi.lParam)->path);
1656 globals.hTypeLibWnd = CreateWindowW(wszTypeLib, wszTitle,
1657 WS_OVERLAPPEDWINDOW|WS_VISIBLE,
1658 CW_USEDEFAULT, CW_USEDEFAULT, 800, 600, NULL, NULL, hInst, NULL);
1659 if(!globals.hTypeLibWnd) return FALSE;
1661 typelib.hStatusBar = CreateStatusWindowW(WS_VISIBLE|WS_CHILD,
1662 wszTitle, globals.hTypeLibWnd, 0);
1664 TypeLibResizeChild();
1665 return TRUE;