typelib.c 53 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553
  1. /*
  2. * OleView (typelib.c)
  3. *
  4. * Copyright 2006 Piotr Caban
  5. *
  6. * This library is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 2.1 of the License, or (at your option) any later version.
  10. *
  11. * This library is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public
  17. * License along with this library; if not, write to the Free Software
  18. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  19. */
  20. #include "main.h"
  21. #include "wine/debug.h"
  22. WINE_DEFAULT_DEBUG_CHANNEL(oleview);
  23. TYPELIB typelib;
  24. static const WCHAR wszTypeLib[] = { 'T','Y','P','E','L','I','B','\0' };
  25. static const WCHAR wszFailed[] = { '<','f','a','i','l','e','d','>','\0' };
  26. static const WCHAR wszUUID[] = { 'u','u','i','d','\0' };
  27. static const WCHAR wszOdl[] = { 'o','d','l','\0' };
  28. static const WCHAR wszVT_BOOL[]
  29. = { 'V','A','R','I','A','N','T','_','B','O','O','L','\0' };
  30. static const WCHAR wszVT_UI1[]
  31. = { 'u','n','s','i','g','n','e','d',' ','c','h','a','r','\0' };
  32. static const WCHAR wszVT_UI2[]
  33. = { 'u','n','s','i','g','n','e','d',' ','s','h','o','r','t','\0' };
  34. static const WCHAR wszVT_UI4[]
  35. = { 'u','n','s','i','g','n','e','d',' ','l','o','n','g','\0' };
  36. static const WCHAR wszVT_UI8[] = { 'u','i','n','t','6','4','\0' };
  37. static const WCHAR wszVT_UINT[]
  38. = { 'u','n','s','i','g','n','e','d',' ','i','n','t','\0' };
  39. static const WCHAR wszVT_I1[] = { 'c','h','a','r','\0' };
  40. static const WCHAR wszVT_I2[] = { 's','h','o','r','t','\0' };
  41. static const WCHAR wszVT_I4[] = { 'l','o','n','g','\0' };
  42. static const WCHAR wszVT_I8[] = { 'i','n','t','6','4','\0' };
  43. static const WCHAR wszVT_R4[] = { 's','i','n','g','l','e','\0' };
  44. static const WCHAR wszVT_INT[] = { 'i','n','t','\0' };
  45. static const WCHAR wszVT_BSTR[] = { 'B','S','T','R','\0' };
  46. static const WCHAR wszVT_CY[] = { 'C','U','R','R','E','N','C','Y','\0' };
  47. static const WCHAR wszVT_VARIANT[] = { 'V','A','R','I','A','N','T','\0' };
  48. static const WCHAR wszVT_VOID[] = { 'v','o','i','d','\0' };
  49. static const WCHAR wszVT_ERROR[] = { 'S','C','O','D','E','\0' };
  50. static const WCHAR wszVT_LPSTR[] = { 'L','P','S','T','R','\0' };
  51. static const WCHAR wszVT_LPWSTR[] = { 'L','P','W','S','T','R','\0' };
  52. static const WCHAR wszVT_HRESULT[] = { 'H','R','E','S','U','L','T','\0' };
  53. static const WCHAR wszVT_UNKNOWN[] = { 'I','U','n','k','n','o','w','n','\0' };
  54. static const WCHAR wszVT_DISPATCH[] = { 'I','D','i','s','p','a','t','c','h','\0' };
  55. static const WCHAR wszVT_DATE[] = { 'D','A','T','E','\0' };
  56. static const WCHAR wszVT_R8[] = { 'd','o','u','b','l','e','\0' };
  57. static const WCHAR wszVT_SAFEARRAY[] = { 'S','A','F','E','A','R','R','A','Y','\0' };
  58. static const WCHAR wszFormat[] = { '0','x','%','.','8','l','x','\0' };
  59. static const WCHAR wszStdCall[] = { '_','s','t','d','c','a','l','l','\0' };
  60. static const WCHAR wszId[] = { 'i','d','\0' };
  61. static const WCHAR wszHelpstring[] = { 'h','e','l','p','s','t','r','i','n','g','\0' };
  62. static const WCHAR wszPropPut[] = { 'p','r','o','p','p','u','t','\0' };
  63. static const WCHAR wszPropGet[] = { 'p','r','o','p','g','e','t','\0' };
  64. static const WCHAR wszPropPutRef[] = { 'p','r','o','p','p','u','t','r','e','f','\0' };
  65. static const WCHAR wszPARAMFLAG_FIN[] = { 'i','n','\0' };
  66. static const WCHAR wszPARAMFLAG_FOUT[] = { 'o','u','t','\0' };
  67. static const WCHAR wszPARAMFLAG_FLCID[] = { 'c','i','d','\0' };
  68. static const WCHAR wszPARAMFLAG_FRETVAL[] = { 'r','e','t','v','a','l','\0' };
  69. static const WCHAR wszPARAMFLAG_FOPT[] = { 'o','p','t','i','o','n','a','l','\0' };
  70. static const WCHAR wszPARAMFLAG_FHASCUSTDATA[]
  71. = { 'h','a','s','c','u','s','t','d','a','t','a','\0' };
  72. static const WCHAR wszDefaultValue[]
  73. = { 'd','e','f','a','u','l','t','v','a','l','u','e','\0' };
  74. static const WCHAR wszReadOnly[] = { 'r','e','a','d','o','n','l','y','\0' };
  75. static const WCHAR wszConst[] = { 'c','o','n','s','t','\0' };
  76. static void ShowLastError(void)
  77. {
  78. DWORD error = GetLastError();
  79. LPWSTR lpMsgBuf;
  80. WCHAR wszTitle[MAX_LOAD_STRING];
  81. LoadStringW(globals.hMainInst, IDS_TYPELIBTITLE, wszTitle, ARRAY_SIZE(wszTitle));
  82. FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
  83. NULL, error, 0, (LPWSTR)&lpMsgBuf, 0, NULL);
  84. MessageBoxW(NULL, lpMsgBuf, wszTitle, MB_OK | MB_ICONERROR);
  85. LocalFree(lpMsgBuf);
  86. return;
  87. }
  88. static void SaveIdl(WCHAR *wszFileName)
  89. {
  90. HTREEITEM hIDL;
  91. TVITEMW tvi;
  92. HANDLE hFile;
  93. DWORD len, dwNumWrite;
  94. char *wszIdl;
  95. TYPELIB_DATA *data;
  96. hIDL = (HTREEITEM)SendMessageW(typelib.hTree, TVM_GETNEXTITEM,
  97. TVGN_CHILD, (LPARAM)TVI_ROOT);
  98. memset(&tvi, 0, sizeof(TVITEMW));
  99. tvi.hItem = hIDL;
  100. SendMessageW(typelib.hTree, TVM_GETITEMW, 0, (LPARAM)&tvi);
  101. data = (TYPELIB_DATA *)tvi.lParam;
  102. hFile = CreateFileW(wszFileName, GENERIC_WRITE, FILE_SHARE_WRITE,
  103. NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  104. if(hFile == INVALID_HANDLE_VALUE)
  105. {
  106. ShowLastError();
  107. return;
  108. }
  109. len = WideCharToMultiByte( CP_UTF8, 0, data->idl, data->idlLen, NULL, 0, NULL, NULL );
  110. wszIdl = HeapAlloc(GetProcessHeap(), 0, len);
  111. WideCharToMultiByte( CP_UTF8, 0, data->idl, data->idlLen, wszIdl, len, NULL, NULL );
  112. if(!WriteFile(hFile, wszIdl, len, &dwNumWrite, NULL))
  113. ShowLastError();
  114. HeapFree(GetProcessHeap(), 0, wszIdl);
  115. CloseHandle(hFile);
  116. }
  117. static void GetSaveIdlAsPath(void)
  118. {
  119. OPENFILENAMEW saveidl;
  120. WCHAR *pFileName;
  121. WCHAR wszPath[MAX_LOAD_STRING];
  122. WCHAR wszDir[MAX_LOAD_STRING];
  123. static const WCHAR wszDefaultExt[] = { 'i','d','l',0 };
  124. static const WCHAR wszIdlFiles[] = { '*','.','i','d','l','\0','\0' };
  125. memset(&saveidl, 0, sizeof(saveidl));
  126. lstrcpyW(wszDir, typelib.wszFileName);
  127. pFileName = wszDir + lstrlenW(wszDir);
  128. while(*pFileName != '.' && *pFileName != '\\' && *pFileName != '/'
  129. && pFileName > wszDir) pFileName -= 1;
  130. if(*pFileName == '.')
  131. {
  132. *pFileName = '\0';
  133. while(*pFileName != '\\' && *pFileName != '/' && pFileName > wszDir)
  134. pFileName -= 1;
  135. }
  136. if(*pFileName == '\\' || *pFileName == '/') pFileName += 1;
  137. lstrcpyW(wszPath, pFileName);
  138. GetCurrentDirectoryW(MAX_LOAD_STRING, wszDir);
  139. saveidl.lStructSize = sizeof(OPENFILENAMEW);
  140. saveidl.hwndOwner = globals.hTypeLibWnd;
  141. saveidl.hInstance = globals.hMainInst;
  142. saveidl.lpstrFilter = wszIdlFiles;
  143. saveidl.lpstrFile = wszPath;
  144. saveidl.nMaxFile = MAX_LOAD_STRING;
  145. saveidl.lpstrInitialDir = wszDir;
  146. saveidl.Flags = OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY;
  147. saveidl.lpstrDefExt = wszDefaultExt;
  148. if (GetSaveFileNameW(&saveidl))
  149. SaveIdl(wszPath);
  150. }
  151. static void AddToStrW(WCHAR *wszDest, const WCHAR *wszSource)
  152. {
  153. lstrcpyW(&wszDest[lstrlenW(wszDest)], wszSource);
  154. }
  155. static void AddToTLDataStrW(TYPELIB_DATA *pTLData, const WCHAR *wszSource)
  156. {
  157. int SourceLen = lstrlenW(wszSource);
  158. pTLData->idl = HeapReAlloc(GetProcessHeap(), 0, pTLData->idl,
  159. sizeof(WCHAR)*(pTLData->idlLen+SourceLen+1));
  160. memcpy(&pTLData->idl[pTLData->idlLen], wszSource, sizeof(WCHAR)*(SourceLen+1));
  161. pTLData->idlLen += SourceLen;
  162. }
  163. static void AddToTLDataStrWithTabsW(TYPELIB_DATA *pTLData, WCHAR *wszSource)
  164. {
  165. int lineLen = lstrlenW(wszSource);
  166. int newLinesNo = 0;
  167. WCHAR *pSourcePos = wszSource;
  168. WCHAR *pSourceBeg;
  169. if(!lineLen) return;
  170. while(*pSourcePos)
  171. {
  172. if(*pSourcePos == L'\n') newLinesNo++;
  173. pSourcePos += 1;
  174. }
  175. if(*(pSourcePos - 1) != L'\n') newLinesNo++;
  176. pTLData->idl = HeapReAlloc(GetProcessHeap(), 0, pTLData->idl,
  177. sizeof(WCHAR)*(pTLData->idlLen+lineLen+4*newLinesNo+1));
  178. pSourcePos = wszSource;
  179. pSourceBeg = wszSource;
  180. while(newLinesNo)
  181. {
  182. if(*pSourcePos != L'\n' && *pSourcePos)
  183. {
  184. pSourcePos += 1;
  185. continue;
  186. }
  187. newLinesNo--;
  188. if(*pSourcePos)
  189. {
  190. *pSourcePos = '\0';
  191. lineLen = lstrlenW(pSourceBeg)+1;
  192. *pSourcePos = '\n';
  193. pSourcePos += 1;
  194. }
  195. else lineLen = lstrlenW(pSourceBeg);
  196. pTLData->idl[pTLData->idlLen] = L' ';
  197. pTLData->idl[pTLData->idlLen+1] = L' ';
  198. pTLData->idl[pTLData->idlLen+2] = L' ';
  199. pTLData->idl[pTLData->idlLen+3] = L' ';
  200. memcpy(&pTLData->idl[pTLData->idlLen+4], pSourceBeg, sizeof(WCHAR)*lineLen);
  201. pTLData->idlLen += lineLen + 4;
  202. pTLData->idl[pTLData->idlLen] = '\0';
  203. pSourceBeg = pSourcePos;
  204. }
  205. }
  206. static TYPELIB_DATA *InitializeTLData(void)
  207. {
  208. TYPELIB_DATA *pTLData;
  209. pTLData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(TYPELIB_DATA));
  210. pTLData->idl = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR));
  211. pTLData->idl[0] = '\0';
  212. return pTLData;
  213. }
  214. static void AddSpaces(TYPELIB_DATA *pTLData, int tabSize)
  215. {
  216. for(; tabSize>0; tabSize--)
  217. AddToTLDataStrW(pTLData, L" ");
  218. }
  219. static void AddChildrenData(HTREEITEM hParent, TYPELIB_DATA *pData)
  220. {
  221. HTREEITEM hCur;
  222. TVITEMW tvi;
  223. memset(&tvi, 0, sizeof(tvi));
  224. hCur = (HTREEITEM)SendMessageW(typelib.hTree, TVM_GETNEXTITEM,
  225. TVGN_CHILD, (LPARAM)hParent);
  226. if(!hCur) return;
  227. do
  228. {
  229. tvi.hItem = hCur;
  230. SendMessageW(typelib.hTree, TVM_GETITEMW, 0, (LPARAM)&tvi);
  231. if(tvi.lParam && ((TYPELIB_DATA *)(tvi.lParam))->idlLen)
  232. AddToTLDataStrWithTabsW(pData, ((TYPELIB_DATA *)(tvi.lParam))->idl);
  233. } while((hCur = (HTREEITEM)SendMessageW(typelib.hTree, TVM_GETNEXTITEM,
  234. TVGN_NEXT, (LPARAM)hCur)));
  235. }
  236. static void CreateTypeInfo(WCHAR *wszAddTo, WCHAR *wszAddAfter, TYPEDESC tdesc, ITypeInfo *pTypeInfo)
  237. {
  238. int i;
  239. BSTR bstrData;
  240. HRESULT hRes;
  241. ITypeInfo *pRefTypeInfo;
  242. WCHAR wszBuf[MAX_LOAD_STRING];
  243. WCHAR wszFormat[] = { '[','%','l','u',']','\0' };
  244. switch(tdesc.vt&VT_TYPEMASK)
  245. {
  246. #define VTADDTOSTR(x) case x:\
  247. AddToStrW(wszAddTo, wsz##x);\
  248. break
  249. VTADDTOSTR(VT_BOOL);
  250. VTADDTOSTR(VT_UI1);
  251. VTADDTOSTR(VT_UI2);
  252. VTADDTOSTR(VT_UI4);
  253. VTADDTOSTR(VT_UI8);
  254. VTADDTOSTR(VT_UINT);
  255. VTADDTOSTR(VT_I1);
  256. VTADDTOSTR(VT_I2);
  257. VTADDTOSTR(VT_I4);
  258. VTADDTOSTR(VT_I8);
  259. VTADDTOSTR(VT_R4);
  260. VTADDTOSTR(VT_INT);
  261. VTADDTOSTR(VT_BSTR);
  262. VTADDTOSTR(VT_CY);
  263. VTADDTOSTR(VT_VARIANT);
  264. VTADDTOSTR(VT_VOID);
  265. VTADDTOSTR(VT_ERROR);
  266. VTADDTOSTR(VT_LPSTR);
  267. VTADDTOSTR(VT_LPWSTR);
  268. VTADDTOSTR(VT_HRESULT);
  269. VTADDTOSTR(VT_UNKNOWN);
  270. VTADDTOSTR(VT_DISPATCH);
  271. VTADDTOSTR(VT_DATE);
  272. VTADDTOSTR(VT_R8);
  273. case VT_CARRAY:
  274. for(i=0; i<U(tdesc).lpadesc->cDims; i++)
  275. {
  276. wsprintfW(wszBuf, wszFormat, U(tdesc).lpadesc->rgbounds[i].cElements);
  277. AddToStrW(wszAddAfter, wszBuf);
  278. }
  279. CreateTypeInfo(wszAddTo, wszAddAfter, U(tdesc).lpadesc->tdescElem, pTypeInfo);
  280. break;
  281. case VT_SAFEARRAY:
  282. AddToStrW(wszAddTo, wszVT_SAFEARRAY);
  283. AddToStrW(wszAddTo, L"(");
  284. CreateTypeInfo(wszAddTo, wszAddAfter, *U(tdesc).lptdesc, pTypeInfo);
  285. AddToStrW(wszAddTo, L")");
  286. break;
  287. case VT_PTR:
  288. CreateTypeInfo(wszAddTo, wszAddAfter, *U(tdesc).lptdesc, pTypeInfo);
  289. AddToStrW(wszAddTo, L"*");
  290. break;
  291. case VT_USERDEFINED:
  292. hRes = ITypeInfo_GetRefTypeInfo(pTypeInfo,
  293. U(tdesc).hreftype, &pRefTypeInfo);
  294. if(SUCCEEDED(hRes))
  295. {
  296. ITypeInfo_GetDocumentation(pRefTypeInfo, MEMBERID_NIL,
  297. &bstrData, NULL, NULL, NULL);
  298. AddToStrW(wszAddTo, bstrData);
  299. SysFreeString(bstrData);
  300. ITypeInfo_Release(pRefTypeInfo);
  301. }
  302. else AddToStrW(wszAddTo, wszFailed);
  303. break;
  304. default:
  305. WINE_FIXME("tdesc.vt&VT_TYPEMASK == %d not supported\n",
  306. tdesc.vt&VT_TYPEMASK);
  307. }
  308. }
  309. static int EnumVars(ITypeInfo *pTypeInfo, int cVars, HTREEITEM hParent)
  310. {
  311. int i;
  312. TVINSERTSTRUCTW tvis;
  313. VARDESC *pVarDesc;
  314. BSTR bstrName;
  315. WCHAR wszText[MAX_LOAD_STRING];
  316. WCHAR wszAfter[MAX_LOAD_STRING];
  317. U(tvis).item.mask = TVIF_TEXT|TVIF_PARAM;
  318. U(tvis).item.cchTextMax = MAX_LOAD_STRING;
  319. U(tvis).item.pszText = wszText;
  320. tvis.hInsertAfter = TVI_LAST;
  321. tvis.hParent = hParent;
  322. for(i=0; i<cVars; i++)
  323. {
  324. TYPELIB_DATA *tld;
  325. if(FAILED(ITypeInfo_GetVarDesc(pTypeInfo, i, &pVarDesc))) continue;
  326. if(FAILED(ITypeInfo_GetDocumentation(pTypeInfo, pVarDesc->memid, &bstrName,
  327. NULL, NULL, NULL))) continue;
  328. tld = InitializeTLData();
  329. U(tvis).item.lParam = (LPARAM) tld;
  330. if(pVarDesc->memid < MIN_VAR_ID)
  331. {
  332. AddToTLDataStrW(tld, L"[");
  333. AddToTLDataStrW(tld, wszId);
  334. AddToTLDataStrW(tld, L"(");
  335. wsprintfW(wszText, wszFormat, pVarDesc->memid);
  336. AddToTLDataStrW(tld, wszText);
  337. memset(wszText, 0, sizeof(wszText));
  338. AddToTLDataStrW(tld, L")");
  339. if(pVarDesc->wVarFlags & VARFLAG_FREADONLY)
  340. {
  341. AddToTLDataStrW(tld, L", ");
  342. AddToTLDataStrW(tld, wszReadOnly);
  343. }
  344. AddToTLDataStrW(tld, L"]\n");
  345. }
  346. memset(wszText, 0, sizeof(wszText));
  347. memset(wszAfter, 0, sizeof(wszAfter));
  348. CreateTypeInfo(wszText, wszAfter, pVarDesc->elemdescVar.tdesc, pTypeInfo);
  349. AddToStrW(wszText, L" ");
  350. if (bstrName) AddToStrW(wszText, bstrName);
  351. AddToStrW(wszText, wszAfter);
  352. AddToTLDataStrW(tld, wszText);
  353. AddToTLDataStrW(tld, L";\n");
  354. SendMessageW(typelib.hTree, TVM_INSERTITEMW, 0, (LPARAM)&tvis);
  355. SysFreeString(bstrName);
  356. ITypeInfo_ReleaseVarDesc(pTypeInfo, pVarDesc);
  357. }
  358. return 0;
  359. }
  360. static int EnumEnums(ITypeInfo *pTypeInfo, int cVars, HTREEITEM hParent)
  361. {
  362. int i;
  363. TVINSERTSTRUCTW tvis;
  364. VARDESC *pVarDesc;
  365. BSTR bstrName;
  366. WCHAR wszText[MAX_LOAD_STRING];
  367. WCHAR wszAfter[MAX_LOAD_STRING];
  368. U(tvis).item.mask = TVIF_TEXT|TVIF_PARAM;
  369. U(tvis).item.cchTextMax = MAX_LOAD_STRING;
  370. U(tvis).item.pszText = wszText;
  371. tvis.hInsertAfter = TVI_LAST;
  372. tvis.hParent = hParent;
  373. for(i=0; i<cVars; i++)
  374. {
  375. TYPELIB_DATA *tld;
  376. if(FAILED(ITypeInfo_GetVarDesc(pTypeInfo, i, &pVarDesc))) continue;
  377. if(FAILED(ITypeInfo_GetDocumentation(pTypeInfo, pVarDesc->memid, &bstrName,
  378. NULL, NULL, NULL))) continue;
  379. tld = InitializeTLData();
  380. U(tvis).item.lParam = (LPARAM) tld;
  381. memset(wszText, 0, sizeof(wszText));
  382. memset(wszAfter, 0, sizeof(wszAfter));
  383. if (pVarDesc->varkind == VAR_CONST)
  384. {
  385. VARIANT var;
  386. VariantInit(&var);
  387. if (VariantChangeType(&var, U(*pVarDesc).lpvarValue, 0, VT_BSTR) == S_OK)
  388. {
  389. AddToStrW(wszText, wszConst);
  390. AddToStrW(wszText, L" ");
  391. AddToStrW(wszAfter, L" = ");
  392. AddToStrW(wszAfter, V_BSTR(&var));
  393. }
  394. }
  395. CreateTypeInfo(wszText, wszAfter, pVarDesc->elemdescVar.tdesc, pTypeInfo);
  396. AddToStrW(wszText, L" ");
  397. AddToStrW(wszText, bstrName);
  398. AddToStrW(wszText, wszAfter);
  399. AddToTLDataStrW(tld, bstrName);
  400. AddToTLDataStrW(tld, wszAfter);
  401. if (i<cVars-1)
  402. AddToTLDataStrW(tld, L",");
  403. AddToTLDataStrW(tld, L"\n");
  404. SendMessageW(typelib.hTree, TVM_INSERTITEMW, 0, (LPARAM)&tvis);
  405. SysFreeString(bstrName);
  406. ITypeInfo_ReleaseVarDesc(pTypeInfo, pVarDesc);
  407. }
  408. return 0;
  409. }
  410. static int EnumFuncs(ITypeInfo *pTypeInfo, TYPEATTR *pTypeAttr, HTREEITEM hParent)
  411. {
  412. int i, j;
  413. int cFuncs;
  414. unsigned namesNo;
  415. TVINSERTSTRUCTW tvis;
  416. FUNCDESC *pFuncDesc;
  417. BSTR bstrName, bstrHelpString, *bstrParamNames;
  418. WCHAR wszText[MAX_LOAD_STRING];
  419. WCHAR wszAfter[MAX_LOAD_STRING];
  420. WCHAR szRhs[] = {'r','h','s',0}; /* Right-hand side of a propput */
  421. BOOL bFirst;
  422. U(tvis).item.mask = TVIF_TEXT|TVIF_PARAM;
  423. tvis.hInsertAfter = TVI_LAST;
  424. tvis.hParent = hParent;
  425. cFuncs = pTypeAttr->cFuncs;
  426. i = 0;
  427. if(pTypeAttr->wTypeFlags & TYPEFLAG_FDUAL) { /* skip 7 members of IDispatch */
  428. cFuncs += 7;
  429. i += 7;
  430. }
  431. for(; i<cFuncs; i++)
  432. {
  433. TYPELIB_DATA *tld;
  434. if(FAILED(ITypeInfo_GetFuncDesc(pTypeInfo, i, &pFuncDesc))) continue;
  435. if(FAILED(ITypeInfo_GetDocumentation(pTypeInfo, pFuncDesc->memid, &bstrName,
  436. &bstrHelpString, NULL, NULL))) continue;
  437. memset(wszText, 0, sizeof(wszText));
  438. memset(wszAfter, 0, sizeof(wszAfter));
  439. tld = InitializeTLData();
  440. U(tvis).item.cchTextMax = SysStringLen(bstrName);
  441. U(tvis).item.pszText = bstrName;
  442. U(tvis).item.lParam = (LPARAM) tld;
  443. bFirst = TRUE;
  444. if(pFuncDesc->memid < MIN_FUNC_ID || pTypeAttr->wTypeFlags & TYPEFLAG_FDUAL)
  445. {
  446. AddToTLDataStrW(tld, L"[");
  447. bFirst = FALSE;
  448. AddToTLDataStrW(tld, wszId);
  449. AddToTLDataStrW(tld, L"(");
  450. wsprintfW(wszText, wszFormat, pFuncDesc->memid);
  451. AddToTLDataStrW(tld, wszText);
  452. AddToTLDataStrW(tld, L")");
  453. memset(wszText, 0, sizeof(wszText));
  454. }
  455. CreateTypeInfo(wszText, wszAfter, pFuncDesc->elemdescFunc.tdesc, pTypeInfo);
  456. switch(pFuncDesc->invkind)
  457. {
  458. case INVOKE_PROPERTYGET:
  459. if(bFirst) AddToTLDataStrW(tld, L"[");
  460. else AddToTLDataStrW(tld, L", ");
  461. bFirst = FALSE;
  462. AddToTLDataStrW(tld, wszPropGet);
  463. break;
  464. case INVOKE_PROPERTYPUT:
  465. if(bFirst) AddToTLDataStrW(tld, L"[");
  466. else AddToTLDataStrW(tld, L", ");
  467. bFirst = FALSE;
  468. AddToTLDataStrW(tld, wszPropPut);
  469. break;
  470. case INVOKE_PROPERTYPUTREF:
  471. if(bFirst) AddToTLDataStrW(tld, L"[");
  472. else AddToTLDataStrW(tld, L", ");
  473. bFirst = FALSE;
  474. AddToTLDataStrW(tld, wszPropPutRef);
  475. break;
  476. default:;
  477. }
  478. if(SysStringLen(bstrHelpString))
  479. {
  480. if(bFirst) AddToTLDataStrW(tld, L"[");
  481. else AddToTLDataStrW(tld, L", ");
  482. bFirst = FALSE;
  483. AddToTLDataStrW(tld, wszHelpstring);
  484. AddToTLDataStrW(tld, L"(\"");
  485. AddToTLDataStrW(tld, bstrHelpString);
  486. AddToTLDataStrW(tld, L"\")");
  487. }
  488. if(!bFirst) AddToTLDataStrW(tld, L"]\n");
  489. if(pTypeAttr->wTypeFlags & TYPEFLAG_FOLEAUTOMATION) {
  490. AddToTLDataStrW(tld, wszVT_HRESULT);
  491. if(lstrcmpW(wszText, wszVT_VOID)) pFuncDesc->cParams++;
  492. }
  493. else {
  494. AddToTLDataStrW(tld, wszText);
  495. AddToTLDataStrW(tld, wszAfter);
  496. }
  497. bstrParamNames = HeapAlloc(GetProcessHeap(), 0,
  498. sizeof(BSTR)*(pFuncDesc->cParams+1));
  499. if(FAILED(ITypeInfo_GetNames(pTypeInfo, pFuncDesc->memid, bstrParamNames,
  500. pFuncDesc->cParams+1, &namesNo)))
  501. {
  502. HeapFree(GetProcessHeap(), 0, bstrParamNames);
  503. continue;
  504. }
  505. SysFreeString(bstrParamNames[0]);
  506. AddToTLDataStrW(tld, L" ");
  507. if(pFuncDesc->memid >= MIN_FUNC_ID)
  508. {
  509. AddToTLDataStrW(tld, wszStdCall);
  510. AddToTLDataStrW(tld, L" ");
  511. }
  512. if (bstrName) AddToTLDataStrW(tld, bstrName);
  513. AddToTLDataStrW(tld, L"(");
  514. for(j=0; j<pFuncDesc->cParams; j++)
  515. {
  516. if(j != 0) AddToTLDataStrW(tld, L",");
  517. if(pFuncDesc->cParams != 1)
  518. {
  519. AddToTLDataStrW(tld, L"\n");
  520. AddSpaces(tld, TAB_SIZE);
  521. }
  522. bFirst = TRUE;
  523. #define ENUM_PARAM_FLAG(x)\
  524. if(U(pFuncDesc->lprgelemdescParam[j]).paramdesc.wParamFlags & x) \
  525. {\
  526. if(bFirst)\
  527. AddToTLDataStrW(tld, L"[");\
  528. else\
  529. {\
  530. AddToTLDataStrW(tld, L", ");\
  531. }\
  532. bFirst = FALSE;\
  533. AddToTLDataStrW(tld, wsz##x);\
  534. }
  535. ENUM_PARAM_FLAG(PARAMFLAG_FIN);
  536. ENUM_PARAM_FLAG(PARAMFLAG_FOUT);
  537. ENUM_PARAM_FLAG(PARAMFLAG_FLCID);
  538. ENUM_PARAM_FLAG(PARAMFLAG_FRETVAL);
  539. ENUM_PARAM_FLAG(PARAMFLAG_FOPT);
  540. ENUM_PARAM_FLAG(PARAMFLAG_FHASCUSTDATA);
  541. if(U(pFuncDesc->lprgelemdescParam[j]).paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT)
  542. {
  543. VARIANT var, *param=&U(pFuncDesc->lprgelemdescParam[j]).paramdesc.pparamdescex->varDefaultValue;
  544. VariantInit(&var);
  545. if(bFirst) AddToTLDataStrW(tld, L"[");
  546. else AddToTLDataStrW(tld, L", ");
  547. bFirst = FALSE;
  548. AddToTLDataStrW(tld, wszDefaultValue);
  549. AddToTLDataStrW(tld, L"(");
  550. if (V_VT(param) == VT_BSTR)
  551. {
  552. AddToTLDataStrW(tld, L"\"");
  553. AddToTLDataStrW(tld, V_BSTR(param));
  554. AddToTLDataStrW(tld, L"\"");
  555. } else if (VariantChangeType(&var, param, 0, VT_BSTR) == S_OK)
  556. AddToTLDataStrW(tld, V_BSTR(&var));
  557. AddToTLDataStrW(tld, L")");
  558. }
  559. if(!bFirst) AddToTLDataStrW(tld, L"] ");
  560. memset(wszText, 0, sizeof(wszText));
  561. memset(wszAfter, 0, sizeof(wszAfter));
  562. CreateTypeInfo(wszText, wszAfter, pFuncDesc->lprgelemdescParam[j].tdesc,
  563. pTypeInfo);
  564. AddToTLDataStrW(tld, wszText);
  565. AddToTLDataStrW(tld, wszAfter);
  566. AddToTLDataStrW(tld, L" ");
  567. if (j+1 < namesNo) {
  568. if (bstrParamNames[j+1])
  569. {
  570. AddToTLDataStrW(tld, bstrParamNames[j+1]);
  571. SysFreeString(bstrParamNames[j+1]);
  572. }
  573. } else {
  574. AddToTLDataStrW(tld, szRhs);
  575. }
  576. }
  577. AddToTLDataStrW(tld, L");\n");
  578. SendMessageW(typelib.hTree, TVM_INSERTITEMW, 0, (LPARAM)&tvis);
  579. HeapFree(GetProcessHeap(), 0, bstrParamNames);
  580. SysFreeString(bstrName);
  581. SysFreeString(bstrHelpString);
  582. ITypeInfo_ReleaseFuncDesc(pTypeInfo, pFuncDesc);
  583. }
  584. return 0;
  585. }
  586. static int EnumImplTypes(ITypeInfo *pTypeInfo, int cImplTypes, HTREEITEM hParent)
  587. {
  588. int i;
  589. TVINSERTSTRUCTW tvis;
  590. ITypeInfo *pRefTypeInfo;
  591. HREFTYPE hRefType;
  592. TYPEATTR *pTypeAttr;
  593. BSTR bstrName;
  594. WCHAR wszInheritedInterfaces[MAX_LOAD_STRING];
  595. if(!cImplTypes) return 0;
  596. LoadStringW(globals.hMainInst, IDS_INHERITINTERFACES, wszInheritedInterfaces,
  597. ARRAY_SIZE(wszInheritedInterfaces));
  598. U(tvis).item.mask = TVIF_TEXT;
  599. U(tvis).item.cchTextMax = MAX_LOAD_STRING;
  600. U(tvis).item.pszText = wszInheritedInterfaces;
  601. tvis.hInsertAfter = TVI_LAST;
  602. tvis.hParent = hParent;
  603. tvis.hParent = TreeView_InsertItemW(typelib.hTree, &tvis);
  604. for(i=0; i<cImplTypes; i++)
  605. {
  606. if(FAILED(ITypeInfo_GetRefTypeOfImplType(pTypeInfo, i, &hRefType))) continue;
  607. if(FAILED(ITypeInfo_GetRefTypeInfo(pTypeInfo, hRefType, &pRefTypeInfo)))
  608. continue;
  609. if(FAILED(ITypeInfo_GetDocumentation(pRefTypeInfo, MEMBERID_NIL, &bstrName,
  610. NULL, NULL, NULL)))
  611. {
  612. ITypeInfo_Release(pRefTypeInfo);
  613. continue;
  614. }
  615. if(FAILED(ITypeInfo_GetTypeAttr(pRefTypeInfo, &pTypeAttr)))
  616. {
  617. ITypeInfo_Release(pRefTypeInfo);
  618. continue;
  619. }
  620. U(tvis).item.cchTextMax = SysStringLen(bstrName);
  621. U(tvis).item.pszText = bstrName;
  622. hParent = TreeView_InsertItemW(typelib.hTree, &tvis);
  623. EnumVars(pRefTypeInfo, pTypeAttr->cVars, hParent);
  624. EnumFuncs(pRefTypeInfo, pTypeAttr, hParent);
  625. EnumImplTypes(pRefTypeInfo, pTypeAttr->cImplTypes, hParent);
  626. SysFreeString(bstrName);
  627. ITypeInfo_ReleaseTypeAttr(pRefTypeInfo, pTypeAttr);
  628. ITypeInfo_Release(pRefTypeInfo);
  629. }
  630. return 0;
  631. }
  632. static void EnumCoclassImplTypes(ITypeInfo *pTypeInfo,
  633. int cImplTypes, TYPELIB_DATA *pTLData)
  634. {
  635. int i;
  636. ITypeInfo *pRefTypeInfo;
  637. HREFTYPE hRefType;
  638. TYPEATTR *pTypeAttr;
  639. BSTR bstrName;
  640. BOOL bFirst;
  641. INT flags;
  642. const WCHAR wszTKIND_INTERFACE[] = { 'i','n','t','e','r','f','a','c','e',' ','\0' };
  643. const WCHAR wszTKIND_DISPATCH[]
  644. = { 'd','i','s','p','i','n','t','e','r','f','a','c','e',' ','\0' };
  645. const WCHAR wszIMPLTYPEFLAG_FDEFAULT[]
  646. = { 'd','e','f','a','u','l','t','\0' };
  647. const WCHAR wszIMPLTYPEFLAG_FSOURCE[]
  648. = { 's','o','u','r','c','e','\0' };
  649. const WCHAR wszIMPLTYPEFLAG_FRESTRICTED[]
  650. = { 'r','e','s','t','r','i','c','t','e','d','\0' };
  651. for(i=0; i<cImplTypes; i++)
  652. {
  653. if(FAILED(ITypeInfo_GetRefTypeOfImplType(pTypeInfo, i, &hRefType))) continue;
  654. if(FAILED(ITypeInfo_GetRefTypeInfo(pTypeInfo, hRefType, &pRefTypeInfo)))
  655. continue;
  656. if(FAILED(ITypeInfo_GetDocumentation(pRefTypeInfo, MEMBERID_NIL, &bstrName,
  657. NULL, NULL, NULL)))
  658. {
  659. ITypeInfo_Release(pRefTypeInfo);
  660. continue;
  661. }
  662. if(FAILED(ITypeInfo_GetTypeAttr(pRefTypeInfo, &pTypeAttr)))
  663. {
  664. ITypeInfo_Release(pRefTypeInfo);
  665. continue;
  666. }
  667. AddSpaces(pTLData, TAB_SIZE);
  668. ITypeInfo_GetImplTypeFlags(pTypeInfo, i, &flags);
  669. bFirst = TRUE;
  670. #define ENUM_IMPLTYPEFLAG(x)\
  671. if(flags & x) \
  672. {\
  673. if(bFirst)\
  674. AddToTLDataStrW(pTLData, L"[");\
  675. else\
  676. {\
  677. AddToTLDataStrW(pTLData, L", ");\
  678. }\
  679. bFirst = FALSE;\
  680. AddToTLDataStrW(pTLData, wsz##x);\
  681. }
  682. ENUM_IMPLTYPEFLAG(IMPLTYPEFLAG_FDEFAULT);
  683. ENUM_IMPLTYPEFLAG(IMPLTYPEFLAG_FSOURCE);
  684. ENUM_IMPLTYPEFLAG(IMPLTYPEFLAG_FRESTRICTED);
  685. if(!bFirst)
  686. AddToTLDataStrW(pTLData, L"] ");
  687. if(pTypeAttr->typekind == TKIND_INTERFACE ||
  688. (pTypeAttr->wTypeFlags & TYPEFLAG_FDUAL))
  689. AddToTLDataStrW(pTLData, wszTKIND_INTERFACE);
  690. else if(pTypeAttr->typekind == TKIND_DISPATCH)
  691. AddToTLDataStrW(pTLData, wszTKIND_DISPATCH);
  692. AddToTLDataStrW(pTLData, L" ");
  693. AddToTLDataStrW(pTLData, bstrName);
  694. AddToTLDataStrW(pTLData, L";\n");
  695. SysFreeString(bstrName);
  696. ITypeInfo_ReleaseTypeAttr(pRefTypeInfo, pTypeAttr);
  697. ITypeInfo_Release(pRefTypeInfo);
  698. }
  699. }
  700. static void AddIdlData(HTREEITEM hCur, TYPELIB_DATA *pTLData)
  701. {
  702. TVITEMW tvi;
  703. hCur = (HTREEITEM)SendMessageW(typelib.hTree, TVM_GETNEXTITEM,
  704. TVGN_CHILD, (LPARAM)hCur);
  705. memset(&tvi, 0, sizeof(TVITEMW));
  706. tvi.mask = TVIF_PARAM;
  707. while(hCur)
  708. {
  709. tvi.hItem = hCur;
  710. SendMessageW(typelib.hTree, TVM_GETITEMW, 0, (LPARAM)&tvi);
  711. if(!((TYPELIB_DATA*)(tvi.lParam))->bHide) {
  712. AddToTLDataStrW(pTLData, L"\n");
  713. AddToTLDataStrWithTabsW(pTLData, ((TYPELIB_DATA*)(tvi.lParam))->idl);
  714. }
  715. hCur = (HTREEITEM)SendMessageW(typelib.hTree, TVM_GETNEXTITEM,
  716. TVGN_NEXT, (LPARAM)hCur);
  717. }
  718. }
  719. static void AddPredefinitions(HTREEITEM hFirst, TYPELIB_DATA *pTLData)
  720. {
  721. HTREEITEM hCur;
  722. TVITEMW tvi;
  723. WCHAR wszText[MAX_LOAD_STRING];
  724. WCHAR wszPredefinition[] = { '/','/',' ','T','L','i','b',' ',':','\n',
  725. '/','/',' ','F','o','r','w','a','r','d',' ','d','e','c','l','a','r','e',' ',
  726. 'a','l','l',' ','t','y','p','e','s',' ','d','e','f','i','n','e','d',' ',
  727. 'i','n',' ','t','h','i','s',' ','t','y','p','e','l','i','b','\0' };
  728. hFirst = (HTREEITEM)SendMessageW(typelib.hTree, TVM_GETNEXTITEM,
  729. TVGN_CHILD, (LPARAM)hFirst);
  730. AddToTLDataStrWithTabsW(pTLData, wszPredefinition);
  731. AddToTLDataStrW(pTLData, L"\n");
  732. hCur = hFirst;
  733. memset(&tvi, 0, sizeof(TVITEMW));
  734. tvi.mask = TVIF_TEXT|TVIF_PARAM;
  735. tvi.cchTextMax = MAX_LOAD_STRING;
  736. tvi.pszText = wszText;
  737. while(hCur)
  738. {
  739. tvi.hItem = hCur;
  740. SendMessageW(typelib.hTree, TVM_GETITEMW, 0, (LPARAM)&tvi);
  741. if(((TYPELIB_DATA*)(tvi.lParam))->bPredefine &&
  742. !((TYPELIB_DATA*)(tvi.lParam))->bHide)
  743. {
  744. AddToStrW(wszText, L";");
  745. AddToTLDataStrWithTabsW(pTLData, wszText);
  746. AddToTLDataStrW(pTLData, L"\n");
  747. }
  748. hCur = (HTREEITEM)SendMessageW(typelib.hTree, TVM_GETNEXTITEM,
  749. TVGN_NEXT, (LPARAM)hCur);
  750. }
  751. }
  752. static void CreateInterfaceInfo(ITypeInfo *pTypeInfo, int cImplTypes, WCHAR *wszName,
  753. WCHAR *wszHelpString, ULONG ulHelpContext, TYPEATTR *pTypeAttr,
  754. TYPELIB_DATA *pTLData)
  755. {
  756. ITypeInfo *pRefTypeInfo;
  757. HREFTYPE hRefType;
  758. BSTR bstrName;
  759. WCHAR wszGuid[MAX_LOAD_STRING];
  760. WCHAR wszHelpContext[MAX_LOAD_STRING];
  761. const WCHAR wszInterface[] = { 'i','n','t','e','r','f','a','c','e',' ','\0' };
  762. const WCHAR wszDispinterface[]
  763. = { 'd','i','s','p','i','n','t','e','r','f','a','c','e',' ','\0' };
  764. const WCHAR wszHelpcontext[] = { 'h','e','l','p','c','o','n','t','e','x','t','\0' };
  765. const WCHAR wszTYPEFLAG_FAPPOBJECT[] = { 'a','p','p','o','b','j','e','c','t','\0' };
  766. const WCHAR wszTYPEFLAG_FCANCREATE[] = { 'c','a','n','c','r','e','a','t','e','\0' };
  767. const WCHAR wszTYPEFLAG_FLICENSED[] = { 'l','i','c','e','n','s','e','d','\0' };
  768. const WCHAR wszTYPEFLAG_FPREDECLID[] = { 'p','r','e','d','e','c','l','i','d','\0' };
  769. const WCHAR wszTYPEFLAG_FHIDDEN[] = { 'h','i','d','d','e','n','\0' };
  770. const WCHAR wszTYPEFLAG_FCONTROL[] = { 'c','o','n','t','r','o','l','\0' };
  771. const WCHAR wszTYPEFLAG_FDUAL[] = { 'd','u','a','l','\0' };
  772. const WCHAR wszTYPEFLAG_FNONEXTENSIBLE[]
  773. = { 'n','o','n','e','x','t','e','n','s','i','b','l','e','\0' };
  774. const WCHAR wszTYPEFLAG_FOLEAUTOMATION[]
  775. = { 'o','l','e','a','u','t','o','m','a','t','i','o','n','\0' };
  776. const WCHAR wszTYPEFLAG_FRESTRICTED[]
  777. = { 'r','e','s','t','r','i','c','t','e','d','\0' };
  778. const WCHAR wszTYPEFLAG_FAGGREGATABLE[]
  779. = { 'a','g','g','r','e','g','a','t','a','b','l','e','\0' };
  780. const WCHAR wszTYPEFLAG_FREPLACEABLE[]
  781. = { 'r','e','p','l','a','c','a','b','l','e','\0' };
  782. const WCHAR wszTYPEFLAG_FREVERSEBIND[]
  783. = { 'r','e','v','e','r','s','e','b','i','n','d','\0' };
  784. const WCHAR wszTYPEFLAG_FPROXY[] = { 'p','r','o','x','y','\0' };
  785. AddToTLDataStrW(pTLData, L"[\n");
  786. if(pTypeAttr->typekind != TKIND_DISPATCH)
  787. {
  788. AddSpaces(pTLData, TAB_SIZE);
  789. AddToTLDataStrW(pTLData, wszOdl);
  790. AddToTLDataStrW(pTLData, L",\n");
  791. }
  792. AddSpaces(pTLData, TAB_SIZE);
  793. AddToTLDataStrW(pTLData, wszUUID);
  794. AddToTLDataStrW(pTLData, L"(");
  795. StringFromGUID2(&(pTypeAttr->guid), wszGuid, MAX_LOAD_STRING);
  796. wszGuid[lstrlenW(wszGuid)-1] = '\0';
  797. AddToTLDataStrW(pTLData, &wszGuid[1]);
  798. AddToTLDataStrW(pTLData, L")");
  799. if(wszHelpString)
  800. {
  801. AddToTLDataStrW(pTLData, L",\n");
  802. AddSpaces(pTLData, TAB_SIZE);
  803. AddToTLDataStrW(pTLData, wszHelpstring);
  804. AddToTLDataStrW(pTLData, L"(\"");
  805. AddToTLDataStrW(pTLData, wszHelpString);
  806. AddToTLDataStrW(pTLData, L"\")");
  807. }
  808. if(ulHelpContext)
  809. {
  810. AddToTLDataStrW(pTLData, L",\n");
  811. AddSpaces(pTLData, TAB_SIZE);
  812. AddToTLDataStrW(pTLData, wszHelpcontext);
  813. AddToTLDataStrW(pTLData, L"(");
  814. wsprintfW(wszHelpContext, wszFormat, ulHelpContext);
  815. AddToTLDataStrW(pTLData, wszHelpContext);
  816. AddToTLDataStrW(pTLData, L")");
  817. }
  818. if(pTypeAttr->wTypeFlags)
  819. {
  820. #define ENUM_FLAGS(x) if(pTypeAttr->wTypeFlags & x)\
  821. {\
  822. AddToTLDataStrW(pTLData, L",\n");\
  823. AddSpaces(pTLData, TAB_SIZE);\
  824. AddToTLDataStrW(pTLData, wsz##x);\
  825. }
  826. ENUM_FLAGS(TYPEFLAG_FAPPOBJECT);
  827. ENUM_FLAGS(TYPEFLAG_FCANCREATE);
  828. ENUM_FLAGS(TYPEFLAG_FLICENSED);
  829. ENUM_FLAGS(TYPEFLAG_FPREDECLID);
  830. ENUM_FLAGS(TYPEFLAG_FHIDDEN);
  831. ENUM_FLAGS(TYPEFLAG_FCONTROL);
  832. ENUM_FLAGS(TYPEFLAG_FDUAL);
  833. ENUM_FLAGS(TYPEFLAG_FNONEXTENSIBLE);
  834. ENUM_FLAGS(TYPEFLAG_FOLEAUTOMATION);
  835. ENUM_FLAGS(TYPEFLAG_FRESTRICTED);
  836. ENUM_FLAGS(TYPEFLAG_FAGGREGATABLE);
  837. ENUM_FLAGS(TYPEFLAG_FREPLACEABLE);
  838. ENUM_FLAGS(TYPEFLAG_FREVERSEBIND);
  839. ENUM_FLAGS(TYPEFLAG_FPROXY);
  840. }
  841. AddToTLDataStrW(pTLData, L"\n]\n");
  842. if(pTypeAttr->typekind != TKIND_DISPATCH) AddToTLDataStrW(pTLData, wszInterface);
  843. else AddToTLDataStrW(pTLData, wszDispinterface);
  844. AddToTLDataStrW(pTLData, wszName);
  845. AddToTLDataStrW(pTLData, L" ");
  846. if(cImplTypes && pTypeAttr->typekind != TKIND_DISPATCH)
  847. {
  848. AddToTLDataStrW(pTLData, L": ");
  849. ITypeInfo_GetRefTypeOfImplType(pTypeInfo, 0, &hRefType);
  850. if (SUCCEEDED(ITypeInfo_GetRefTypeInfo(pTypeInfo, hRefType, &pRefTypeInfo)))
  851. {
  852. ITypeInfo_GetDocumentation(pRefTypeInfo, MEMBERID_NIL, &bstrName,
  853. NULL, NULL, NULL);
  854. AddToTLDataStrW(pTLData, bstrName);
  855. AddToTLDataStrW(pTLData, L" ");
  856. SysFreeString(bstrName);
  857. ITypeInfo_Release(pRefTypeInfo);
  858. }
  859. else
  860. AddToTLDataStrW(pTLData, wszFailed);
  861. }
  862. AddToTLDataStrW(pTLData, L"{\n");
  863. AddToStrW(pTLData->wszInsertAfter, L"};\n");
  864. }
  865. static void CreateTypedefHeader(ITypeInfo *pTypeInfo,
  866. TYPEATTR *pTypeAttr, TYPELIB_DATA *pTLData)
  867. {
  868. BOOL bFirst = TRUE;
  869. WCHAR wszGuid[MAX_LOAD_STRING];
  870. const WCHAR wszTypedef[] = { 't','y','p','e','d','e','f',' ','\0' };
  871. const WCHAR wszPublic[] = { 'p','u','b','l','i','c','\0' };
  872. AddToTLDataStrW(pTLData, wszTypedef);
  873. if(memcmp(&pTypeAttr->guid, &GUID_NULL, sizeof(GUID)))
  874. {
  875. AddToTLDataStrW(pTLData, L"[");
  876. bFirst = FALSE;
  877. AddToTLDataStrW(pTLData, wszUUID);
  878. AddToTLDataStrW(pTLData, L"(");
  879. StringFromGUID2(&(pTypeAttr->guid), wszGuid, MAX_LOAD_STRING);
  880. wszGuid[lstrlenW(wszGuid)-1] = '\0';
  881. AddToTLDataStrW(pTLData, &wszGuid[1]);
  882. AddToTLDataStrW(pTLData, L")");
  883. }
  884. if(pTypeAttr->typekind == TKIND_ALIAS)
  885. {
  886. if(bFirst) AddToTLDataStrW(pTLData, L"[");
  887. else AddToTLDataStrW(pTLData, L", ");
  888. bFirst = FALSE;
  889. AddToTLDataStrW(pTLData, wszPublic);
  890. }
  891. if(!bFirst) AddToTLDataStrW(pTLData, L"]\n");
  892. }
  893. static void CreateCoclassHeader(ITypeInfo *pTypeInfo,
  894. TYPEATTR *pTypeAttr, TYPELIB_DATA *pTLData)
  895. {
  896. WCHAR wszGuid[MAX_LOAD_STRING];
  897. BSTR bstrHelpString;
  898. const WCHAR wszNoncreatable[]
  899. = { 'n','o','n','c','r','e','a','t','a','b','l','e','\0' };
  900. AddToTLDataStrW(pTLData, L"[\n");
  901. AddSpaces(pTLData, TAB_SIZE);
  902. AddToTLDataStrW(pTLData, wszUUID);
  903. AddToTLDataStrW(pTLData, L"(");
  904. StringFromGUID2(&(pTypeAttr->guid), wszGuid, MAX_LOAD_STRING);
  905. wszGuid[lstrlenW(wszGuid)-1] = '\0';
  906. AddToTLDataStrW(pTLData, &wszGuid[1]);
  907. AddToTLDataStrW(pTLData, L")");
  908. if(SUCCEEDED(ITypeInfo_GetDocumentation(pTypeInfo, MEMBERID_NIL, NULL,
  909. &bstrHelpString, NULL, NULL)))
  910. {
  911. if(SysStringLen(bstrHelpString))
  912. {
  913. AddToTLDataStrW(pTLData, L",\n");
  914. AddSpaces(pTLData, TAB_SIZE);
  915. AddToTLDataStrW(pTLData, wszHelpstring);
  916. AddToTLDataStrW(pTLData, L"(\"");
  917. AddToTLDataStrW(pTLData, bstrHelpString);
  918. AddToTLDataStrW(pTLData, L"\")");
  919. }
  920. SysFreeString(bstrHelpString);
  921. }
  922. if(!(pTypeAttr->wTypeFlags & TYPEFLAG_FCANCREATE))
  923. {
  924. AddToTLDataStrW(pTLData, L",\n");
  925. AddSpaces(pTLData, TAB_SIZE);
  926. AddToTLDataStrW(pTLData, wszNoncreatable);
  927. }
  928. AddToTLDataStrW(pTLData, L"\n]\n");
  929. }
  930. static int PopulateTree(void)
  931. {
  932. TVINSERTSTRUCTW tvis;
  933. TVITEMW tvi;
  934. ITypeLib *pTypeLib;
  935. TLIBATTR *pTLibAttr;
  936. ITypeInfo *pTypeInfo, *pRefTypeInfo;
  937. HREFTYPE hRefType;
  938. TYPEATTR *pTypeAttr;
  939. INT count, i;
  940. ULONG ulHelpContext;
  941. BSTR bstrName;
  942. BSTR bstrData;
  943. WCHAR wszText[MAX_LOAD_STRING];
  944. WCHAR wszAfter[MAX_LOAD_STRING];
  945. HRESULT hRes;
  946. HTREEITEM hParent;
  947. HTREEITEM hMain;
  948. BOOL bInsert;
  949. TYPELIB_DATA *tldDispatch;
  950. TYPELIB_DATA *tld;
  951. const WCHAR wszGeneratedInfo[] = { '/','/',' ','G','e','n','e','r','a','t','e','d',
  952. ' ','.','I','D','L',' ','f','i','l','e',' ','(','b','y',' ','t','h','e',' ',
  953. 'O','L','E','/','C','O','M',' ','O','b','j','e','c','t',' ',
  954. 'V','i','e','w','e','r',')','\n','/','/','\n','/','/',' ',
  955. 't','y','p','e','l','i','b',' ','f','i','l','e','n','a','m','e',':',' ','\0'};
  956. const WCHAR wszFormat[] = { '%','s',' ','(','%','s',')','\0' };
  957. const WCHAR wszFormat2[] = { 'v','e','r','s','i','o','n',
  958. '(','%','l','d','.','%','l','d',')','\0' };
  959. const WCHAR wszTKIND_ENUM[] = { 't','y','p','e','d','e','f',' ','e','n','u','m',' ','\0' };
  960. const WCHAR wszTKIND_RECORD[]
  961. = { 't','y','p','e','d','e','f',' ','s','t','r','u','c','t',' ','\0' };
  962. const WCHAR wszTKIND_MODULE[] = { 'm','o','d','u','l','e',' ','\0' };
  963. const WCHAR wszTKIND_INTERFACE[] = { 'i','n','t','e','r','f','a','c','e',' ','\0' };
  964. const WCHAR wszTKIND_DISPATCH[]
  965. = { 'd','i','s','p','i','n','t','e','r','f','a','c','e',' ','\0' };
  966. const WCHAR wszTKIND_COCLASS[] = { 'c','o','c','l','a','s','s',' ','\0' };
  967. const WCHAR wszTKIND_ALIAS[] = { 't','y','p','e','d','e','f',' ','\0' };
  968. const WCHAR wszTKIND_UNION[]
  969. = { 't','y','p','e','d','e','f',' ','u','n','i','o','n',' ','\0' };
  970. const WCHAR wszLibrary[] = { 'l','i','b','r','a','r','y',' ','\0' };
  971. const WCHAR wszTag[] = { 't','a','g','\0' };
  972. WCHAR wszProperties[] = { 'p','r','o','p','e','r','t','i','e','s','\0' };
  973. WCHAR wszMethods[] = { 'm','e','t','h','o','d','s','\0' };
  974. U(tvis).item.mask = TVIF_TEXT|TVIF_PARAM;
  975. U(tvis).item.cchTextMax = MAX_LOAD_STRING;
  976. U(tvis).item.pszText = wszText;
  977. tvis.hInsertAfter = TVI_LAST;
  978. tvis.hParent = TVI_ROOT;
  979. if(FAILED((hRes = LoadTypeLib(typelib.wszFileName, &pTypeLib))))
  980. {
  981. WCHAR wszMessage[MAX_LOAD_STRING];
  982. WCHAR wszError[MAX_LOAD_STRING];
  983. DWORD_PTR args[2];
  984. LoadStringW(globals.hMainInst, IDS_ERROR_LOADTYPELIB, wszError, ARRAY_SIZE(wszError));
  985. args[0] = (DWORD_PTR)typelib.wszFileName;
  986. args[1] = hRes;
  987. FormatMessageW(FORMAT_MESSAGE_FROM_STRING|FORMAT_MESSAGE_ARGUMENT_ARRAY,
  988. wszError, 0, 0, wszMessage, ARRAY_SIZE(wszMessage), (__ms_va_list*)args);
  989. MessageBoxW(globals.hMainWnd, wszMessage, NULL, MB_OK|MB_ICONEXCLAMATION);
  990. return 1;
  991. }
  992. count = ITypeLib_GetTypeInfoCount(pTypeLib);
  993. ITypeLib_GetDocumentation(pTypeLib, -1, &bstrName, &bstrData, NULL, NULL);
  994. ITypeLib_GetLibAttr(pTypeLib, &pTLibAttr);
  995. tld = InitializeTLData();
  996. U(tvis).item.lParam = (LPARAM) tld;
  997. AddToTLDataStrW(tld, wszGeneratedInfo);
  998. AddToTLDataStrW(tld, typelib.wszFileName);
  999. AddToTLDataStrW(tld, L"\n\n[\n");
  1000. AddSpaces(tld, TAB_SIZE);
  1001. AddToTLDataStrW(tld, wszUUID);
  1002. AddToTLDataStrW(tld, L"(");
  1003. StringFromGUID2(&(pTLibAttr->guid), wszText, MAX_LOAD_STRING);
  1004. wszText[lstrlenW(wszText)-1] = '\0';
  1005. AddToTLDataStrW(tld, &wszText[1]);
  1006. AddToTLDataStrW(tld, L"),\n");
  1007. AddSpaces(tld, TAB_SIZE);
  1008. wsprintfW(wszText, wszFormat2, pTLibAttr->wMajorVerNum, pTLibAttr->wMinorVerNum);
  1009. AddToTLDataStrW(tld, wszText);
  1010. if (bstrData)
  1011. {
  1012. /* helpstring is optional */
  1013. AddToTLDataStrW(tld, L",\n");
  1014. AddSpaces(tld, TAB_SIZE);
  1015. AddToTLDataStrW(tld, wszHelpstring);
  1016. AddToTLDataStrW(tld, L"(\"");
  1017. AddToTLDataStrW(tld, bstrData);
  1018. AddToTLDataStrW(tld, L"\")");
  1019. }
  1020. AddToTLDataStrW(tld, L"\n]\n");
  1021. AddToTLDataStrW(tld, wszLibrary);
  1022. if (bstrName) AddToTLDataStrW(tld, bstrName);
  1023. AddToTLDataStrW(tld, L"\n{\n");
  1024. AddToStrW(tld->wszInsertAfter, L"};");
  1025. wsprintfW(wszText, wszFormat, bstrName, bstrData);
  1026. SysFreeString(bstrName);
  1027. SysFreeString(bstrData);
  1028. tvis.hParent = (HTREEITEM)SendMessageW(typelib.hTree,
  1029. TVM_INSERTITEMW, 0, (LPARAM)&tvis);
  1030. for(i=0; i<count; i++)
  1031. {
  1032. bInsert = TRUE;
  1033. ITypeLib_GetTypeInfo(pTypeLib, i, &pTypeInfo);
  1034. ITypeInfo_GetDocumentation(pTypeInfo, MEMBERID_NIL, &bstrName, &bstrData,
  1035. &ulHelpContext, NULL);
  1036. ITypeInfo_GetTypeAttr(pTypeInfo, &pTypeAttr);
  1037. memset(wszText, 0, sizeof(wszText));
  1038. memset(wszAfter, 0, sizeof(wszAfter));
  1039. tld = InitializeTLData();
  1040. U(tvis).item.lParam = (LPARAM)tld;
  1041. switch(pTypeAttr->typekind)
  1042. {
  1043. case TKIND_ENUM:
  1044. AddToStrW(wszText, wszTKIND_ENUM);
  1045. AddToStrW(wszText, bstrName);
  1046. CreateTypedefHeader(pTypeInfo, pTypeAttr, tld);
  1047. AddToTLDataStrW(tld, &wszTKIND_ENUM[lstrlenW(wszTKIND_ALIAS)]);
  1048. AddToTLDataStrW(tld, L"{\n");
  1049. AddToStrW(tld->wszInsertAfter, L"} ");
  1050. AddToStrW(tld->wszInsertAfter, bstrName);
  1051. AddToStrW(tld->wszInsertAfter, L";\n");
  1052. bInsert = FALSE;
  1053. hParent = TreeView_InsertItemW(typelib.hTree, &tvis);
  1054. EnumEnums(pTypeInfo, pTypeAttr->cVars, hParent);
  1055. AddChildrenData(hParent, tld);
  1056. AddToTLDataStrW(tld, tld->wszInsertAfter);
  1057. break;
  1058. case TKIND_RECORD:
  1059. AddToTLDataStrW(tld, wszTKIND_RECORD);
  1060. AddToTLDataStrW(tld, wszTag);
  1061. AddToTLDataStrW(tld, bstrName);
  1062. AddToTLDataStrW(tld, L" {\n");
  1063. AddToStrW(tld->wszInsertAfter, L"} ");
  1064. AddToStrW(tld->wszInsertAfter, bstrName);
  1065. AddToStrW(tld->wszInsertAfter, L";\n");
  1066. AddToStrW(wszText, wszTKIND_RECORD);
  1067. AddToStrW(wszText, bstrName);
  1068. break;
  1069. case TKIND_MODULE:
  1070. AddToStrW(wszText, wszTKIND_MODULE);
  1071. AddToStrW(wszText, bstrName);
  1072. break;
  1073. case TKIND_INTERFACE:
  1074. CreateInterfaceInfo(pTypeInfo, pTypeAttr->cImplTypes, bstrName,
  1075. bstrData, ulHelpContext, pTypeAttr, tld);
  1076. tld->bPredefine = TRUE;
  1077. AddToStrW(wszText, wszTKIND_INTERFACE);
  1078. AddToStrW(wszText, bstrName);
  1079. break;
  1080. case TKIND_COCLASS:
  1081. AddToStrW(wszText, wszTKIND_COCLASS);
  1082. AddToStrW(wszText, bstrName);
  1083. CreateCoclassHeader(pTypeInfo, pTypeAttr, tld);
  1084. AddToTLDataStrW(tld, wszTKIND_COCLASS);
  1085. AddToTLDataStrW(tld, bstrName);
  1086. AddToTLDataStrW(tld, L" {\n");
  1087. EnumCoclassImplTypes(pTypeInfo, pTypeAttr->cImplTypes, tld);
  1088. AddToStrW(tld->wszInsertAfter, L"};\n");
  1089. bInsert = FALSE;
  1090. hParent = TreeView_InsertItemW(typelib.hTree, &tvis);
  1091. AddToTLDataStrW(tld, tld->wszInsertAfter);
  1092. break;
  1093. case TKIND_UNION:
  1094. AddToStrW(wszText, wszTKIND_UNION);
  1095. AddToStrW(wszText, bstrName);
  1096. break;
  1097. case TKIND_DISPATCH:
  1098. CreateInterfaceInfo(pTypeInfo, pTypeAttr->cImplTypes, bstrName,
  1099. bstrData, ulHelpContext, pTypeAttr, tld);
  1100. tld->bPredefine = TRUE;
  1101. if(pTypeAttr->wTypeFlags & TYPEFLAG_FDUAL)
  1102. tld->bHide = TRUE;
  1103. AddToStrW(wszText, wszTKIND_DISPATCH);
  1104. AddToStrW(wszText, bstrName);
  1105. hParent = TreeView_InsertItemW(typelib.hTree, &tvis);
  1106. hMain = tvis.hParent;
  1107. tldDispatch = tld;
  1108. lstrcpyW(wszText, wszProperties);
  1109. tvis.hParent = hParent;
  1110. tld = InitializeTLData();
  1111. U(tvis).item.lParam = (LPARAM) tld;
  1112. AddToTLDataStrW(tld, wszProperties);
  1113. AddToTLDataStrW(tld, L":\n");
  1114. tvis.hParent = TreeView_InsertItemW(typelib.hTree, &tvis);
  1115. EnumVars(pTypeInfo, pTypeAttr->cVars, tvis.hParent);
  1116. AddChildrenData(tvis.hParent, tld);
  1117. lstrcpyW(wszText, wszMethods);
  1118. tvis.hParent = hParent;
  1119. tld = InitializeTLData();
  1120. U(tvis).item.lParam = (LPARAM) tld;
  1121. AddToTLDataStrW(tld, wszMethods);
  1122. AddToTLDataStrW(tld, L":\n");
  1123. tvis.hParent = TreeView_InsertItemW(typelib.hTree, &tvis);
  1124. EnumFuncs(pTypeInfo, pTypeAttr, tvis.hParent);
  1125. AddChildrenData(tvis.hParent, tld);
  1126. EnumImplTypes(pTypeInfo, pTypeAttr->cImplTypes, hParent);
  1127. AddChildrenData(hParent, tldDispatch);
  1128. AddToTLDataStrW(tldDispatch, tldDispatch->wszInsertAfter);
  1129. bInsert = FALSE;
  1130. tvis.hParent = hMain;
  1131. if(SUCCEEDED(ITypeInfo_GetRefTypeOfImplType(pTypeInfo, -1, &hRefType)))
  1132. {
  1133. bInsert = TRUE;
  1134. ITypeInfo_ReleaseTypeAttr(pTypeInfo, pTypeAttr);
  1135. SysFreeString(bstrName);
  1136. SysFreeString(bstrData);
  1137. memset(wszText, 0, sizeof(wszText));
  1138. tld = InitializeTLData();
  1139. U(tvis).item.lParam = (LPARAM) tld;
  1140. ITypeInfo_GetRefTypeInfo(pTypeInfo, hRefType, &pRefTypeInfo);
  1141. ITypeInfo_GetDocumentation(pRefTypeInfo, MEMBERID_NIL, &bstrName,
  1142. &bstrData, &ulHelpContext, NULL);
  1143. ITypeInfo_GetTypeAttr(pRefTypeInfo, &pTypeAttr);
  1144. CreateInterfaceInfo(pTypeInfo, pTypeAttr->cImplTypes, bstrName,
  1145. bstrData, ulHelpContext, pTypeAttr, tld);
  1146. tld->bPredefine = TRUE;
  1147. AddToStrW(wszText, wszTKIND_INTERFACE);
  1148. AddToStrW(wszText, bstrName);
  1149. ITypeInfo_Release(pRefTypeInfo);
  1150. }
  1151. break;
  1152. case TKIND_ALIAS:
  1153. AddToStrW(wszText, wszTKIND_ALIAS);
  1154. CreateTypeInfo(wszText, wszAfter, pTypeAttr->tdescAlias, pTypeInfo);
  1155. AddToStrW(wszText, L" ");
  1156. AddToStrW(wszText, bstrName);
  1157. AddToStrW(wszText, wszAfter);
  1158. CreateTypedefHeader(pTypeInfo, pTypeAttr, tld);
  1159. AddToTLDataStrW(tld, &wszText[lstrlenW(wszTKIND_ALIAS)]);
  1160. AddToTLDataStrW(tld, L";\n");
  1161. break;
  1162. default:
  1163. lstrcpyW(wszText, bstrName);
  1164. WINE_FIXME("pTypeAttr->typekind == %d not supported\n",
  1165. pTypeAttr->typekind);
  1166. }
  1167. if(bInsert)
  1168. {
  1169. hParent = TreeView_InsertItemW(typelib.hTree, &tvis);
  1170. EnumVars(pTypeInfo, pTypeAttr->cVars, hParent);
  1171. EnumFuncs(pTypeInfo, pTypeAttr, hParent);
  1172. EnumImplTypes(pTypeInfo, pTypeAttr->cImplTypes, hParent);
  1173. if(memcmp(bstrName, wszVT_UNKNOWN, sizeof(wszVT_UNKNOWN)))
  1174. AddChildrenData(hParent, tld);
  1175. AddToTLDataStrW(tld, tld->wszInsertAfter);
  1176. }
  1177. ITypeInfo_ReleaseTypeAttr(pTypeInfo, pTypeAttr);
  1178. ITypeInfo_Release(pTypeInfo);
  1179. SysFreeString(bstrName);
  1180. SysFreeString(bstrData);
  1181. }
  1182. SendMessageW(typelib.hTree, TVM_EXPAND, TVE_EXPAND, (LPARAM)tvis.hParent);
  1183. memset(&tvi, 0, sizeof(TVITEMW));
  1184. tvi.mask = TVIF_PARAM;
  1185. tvi.hItem = tvis.hParent;
  1186. SendMessageW(typelib.hTree, TVM_GETITEMW, 0, (LPARAM)&tvi);
  1187. AddPredefinitions(tvi.hItem, (TYPELIB_DATA*)(tvi.lParam));
  1188. AddIdlData(tvi.hItem, (TYPELIB_DATA*)(tvi.lParam));
  1189. AddToTLDataStrW((TYPELIB_DATA*)(tvi.lParam),
  1190. ((TYPELIB_DATA*)(tvi.lParam))->wszInsertAfter);
  1191. ITypeLib_Release(pTypeLib);
  1192. return 0;
  1193. }
  1194. void UpdateData(HTREEITEM item)
  1195. {
  1196. TVITEMW tvi;
  1197. memset(&tvi, 0, sizeof(TVITEMW));
  1198. tvi.mask = TVIF_PARAM;
  1199. tvi.hItem = item;
  1200. SendMessageW(typelib.hTree, TVM_GETITEMW, 0, (LPARAM)&tvi);
  1201. if(!tvi.lParam)
  1202. {
  1203. SetWindowTextW(typelib.hEdit, L" ");
  1204. return;
  1205. }
  1206. SetWindowTextW(typelib.hEdit, ((TYPELIB_DATA*)tvi.lParam)->idl);
  1207. }
  1208. static void TypeLibResizeChild(void)
  1209. {
  1210. RECT client, stat;
  1211. MoveWindow(typelib.hStatusBar, 0, 0, 0, 0, TRUE);
  1212. if(IsWindowVisible(typelib.hStatusBar))
  1213. GetClientRect(typelib.hStatusBar, &stat);
  1214. else stat.bottom = 0;
  1215. GetClientRect(globals.hTypeLibWnd, &client);
  1216. MoveWindow(typelib.hPaneWnd, 0, 0,
  1217. client.right, client.bottom-stat.bottom, TRUE);
  1218. }
  1219. static void TypeLibMenuCommand(WPARAM wParam, HWND hWnd)
  1220. {
  1221. BOOL vis;
  1222. switch(wParam)
  1223. {
  1224. case IDM_SAVEAS:
  1225. GetSaveIdlAsPath();
  1226. break;
  1227. case IDM_STATUSBAR:
  1228. vis = IsWindowVisible(typelib.hStatusBar);
  1229. ShowWindow(typelib.hStatusBar, vis ? SW_HIDE : SW_SHOW);
  1230. CheckMenuItem(GetMenu(hWnd), LOWORD(wParam),
  1231. vis ? MF_UNCHECKED : MF_CHECKED);
  1232. TypeLibResizeChild();
  1233. break;
  1234. case IDM_CLOSE:
  1235. DestroyWindow(hWnd);
  1236. break;
  1237. }
  1238. }
  1239. static void UpdateTypeLibStatusBar(int itemID)
  1240. {
  1241. WCHAR info[MAX_LOAD_STRING];
  1242. if(!LoadStringW(globals.hMainInst, itemID, info, ARRAY_SIZE(info)))
  1243. LoadStringW(globals.hMainInst, IDS_READY, info, ARRAY_SIZE(info));
  1244. SendMessageW(typelib.hStatusBar, SB_SETTEXTW, 0, (LPARAM)info);
  1245. }
  1246. static void EmptyTLTree(void)
  1247. {
  1248. HTREEITEM cur, del;
  1249. TVITEMW tvi;
  1250. tvi.mask = TVIF_PARAM;
  1251. cur = (HTREEITEM)SendMessageW(typelib.hTree, TVM_GETNEXTITEM,
  1252. TVGN_CHILD, (LPARAM)TVI_ROOT);
  1253. while(TRUE)
  1254. {
  1255. del = cur;
  1256. cur = (HTREEITEM)SendMessageW(typelib.hTree, TVM_GETNEXTITEM,
  1257. TVGN_CHILD, (LPARAM)del);
  1258. if(!cur) cur = (HTREEITEM)SendMessageW(typelib.hTree,
  1259. TVM_GETNEXTITEM, TVGN_NEXT, (LPARAM)del);
  1260. if(!cur) cur = (HTREEITEM)SendMessageW(typelib.hTree,
  1261. TVM_GETNEXTITEM, TVGN_PARENT, (LPARAM)del);
  1262. tvi.hItem = del;
  1263. SendMessageW(typelib.hTree, TVM_GETITEMW, 0, (LPARAM)&tvi);
  1264. if(tvi.lParam)
  1265. {
  1266. HeapFree(GetProcessHeap(), 0, ((TYPELIB_DATA *)tvi.lParam)->idl);
  1267. HeapFree(GetProcessHeap(), 0, (TYPELIB_DATA *)tvi.lParam);
  1268. }
  1269. SendMessageW(typelib.hTree, TVM_DELETEITEM, 0, (LPARAM)del);
  1270. if(!cur) break;
  1271. }
  1272. }
  1273. static LRESULT CALLBACK TypeLibProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  1274. {
  1275. switch(uMsg)
  1276. {
  1277. case WM_CREATE:
  1278. {
  1279. if(!CreatePanedWindow(hWnd, &typelib.hPaneWnd, globals.hMainInst))
  1280. DestroyWindow(hWnd);
  1281. typelib.hTree = CreateWindowExW(WS_EX_CLIENTEDGE, WC_TREEVIEWW, NULL,
  1282. WS_CHILD|WS_VISIBLE|TVS_HASLINES|TVS_HASBUTTONS|TVS_LINESATROOT,
  1283. 0, 0, 0, 0, typelib.hPaneWnd, (HMENU)TYPELIB_TREE,
  1284. globals.hMainInst, NULL);
  1285. typelib.hEdit = CreateWindowExW(WS_EX_CLIENTEDGE, WC_EDITW, NULL,
  1286. WS_CHILD|WS_VISIBLE|ES_MULTILINE|ES_READONLY|WS_HSCROLL|WS_VSCROLL,
  1287. 0, 0, 0, 0, typelib.hPaneWnd, NULL, globals.hMainInst, NULL);
  1288. SetLeft(typelib.hPaneWnd, typelib.hTree);
  1289. SetRight(typelib.hPaneWnd, typelib.hEdit);
  1290. if(PopulateTree()) DestroyWindow(hWnd);
  1291. else SetFocus(typelib.hTree);
  1292. break;
  1293. }
  1294. case WM_COMMAND:
  1295. TypeLibMenuCommand(LOWORD(wParam), hWnd);
  1296. break;
  1297. case WM_MENUSELECT:
  1298. UpdateTypeLibStatusBar(LOWORD(wParam));
  1299. break;
  1300. case WM_SETFOCUS:
  1301. SetFocus(typelib.hTree);
  1302. break;
  1303. case WM_SIZE:
  1304. if(wParam == SIZE_MINIMIZED) break;
  1305. TypeLibResizeChild();
  1306. break;
  1307. case WM_DESTROY:
  1308. EmptyTLTree();
  1309. break;
  1310. default:
  1311. return DefWindowProcW(hWnd, uMsg, wParam, lParam);
  1312. }
  1313. return 0;
  1314. }
  1315. BOOL TypeLibRegisterClassW(void)
  1316. {
  1317. WNDCLASSW wcc;
  1318. memset(&wcc, 0, sizeof(WNDCLASSW));
  1319. wcc.lpfnWndProc = TypeLibProc;
  1320. wcc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
  1321. wcc.hCursor = LoadCursorW(0, (LPCWSTR)IDC_ARROW);
  1322. wcc.lpszMenuName = MAKEINTRESOURCEW(IDM_TYPELIB);
  1323. wcc.lpszClassName = wszTypeLib;
  1324. if(!RegisterClassW(&wcc))
  1325. return FALSE;
  1326. return TRUE;
  1327. }
  1328. BOOL CreateTypeLibWindow(HINSTANCE hInst, WCHAR *wszFileName)
  1329. {
  1330. WCHAR wszTitle[MAX_LOAD_STRING];
  1331. LoadStringW(hInst, IDS_TYPELIBTITLE, wszTitle, ARRAY_SIZE(wszTitle));
  1332. if(wszFileName) lstrcpyW(typelib.wszFileName, wszFileName);
  1333. else
  1334. {
  1335. TVITEMW tvi;
  1336. memset(&tvi, 0, sizeof(TVITEMW));
  1337. tvi.hItem = (HTREEITEM)SendMessageW(globals.hTree, TVM_GETNEXTITEM,
  1338. TVGN_CARET, 0);
  1339. SendMessageW(globals.hTree, TVM_GETITEMW, 0, (LPARAM)&tvi);
  1340. lstrcpyW(typelib.wszFileName, ((ITEM_INFO*)tvi.lParam)->path);
  1341. }
  1342. globals.hTypeLibWnd = CreateWindowW(wszTypeLib, wszTitle,
  1343. WS_OVERLAPPEDWINDOW|WS_VISIBLE,
  1344. CW_USEDEFAULT, CW_USEDEFAULT, 800, 600, NULL, NULL, hInst, NULL);
  1345. if(!globals.hTypeLibWnd) return FALSE;
  1346. typelib.hStatusBar = CreateStatusWindowW(WS_VISIBLE|WS_CHILD,
  1347. wszTitle, globals.hTypeLibWnd, 0);
  1348. TypeLibResizeChild();
  1349. return TRUE;
  1350. }