home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / VFP50 / API / SAMPLES / FOXTLIB / FOXTLI~1.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1996-08-01  |  18.2 KB  |  770 lines

  1. // FoxtlibCtl.cpp : Implementation of the CFoxtlibCtrl OLE control class.
  2.  
  3. #include "stdafx.h"
  4. #include "foxtlib.h"
  5. #include "FoxtlibCtl.h"
  6. #include "FoxtlibPpg.h"
  7. #include "pro_ext.h"
  8.  
  9. #ifdef _DEBUG
  10. #define new DEBUG_NEW
  11. #undef THIS_FILE
  12. static char THIS_FILE[] = __FILE__;
  13. #endif
  14.  
  15.  
  16.  
  17. IMPLEMENT_DYNCREATE(CFoxtlibCtrl, COleControl)
  18.  
  19.  
  20. /////////////////////////////////////////////////////////////////////////////
  21. // Message map
  22.  
  23. BEGIN_MESSAGE_MAP(CFoxtlibCtrl, COleControl)
  24.     //{{AFX_MSG_MAP(CFoxtlibCtrl)
  25.     // NOTE - ClassWizard will add and remove message map entries
  26.     //    DO NOT EDIT what you see in these blocks of generated code !
  27.     //}}AFX_MSG_MAP
  28.     ON_OLEVERB(AFX_IDS_VERB_EDIT, OnEdit)
  29.     ON_OLEVERB(AFX_IDS_VERB_PROPERTIES, OnProperties)
  30. END_MESSAGE_MAP()
  31.  
  32.  
  33. /////////////////////////////////////////////////////////////////////////////
  34. // Dispatch map
  35.  
  36. BEGIN_DISPATCH_MAP(CFoxtlibCtrl, COleControl)
  37.     //{{AFX_DISPATCH_MAP(CFoxtlibCtrl)
  38.     DISP_FUNCTION(CFoxtlibCtrl, "TLLoadTypeLib", TLLoadTypeLib, VT_I4, VTS_BSTR)
  39.     DISP_FUNCTION(CFoxtlibCtrl, "TLRelease", TLRelease, VT_I4, VTS_I4)
  40.     DISP_FUNCTION(CFoxtlibCtrl, "TLGetTypeInfoCount", TLGetTypeInfoCount, VT_I4, VTS_I4)
  41.     DISP_FUNCTION(CFoxtlibCtrl, "TLGetTypeAttr", TLGetTypeAttr, VT_I4, VTS_I4 VTS_BSTR)
  42.     DISP_FUNCTION(CFoxtlibCtrl, "TLGetTypeInfo", TLGetTypeInfo, VT_I4, VTS_I4 VTS_I4)
  43.     DISP_FUNCTION(CFoxtlibCtrl, "TLGetDocumentation", TLGetDocumentation, VT_I4, VTS_I4 VTS_BSTR VTS_I4 VTS_I4)
  44.     DISP_FUNCTION(CFoxtlibCtrl, "TIGetNames", TIGetNames, VT_I4, VTS_I4 VTS_BSTR VTS_I4)
  45.     DISP_FUNCTION(CFoxtlibCtrl, "TIGetFuncDesc", TIGetFuncDesc, VT_I4, VTS_I4 VTS_BSTR VTS_I4 VTS_BSTR)
  46.     //}}AFX_DISPATCH_MAP
  47. END_DISPATCH_MAP()
  48.  
  49.  
  50. /////////////////////////////////////////////////////////////////////////////
  51. // Event map
  52.  
  53. BEGIN_EVENT_MAP(CFoxtlibCtrl, COleControl)
  54.     //{{AFX_EVENT_MAP(CFoxtlibCtrl)
  55.     // NOTE - ClassWizard will add and remove event map entries
  56.     //    DO NOT EDIT what you see in these blocks of generated code !
  57.     //}}AFX_EVENT_MAP
  58. END_EVENT_MAP()
  59.  
  60.  
  61. /////////////////////////////////////////////////////////////////////////////
  62. // Property pages
  63.  
  64. // TODO: Add more property pages as needed.  Remember to increase the count!
  65. BEGIN_PROPPAGEIDS(CFoxtlibCtrl, 1)
  66.     PROPPAGEID(CFoxtlibPropPage::guid)
  67. END_PROPPAGEIDS(CFoxtlibCtrl)
  68.  
  69.  
  70. /////////////////////////////////////////////////////////////////////////////
  71. // Initialize class factory and guid
  72.  
  73. IMPLEMENT_OLECREATE_EX(CFoxtlibCtrl, "FOXTLIB.FoxtlibCtrl.1",
  74.     0x22852ee3, 0xb01b, 0x11cf, 0xb8, 0x26, 0, 0xa0, 0xc9, 0x5, 0x5d, 0x9e)
  75.  
  76.  
  77. /////////////////////////////////////////////////////////////////////////////
  78. // Type library ID and version
  79.  
  80. IMPLEMENT_OLETYPELIB(CFoxtlibCtrl, _tlid, _wVerMajor, _wVerMinor)
  81.  
  82.  
  83. /////////////////////////////////////////////////////////////////////////////
  84. // Interface IDs
  85.  
  86. const IID BASED_CODE IID_DFoxtlib =
  87.         { 0x22852ee9, 0xb01b, 0x11cf, { 0xb8, 0x26, 0, 0xa0, 0xc9, 0x5, 0x5d, 0x9e } };
  88. const IID BASED_CODE IID_DFoxtlibEvents =
  89.         { 0x22852eea, 0xb01b, 0x11cf, { 0xb8, 0x26, 0, 0xa0, 0xc9, 0x5, 0x5d, 0x9e } };
  90.  
  91.  
  92. /////////////////////////////////////////////////////////////////////////////
  93. // Control type information
  94.  
  95. static const DWORD BASED_CODE _dwFoxtlibOleMisc =
  96.     OLEMISC_INVISIBLEATRUNTIME |
  97.     OLEMISC_SETCLIENTSITEFIRST |
  98.     OLEMISC_INSIDEOUT |
  99.     OLEMISC_CANTLINKINSIDE |
  100.     OLEMISC_RECOMPOSEONRESIZE;
  101.  
  102. IMPLEMENT_OLECTLTYPE(CFoxtlibCtrl, IDS_FOXTLIB, _dwFoxtlibOleMisc)
  103.  
  104.  
  105. /////////////////////////////////////////////////////////////////////////////
  106. // CFoxtlibCtrl::CFoxtlibCtrlFactory::UpdateRegistry -
  107. // Adds or removes system registry entries for CFoxtlibCtrl
  108.  
  109. BOOL CFoxtlibCtrl::CFoxtlibCtrlFactory::UpdateRegistry(BOOL bRegister)
  110. {
  111.     // TODO: Verify that your control follows apartment-model threading rules.
  112.     // Refer to MFC TechNote 64 for more information.
  113.     // If your control does not conform to the apartment-model rules, then
  114.     // you must modify the code below, changing the 6th parameter from
  115.     // afxRegInsertable | afxRegApartmentThreading to afxRegInsertable.
  116.  
  117.     if (bRegister)
  118.         return AfxOleRegisterControlClass(
  119.             AfxGetInstanceHandle(),
  120.             m_clsid,
  121.             m_lpszProgID,
  122.             IDS_FOXTLIB,
  123.             IDB_FOXTLIB,
  124.             afxRegInsertable | afxRegApartmentThreading,
  125.             _dwFoxtlibOleMisc,
  126.             _tlid,
  127.             _wVerMajor,
  128.             _wVerMinor);
  129.     else
  130.         return AfxOleUnregisterClass(m_clsid, m_lpszProgID);
  131. }
  132.  
  133.  
  134. /////////////////////////////////////////////////////////////////////////////
  135. // CFoxtlibCtrl::CFoxtlibCtrl - Constructor
  136.  
  137. CFoxtlibCtrl::CFoxtlibCtrl()
  138. {
  139.     InitializeIIDs(&IID_DFoxtlib, &IID_DFoxtlibEvents);
  140.     if (!_OCXAPI(AfxGetInstanceHandle(),DLL_PROCESS_ATTACH))
  141.     {
  142.         ::MessageBox(0,"This OCX can only be hosted by Visual Foxpro","",0);
  143.         //Here you can do whatever you want when the host isn't VFP:
  144.         // you might want to reject loading or you might want to set a property
  145.         //saying that the host isn't VFP and the control will use other means
  146.         // to achieve it's purpose.
  147.     }
  148. }
  149.  
  150.  
  151. /////////////////////////////////////////////////////////////////////////////
  152. // CFoxtlibCtrl::~CFoxtlibCtrl - Destructor
  153.  
  154. CFoxtlibCtrl::~CFoxtlibCtrl()
  155. {
  156.     _OCXAPI(AfxGetInstanceHandle(),DLL_PROCESS_DETACH);
  157. }
  158.  
  159.  
  160. /////////////////////////////////////////////////////////////////////////////
  161. // CFoxtlibCtrl::OnDraw - Drawing function
  162.  
  163. void CFoxtlibCtrl::OnDraw(
  164.             CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid)
  165. {
  166.     // TODO: Replace the following code with your own drawing code.
  167.     pdc->FillRect(rcBounds, CBrush::FromHandle((HBRUSH)GetStockObject(WHITE_BRUSH)));
  168.     pdc->Ellipse(rcBounds);
  169. }
  170.  
  171.  
  172. /////////////////////////////////////////////////////////////////////////////
  173. // CFoxtlibCtrl::DoPropExchange - Persistence support
  174.  
  175. void CFoxtlibCtrl::DoPropExchange(CPropExchange* pPX)
  176. {
  177.     ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor));
  178.     COleControl::DoPropExchange(pPX);
  179.  
  180.     // TODO: Call PX_ functions for each persistent custom property.
  181.  
  182. }
  183.  
  184.  
  185. /////////////////////////////////////////////////////////////////////////////
  186. // CFoxtlibCtrl::OnResetState - Reset control to default state
  187.  
  188. void CFoxtlibCtrl::OnResetState()
  189. {
  190.     COleControl::OnResetState();  // Resets defaults found in DoPropExchange
  191.  
  192.     // TODO: Reset any other control state here.
  193. }
  194.  
  195.  
  196. /////
  197.  
  198.  
  199.  
  200. #include "winnls.h"
  201.  
  202. void OLEFreeString(void **ppsz)
  203. {
  204.     HRESULT     hr;
  205.     IMalloc        *pIMalloc;
  206.  
  207.     if (NULL != ppsz && NULL != *ppsz)
  208.     {
  209.         hr = CoGetMalloc(MEMCTX_TASK, &pIMalloc);
  210.  
  211.         if (FAILED(hr))
  212.             return;
  213.         
  214.         pIMalloc->Free(*ppsz);
  215.  
  216.         pIMalloc->Release();
  217.         
  218.         *ppsz = NULL;
  219.     }
  220.     
  221.     return;
  222. }
  223.  
  224. HRESULT OLECopyAnsiToOle(TEXT *pszA, OLECHAR *pszW, int cbW)
  225. {
  226.     ULONG    cchW;
  227.     HRESULT    hr;
  228.  
  229.  
  230.     hr = NOERROR;
  231.     
  232.     cchW = cbW / sizeof(OLECHAR);    // do this here in case cbW == 1 which is invalid
  233.     
  234.     if (!pszW || !cchW)
  235.     {
  236.         hr = ResultFromScode(E_INVALIDARG);
  237.     }
  238.     else
  239.     {
  240.         *pszW = '\0';
  241.         
  242.         if (pszA && *pszA)
  243.         {
  244. #if WIN32
  245.             if (MultiByteToWideChar(CP_ACP, 0, (LPSTR)pszA, -1, pszW, cchW) == 0)
  246.             {
  247.                 *pszW = '\0';
  248.                 hr = ResultFromScode(E_FAIL);
  249.             }
  250. #elif MAC_OS
  251.             // NO MAC UNICODE YET
  252.             strncpy(pszW, (char *) pszA, cchW);
  253. #endif
  254.         }
  255.     }
  256.  
  257.     return (hr);
  258. }
  259.  
  260.  
  261. HRESULT OLEConvertStringAlloc(ULONG ulSize, void **ppv)
  262. {
  263.     HRESULT     hr;
  264.     IMalloc    *pIMalloc;
  265.  
  266.     // Reject zero-length strings, because a valid, but empty, ptr. would get
  267.     // allocated, which might confuse the caller.
  268.     if ((ulSize == 0) || (ppv == NULL))
  269.     {
  270.         return (ResultFromScode(E_INVALIDARG));
  271.     }
  272.  
  273.     *ppv = NULL;
  274.     
  275.     hr = CoGetMalloc(MEMCTX_TASK, &pIMalloc);
  276.  
  277.     if (!SUCCEEDED(hr))
  278.         return (hr);
  279.  
  280.     *ppv = pIMalloc->Alloc(ulSize);
  281.     pIMalloc->Release();
  282.  
  283.     if (*ppv != NULL)
  284.         memset(*ppv, 0, ulSize);
  285.  
  286.     return ((*ppv == NULL) ? ResultFromScode(E_OUTOFMEMORY) : ResultFromScode(NOERROR));
  287. }
  288.  
  289.  
  290.  
  291. HRESULT OLEAnsiToOleString(TEXT *pszA, OLECHAR **ppszW)
  292. {
  293.     ULONG   cch,     // character count
  294.             cb;        // byte count
  295.     HRESULT hr;
  296.  
  297.  
  298.     if (!ppszW)
  299.         return (ResultFromScode(E_INVALIDARG));
  300.  
  301.     *ppszW = NULL;
  302.     hr = NOERROR;
  303.  
  304.     if (pszA)
  305.     {
  306. #if WIN32
  307.         cch = MultiByteToWideChar(CP_ACP, 0, (LPSTR)pszA, -1, NULL, 0);
  308. #elif MAC_OS
  309.         // NO MAC UNICODE YET
  310.         cch = strlen((char *) pszA) + 1;
  311. #endif
  312.  
  313.         cb = cch * sizeof(OLECHAR);
  314.     }
  315.         
  316.     if (SUCCEEDED(hr = OLEConvertStringAlloc(cb, (void **)ppszW)))
  317.     {
  318.         hr = OLECopyAnsiToOle(pszA, *ppszW, cb);
  319.         if (FAILED(hr))
  320.             OLEFreeString((void **)ppszW);    // This will set *ppszW = NULL.
  321.     }
  322.     return (hr);
  323. }
  324.  
  325.  
  326. HRESULT OLECopyOleToAnsi(OLECHAR *pszW, TEXT *pszA, int cbA)
  327. {
  328.     HRESULT    hr = NOERROR;
  329.     
  330.     if (!pszA || !cbA)
  331.     {
  332.         hr = ResultFromScode(E_INVALIDARG);
  333.     }
  334.     else
  335.     {
  336.         *pszA = '\0';
  337.         
  338.         if (pszW && *pszW)
  339.         {
  340. #if WIN32
  341.             if (WideCharToMultiByte(CP_ACP, 0, pszW, -1, (LPSTR)pszA, cbA, NULL, NULL) == 0)
  342.             {
  343.                 *pszA = '\0';
  344.                 hr = ResultFromScode(E_FAIL);
  345.             }
  346. #elif MAC_OS
  347.             // NO MAC UNICODE YET
  348.             strncpy((char *) pszA, pszW, cbA);
  349. #endif
  350.         }
  351.     }
  352.  
  353.     return (hr);
  354. }
  355.  
  356. HRESULT OLEOleToAnsiString(OLECHAR *pszW, TEXT **ppszA)
  357. {
  358.     ULONG   cch,     // character count
  359.             cb;        // byte count
  360.     HRESULT hr;
  361.  
  362.  
  363.     if (!ppszA)
  364.         return (ResultFromScode(E_INVALIDARG));
  365.  
  366.     *ppszA = NULL;
  367.     hr = NOERROR;
  368.  
  369.     if (pszW)
  370.     {
  371. #if WIN32
  372.         cch = WideCharToMultiByte(CP_ACP, 0, pszW, -1, NULL, 0, NULL, NULL);
  373. #elif MAC_OS
  374.         // NO MAC UNICODE YET
  375.         cch = strlen(pszW) + 1;
  376. #endif
  377.  
  378.         cb = cch;
  379.         
  380.         if (SUCCEEDED(hr = OLEConvertStringAlloc(cb, (void **)ppszA)))
  381.         {
  382.             hr = OLECopyOleToAnsi(pszW, *ppszA, cb);
  383.             if (FAILED(hr))
  384.                 OLEFreeString((void **)ppszA);    // This will set *ppszA = NULL.
  385.         }
  386.     }
  387.     
  388.     return (hr);
  389. }
  390.  
  391.  
  392.  
  393. void StoreBstr(Locator *ploc,int index, BSTR *lpBstr) {
  394.     char *szBuff;
  395.     Value val;
  396.     OLEOleToAnsiString(*lpBstr,&szBuff);
  397.     SysFreeString(*lpBstr);
  398.     val.ev_type = 'C';
  399.     ploc->l_sub1 = index;
  400.     if (szBuff) {
  401.         val.ev_length = strlen(szBuff);
  402.         val.ev_handle = _AllocHand(val.ev_length);
  403.         _HLock(val.ev_handle);
  404.         _MemMove(_HandToPtr(val.ev_handle),szBuff,val.ev_length);
  405.         _Store(ploc,&val);
  406.         _HUnLock(val.ev_handle);
  407.         _FreeHand(val.ev_handle);
  408.     } else {
  409.         val.ev_length = val.ev_handle = 0;
  410.         _Store(ploc,&val);
  411.     }
  412. }
  413.  
  414.  
  415. /////////////////////////////////////////////////////////////////////////////
  416. // CFoxtlibCtrl message handlers
  417.  
  418.  
  419.  
  420. long CFoxtlibCtrl::TLLoadTypeLib(LPCTSTR szFileName) 
  421. {
  422.     OLECHAR *OFileName;
  423.     HRESULT hr;
  424.     ITypeLib * lptlib;
  425.     OLEAnsiToOleString((TEXT *)szFileName,&OFileName);
  426.     hr =  ::LoadTypeLib(OFileName, &lptlib);
  427.     OLEFreeString((void **)&OFileName);
  428.     if (SUCCEEDED(hr))
  429.         return (long)lptlib;
  430.  
  431.     return 0;
  432. }
  433.  
  434. long CFoxtlibCtrl::TLRelease(long pTypeInfo) 
  435. {
  436.     int nResult;
  437.     __try {
  438.         nResult = ((ITypeLib *)pTypeInfo)->Release();
  439.     } __except  (EXCEPTION_EXECUTE_HANDLER) {
  440.  
  441.         nResult = 0;
  442.     }
  443.     return nResult;
  444. }
  445.  
  446. long CFoxtlibCtrl::TLGetTypeInfoCount(long pTypeInfo) 
  447. {
  448.     int nResult;
  449.     __try {
  450.         nResult = ((ITypeLib *)pTypeInfo)->GetTypeInfoCount();
  451.     } __except  (EXCEPTION_EXECUTE_HANDLER) {
  452.  
  453.         nResult = 0;
  454.     }
  455.     return nResult;
  456. }
  457.  
  458. long CFoxtlibCtrl::TLGetTypeAttr(long pTypeInfo, LPCTSTR szArrName) 
  459. {
  460.     int nResult = 1;
  461.     TYPEATTR *lpTypeAttr;
  462.     Locator loc;
  463.     Value val;
  464.     OLECHAR szGuid[128];
  465.     char *szBuff;
  466.     __try {
  467.         if (_FindVar(_NameTableIndex((char *)szArrName),-1,&loc)) {
  468.             ((ITypeInfo *)pTypeInfo)->GetTypeAttr(&lpTypeAttr);
  469.             if (_ALen(loc.l_NTI, AL_ELEMENTS) < 16)
  470.             {
  471.                 throw(631); //"Array argument not of proper size.");
  472.             }
  473.  
  474.             //1 = Guid
  475.             StringFromGUID2(lpTypeAttr->guid,(LPOLESTR )&szGuid,sizeof(szGuid));
  476.             OLEOleToAnsiString(szGuid,&szBuff);
  477.             val.ev_type = 'C';
  478.             val.ev_length = strlen(szBuff);
  479.             val.ev_handle = _AllocHand(val.ev_length);
  480.             _HLock(val.ev_handle);
  481.             _MemMove((char *)_HandToPtr(val.ev_handle),szBuff,val.ev_length);
  482.             OLEFreeString((void **)&szBuff);
  483.             _HUnLock(val.ev_handle);
  484.  
  485.             loc.l_sub1 = 1;
  486.             _Store(&loc,&val);
  487.             _FreeHand(val.ev_handle);
  488.  
  489.             //2 = LCID
  490.             loc.l_sub1 = 2;
  491.             val.ev_type = 'I';
  492.             val.ev_long = lpTypeAttr->lcid;
  493.             _Store(&loc,&val);
  494.  
  495.             //3 dwReserved
  496.             loc.l_sub1 = 3;
  497.             val.ev_type = 'I';
  498.             val.ev_long = lpTypeAttr->dwReserved;
  499.             _Store(&loc,&val);
  500.  
  501.             //4 Constructor
  502.             loc.l_sub1 = 4;
  503.             val.ev_type = 'I';
  504.             val.ev_long = lpTypeAttr->memidConstructor;
  505.             _Store(&loc,&val);
  506.  
  507.             //5 Destructor
  508.             loc.l_sub1 = 5;
  509.             val.ev_type = 'I';
  510.             val.ev_long = lpTypeAttr->memidDestructor;
  511.             _Store(&loc,&val);
  512.  
  513.             //6 lpstrSchema reserved
  514.             loc.l_sub1 = 6;
  515.             val.ev_type = 'I';
  516.             val.ev_long = (int)lpTypeAttr->lpstrSchema;
  517.             _Store(&loc,&val);
  518.  
  519.             //7 size Instance
  520.             loc.l_sub1 = 7;
  521.             val.ev_type = 'I';
  522.             val.ev_long = lpTypeAttr->cbSizeInstance;
  523.             _Store(&loc,&val);
  524.  
  525.             //8 TypeKind
  526.             loc.l_sub1 = 8;
  527.             val.ev_type = 'I';
  528.             val.ev_long = lpTypeAttr->typekind;
  529.             _Store(&loc,&val);
  530.  
  531.             //9 cFuncs
  532.             loc.l_sub1 = 9;
  533.             val.ev_type = 'I';
  534.             val.ev_long = lpTypeAttr->cFuncs;
  535.             _Store(&loc,&val);
  536.  
  537.             //10 cVars
  538.             loc.l_sub1 = 10;
  539.             val.ev_type = 'I';
  540.             val.ev_long = lpTypeAttr->cVars;
  541.             _Store(&loc,&val);
  542.  
  543.             //11 cImplTypes
  544.             loc.l_sub1 = 11;
  545.             val.ev_type = 'I';
  546.             val.ev_long = lpTypeAttr->cImplTypes;
  547.             _Store(&loc,&val);
  548.  
  549.             //12 cbSizeVft
  550.             loc.l_sub1 = 12;
  551.             val.ev_type = 'I';
  552.             val.ev_long = lpTypeAttr->cbSizeVft;
  553.             _Store(&loc,&val);
  554.  
  555.             //13 cbAlignment
  556.             loc.l_sub1 = 13;
  557.             val.ev_type = 'I';
  558.             val.ev_long = lpTypeAttr->cbAlignment;
  559.             _Store(&loc,&val);
  560.  
  561.             //14 wTypeFlags
  562.             loc.l_sub1 = 14;
  563.             val.ev_type = 'I';
  564.             val.ev_long = lpTypeAttr->wTypeFlags;
  565.             _Store(&loc,&val);
  566.  
  567.             //15 wMajorVerNum
  568.             loc.l_sub1 = 15;
  569.             val.ev_type = 'I';
  570.             val.ev_long = lpTypeAttr->wMajorVerNum;
  571.             _Store(&loc,&val);
  572.  
  573.             //16 wMinorVerNum
  574.             loc.l_sub1 = 16;
  575.             val.ev_type = 'I';
  576.             val.ev_long = lpTypeAttr->wMinorVerNum;
  577.             _Store(&loc,&val);
  578.  
  579.             ((ITypeInfo *)pTypeInfo)->ReleaseTypeAttr(lpTypeAttr);
  580.  
  581.         }
  582.     } __except  (EXCEPTION_EXECUTE_HANDLER) {
  583.         nResult = 0;
  584.     }
  585.     return nResult;
  586. }
  587.  
  588. long CFoxtlibCtrl::TLGetTypeInfo(long pTypeInfo,long nIndex) 
  589. {
  590.     ITypeInfo * lpTypeInfo;
  591.     int nResult;
  592.     __try {
  593.         nResult = ((ITypeLib *)pTypeInfo)->GetTypeInfo(nIndex,&lpTypeInfo);
  594.         if (SUCCEEDED(nResult))
  595.             nResult = (int) lpTypeInfo;
  596.  
  597.     } __except  (EXCEPTION_EXECUTE_HANDLER) {
  598.         nResult = 0;
  599.     }
  600.     return nResult;
  601. }
  602. //                =GetDocumentation(m.ITypeInfo,@ta,m.j)
  603.  
  604. long CFoxtlibCtrl::TLGetDocumentation(long pTypeInfo, LPCTSTR szArrName, long nIndex,long nKind) 
  605. {
  606.     //Kind = 0 for TypeLib, 1 for TypeInfo
  607.     int nResult = 1;
  608.     BSTR bstrName;
  609.     BSTR bstrDocString;
  610.     unsigned long dwHelpContext;
  611.     BSTR bstrHelpFile;
  612.     Locator loc;
  613.     __try {
  614.         if (_FindVar(_NameTableIndex((char *)szArrName),-1,&loc)) {
  615.             if (nKind)
  616.             {
  617.                 ((ITypeInfo *)pTypeInfo)->GetDocumentation(nIndex ,&bstrName,&bstrDocString,
  618.                     &dwHelpContext,&bstrHelpFile);
  619.             } else {
  620.                 ((ITypeLib *)pTypeInfo)->GetDocumentation(nIndex ,&bstrName,&bstrDocString,
  621.                     &dwHelpContext,&bstrHelpFile);
  622.             }
  623.             if (_ALen(loc.l_NTI, AL_ELEMENTS) < 3)
  624.             {
  625.                 throw(631); //"Array argument not of proper size.");
  626.             }
  627.  
  628.             StoreBstr(&loc,1,&bstrName);
  629.             StoreBstr(&loc,2,&bstrDocString);
  630.             StoreBstr(&loc,3,&bstrHelpFile);
  631.         }
  632.  
  633.     } __except  (EXCEPTION_EXECUTE_HANDLER) {
  634.         nResult = 0;
  635.     }
  636.     return nResult;
  637. }
  638.  
  639. long CFoxtlibCtrl::TIGetNames(long pTypeInfo, LPCTSTR szArrName, long nMemId) 
  640. {
  641.     int nResult = 1;
  642.     Locator loc;
  643.     __try {
  644.         if (_FindVar(_NameTableIndex((char *)szArrName),-1,&loc)) {
  645.             BSTR rgbstrNames[20];
  646.             int cNames = 0;
  647.  
  648.             ((ITypeInfo *)pTypeInfo)->GetNames(nMemId,rgbstrNames,20,(UINT *)&cNames);
  649.             if (cNames)
  650.             {
  651.  
  652.                 if (_ALen(loc.l_NTI, AL_ELEMENTS) < cNames)
  653.                 {
  654.                     throw(631); //"Array argument not of proper size.");
  655.                 }
  656.                 for (int i=1 ; i <= cNames ; i++)    {    //index through Fox array
  657.                     StoreBstr(&loc, i, &rgbstrNames[i-1]);
  658.                 }
  659.             }
  660.             nResult = cNames;
  661.         }
  662.  
  663.     } __except  (EXCEPTION_EXECUTE_HANDLER) {
  664.         nResult = 0;
  665.     }
  666.     return nResult;
  667. }
  668.  
  669. long CFoxtlibCtrl::TIGetFuncDesc(long pTypeInfo, LPCTSTR szArrName, long nIndex, LPCTSTR szParmsArr) 
  670. {
  671.     int nResult = 1;
  672.     Locator loc,ploc;
  673.     Value val;
  674.     __try {
  675.         if (_FindVar(_NameTableIndex((char *)szArrName),-1,&loc)) {
  676.             FUNCDESC * lpFuncDesc;
  677.  
  678.             if (_ALen(loc.l_NTI, AL_ELEMENTS) < 5)
  679.             {
  680.                 throw(631); //"Array argument not of proper size.");
  681.             }
  682.             ((ITypeInfo *)pTypeInfo)->GetFuncDesc(nIndex,&lpFuncDesc);
  683.  
  684.             //1 = memid
  685.             loc.l_sub1 = 1;
  686.             val.ev_type = 'I';
  687.             val.ev_long = lpFuncDesc->memid;
  688.             _Store(&loc,&val);
  689.  
  690.             if (_FindVar(_NameTableIndex((char *)szParmsArr),-1,&ploc)) {
  691.                 int nelem = lpFuncDesc->cParams + lpFuncDesc->cParamsOpt;
  692.                 if (_ALen(loc.l_NTI, AL_ELEMENTS) < nelem)
  693.                 {
  694.                     throw(631); //"Array argument not of proper size.");
  695.                 }
  696.                 ploc.l_sub1 = 1;
  697.                 val.ev_type = 'I';
  698.                 val.ev_long = (long) lpFuncDesc->elemdescFunc.tdesc.vt;
  699.                 _Store(&ploc,&val);
  700.                 for (int i = 0 ; i < nelem ; i++) {
  701.                     ploc.l_sub1 = 2 + i;        //start parms at xbase array element #2
  702.                     val.ev_type = 'I';
  703.                     val.ev_long = (long)lpFuncDesc->lprgelemdescParam[i].tdesc.vt;
  704.                     _Store(&ploc,&val);
  705.  
  706.                 }
  707.  
  708.  
  709.             }
  710.  
  711.             //2 = FUNCKIND
  712.             loc.l_sub1 = 2;
  713.             val.ev_type = 'I';
  714.             val.ev_long = lpFuncDesc->funckind;
  715.             _Store(&loc,&val);
  716.  
  717.             //3 = INVOKEKIND
  718.             loc.l_sub1 = 3;
  719.             val.ev_type = 'I';
  720.             val.ev_long = lpFuncDesc->invkind;
  721.             _Store(&loc,&val);
  722.  
  723.  
  724.             //4 = CALLCONV
  725.             loc.l_sub1 = 4;
  726.             val.ev_type = 'I';
  727.             val.ev_long = lpFuncDesc->callconv;
  728.             _Store(&loc,&val);
  729.  
  730.             //5 = cParams
  731.             loc.l_sub1 = 5;
  732.             val.ev_type = 'I';
  733.             val.ev_long = lpFuncDesc->cParams;
  734.             _Store(&loc,&val);
  735.  
  736.             //6 = cParamsOpt
  737.             loc.l_sub1 = 6;
  738.             val.ev_type = 'I';
  739.             val.ev_long = lpFuncDesc->cParamsOpt;
  740.             _Store(&loc,&val);
  741.  
  742.             //7 = oVft;
  743.             loc.l_sub1 = 7;
  744.             val.ev_type = 'I';
  745.             val.ev_long = lpFuncDesc->oVft;
  746.             _Store(&loc,&val);
  747.  
  748.             //8 = cScodes
  749.             loc.l_sub1 = 8;
  750.             val.ev_type = 'I';
  751.             val.ev_long = lpFuncDesc->cScodes;
  752.             _Store(&loc,&val);
  753.  
  754.  
  755.             //9 = wFuncFlags
  756.             loc.l_sub1 = 9;
  757.             val.ev_type = 'I';
  758.             val.ev_long = lpFuncDesc->wFuncFlags;
  759.             _Store(&loc,&val);
  760.  
  761.  
  762.             ((ITypeInfo *)pTypeInfo)->ReleaseFuncDesc(lpFuncDesc);
  763.         }
  764.  
  765.     } __except  (EXCEPTION_EXECUTE_HANDLER) {
  766.         nResult = 0;
  767.     }
  768.     return nResult;
  769. }
  770.