TLBODL.CPP
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:52k
源码类别:

Windows编程

开发平台:

Visual C++

  1. // tlbodl.cpp : implementation file
  2. //
  3. // This is a part of the Microsoft Foundation Classes C++ library.
  4. // Copyright (C) 1992-1998 Microsoft Corporation
  5. // All rights reserved.
  6. //
  7. // This source code is only intended as a supplement to the
  8. // Microsoft Foundation Classes Reference and related
  9. // electronic documentation provided with the library.
  10. // See these sources for detailed information regarding the
  11. // Microsoft Foundation Classes product.
  12. #include "stdafx.h"
  13. #include "iviewers.h"
  14. #include "iview.h"
  15. #include "util.h"
  16. #include "iviewers.h"
  17. #include "iviewer.h"
  18. #include "typelib.h"
  19. #include "tree.h"
  20. #include "tlbodl.h"
  21. #ifdef _DEBUG
  22. #undef THIS_FILE
  23. static char BASED_CODE THIS_FILE[] = __FILE__;
  24. #endif
  25. #define MAX_NAMES   64     // max parameters to a function
  26. IStream* CreateMemoryStream();
  27. int StringFromGUID2T(REFGUID rguid, LPTSTR lpszGUID, int cbMax);
  28. // if defined, when typedefs are written out a tag is created
  29. // by concatinating "tag" with the typedef name.
  30. #define _WRITE_TAG 1
  31. /////////////////////////////////////////////////////////////////////////////
  32. // CTypeLibODLView
  33. IMPLEMENT_DYNCREATE(CTypeLibODLView, CEditView)
  34. CTypeLibODLView::CTypeLibODLView()
  35. {
  36. }
  37. CTypeLibODLView::~CTypeLibODLView()
  38. {
  39. }
  40. BEGIN_MESSAGE_MAP(CTypeLibODLView, CEditView)
  41. //{{AFX_MSG_MAP(CTypeLibODLView)
  42. ON_WM_DESTROY()
  43. //}}AFX_MSG_MAP
  44. END_MESSAGE_MAP()
  45. /////////////////////////////////////////////////////////////////////////////
  46. // CTypeLibODLView drawing
  47. void CTypeLibODLView::OnDraw(CDC* pDC)
  48. {
  49. }
  50. /////////////////////////////////////////////////////////////////////////////
  51. // CTypeLibODLView diagnostics
  52. #ifdef _DEBUG
  53. void CTypeLibODLView::AssertValid() const
  54. {
  55. CEditView::AssertValid();
  56. }
  57. void CTypeLibODLView::Dump(CDumpContext& dc) const
  58. {
  59. CEditView::Dump(dc);
  60. }
  61. #endif //_DEBUG
  62. /////////////////////////////////////////////////////////////////////////////
  63. // CTypeLibODLView message handlers
  64. BOOL CTypeLibODLView::PreCreateWindow(CREATESTRUCT& cs)
  65. {
  66. cs.style |= ES_READONLY | ES_MULTILINE | WS_VSCROLL | WS_HSCROLL ;
  67. return CEditView::PreCreateWindow(cs);
  68. }
  69. void CTypeLibODLView::OnInitialUpdate()
  70. {
  71. m_Font.CreateFont( -11, 0, 0, 0, 0, 0,
  72. 0, 0, ANSI_CHARSET, 0, 0, 0,
  73. FIXED_PITCH | FF_DONTCARE, _T("Courier New") ) ;
  74. SetFont( &m_Font );
  75. CEditView::OnInitialUpdate();
  76. }
  77. void CTypeLibODLView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint)
  78. {
  79. CTypeLibWnd* pFrame = (CTypeLibWnd*)GetParent()->GetParent() ;
  80. ASSERT(pFrame->IsKindOf(RUNTIME_CLASS(CTypeLibWnd)));
  81. if (pFrame->m_pSelectedItem == NULL)
  82. {
  83. SetWindowText(_T("")) ;
  84. return ;
  85. }
  86. SetRedraw( FALSE ) ;
  87. BeginWaitCursor() ;
  88. CString     sText;
  89. HRESULT     hr = S_OK ;
  90. IStream*    pstm = NULL ;
  91. TRY
  92. {
  93. pstm = CreateMemoryStream() ;
  94. switch(pFrame->m_pSelectedItem->m_Type)
  95. {
  96. case CTreeItem::typeTypeLib:
  97. case CTreeItem::typeTypeLib2:
  98.  hr = DeCompileTypeLib( pstm, pFrame->m_pSelectedItem->GetTypeLib() ) ;
  99. break ;
  100. case CTreeItem::typeEnum:
  101. case CTreeItem::typeRecord:
  102. case CTreeItem::typeModule:
  103. case CTreeItem::typeInterface:
  104. case CTreeItem::typeDispinterface:
  105. case CTreeItem::typeCoClass:
  106. case CTreeItem::typeAlias:
  107. case CTreeItem::typeUnion:
  108. case CTreeItem::typeTypeInfo:
  109. case CTreeItem::typeTypeInfo2:
  110. switch(pFrame->m_pSelectedItem->GetTypeKind())
  111. {
  112. case TKIND_ENUM:
  113. case TKIND_RECORD:
  114. case TKIND_UNION:
  115. case TKIND_ALIAS:
  116.  hr = DeCompileTypedef( pstm, pFrame->m_pSelectedItem->GetTypeInfo() ) ;
  117. break ;
  118. case TKIND_MODULE:
  119.  hr = DeCompileModule( pstm, pFrame->m_pSelectedItem->GetTypeInfo() ) ;
  120. break ;
  121. case TKIND_INTERFACE:
  122.  hr = DeCompileInterface( pstm, pFrame->m_pSelectedItem->GetTypeInfo() ) ;
  123. break ;
  124. case TKIND_DISPATCH:
  125.  hr = DeCompileDispinterface( pstm, pFrame->m_pSelectedItem->GetTypeInfo() ) ;
  126. break ;
  127. case TKIND_COCLASS:
  128.  hr = DeCompileCoClass( pstm, pFrame->m_pSelectedItem->GetTypeInfo() ) ;
  129. break ;
  130. default:
  131. sText = _T("<<unclassified typeinfo>>");
  132. break ;
  133. }
  134. break ;
  135. case CTreeItem::typeMethod:
  136.  hr = DeCompileFunc( pstm, pFrame->m_pSelectedItem->GetTypeInfo(), pFrame->m_pSelectedItem->m_uiMemid ) ;
  137. break ;
  138. case CTreeItem::typeProperty:
  139.  hr = DeCompileVar( pstm, pFrame->m_pSelectedItem->GetTypeInfo(), pFrame->m_pSelectedItem->m_uiMemid ) ;
  140. break ;
  141. case CTreeItem::typeConstant:
  142.  hr = DeCompileConst( pstm, pFrame->m_pSelectedItem->GetTypeInfo(), pFrame->m_pSelectedItem->m_uiMemid ) ;
  143. break ;
  144. case CTreeItem::typeUnknown:
  145. case CTreeItem::typeUnknown2:
  146. case CTreeItem::typeEnums:
  147. case CTreeItem::typeRecords:
  148. case CTreeItem::typeModules:
  149. case CTreeItem::typeInterfaces:
  150. case CTreeItem::typeDispinterfaces:
  151. case CTreeItem::typeCoClasses:
  152. case CTreeItem::typeAliases:
  153. case CTreeItem::typeUnions:
  154. case CTreeItem::typeMethods:
  155. case CTreeItem::typeMethods2:
  156. case CTreeItem::typeProperties:
  157. case CTreeItem::typeProperties2:
  158. case CTreeItem::typeConstants:
  159. case CTreeItem::typeConstants2:
  160. case CTreeItem::typeImplTypes:
  161. case CTreeItem::typeImplTypes2:
  162. default:
  163. //bstr = ::SysAllocString(OLESTR(""));
  164. break ;
  165. }
  166. if (hr != S_OK)
  167. AfxThrowOleException( hr ) ;
  168. if (pstm)
  169. {
  170. STATSTG statstg ;
  171. if (FAILED(hr = pstm->Stat( &statstg,STATFLAG_NONAME )))
  172. AfxThrowOleException( hr ) ;
  173. // Seek to beginning
  174. LARGE_INTEGER li ;
  175. LISet32( li, 0 ) ;
  176. if (FAILED(hr = pstm->Seek( li, STREAM_SEEK_SET, NULL )))
  177. AfxThrowOleException( hr ) ;
  178. // Read into string
  179. LPSTR lpszBuf = sText.GetBuffer(statstg.cbSize.LowPart+1);
  180. if (FAILED(hr = pstm->Read( lpszBuf, statstg.cbSize.LowPart, NULL )))
  181. AfxThrowOleException( hr ) ;
  182. lpszBuf[statstg.cbSize.LowPart] = '';
  183. sText.ReleaseBuffer();
  184. }
  185. SetWindowText(sText);
  186. pstm->Release() ;
  187. }
  188. CATCH(CException, pException)
  189. {
  190. SetWindowText( _T("// Could not decompile selected item") ) ;
  191. if (pstm)
  192. pstm->Release() ;
  193. if (pException->IsKindOf(RUNTIME_CLASS(COleException)))
  194. hr = ((COleException*)pException)->m_sc ;
  195. else if (pException->IsKindOf(RUNTIME_CLASS(COleException)))
  196. hr = E_OUTOFMEMORY ;
  197. if (hr == S_OK)
  198. hr = GetLastError() ;
  199. ErrorMessage( "Could not decompile selected item", hr ) ;
  200. }
  201. END_CATCH
  202. SetRedraw( TRUE ) ;
  203. EndWaitCursor() ;
  204. SendMessage(EM_SETSEL, 0, 0)  ;
  205. }
  206. void CTypeLibODLView::OnDestroy()
  207. {
  208. CEditView::OnDestroy();
  209. m_Font.DeleteObject() ;
  210. }
  211. // Write string s with no indent and no CR
  212. #define WRITE( s )          WriteLine( pstm, s, 0, FALSE )
  213. // Write string s with indent and no CR
  214. #define WRITE1( s )         WriteLine( pstm, s, uiIndent, FALSE )
  215. #define WRITE2( s, ui )     WriteLine( pstm, s, uiIndent+ui, FALSE )
  216. // Write string s with indent and CR
  217. #define WRITELINE( s )      WriteLine( pstm, s, uiIndent, TRUE )
  218. #define WRITELINE2( s, ui ) WriteLine( pstm, s, uiIndent+ui, TRUE )
  219. #define WRITECR( s )        WriteLine( pstm, s, 0, TRUE )
  220. #define WRITERAW( p, len )     WriteRaw( pstm, p, len )
  221. #define WRITEBSTR( p )         WriteBSTR( pstm, p )
  222. inline void WriteRaw( IStream* pstm, const void* pv, UINT cb )
  223. {
  224. HRESULT hr ;
  225. if (FAILED(hr = pstm->Write( pv, cb, NULL )))
  226. AfxThrowOleException( hr ) ;
  227. }
  228. inline void WriteLine( IStream* pstm, const CString &rstr, UINT uiIndent, BOOL fNewLine )
  229. {
  230. while(uiIndent--)
  231. {
  232. WriteRaw( pstm, _T("    "), 4 * sizeof(TCHAR));
  233. }
  234. WriteRaw( pstm, rstr, rstr.GetLength() * sizeof(TCHAR)) ;
  235. if (fNewLine)
  236. WriteRaw(pstm, _T("rn"), 2 * sizeof(TCHAR)) ;
  237. }
  238. inline void WriteBSTR( IStream* pstm, BSTR bstr )
  239. {
  240. UINT len = ::SysStringLen(bstr) ;
  241. if (!len)
  242. return ;
  243. USES_CONVERSION;
  244. LPTSTR lpszSource = OLE2T(bstr);
  245. TCHAR *pstrTemp = new TCHAR[((len + 1) * sizeof(TCHAR)) * 2];
  246. LPTSTR lpD, lpS = lpszSource ;
  247. lpD = pstrTemp;
  248. for (UINT n = 0 ; n < len ; n++)
  249. {
  250. if (!isprint(*lpS) || (*lpS) == '"' || (*lpS) == '\')
  251. {
  252. // "  \ a  b  f  n  r  t  v
  253. *lpD++ = '\' ;
  254. switch(*lpS)
  255. {
  256. case '"':
  257. *lpD++ = '"' ;
  258. break ;
  259. case '\':
  260. *lpD++ = '\' ;
  261. break ;
  262. case 'a':
  263. *lpD++ = 'a' ;
  264. break ;
  265. case 'b':
  266. *lpD++ = 'b' ;
  267. break ;
  268. case 'f':
  269. *lpD++ = 'f' ;
  270. break ;
  271. case 'n':
  272. *lpD++ = 'n' ;
  273. break ;
  274. case 'r':
  275. *lpD++ = 'r' ;
  276. break ;
  277. case 't':
  278. *lpD++ = 't' ;
  279. break ;
  280. case 'v':
  281. *lpD++ = 'v' ;
  282. break ;
  283. case '':
  284. *lpD++ = '0' ;
  285. break ;
  286. default:
  287. lpD += wsprintf( lpD, _T("x%02X"), (UINT)*lpS );
  288. break ;
  289. }
  290. lpS++;
  291. }
  292. else
  293. *lpD++ = *lpS++;
  294. }
  295. *lpD = '';
  296. WriteRaw( pstm, pstrTemp, lstrlen(pstrTemp)*sizeof(TCHAR) ) ;
  297. delete []pstrTemp ;
  298. }
  299. //  // typelib.tlb
  300. //  [
  301. //    uuid(<00026b00-0000-0000-C000-000000000046>),
  302. //    version (<major>.<minor>),
  303. //    helpfile ("<helpfile.hlp>"),
  304. //    helpstring("<helpstring>"),
  305. //    helpcontext(<helpcontext>)
  306. //  ]
  307. //  library <libname>
  308. //  {
  309. //      importlib("<import.tlb>");
  310. //
  311. //  };
  312. HRESULT CTypeLibODLView::DeCompileTypeLib( IStream* pstm, ITypeLib* ptlb, UINT uiIndent /* = 0 */ )
  313. {
  314. USES_CONVERSION;
  315. HRESULT         hr = S_OK ;
  316. BSTR            bstrName = NULL ;
  317. BSTR            bstrDoc = NULL ;
  318. BSTR            bstrHelp = NULL ;
  319. DWORD           dwHelpID ;
  320. TLIBATTR*       plibattr = NULL ;
  321. ITypeInfo*      pti = NULL ;
  322. TYPEATTR*       pattr = NULL ;
  323. ASSERT(ptlb) ;
  324. TRY
  325. {
  326. TCHAR szGUID[64] ;
  327. CString str;
  328. hr = ptlb->GetLibAttr(&plibattr);
  329. if (FAILED(hr))
  330. AfxThrowOleException( hr ) ;
  331. // write header with library filename
  332. WRITELINE(_T("// Generated .ODL file (by Ole2View)"));
  333. WRITELINE(_T("// "));
  334. WRITE1(_T("// typelib filename: "));
  335. hr = ::QueryPathOfRegTypeLib(plibattr->guid, plibattr->wMajorVerNum, plibattr->wMinorVerNum, plibattr->lcid, &bstrName);
  336. if (SUCCEEDED(hr))
  337. {
  338. LPCTSTR lpszName = OLE2CT(bstrName);
  339. ::SysFreeString(bstrName);
  340. bstrName = NULL;
  341. LPTSTR p = _tcsrchr(lpszName, '\');
  342. if (p != NULL && *p && *(p+1))
  343. WRITECR( p+1 ) ;
  344. else
  345. WRITECR( lpszName ) ;
  346. }
  347. else
  348. {
  349. // It's possible we're viewing a type lib that was never registered
  350. WRITECR( _T("<could not determine filename>") ) ;
  351. }
  352. WRITELINE( _T("[") ) ;
  353. StringFromGUID2T( plibattr->guid, szGUID, sizeof(szGUID) );
  354. WRITE1(_T("  uuid(")) ; WRITE(szGUID); WRITECR(_T("),"))  ;
  355. str.Format( _T("  version(%d.%d)"), plibattr->wMajorVerNum, plibattr->wMinorVerNum ) ;
  356. WRITE1(str) ;
  357. hr = ptlb->GetDocumentation( MEMBERID_NIL, &bstrName, &bstrDoc, &dwHelpID, &bstrHelp );
  358. if (FAILED(hr))
  359. AfxThrowOleException( hr ) ;
  360. if (bstrDoc && *bstrDoc)
  361. {
  362. WRITECR(_T(",")) ;
  363. WRITE1(_T("  helpstring("")) ;
  364. WRITEBSTR( bstrDoc ) ;
  365. WRITE(_T("")")) ;
  366. }
  367. if (bstrHelp && *bstrHelp)
  368. {
  369. WRITECR(",") ;
  370. LPCTSTR lpszHelp = OLE2CT(bstrHelp);
  371. ::SysFreeString(bstrHelp);
  372. bstrHelp = NULL;
  373. LPTSTR p = _tcsrchr(lpszHelp, '\');
  374. if (p != NULL && *p && *(p+1))
  375. str.Format( _T("  helpfile("%s"),"), p+1 ) ;
  376. else
  377. str.Format( _T("  helpfile("%s"),"), lpszHelp ) ;
  378. WRITELINE( str ) ;
  379. str.Format( _T("  helpcontext(%#08.8x)"), dwHelpID ) ;
  380. WRITE1( str ) ;
  381. }
  382. WRITECR(_T("")) ;
  383. WRITELINE(_T("]") ) ;
  384. WRITE1( _T("library ") ) ;
  385. WRITEBSTR(bstrName) ;
  386. WRITECR(_T("")) ;
  387. WRITELINE( _T("(") ) ;
  388. // TODO:  Grovel through all typeinfos for any referenced types
  389. // that are defined in imported libs
  390. //uiInfos = ptlb->GetTypeInfoCount() ;
  391. //for (UINT n = 0 ; n < uiInfos ; n++)
  392. //{
  393. //}
  394. WRITELINE(_T("// BUGBUG:  There most likely were "importlib()" statements in"));
  395. WRITELINE(_T("//          in the source.  While it appears possible to be able"));
  396. WRITELINE(_T("//          to identify them, it is non-trivial and is currently"));
  397. WRITELINE(_T("//          not supported."));
  398. WRITELINE(_T("// "));
  399. UINT uiInfos = ptlb->GetTypeInfoCount() ;
  400. for (UINT n = 0 ; n < uiInfos ; n++)
  401. {
  402. if (FAILED(hr = ptlb->GetTypeInfo( n, &pti )))
  403. AfxThrowOleException(hr) ;
  404. if (FAILED(hr = pti->GetTypeAttr( &pattr )))
  405. AfxThrowOleException(hr) ;
  406. switch(pattr->typekind)
  407. {
  408. case TKIND_ENUM:
  409. case TKIND_RECORD:
  410. case TKIND_UNION:
  411. case TKIND_ALIAS:
  412.  hr = DeCompileTypedef( pstm, pti, uiIndent + 1 ) ;
  413. break ;
  414. case TKIND_MODULE:
  415.  hr = DeCompileModule( pstm, pti, uiIndent + 1 ) ;
  416. break ;
  417. case TKIND_INTERFACE:
  418.  hr = DeCompileInterface( pstm, pti, uiIndent + 1 ) ;
  419. break ;
  420. case TKIND_DISPATCH:
  421.  hr = DeCompileDispinterface( pstm, pti, uiIndent + 1 ) ;
  422. break ;
  423. case TKIND_COCLASS:
  424.  hr = DeCompileCoClass( pstm, pti, uiIndent + 1 ) ;
  425. break ;
  426. }
  427. if (n != uiInfos - 1)
  428. WRITECR(_T("")) ;
  429. pti->ReleaseTypeAttr( pattr ) ;
  430. pti->Release() ;
  431. pti = NULL ;
  432. pattr = NULL ;
  433. }
  434. // Last line of the .ODL file
  435. WRITELINE( ");" ) ;
  436. SysFreeString( bstrName ) ;
  437. bstrName = NULL ;
  438. SysFreeString( bstrDoc ) ;
  439. bstrDoc = NULL ;
  440. SysFreeString( bstrHelp ) ;
  441. bstrHelp = NULL ;
  442. if (plibattr)
  443. ptlb->ReleaseTLibAttr( plibattr ) ;
  444. }
  445. CATCH(CException, pException)
  446. {
  447. if (pti)
  448. {
  449. if (pattr)
  450. pti->ReleaseTypeAttr( pattr ) ;
  451. pti->Release() ;
  452. }
  453. if (plibattr)
  454. ptlb->ReleaseTLibAttr( plibattr ) ;
  455. if (bstrName)
  456. SysFreeString( bstrName ) ;
  457. if (bstrDoc)
  458. SysFreeString( bstrDoc ) ;
  459. if (bstrHelp)
  460. SysFreeString( bstrHelp ) ;
  461. THROW_LAST() ;
  462. }
  463. END_CATCH
  464. return hr ;
  465. }
  466. // if typekind == TKIND_ALIAS
  467. //      typedef [attributes] basetype aliasname;
  468. //
  469. // if typekind == TKIND_ENUM
  470. //  typedef [attributes] enum [tag] {
  471. //      enumlist
  472. //  } enumname;
  473. // enumlist is made up of members of the form
  474. //      name = value,
  475. // or "= value" can be ommitted
  476. //
  477. // if typekind == TKIND_UNION or TKIND_RECORD
  478. // typedef [attributes] union/struct [tag] {
  479. //      memberlist
  480. // } union/structname;
  481. //
  482. // attributes can be
  483. //      [uuid(<00026b00-0000-0000-C000-000000000046>), version (<major>.<minor>),
  484. //       helpstring("<helpstring>"), helpcontext(<id), hidden, restricted,
  485. //       public]
  486. //
  487. // memberlist is made up of members of the form
  488. //      type name[bounds];
  489. //
  490. HRESULT CTypeLibODLView::DeCompileTypedef( IStream* pstm, ITypeInfo* pti, UINT uiIndent /* = 0 */ )
  491. {
  492. USES_CONVERSION;
  493. HRESULT     hr = S_OK ;
  494. TYPEATTR*   pattr = NULL ;
  495. BSTR            bstrName = NULL ;
  496. BSTR            bstrDoc = NULL ;
  497. BSTR            bstrHelp = NULL ;
  498. DWORD           dwHelpID ;
  499. WRITE1("typedef ") ;
  500. TRY
  501. {
  502. if (FAILED(hr = pti->GetTypeAttr( &pattr)))
  503. AfxThrowOleException( hr ) ;
  504. BOOL    fAttributes = FALSE ;      // any attributes?
  505. BOOL    fAttribute = FALSE ;       // at least one (insert ",")
  506. // Was 'uuid' specified?
  507. if (!IsEqualGUID( pattr->guid, GUID_NULL ))
  508. {
  509. TCHAR szGUID[64] ;
  510. StringFromGUID2T( pattr->guid, szGUID, sizeof(szGUID) ) ;
  511. fAttributes = TRUE ;
  512. WRITE("[uuid(") ;
  513. WRITE(szGUID) ;
  514. WRITE(")") ;
  515. fAttribute = TRUE ;
  516. }
  517. // was version specified
  518. if (pattr->wMajorVerNum || pattr->wMinorVerNum)
  519. {
  520. if (fAttributes == FALSE)
  521. WRITE("[") ;
  522. fAttributes = TRUE ;
  523. if (fAttribute)
  524. WRITE(", ") ;
  525. CString str ;
  526. str.Format(_T("version(%d.%d)"), pattr->wMajorVerNum, pattr->wMinorVerNum) ;
  527. WRITE(str) ;
  528. fAttribute = TRUE ;
  529. }
  530. if (SUCCEEDED(pti->GetDocumentation( MEMBERID_NIL, &bstrName, &bstrDoc, &dwHelpID, &bstrHelp )))
  531. {
  532. CString str ;
  533. if (bstrDoc && *bstrDoc)
  534. {
  535. if (fAttributes == FALSE) WRITE("[") ;
  536. fAttributes = TRUE ;
  537. if (fAttribute)
  538. WRITE(", ") ;
  539. LPCTSTR lpszDoc = OLE2CT(bstrDoc);
  540. ::SysFreeString(bstrDoc);
  541. bstrDoc = NULL;
  542. str.Format( _T("helpstring("%s")"), lpszDoc );
  543. WRITE( str ) ;
  544. if (dwHelpID > 0)
  545. {
  546. str.Format( _T(", helpcontext(%#08.8x)"), dwHelpID ) ;
  547. WRITE( str ) ;
  548. }
  549. }
  550. else if (dwHelpID > 0)
  551. {
  552. if (fAttributes == FALSE) WRITE("[") ;
  553. fAttributes = TRUE ;
  554. if (fAttribute)
  555. WRITE(", ") ;
  556. str.Format( _T("helpcontext(%#08.8x)"), dwHelpID ) ;
  557. WRITE( str ) ;
  558. fAttribute = TRUE ;
  559. }
  560. }
  561. if (pattr->typekind == TKIND_ALIAS)
  562. {
  563. if (fAttributes == FALSE) WRITE("[") ;
  564. fAttributes = TRUE ;
  565. if (fAttribute)
  566. WRITE(", ") ;
  567. WRITE("public") ;       // if it's in the tlb it had public
  568. }
  569. if (fAttributes)
  570. WRITE("] ") ;
  571. switch(pattr->typekind)
  572. {
  573. case TKIND_RECORD:
  574. #ifdef _WRITE_TAG
  575. WRITE("struct tag") ;
  576. WRITEBSTR(bstrName) ;
  577. #else
  578. WRITE("struct ") ;
  579. #endif
  580. WRITECR(" {" );
  581. break ;
  582. case TKIND_UNION:
  583. #ifdef _WRITE_TAG
  584. WRITE("union tag") ;
  585. WRITEBSTR(bstrName) ;
  586. #else
  587. WRITE("union ") ;
  588. #endif
  589. WRITECR(" {" );
  590. break ;
  591. case TKIND_ALIAS:  //typedef
  592. // write base type
  593. WRITE(TYPEDESCtoString( pti, &pattr->tdescAlias )) ;
  594. WRITE(" ") ;
  595. // write aliasname
  596. break ;
  597. case TKIND_ENUM:
  598. WRITECR("enum {" );
  599. break ;
  600. default:
  601. ASSERT(0) ;
  602. break ;
  603. }
  604. if (pattr->typekind == TKIND_RECORD || pattr->typekind == TKIND_UNION)
  605. {
  606. for (UINT n = 0 ; n < pattr->cVars ; n++)
  607. DumpVar( pstm, pti, pattr, n, uiIndent + 1 ) ;
  608. WRITE1("} ");
  609. }
  610. if (pattr->typekind == TKIND_ENUM)
  611. {
  612. for (int n = 0 ; n < pattr->cVars ; n++)
  613. {
  614. DumpConst( pstm, pti, pattr, n, uiIndent + 1, FALSE ) ;
  615. if (n < pattr->cVars-1)
  616. WRITECR(",") ;
  617. else
  618. WRITECR("") ;
  619. }
  620. WRITE1("} ");
  621. }
  622. WRITEBSTR(bstrName) ;
  623. WRITECR(";") ;
  624. if (bstrName)
  625. SysFreeString( bstrName ) ;
  626. if (bstrDoc)
  627. SysFreeString( bstrDoc ) ;
  628. if (bstrHelp)
  629. SysFreeString( bstrHelp ) ;
  630. pti->ReleaseTypeAttr( pattr ) ;
  631. }
  632. CATCH(CException, pException)
  633. {
  634. if (bstrName)
  635. SysFreeString( bstrName ) ;
  636. if (bstrDoc)
  637. SysFreeString( bstrDoc ) ;
  638. if (bstrHelp)
  639. SysFreeString( bstrHelp ) ;
  640. if (pattr)
  641. pti->ReleaseTypeAttr( pattr ) ;
  642. THROW_LAST();
  643. }
  644. END_CATCH
  645. return hr ;
  646. }
  647. //  [
  648. //    attributes
  649. //  ]
  650. //  module modulename {
  651. //      elementlist
  652. //  };
  653. //  attributes are
  654. //      uuid, version, helpstring, helpcontext, dllname
  655. //      The dllname attribute is required.
  656. //
  657. //  [attributes] returntype [calling convention] funcname(params);
  658. //  [attributes] const constname = constval;
  659. //
  660. HRESULT CTypeLibODLView::DeCompileModule( IStream* pstm, ITypeInfo* pti, UINT uiIndent /* = 0 */ )
  661. {
  662. HRESULT     hr = S_OK ;
  663. TYPEATTR*   pattr = NULL ;
  664. BSTR            bstrName = NULL ;
  665. BSTR            bstrDoc = NULL ;
  666. BSTR            bstrHelp = NULL ;
  667. DWORD           dwHelpID ;
  668. TRY
  669. {
  670. if (FAILED(hr = pti->GetTypeAttr( &pattr)))
  671. AfxThrowOleException( hr ) ;
  672. WRITELINE(_T("// BUGBUG:   There appears to be no way to retrieve the dllname of"));
  673. WRITELINE(_T("//           a module via ITypeInfo in a reliable way. "));
  674. WRITELINE(_T("//           ITypeInfo::GetDllEntry offers a possibility, but it will"));
  675. WRITELINE(_T("//           only work if the module has entries in it."));
  676. WRITELINE(_T("// "));
  677. WRITELINE(_T("[")) ;
  678. WRITE1( _T("  dllname(")) ;
  679. /*
  680. if (FAILED(hr = pti->GetDllEntry(MEMBERID_NIL, INVOKE_FUNC, &bstrName, NULL, NULL)))
  681. AfxThrowOleException( hr ) ;
  682. WRITEBSTR(bstrName) ;
  683. SysFreeString(bstrName) ;
  684. bstrName = NULL ;
  685. */
  686. WRITE(_T(")")) ;
  687. // Was 'uuid' specified?
  688. if (!IsEqualGUID( pattr->guid, GUID_NULL ))
  689. {
  690. TCHAR szGUID[64] ;
  691. StringFromGUID2T( pattr->guid, szGUID, sizeof(szGUID) ) ;
  692. WRITECR(",") ;
  693. WRITE1("  uuid(") ;
  694. WRITE(szGUID) ;
  695. WRITE(")") ;
  696. }
  697. // was version specified
  698. if (pattr->wMajorVerNum || pattr->wMinorVerNum)
  699. {
  700. WRITECR(",") ;
  701. CString str ;
  702. str.Format(_T("  version(%d.%d)"), pattr->wMajorVerNum, pattr->wMinorVerNum) ;
  703. WRITE1(str) ;
  704. }
  705. if (SUCCEEDED(pti->GetDocumentation( MEMBERID_NIL, &bstrName, &bstrDoc, &dwHelpID, &bstrHelp )))
  706. {
  707. CString str ;
  708. if (bstrDoc && *bstrDoc)
  709. {
  710. WRITECR(",") ;
  711. USES_CONVERSION;
  712. LPCTSTR lpszDoc = OLE2CT(bstrDoc);
  713. ::SysFreeString(bstrDoc);
  714. bstrDoc = NULL;
  715. str.Format( _T("  helpstring("%s")"), lpszDoc ) ;
  716. WRITE1( str ) ;
  717. if (dwHelpID > 0)
  718. {
  719. WRITECR(",") ;
  720. str.Format( _T("  helpcontext(%#08.8x)"), dwHelpID ) ;
  721. WRITE1( str ) ;
  722. }
  723. }
  724. else if (dwHelpID > 0)
  725. {
  726. WRITECR(",") ;
  727. str.Format( _T("  helpcontext(%#08.8x)"), dwHelpID ) ;
  728. WRITE1( str ) ;
  729. }
  730. }
  731. WRITECR("") ;
  732. WRITELINE(_T("]")) ;
  733. WRITE1(_T("module ")) ;
  734. WRITEBSTR( bstrName ) ;
  735. WRITECR( _T(" {")) ;
  736. for (int n = 0 ; n < pattr->cFuncs ; n++)
  737. DumpFunc( pstm, pti, pattr, n, uiIndent + 1 ) ;
  738. for (n = 0 ; n < pattr->cVars ; n++)
  739. DumpConst( pstm, pti, pattr, n, uiIndent + 1, TRUE ) ;
  740. WRITELINE("};") ;
  741. if (bstrName)
  742. SysFreeString( bstrName ) ;
  743. if (bstrDoc)
  744. SysFreeString( bstrDoc ) ;
  745. if (bstrHelp)
  746. SysFreeString( bstrHelp ) ;
  747. pti->ReleaseTypeAttr( pattr ) ;
  748. }
  749. CATCH(CException, pException)
  750. {
  751. if (bstrName)
  752. SysFreeString( bstrName ) ;
  753. if (bstrDoc)
  754. SysFreeString( bstrDoc ) ;
  755. if (bstrHelp)
  756. SysFreeString( bstrHelp ) ;
  757. if (pattr)
  758. pti->ReleaseTypeAttr( pattr ) ;
  759. THROW_LAST();
  760. }
  761. END_CATCH
  762. return hr ;
  763. }
  764. //  [
  765. //    attributes
  766. //  ]
  767. //  interface interfacename  [:baseinterface] {
  768. //      functionlist
  769. //  };
  770. //
  771. //  attributes include source, default, and restricted
  772. //
  773. HRESULT CTypeLibODLView::DeCompileInterface( IStream* pstm, ITypeInfo* pti, UINT uiIndent /* = 0 */ )
  774. {
  775. HRESULT     hr = S_OK ;
  776. TYPEATTR*   pattr = NULL ;
  777. BSTR            bstrName = NULL ;
  778. BSTR            bstrDoc = NULL ;
  779. BSTR            bstrHelp = NULL ;
  780. DWORD           dwHelpID ;
  781. ITypeInfo*      ptiImpl = NULL ;
  782. TRY
  783. {
  784. if (FAILED(hr = pti->GetTypeAttr( &pattr)))
  785. AfxThrowOleException( hr ) ;
  786. WRITELINE(_T("[")) ;
  787. WRITE1( _T("  odl")) ;
  788. TCHAR szGUID[64] ;
  789. StringFromGUID2T( pattr->guid, szGUID, sizeof(szGUID) ) ;
  790. WRITECR(",") ;
  791. WRITE1("  uuid(") ;
  792. WRITE(szGUID) ;
  793. WRITE(")") ;
  794. // was version specified
  795. if (pattr->wMajorVerNum || pattr->wMinorVerNum)
  796. {
  797. WRITECR(",") ;
  798. CString str ;
  799. str.Format(_T("  version(%d.%d)"), pattr->wMajorVerNum, pattr->wMinorVerNum) ;
  800. WRITE1(str) ;
  801. }
  802. if (SUCCEEDED(pti->GetDocumentation( MEMBERID_NIL, &bstrName, &bstrDoc, &dwHelpID, &bstrHelp )))
  803. {
  804. CString str ;
  805. if (bstrDoc && *bstrDoc)
  806. {
  807. WRITECR(",") ;
  808. USES_CONVERSION;
  809. LPCTSTR lpszDoc = OLE2CT(bstrDoc);
  810. ::SysFreeString(bstrDoc);
  811. bstrDoc = NULL;
  812. str.Format( _T("  helpstring("%s")"), lpszDoc ) ;
  813. WRITE1( str ) ;
  814. if (dwHelpID > 0)
  815. {
  816. WRITECR(",") ;
  817. str.Format( _T("  helpcontext(%#08.8x)"), dwHelpID ) ;
  818. WRITE1( str ) ;
  819. }
  820. }
  821. else if (dwHelpID > 0)
  822. {
  823. WRITECR(",") ;
  824. str.Format( _T("  helpcontext(%#08.8x)"), dwHelpID ) ;
  825. WRITE1( str ) ;
  826. }
  827. }
  828. // source, default, or restricted
  829. if (pattr->wTypeFlags == TYPEFLAG_FHIDDEN)
  830. {
  831. WRITECR(",") ;
  832. WRITE1("  hidden") ;
  833. }
  834. /*
  835. int    implflags = NULL ;
  836. if (FAILED(hr = pti->GetImplTypeFlags(0, &implflags )))
  837. AfxThrowOleException(hr) ;
  838. if (implflags & IMPLTYPEFLAG_FDEFAULT)
  839. {
  840. WRITECR(",") ;
  841. WRITE1("  default") ;
  842. }
  843. if (implflags & IMPLTYPEFLAG_FSOURCE)
  844. {
  845. WRITECR(",") ;
  846. WRITE1("  source") ;
  847. }
  848. if (implflags & IMPLTYPEFLAG_FRESTRICTED)
  849. {
  850. WRITECR(",") ;
  851. WRITE1("  restricted") ;
  852. }
  853.  */
  854. WRITECR("") ;
  855. WRITELINE(_T("]")) ;
  856. WRITE1(_T("interface ")) ;
  857. // interface name
  858. WRITEBSTR( bstrName ) ;
  859. if (bstrName)
  860. SysFreeString( bstrName ) ;
  861. if (bstrDoc)
  862. SysFreeString( bstrDoc ) ;
  863. if (bstrHelp)
  864. SysFreeString( bstrHelp ) ;
  865. bstrName = bstrDoc = bstrHelp = NULL ;
  866. // is there a base interface?
  867. for (UINT n = 0 ; n <  pattr->cImplTypes; n++)
  868. {
  869. HREFTYPE href = NULL ;
  870. if (FAILED(hr = pti->GetRefTypeOfImplType(n, &href)))
  871. AfxThrowOleException(hr) ;
  872. if (FAILED(hr = pti->GetRefTypeInfo( href, &ptiImpl )))
  873. AfxThrowOleException(hr) ;
  874. if (FAILED(hr = ptiImpl->GetDocumentation( MEMBERID_NIL, &bstrName, &bstrDoc, &dwHelpID, &bstrHelp )))
  875. AfxThrowOleException(hr) ;
  876. WRITE(_T(" : ")) ;
  877. WRITEBSTR( bstrName ) ;
  878. SysFreeString( bstrName ) ;
  879. bstrName = NULL ;
  880. SysFreeString( bstrDoc ) ;
  881. bstrDoc = NULL ;
  882. SysFreeString( bstrHelp ) ;
  883. bstrHelp = NULL ;
  884. ptiImpl->Release() ;
  885. ptiImpl = NULL ;
  886. }
  887. WRITECR(_T(" {")) ;
  888. for (n = 0 ; n < pattr->cFuncs ; n++)
  889. DumpFunc( pstm, pti, pattr, n, uiIndent + 1 ) ;
  890. WRITELINE("};") ;
  891. if (bstrName)
  892. SysFreeString( bstrName ) ;
  893. if (bstrDoc)
  894. SysFreeString( bstrDoc ) ;
  895. if (bstrHelp)
  896. SysFreeString( bstrHelp ) ;
  897. pti->ReleaseTypeAttr( pattr ) ;
  898. }
  899. CATCH(CException, pException)
  900. {
  901. if (ptiImpl)
  902. ptiImpl->Release() ;
  903. if (bstrName)
  904. SysFreeString( bstrName ) ;
  905. if (bstrDoc)
  906. SysFreeString( bstrDoc ) ;
  907. if (bstrHelp)
  908. SysFreeString( bstrHelp ) ;
  909. if (pattr)
  910. pti->ReleaseTypeAttr( pattr ) ;
  911. THROW_LAST();
  912. }
  913. END_CATCH
  914. return hr ;
  915. }
  916. //  Syntax 1
  917. //
  918. //  [
  919. //    attributes
  920. //  ]
  921. //  dispinterface intfname {
  922. //      properties:
  923. //          proplist
  924. //      methods:
  925. //          methlist
  926. //  };
  927. //
  928. //  Syntax 2
  929. //
  930. //  [
  931. //    attributes
  932. //  ]
  933. //  dispinterface intfname {
  934. //      interface interfacename
  935. //  };
  936. //
  937. HRESULT CTypeLibODLView::DeCompileDispinterface( IStream* pstm, ITypeInfo* pti, UINT uiIndent /* = 0 */ )
  938. {
  939. HRESULT     hr = S_OK ;
  940. TYPEATTR*   pattr = NULL ;
  941. BSTR            bstrName = NULL ;
  942. BSTR            bstrDoc = NULL ;
  943. BSTR            bstrHelp = NULL ;
  944. DWORD           dwHelpID ;
  945. ITypeInfo*      ptiImpl = NULL ;
  946. TRY
  947. {
  948. if (FAILED(hr = pti->GetTypeAttr( &pattr)))
  949. AfxThrowOleException( hr ) ;
  950. WRITELINE(_T("[")) ;
  951. TCHAR szGUID[64] ;
  952. StringFromGUID2T( pattr->guid, szGUID, sizeof(szGUID) ) ;
  953. WRITE1("  uuid(") ;
  954. WRITE(szGUID) ;
  955. WRITE(")") ;
  956. // was version specified
  957. if (pattr->wMajorVerNum || pattr->wMinorVerNum)
  958. {
  959. WRITECR(",") ;
  960. CString str ;
  961. str.Format(_T("  version(%d.%d)"), pattr->wMajorVerNum, pattr->wMinorVerNum) ;
  962. WRITE1(str) ;
  963. }
  964. if (SUCCEEDED(pti->GetDocumentation( MEMBERID_NIL, &bstrName, &bstrDoc, &dwHelpID, &bstrHelp )))
  965. {
  966. CString str ;
  967. if (bstrDoc && *bstrDoc)
  968. {
  969. WRITECR(",") ;
  970. USES_CONVERSION;
  971. LPCTSTR lpszDoc = OLE2CT(bstrDoc);
  972. ::SysFreeString(bstrDoc);
  973. bstrDoc = NULL;
  974. str.Format( _T("  helpstring("%s")"), lpszDoc ) ;
  975. WRITE1( str ) ;
  976. if (dwHelpID > 0)
  977. {
  978. WRITECR(",") ;
  979. str.Format( _T("  helpcontext(%#08.8x)"), dwHelpID ) ;
  980. WRITE1( str ) ;
  981. }
  982. }
  983. else if (dwHelpID > 0)
  984. {
  985. WRITECR(",") ;
  986. str.Format( _T("  helpcontext(%#08.8x)"), dwHelpID ) ;
  987. WRITE1( str ) ;
  988. }
  989. }
  990. // source, default, or restricted
  991. if (pattr->wTypeFlags == TYPEFLAG_FHIDDEN)
  992. {
  993. WRITECR(",") ;
  994. WRITE1("  hidden") ;
  995. }
  996. if (pattr->wTypeFlags == TYPEFLAG_FDUAL)
  997. {
  998. WRITECR(",") ;
  999. WRITE1("  dual") ;
  1000. }
  1001. WRITECR("") ;
  1002. WRITELINE(_T("]")) ;
  1003. WRITE1(_T("dispinterface ")) ;
  1004. // interface name
  1005. WRITEBSTR( bstrName ) ;
  1006. if (bstrName)
  1007. SysFreeString( bstrName ) ;
  1008. if (bstrDoc)
  1009. SysFreeString( bstrDoc ) ;
  1010. if (bstrHelp)
  1011. SysFreeString( bstrHelp ) ;
  1012. bstrName = bstrDoc = bstrHelp = NULL ;
  1013. WRITECR(_T(" {")) ;
  1014. WRITELINE2(_T("properties:"), 1) ;
  1015. for (UINT n = 0 ; n < pattr->cVars ; n++)
  1016. DumpVar( pstm, pti, pattr, n, uiIndent + 2 ) ;
  1017. WRITELINE2(_T("methods:"), 1) ;
  1018. for (n = 0 ; n < pattr->cFuncs ; n++)
  1019. DumpFunc( pstm, pti, pattr, n, uiIndent + 2 ) ;
  1020. WRITELINE("};") ;
  1021. if (bstrName)
  1022. SysFreeString( bstrName ) ;
  1023. if (bstrDoc)
  1024. SysFreeString( bstrDoc ) ;
  1025. if (bstrHelp)
  1026. SysFreeString( bstrHelp ) ;
  1027. pti->ReleaseTypeAttr( pattr ) ;
  1028. }
  1029. CATCH(CException, pException)
  1030. {
  1031. if (ptiImpl)
  1032. ptiImpl->Release() ;
  1033. if (bstrName)
  1034. SysFreeString( bstrName ) ;
  1035. if (bstrDoc)
  1036. SysFreeString( bstrDoc ) ;
  1037. if (bstrHelp)
  1038. SysFreeString( bstrHelp ) ;
  1039. if (pattr)
  1040. pti->ReleaseTypeAttr( pattr ) ;
  1041. }
  1042. END_CATCH
  1043. return hr ;
  1044. }
  1045. //  [
  1046. //    attributes
  1047. //  ]
  1048. //  coclass classname {
  1049. //      [attributes2] [interface | dispinterface] interfacename;
  1050. //      ...
  1051. //  };
  1052. //
  1053. //  attributes
  1054. //      uuid, helpstring, helpcontext, licensed, version, and appobject
  1055. //
  1056. HRESULT CTypeLibODLView::DeCompileCoClass( IStream* pstm, ITypeInfo* pti, UINT uiIndent /* = 0 */ )
  1057. {
  1058. HRESULT     hr = S_OK ;
  1059. TYPEATTR*   pattr = NULL ;
  1060. BSTR            bstrName = NULL ;
  1061. BSTR            bstrDoc = NULL ;
  1062. BSTR            bstrHelp = NULL ;
  1063. DWORD           dwHelpID ;
  1064. ITypeInfo*      ptiImpl = NULL ;
  1065. TYPEATTR*       pattrImpl = NULL ;
  1066. TRY
  1067. {
  1068. if (FAILED(hr = pti->GetTypeAttr( &pattr)))
  1069. AfxThrowOleException( hr ) ;
  1070. WRITELINE(_T("[")) ;
  1071. TCHAR szGUID[64] ;
  1072. StringFromGUID2T( pattr->guid, szGUID, sizeof(szGUID) ) ;
  1073. WRITE1("  uuid(") ;
  1074. WRITE(szGUID) ;
  1075. WRITE(")") ;
  1076. // was version specified
  1077. if (pattr->wMajorVerNum || pattr->wMinorVerNum)
  1078. {
  1079. WRITECR(",") ;
  1080. CString str ;
  1081. str.Format(_T("  version(%d.%d)"), pattr->wMajorVerNum, pattr->wMinorVerNum) ;
  1082. WRITE1(str) ;
  1083. }
  1084. if (SUCCEEDED(pti->GetDocumentation( MEMBERID_NIL, &bstrName, &bstrDoc, &dwHelpID, &bstrHelp )))
  1085. {
  1086. CString str ;
  1087. if (bstrDoc && *bstrDoc)
  1088. {
  1089. WRITECR(",") ;
  1090. USES_CONVERSION;
  1091. LPCTSTR lpszDoc = OLE2CT(bstrDoc);
  1092. ::SysFreeString(bstrDoc);
  1093. bstrDoc = NULL;
  1094. str.Format( _T("  helpstring("%s")"), lpszDoc ) ;
  1095. WRITE1( str ) ;
  1096. if (dwHelpID > 0)
  1097. {
  1098. WRITECR(",") ;
  1099. str.Format( _T("  helpcontext(%#08.8x)"), dwHelpID ) ;
  1100. WRITE1( str ) ;
  1101. }
  1102. }
  1103. else if (dwHelpID > 0)
  1104. {
  1105. WRITECR(",") ;
  1106. str.Format( _T("  helpcontext(%#08.8x)"), dwHelpID ) ;
  1107. WRITE1( str ) ;
  1108. }
  1109. }
  1110. if (pattr->wTypeFlags == TYPEFLAG_FAPPOBJECT)
  1111. {
  1112. WRITECR(",") ;
  1113. WRITE1("  appobject") ;
  1114. }
  1115. if (pattr->wTypeFlags == TYPEFLAG_FHIDDEN)
  1116. {
  1117. WRITECR(",") ;
  1118. WRITE1("  hidden") ;
  1119. }
  1120. if (pattr->wTypeFlags == TYPEFLAG_FLICENSED)
  1121. {
  1122. WRITECR(",") ;
  1123. WRITE1("  licensed") ;
  1124. }
  1125. if (pattr->wTypeFlags == TYPEFLAG_FCONTROL)
  1126. {
  1127. WRITECR(",") ;
  1128. WRITE1("  control") ;
  1129. }
  1130. WRITECR("") ;
  1131. WRITELINE(_T("]")) ;
  1132. WRITE1(_T("coclass ")) ;
  1133. // coclass name
  1134. WRITEBSTR( bstrName ) ;
  1135. if (bstrName)
  1136. SysFreeString( bstrName ) ;
  1137. if (bstrDoc)
  1138. SysFreeString( bstrDoc ) ;
  1139. if (bstrHelp)
  1140. SysFreeString( bstrHelp ) ;
  1141. bstrName = bstrDoc = bstrHelp = NULL ;
  1142. WRITECR(_T(" {")) ;
  1143. //  [attributes2] [interface | dispinterface] interfacename;
  1144. for (UINT n = 0 ; n < pattr->cImplTypes ; n++)
  1145. {
  1146. HREFTYPE href = NULL ;
  1147. int impltype = NULL ;
  1148. if (FAILED(hr = pti->GetImplTypeFlags( n, &impltype )))
  1149. AfxThrowOleException(hr) ;
  1150. if (FAILED(hr = pti->GetRefTypeOfImplType(n, &href)))
  1151. AfxThrowOleException(hr) ;
  1152. if (FAILED(hr = pti->GetRefTypeInfo( href, &ptiImpl )))
  1153. AfxThrowOleException(hr) ;
  1154. if (FAILED(hr = ptiImpl->GetDocumentation( MEMBERID_NIL, &bstrName, &bstrDoc, &dwHelpID, &bstrHelp )))
  1155. AfxThrowOleException(hr) ;
  1156. if (FAILED(hr = ptiImpl->GetTypeAttr( &pattrImpl)))
  1157. AfxThrowOleException( hr ) ;
  1158. WRITE2(_T(""), 1 ) ;
  1159. if (impltype)
  1160. {
  1161. WRITE(_T("[")) ;
  1162. BOOL    fComma = FALSE ;
  1163. if (impltype & IMPLTYPEFLAG_FDEFAULT)
  1164. {
  1165. WRITE(_T("default")) ;
  1166. fComma = TRUE ;
  1167. }
  1168. if (impltype & IMPLTYPEFLAG_FSOURCE)
  1169. {
  1170. if (fComma)
  1171. WRITE(_T(", ")) ;
  1172. WRITE(_T("source")) ;
  1173. fComma = TRUE ;
  1174. }
  1175. if (impltype & IMPLTYPEFLAG_FRESTRICTED)
  1176. {
  1177. if (fComma)
  1178. WRITE(_T(", ")) ;
  1179. WRITE(_T("restricted")) ;
  1180. }
  1181. WRITE(_T("] "));
  1182. }
  1183. if (pattrImpl->typekind == TKIND_INTERFACE)
  1184. WRITE(_T("interface ")) ;
  1185. if (pattrImpl->typekind == TKIND_DISPATCH)
  1186. WRITE(_T("dispinterface ")) ;
  1187. WRITE( bstrName ) ;
  1188. WRITECR(_T(";")) ;
  1189. SysFreeString( bstrName ) ;
  1190. bstrName = NULL ;
  1191. SysFreeString( bstrDoc ) ;
  1192. bstrDoc = NULL ;
  1193. SysFreeString( bstrHelp ) ;
  1194. bstrHelp = NULL ;
  1195. ptiImpl->ReleaseTypeAttr( pattrImpl ) ;
  1196. pattrImpl = NULL ;
  1197. ptiImpl->Release() ;
  1198. ptiImpl = NULL ;
  1199. }
  1200. WRITELINE("};") ;
  1201. if (bstrName)
  1202. SysFreeString( bstrName ) ;
  1203. if (bstrDoc)
  1204. SysFreeString( bstrDoc ) ;
  1205. if (bstrHelp)
  1206. SysFreeString( bstrHelp ) ;
  1207. pti->ReleaseTypeAttr( pattr ) ;
  1208. }
  1209. CATCH(CException, pException)
  1210. {
  1211. if (ptiImpl)
  1212. {
  1213. if (pattrImpl)
  1214. ptiImpl->ReleaseTypeAttr( pattrImpl ) ;
  1215. ptiImpl->Release() ;
  1216. }
  1217. if (bstrName)
  1218. SysFreeString( bstrName ) ;
  1219. if (bstrDoc)
  1220. SysFreeString( bstrDoc ) ;
  1221. if (bstrHelp)
  1222. SysFreeString( bstrHelp ) ;
  1223. if (pattr)
  1224. pti->ReleaseTypeAttr( pattr ) ;
  1225. THROW_LAST();
  1226. }
  1227. END_CATCH
  1228. return hr ;
  1229. }
  1230. HRESULT CTypeLibODLView::DeCompileFunc( IStream* pstm, ITypeInfo* pti, MEMBERID memid, UINT uiIndent /* = 0 */ )
  1231. {
  1232. HRESULT     hr = S_OK ;
  1233. TYPEATTR*   pattr = NULL ;
  1234. ASSERT(pti) ;
  1235. TRY
  1236. {
  1237. if (FAILED(hr = pti->GetTypeAttr( &pattr)))
  1238. AfxThrowOleException( hr ) ;
  1239. if (FAILED(hr = DumpFunc( pstm, pti, pattr, memid, uiIndent )))
  1240. AfxThrowOleException( hr ) ;
  1241. pti->ReleaseTypeAttr( pattr ) ;
  1242. }
  1243. CATCH(CException, pException)
  1244. {
  1245. if (pattr)
  1246. pti->ReleaseTypeAttr( pattr ) ;
  1247. THROW_LAST();
  1248. }
  1249. END_CATCH
  1250. return hr ;
  1251. }
  1252. HRESULT CTypeLibODLView::DumpFunc( IStream* pstm, ITypeInfo* pti, TYPEATTR* pattr, MEMBERID memid, UINT uiIndent /* = 0 */ )
  1253. {
  1254. HRESULT     hr = S_OK ;
  1255. FUNCDESC*   pfuncdesc = NULL ;
  1256. BSTR            rgbstrNames[MAX_NAMES] ;
  1257. BSTR            bstrName = NULL ;
  1258. BSTR            bstrDoc = NULL ;
  1259. BSTR            bstrHelp = NULL ;
  1260. DWORD           dwHelpID ;
  1261. ASSERT(pti) ;
  1262. for (UINT ui = 0 ; ui < MAX_NAMES ; ui++)
  1263. rgbstrNames[ui] = NULL ;
  1264. TRY
  1265. {
  1266. if (FAILED(hr = pti->GetFuncDesc( memid, &pfuncdesc )))
  1267. AfxThrowOleException( hr ) ;
  1268. // If pattr->typekind == TKIND_DISPATCH (dispinterface)
  1269. //    [attributes] returntype methname(params);
  1270. // where attributes can be
  1271. //      id(<id>), propput, propget,
  1272. //      propputref, bindable, defaultbind, displaybind,
  1273. //      requestedit, source, vararg, hidden, helpstring("<helpstring>"),
  1274. //      helpcontext(<id>)
  1275. //
  1276. // If pattr->typekind == TKIND_INTERFACE || TKIND_MODULE
  1277. //  [attributes] returntype [calling convention]  funcname(params);
  1278. // where attributes can be
  1279. //      restricted, bindable, defaultbind, displaybind,
  1280. //      requestedit, source, vararg, hidden, helpstring("<helpstring>"),
  1281. //      helpcontext(<id>)
  1282. // and calling convention can be
  1283. //      pascal, cdecl, stdcall
  1284. //
  1285. // Write [attributes]
  1286. //
  1287. BOOL    fAttributes = FALSE ;      // any attributes?
  1288. BOOL    fAttribute = FALSE ;       // at least one (insert ",")
  1289. WRITE1("") ;    // indent
  1290. CString str ;
  1291. if (pattr->typekind == TKIND_DISPATCH)
  1292. {
  1293. fAttributes = TRUE ;
  1294. fAttribute = TRUE ;
  1295. str.Format(_T("[id(%d)"), memid) ;
  1296. WRITE(str) ;
  1297. }
  1298. else if (pattr->typekind == TKIND_MODULE)
  1299. {
  1300. fAttributes = TRUE ;
  1301. fAttribute = TRUE ;
  1302. str.Format(_T("[entry(%d)"), memid) ;
  1303. WRITE(str) ;
  1304. }
  1305. else
  1306. // if there are some attributes
  1307. if ((pfuncdesc->invkind > 1)|| pfuncdesc->wFuncFlags || pfuncdesc->cParamsOpt == -1)
  1308. {
  1309. WRITE("[") ;
  1310. fAttributes = TRUE ;
  1311. }
  1312. if (pfuncdesc->invkind & INVOKE_PROPERTYGET)
  1313. {
  1314. if (fAttribute)
  1315. WRITE(", ") ;
  1316. fAttribute = TRUE ;
  1317. WRITE("propget") ;
  1318. }
  1319. if (pfuncdesc->invkind & INVOKE_PROPERTYPUT)
  1320. {
  1321. if (fAttribute)
  1322. WRITE(", ") ;
  1323. fAttribute = TRUE ;
  1324. WRITE("propput") ;
  1325. }
  1326. if (pfuncdesc->invkind & INVOKE_PROPERTYPUTREF)
  1327. {
  1328. if (fAttribute)
  1329. WRITE(", ") ;
  1330. fAttribute = TRUE ;
  1331. WRITE("propputref") ;
  1332. }
  1333. if (pfuncdesc->wFuncFlags & FUNCFLAG_FRESTRICTED)
  1334. {
  1335. if (fAttribute)
  1336. WRITE(", ") ;
  1337. fAttribute = TRUE ;
  1338. WRITE("restricted") ;
  1339. }
  1340. if (pfuncdesc->wFuncFlags & FUNCFLAG_FSOURCE)
  1341. {
  1342. if (fAttribute)
  1343. WRITE(", ") ;
  1344. fAttribute = TRUE ;
  1345. WRITE("source") ;
  1346. }
  1347. if (pfuncdesc->wFuncFlags & FUNCFLAG_FBINDABLE)
  1348. {
  1349. if (fAttribute)
  1350. WRITE(", ") ;
  1351. fAttribute = TRUE ;
  1352. WRITE("bindable") ;
  1353. }
  1354. if (pfuncdesc->wFuncFlags & FUNCFLAG_FREQUESTEDIT)
  1355. {
  1356. if (fAttribute)
  1357. WRITE(", ") ;
  1358. fAttribute = TRUE ;
  1359. WRITE("requestedit") ;
  1360. }
  1361. if (pfuncdesc->wFuncFlags & FUNCFLAG_FDISPLAYBIND)
  1362. {
  1363. if (fAttribute)
  1364. WRITE(", ") ;
  1365. fAttribute = TRUE ;
  1366. WRITE("displaybind") ;
  1367. }
  1368. if (pfuncdesc->wFuncFlags & FUNCFLAG_FDEFAULTBIND)
  1369. {
  1370. if (fAttribute)
  1371. WRITE(", ") ;
  1372. fAttribute = TRUE ;
  1373. WRITE("defaultbind") ;
  1374. }
  1375. if (pfuncdesc->wFuncFlags & FUNCFLAG_FHIDDEN)
  1376. {
  1377. if (fAttribute)
  1378. WRITE(", ") ;
  1379. fAttribute = TRUE ;
  1380. WRITE("hidden") ;
  1381. }
  1382. if (pfuncdesc->cParamsOpt == -1)    // cParamsOpt > 0 indicates VARIANT style
  1383. {
  1384. if (fAttribute)
  1385. WRITE(", ") ;
  1386. fAttribute = TRUE ;
  1387. WRITE("vararg") ;         // optional params
  1388. }
  1389. if (SUCCEEDED(pti->GetDocumentation( pfuncdesc->memid, &bstrName, &bstrDoc, &dwHelpID, &bstrHelp )))
  1390. {
  1391. CString str ;
  1392. if (bstrDoc && *bstrDoc)
  1393. {
  1394. if (fAttributes == FALSE) WRITE("[") ;
  1395. fAttributes = TRUE ;
  1396. if (fAttribute)
  1397. WRITE(", ") ;
  1398. USES_CONVERSION;
  1399. LPCTSTR lpszDoc = OLE2CT(bstrDoc);
  1400. ::SysFreeString(bstrDoc);
  1401. bstrDoc = NULL;
  1402. str.Format( _T("helpstring("%s")"), lpszDoc ) ;
  1403. WRITE( str ) ;
  1404. if (dwHelpID > 0)
  1405. {
  1406. str.Format( _T(", helpcontext(%#08.8x)"), dwHelpID ) ;
  1407. WRITE( str ) ;
  1408. }
  1409. }
  1410. else if (dwHelpID > 0)
  1411. {
  1412. if (fAttributes == FALSE) WRITE("[") ;
  1413. if (fAttribute)
  1414. WRITE(", ") ;
  1415. fAttributes = TRUE ;
  1416. str.Format( _T("helpcontext(%#08.8x)"), dwHelpID ) ;
  1417. WRITE( str ) ;
  1418. }
  1419. }
  1420. if (fAttributes)
  1421. WRITE("] ") ;
  1422. // Write return type
  1423. WRITE(TYPEDESCtoString( pti, &pfuncdesc->elemdescFunc.tdesc )) ;
  1424. WRITE(" ") ;
  1425. if (pattr->typekind != TKIND_DISPATCH)
  1426. {   // Write calling convention
  1427. switch(pfuncdesc->callconv)
  1428. {
  1429. case CC_CDECL:      WRITE("_cdecl ") ;           break ;
  1430. //case CC_MSCPASCAL:  WRITE("_mspascal ") ;        break ;
  1431. case CC_PASCAL:     WRITE("_pascal ") ;          break ;
  1432. case CC_MACPASCAL:  WRITE("_macpascal ") ;       break ;
  1433. case CC_STDCALL :   WRITE("_stdcall ") ;          break ;
  1434. //case CC_RESERVED:   WRITE("_reserved ") ;         break ;
  1435. case CC_SYSCALL:    WRITE("_syscall ") ;          break ;
  1436. case CC_MPWCDECL:   WRITE("_mpwcdecl ") ;         break ;
  1437. case CC_MPWPASCAL:  WRITE("_mpwpascal ") ;        break ;
  1438. }
  1439. }
  1440. // Write methodname
  1441. // HACK:  If a property has the propput or propputref attributes the
  1442. // 'right hand side' (rhs) is *always* the last parameter and MkTypeLib
  1443. // strips the parameter name.  Thus you will always get 1 less name
  1444. // back from ::GetNames than normal.
  1445. //
  1446. // Thus for the example below
  1447. //  [propput] void Color([in] VARIANT rgb, [in] VARIANT rgb2 );
  1448. // without taking this into consderation the output would be
  1449. //  [propput] void Color([in] VARIANT rgb, [in] VARIANT );
  1450. // when it should be
  1451. //  [propput] void Color([in] VARIANT rgb, [in] VARIANT rhs );
  1452. //
  1453. // Another weirdness comes from a bug (which will never be fixed)
  1454. // where optional parameters on property functions were allowed.
  1455. // Because they were allowed by accident people used them, so they
  1456. // are still allowed.
  1457. //
  1458. UINT cNames = 0 ;
  1459. if (FAILED( hr = pti->GetNames( pfuncdesc->memid, rgbstrNames, MAX_NAMES, &cNames )))
  1460. AfxThrowOleException( hr ) ;
  1461. // fix for 'rhs' problem
  1462. if ((int)cNames < pfuncdesc->cParams + 1)
  1463. {
  1464. rgbstrNames[cNames] = ::SysAllocString(OLESTR("rhs")) ;
  1465. cNames++ ;
  1466. }
  1467. ASSERT((int)cNames == pfuncdesc->cParams+1) ;
  1468. WRITEBSTR( rgbstrNames[0] ) ;
  1469. WRITE("(") ;
  1470. // params have the format
  1471. //   [attributes] type paramname
  1472. // where attributes can be
  1473. //   in, out, optional, string   (string is not valid for TKIND_MODULE)
  1474. //
  1475. if (pfuncdesc->cParams > 1)
  1476. WRITECR("") ;
  1477. for ( int n = 0 ; n < pfuncdesc->cParams ; n++ )
  1478. {
  1479. if (pfuncdesc->cParams > 1)
  1480. WRITE2("", 4 ) ;    // indent 4
  1481. fAttributes = FALSE ;
  1482. fAttribute = FALSE ;
  1483. if (pfuncdesc->lprgelemdescParam[n].idldesc.wIDLFlags)
  1484. {
  1485. WRITE("[") ;
  1486. fAttributes = TRUE ;
  1487. }
  1488. if (pfuncdesc->lprgelemdescParam[n].idldesc.wIDLFlags & IDLFLAG_FIN)
  1489. {
  1490. if (fAttribute)
  1491. WRITE(", ") ;
  1492. WRITE("in") ;
  1493. fAttribute = TRUE ;
  1494. }
  1495. if (pfuncdesc->lprgelemdescParam[n].idldesc.wIDLFlags & IDLFLAG_FOUT)
  1496. {
  1497. if (fAttribute)
  1498. WRITE(", ") ;
  1499. WRITE("out") ;
  1500. fAttribute = TRUE ;
  1501. }
  1502. if (pfuncdesc->lprgelemdescParam[n].idldesc.wIDLFlags & IDLFLAG_FLCID)
  1503. {
  1504. if (fAttribute)
  1505. WRITE(", ") ;
  1506. WRITE("lcid") ;
  1507. fAttribute = TRUE ;
  1508. }
  1509. if (pfuncdesc->lprgelemdescParam[n].idldesc.wIDLFlags & IDLFLAG_FRETVAL)
  1510. {
  1511. if (fAttribute)
  1512. WRITE(", ") ;
  1513. WRITE("retval") ;
  1514. fAttribute = TRUE ;
  1515. }
  1516. // If we have an optional last parameter and we're on the last paramter
  1517. // or we are into the optional parameters...
  1518. if ((pfuncdesc->cParamsOpt == -1 && n == pfuncdesc->cParams - 1) ||
  1519. (n > (pfuncdesc->cParams - pfuncdesc->cParamsOpt)))
  1520. {
  1521. if (fAttribute)
  1522. WRITE(", ") ;
  1523. if (!fAttributes)
  1524. WRITE("[") ;
  1525. WRITE("optional") ;
  1526. fAttributes = TRUE ;
  1527. fAttribute = TRUE ;
  1528. }
  1529. if (fAttributes)
  1530. WRITE("] ") ;
  1531. // type
  1532. CString str ;
  1533. if ((pfuncdesc->lprgelemdescParam[n].tdesc.vt & 0x0FFF) == VT_CARRAY)
  1534. {
  1535. // type name[n]
  1536. WRITE(TYPEDESCtoString( pti, &pfuncdesc->lprgelemdescParam[n].tdesc.lpadesc->tdescElem )) ;
  1537. WRITE(" ") ;
  1538. WRITEBSTR(rgbstrNames[n+1]) ;
  1539. // Allocate cDims * lstrlen("[123456]")
  1540. for (USHORT n = 0 ; n < pfuncdesc->lprgelemdescParam[n].tdesc.lpadesc->cDims ; n++)
  1541. {
  1542. str.Format( _T("[%d]"), pfuncdesc->lprgelemdescParam[n].tdesc.lpadesc->rgbounds[n].cElements ) ;
  1543. WRITE(str) ;
  1544. }
  1545. }
  1546. else
  1547. {
  1548. WRITE(TYPEDESCtoString( pti, &pfuncdesc->lprgelemdescParam[n].tdesc ) + " " ) ;
  1549. WRITEBSTR(rgbstrNames[n+1]) ;
  1550. }
  1551. if (n < pfuncdesc->cParams - 1)
  1552. WRITECR(", ") ;
  1553. }
  1554. WRITECR(");") ;
  1555. for (UINT ui = 0 ; ui < MAX_NAMES ; ui++)
  1556. if (rgbstrNames[ui])
  1557. SysFreeString(rgbstrNames[ui]) ;
  1558. if (bstrName)
  1559. SysFreeString( bstrName ) ;
  1560. if (bstrDoc)
  1561. SysFreeString( bstrDoc ) ;
  1562. if (bstrHelp)
  1563. SysFreeString( bstrHelp ) ;
  1564. pti->ReleaseFuncDesc( pfuncdesc ) ;
  1565. }
  1566. CATCH(CException, pException)
  1567. {
  1568. for (UINT ui = 0 ; ui < MAX_NAMES ; ui++)
  1569. if (rgbstrNames[ui])
  1570. SysFreeString(rgbstrNames[ui]) ;
  1571. if (bstrName)
  1572. SysFreeString( bstrName ) ;
  1573. if (bstrDoc)
  1574. SysFreeString( bstrDoc ) ;
  1575. if (bstrHelp)
  1576. SysFreeString( bstrHelp ) ;
  1577. if (pfuncdesc)
  1578. pti->ReleaseFuncDesc( pfuncdesc ) ;
  1579. THROW_LAST();
  1580. }
  1581. END_CATCH
  1582. return hr ;
  1583. }
  1584. HRESULT CTypeLibODLView::DeCompileVar( IStream* pstm, ITypeInfo* pti, MEMBERID memid, UINT uiIndent /* = 0 */)
  1585. {
  1586. HRESULT     hr = S_OK ;
  1587. TYPEATTR*   pattr = NULL ;
  1588. ASSERT(pti) ;
  1589. TRY
  1590. {
  1591. if (FAILED(hr = pti->GetTypeAttr( &pattr)))
  1592. AfxThrowOleException( hr ) ;
  1593. if (FAILED(hr = DumpVar( pstm, pti, pattr, memid, uiIndent )))
  1594. AfxThrowOleException( hr ) ;
  1595. pti->ReleaseTypeAttr( pattr ) ;
  1596. }
  1597. CATCH(CException, pException)
  1598. {
  1599. if (pattr)
  1600. pti->ReleaseTypeAttr( pattr ) ;
  1601. THROW_LAST();
  1602. }
  1603. END_CATCH
  1604. return hr ;
  1605. }
  1606. HRESULT CTypeLibODLView::DumpVar( IStream* pstm, ITypeInfo* pti, TYPEATTR* pattr, MEMBERID memid, UINT uiIndent /* = 0 */)
  1607. {
  1608. HRESULT     hr = S_OK ;
  1609. VARDESC*    pvardesc = NULL ;
  1610. BSTR            rgbstrNames[1] ;
  1611. BSTR            bstrName = NULL ;
  1612. BSTR            bstrDoc = NULL ;
  1613. BSTR            bstrHelp = NULL ;
  1614. DWORD           dwHelpID ;
  1615. ASSERT(pti) ;
  1616. TRY
  1617. {
  1618. if (FAILED(hr = pti->GetVarDesc( memid, &pvardesc )))
  1619. AfxThrowOleException( hr ) ;
  1620. ASSERT(pvardesc->varkind != VAR_CONST) ;    // must not be a const
  1621. // If pattr->typekind == TKIND_RECORD (struct) || TKIND_UNION
  1622. //    type name[array];
  1623. //
  1624. // If pattr->typekind == TKIND_DISPATCH (dispinterface)
  1625. //    [id(<id>), bindable, defaultbind, displaybind, readonly,
  1626. //      requestedit, source, hidden, helpstring("<helpstring>"),
  1627. //      helpcontext(<id>)] type name;
  1628. //
  1629. BOOL    fAttributes = FALSE ;
  1630. WRITE1("") ;    // indent
  1631. if (pattr->typekind == TKIND_DISPATCH)
  1632. {
  1633. CString str ;
  1634. fAttributes = TRUE ;
  1635. str.Format(_T("[id(%d)"), memid) ;
  1636. WRITE(str) ;
  1637. if (pvardesc->wVarFlags & VARFLAG_FREADONLY)
  1638. WRITE(", readonly") ;
  1639. if (pvardesc->wVarFlags & VARFLAG_FSOURCE)
  1640. WRITE(", source") ;
  1641. if (pvardesc->wVarFlags & VARFLAG_FBINDABLE)
  1642. WRITE(", bindable") ;
  1643. if (pvardesc->wVarFlags & VARFLAG_FREQUESTEDIT)
  1644. WRITE(", requestedit") ;
  1645. if (pvardesc->wVarFlags & VARFLAG_FDISPLAYBIND)
  1646. WRITE(", displaybind") ;
  1647. if (pvardesc->wVarFlags & VARFLAG_FDEFAULTBIND)
  1648. WRITE(", defaultbind") ;
  1649. if (pvardesc->wVarFlags & VARFLAG_FHIDDEN)
  1650. WRITE(", hidden") ;
  1651. }
  1652. if (SUCCEEDED(pti->GetDocumentation( pvardesc->memid, &bstrName, &bstrDoc, &dwHelpID, &bstrHelp )))
  1653. {
  1654. CString str ;
  1655. if (bstrDoc && *bstrDoc)
  1656. {
  1657. if (fAttributes == FALSE)
  1658. WRITE("[") ;
  1659. else
  1660. WRITE(", ") ;
  1661. fAttributes = TRUE ;
  1662. USES_CONVERSION;
  1663. LPCTSTR lpszDoc = OLE2CT(bstrDoc);
  1664. ::SysFreeString(bstrDoc);
  1665. bstrDoc = NULL;
  1666. str.Format( _T("helpstring("%s")"), lpszDoc ) ;
  1667. WRITE( str ) ;
  1668. if (dwHelpID > 0)
  1669. {
  1670. str.Format( _T(", helpcontext(%#08.8x)"), dwHelpID ) ;
  1671. WRITE( str ) ;
  1672. }
  1673. }
  1674. else if (dwHelpID > 0)
  1675. {
  1676. if (fAttributes == FALSE)
  1677. WRITE("[") ;
  1678. else
  1679. WRITE(", ") ;
  1680. fAttributes = TRUE ;
  1681. str.Format( _T("helpcontext(%#08.8x)"), dwHelpID ) ;
  1682. WRITE( str ) ;
  1683. }
  1684. }
  1685. if (fAttributes)
  1686. WRITE("] ") ;
  1687. UINT cNames ;
  1688. if (FAILED( hr = pti->GetNames( pvardesc->memid, rgbstrNames, 1, (UINT FAR*)&cNames )))
  1689. AfxThrowOleException( hr ) ;
  1690. CString str ;
  1691. if ((pvardesc->elemdescVar.tdesc.vt & 0x0FFF) == VT_CARRAY)
  1692. {
  1693. // type name[n]
  1694. WRITE(TYPEDESCtoString( pti, &pvardesc->elemdescVar.tdesc.lpadesc->tdescElem )) ;
  1695. WRITE(" ") ;
  1696. if (rgbstrNames[0])
  1697. WRITEBSTR(rgbstrNames[0]);
  1698. else
  1699. WRITE(_T("(nameless)")) ;
  1700. // Allocate cDims * lstrlen("[123456]")
  1701. for (USHORT n = 0 ; n < pvardesc->elemdescVar.tdesc.lpadesc->cDims ; n++)
  1702. {
  1703. str.Format( _T("[%d]"), pvardesc->elemdescVar.tdesc.lpadesc->rgbounds[n].cElements ) ;
  1704. WRITE(str) ;
  1705. }
  1706. }
  1707. else
  1708. {
  1709. WRITE(TYPEDESCtoString( pti, &pvardesc->elemdescVar.tdesc ) + _T(" "));
  1710. if (rgbstrNames[0])
  1711. WRITEBSTR(rgbstrNames[0]);
  1712. else
  1713. WRITE(_T("(nameless)")) ;
  1714. }
  1715. WRITECR(";") ;
  1716. if (bstrName)
  1717. SysFreeString( bstrName ) ;
  1718. if (bstrDoc)
  1719. SysFreeString( bstrDoc ) ;
  1720. if (bstrHelp)
  1721. SysFreeString( bstrHelp ) ;
  1722. pti->ReleaseVarDesc( pvardesc ) ;
  1723. }
  1724. CATCH(CException, pException)
  1725. {
  1726. if (bstrName)
  1727. SysFreeString( bstrName ) ;
  1728. if (bstrDoc)
  1729. SysFreeString( bstrDoc ) ;
  1730. if (bstrHelp)
  1731. SysFreeString( bstrHelp ) ;
  1732. if (pvardesc)
  1733. pti->ReleaseVarDesc( pvardesc ) ;
  1734. THROW_LAST();
  1735. }
  1736. END_CATCH
  1737. return hr ;
  1738. }
  1739. // if fConst ==  TURE
  1740. //  const type name = value ;
  1741. // else
  1742. //  name = value  (no commas)
  1743. //
  1744. HRESULT CTypeLibODLView::DeCompileConst( IStream* pstm, ITypeInfo* pti, MEMBERID memid, UINT uiIndent /* = 0 */, BOOL fConst /* = TRUE */  )
  1745. {
  1746. HRESULT     hr = S_OK ;
  1747. TYPEATTR*       pattr = NULL ;
  1748. ASSERT(pti) ;
  1749. TRY
  1750. {
  1751. if (FAILED(hr = pti->GetTypeAttr( &pattr)))
  1752. AfxThrowOleException( hr ) ;
  1753. if (FAILED(hr = DumpConst( pstm, pti, pattr, memid, uiIndent, fConst )))
  1754. AfxThrowOleException( hr ) ;
  1755. pti->ReleaseTypeAttr( pattr ) ;
  1756. }
  1757. CATCH(CException, pException)
  1758. {
  1759. if (pattr)
  1760. pti->ReleaseTypeAttr( pattr ) ;
  1761. THROW_LAST();
  1762. }
  1763. END_CATCH
  1764. return hr ;
  1765. }
  1766. HRESULT CTypeLibODLView::DumpConst( IStream* pstm, ITypeInfo* pti, TYPEATTR* pattr, MEMBERID memid, UINT uiIndent /* = 0 */, BOOL fConst /* = TRUE */  )
  1767. {
  1768. USES_CONVERSION;
  1769. HRESULT     hr = S_OK ;
  1770. VARDESC*    pvardesc = NULL ;
  1771. BSTR            rgbstrNames[1] ;
  1772. BSTR            bstrName = NULL ;
  1773. BSTR            bstrDoc = NULL ;
  1774. BSTR            bstrHelp = NULL ;
  1775. DWORD           dwHelpID ;
  1776. ASSERT(pti) ;
  1777. VARIANT varValue ;
  1778. VariantInit( &varValue ) ;
  1779. TRY
  1780. {
  1781. if (FAILED(hr = pti->GetVarDesc( memid, &pvardesc )))
  1782. AfxThrowOleException( hr ) ;
  1783. ASSERT(pvardesc->varkind == VAR_CONST) ;
  1784. CString str = TYPEDESCtoString( pti, &pvardesc->elemdescVar.tdesc ) ;
  1785. if (FAILED(hr = VariantChangeType( &varValue, pvardesc->lpvarValue, 0, VT_BSTR )))
  1786. {
  1787. if (pvardesc->lpvarValue->vt == VT_ERROR || pvardesc->lpvarValue->vt == VT_HRESULT)
  1788. {
  1789. varValue.vt = VT_BSTR ;
  1790. varValue.bstrVal = ::SysAllocString(T2OLE(_GetScodeString(pvardesc->lpvarValue->scode))) ;
  1791. hr = S_OK ;
  1792. }
  1793. else
  1794. AfxThrowOleException( hr ) ;
  1795. }
  1796. BOOL fIndent = FALSE ;
  1797. if (fConst)
  1798. {
  1799. CString str ;
  1800. if (pattr->typekind == TKIND_MODULE)
  1801. {
  1802. str.Format(_T("[entry(%d)"), memid) ;
  1803. WRITE1(str) ;
  1804. fIndent = TRUE ;
  1805. }
  1806. // [helpstring("<helpstring>"), helpcontext(<id>)] const type name = expression ;
  1807. if (SUCCEEDED(pti->GetDocumentation( pvardesc->memid, &bstrName, &bstrDoc, &dwHelpID, &bstrHelp )))
  1808. {
  1809. if (bstrDoc && *bstrDoc)
  1810. {
  1811. if (!fIndent)
  1812. WRITE1("[") ;
  1813. else
  1814. WRITE(", ") ;
  1815. LPCTSTR lpszDoc = OLE2CT(bstrDoc);
  1816. ::SysFreeString(bstrDoc);
  1817. bstrDoc = NULL;
  1818. str.Format( _T("helpstring("%s")"), lpszDoc ) ;
  1819. WRITE( str ) ;
  1820. if (dwHelpID > 0)
  1821. {
  1822. str.Format( _T(", helpcontext(%#08.8x)"), dwHelpID ) ;
  1823. WRITE( str ) ;
  1824. }
  1825. WRITE("] ");
  1826. fIndent = TRUE ;
  1827. }
  1828. else if (dwHelpID > 0)
  1829. {
  1830. if (!fIndent)
  1831. WRITE1("[") ;
  1832. else
  1833. WRITE(", ") ;
  1834. str.Format( _T("helpcontext(%#08.8x)] "), dwHelpID ) ;
  1835. WRITE( str ) ;
  1836. fIndent = TRUE ;
  1837. }
  1838. }
  1839. }
  1840. UINT cNames ;
  1841. if (FAILED( hr = pti->GetNames( pvardesc->memid, rgbstrNames, 1, (UINT FAR*)&cNames )))
  1842. AfxThrowOleException( hr ) ;
  1843. if (fConst)
  1844. {
  1845. if (!fIndent)
  1846. WRITE1(_T("")) ;
  1847. WRITE("const ") ; WRITE( str ) ; WRITE( " " ) ;
  1848. }
  1849. else
  1850. WRITE1("") ;
  1851. WRITEBSTR( rgbstrNames[0] ) ; WRITE( " = " ) ;
  1852. if (pvardesc->lpvarValue->vt == VT_BSTR)
  1853. {
  1854. WRITE( """ ) ;
  1855. WRITEBSTR( varValue.bstrVal ) ;
  1856. WRITE( """ ) ;
  1857. }
  1858. else
  1859. WRITEBSTR( varValue.bstrVal) ;
  1860. if (fConst)
  1861. WRITECR(";") ;
  1862. VariantClear( &varValue ) ;
  1863. if (bstrName)
  1864. SysFreeString( bstrName ) ;
  1865. if (bstrDoc)
  1866. SysFreeString( bstrDoc ) ;
  1867. if (bstrHelp)
  1868. SysFreeString( bstrHelp ) ;
  1869. pti->ReleaseVarDesc( pvardesc ) ;
  1870. }
  1871. CATCH(CException, pException)
  1872. {
  1873. VariantClear( &varValue ) ;
  1874. if (bstrName)
  1875. SysFreeString( bstrName ) ;
  1876. if (bstrDoc)
  1877. SysFreeString( bstrDoc ) ;
  1878. if (bstrHelp)
  1879. SysFreeString( bstrHelp ) ;
  1880. if (pvardesc)
  1881. pti->ReleaseVarDesc( pvardesc ) ;
  1882. THROW_LAST();
  1883. }
  1884. END_CATCH
  1885. return hr ;
  1886. }
  1887. IStream* CreateMemoryStream()
  1888. {
  1889. LPSTREAM lpStream = NULL;
  1890. // Create a stream object on a memory block.
  1891. HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE|GMEM_SHARE, 0);
  1892. if (hGlobal != NULL)
  1893. {
  1894. HRESULT hr ;
  1895. if (FAILED(hr = CreateStreamOnHGlobal(hGlobal, TRUE, &lpStream)))
  1896. {
  1897. TRACE0("CreateStreamOnHGlobal failed.n");
  1898. GlobalFree(hGlobal);
  1899. AfxThrowOleException( hr ) ;
  1900. }
  1901. }
  1902. else
  1903. {
  1904. TRACE0("Failed to allocate memory for stream.n");
  1905. AfxThrowMemoryException() ;
  1906. }
  1907. return lpStream;
  1908. }
  1909. int StringFromGUID2T(REFGUID rguid, LPTSTR lpszGUID, int cbMax )
  1910. {
  1911. USES_CONVERSION;
  1912. OLECHAR* lpszOle = (OLECHAR*)_alloca(cbMax*sizeof(OLECHAR));
  1913. int nCount = ::StringFromGUID2(rguid,lpszOle, cbMax*sizeof(OLECHAR));
  1914. if (nCount == 0)
  1915. {
  1916. lpszGUID[0] = '';
  1917. return 0; // buffer too small for the returned string
  1918. }
  1919. LPTSTR lpszRes = OLE2T(lpszOle);
  1920. lstrcpy(lpszGUID, lpszRes);
  1921. return 0;
  1922. }