ActiveX¿Ø¼þµÄMFCÉè¼ÆÖ®ÂÃ

sa.PtrOfIndex(lindex, (void**)&prect); m_cells[i-llb1][j-llb2].m_rect = prect; } }

sa.Unlock();

InvalidateControl(); SetModifiedFlag(); }

ÆäʵֻҪ½«TextsÊôÐԵĴúÂ뿽±´¹ýÀ´£¬ÉÔ΢ÐÞ¸ÄһϾͿÉÒÔÁË£¬ÕâÀïµÄ GUID_LibºÍGUID_Rect¶¨ÒåÔÚLiteGridCtrl.cppÖУ¬ÈçÏ£º const GUID GUID_Lib =

{ 0x191618F9, 0xEBF9, 0x4538, { 0x9E, 0x10, 0xD9, 0xC5, 0x62, 0x7E, 0xAE, 0xA9 } }; const GUID GUID_Rect =

{ 0x6BF5EE0C, 0x373A, 0x4893, { 0x89, 0xEB, 0x2C, 0x02, 0x08, 0xD3, 0xD4, 0xEB } };

3.ÔÚVBµÄForm_LoadÖÐÌí¼ÓÈçÏ´úÂë Private Sub Form_Load()

Dim str(0 To 9, 0 To 9) As String Dim stro() As String Dim i As Integer Dim j As Integer For i = 0 To 9 For j = 0 To 9

str(i, j) = i & \ Next Next

LiteGrid1.Texts = str stro = LiteGrid1.Texts Dim v() As Rect Dim x As Integer Dim y As Integer x = 0 y = 0

v = LiteGrid1.Rects

For i = LBound(v) To UBound(v) y = 0

For j = LBound(v, 2) To UBound(v, 2) v(i, j).Left = x v(i, j).Top = y

v(i, j).Right = x + 40 v(i, j).bottom = y + 16 y = y + 20 Next x = x + 50

Next

LiteGrid1.Rects = v End Sub

Ç°ÃæµÄÒ»¶ÎÊÇÉÏÒ»²½ÖеÄÄÚÈÝ£¬Ò²¸øÁÐÁ˳öÀ´£¬ÔËÐÐһϻᷢÏÖ¿ò¿òûÓв¢ÔÚÒ»ÆðÁË£¬·Ö¿ªÁËЩ£¬Ö¤Ã÷RectÊôÐÔµÄGetºÍSet¶¼Êǵ÷Óóɹ¦ÁË¡£ ËùÒÔ£¬Æäʵ»¹ÊÇÂù¼òµ¥µÄ

±¾À´ÊÇÏëÒªÓÃSafeArrayAllocDescriptorºÍSafeArrayAllocDataÀ´Ä£Äâ SafeArrayCreateExµÄ£¬¶øÇÒÊÂʵÉϺÃÏóÒ²²»»á³ö´íµÄ£¬SAFEARRAYµÄ¸÷¸ö³ÉÔ±µÄÖµÁ½ÖÖ·½·¨µÃµ½µÄ¶¼Ò»Ñù£¬ÈçÏ£º SAFEARRAY* psa = NULL;

SafeArrayAllocDescriptor(2, &psa); psa->rgsabound[0].lLbound = 0; psa->rgsabound[0].cElements = 10; psa->rgsabound[1].lLbound = 0; psa->rgsabound[1].cElements = 10; psa->cbElements = sizeof(RECT); psa->fFeatures = FADF_RECORD;

HRESULT hresult = SafeArrayAllocData(psa); if(FAILED(hresult)){

SafeArrayDestroyDescriptor(psa); return vaResult; }

¿ÉÊÇ£¬ÒâÍâµÄÊǾ¹È»GetRectsºÍSetRectsÈ«¶¼Ã»ÓÐÕýÈ·Ö´ÐÐ È»ºóÔÚºóÃæ¼ÓÉÏ

SafeArraySetRecordInfo(psa, pRecInfo);

¾ÍOKÁË¡£

ËùÒÔ¿´ÆðÀ´ËƺõÕâ¸ö IRecordInfoÊÇÒþ²ØÔÚSAFEARRAY½á¹¹Öе쬾ßÌå·ÅÄÄÀ¾Í²»È¥¹ÜËüÁË£¬Ñо¿Õâ¸öºÃÏóҲûʲôÒâÒåµÄ£¬Èç¹ûÄÄλÅóÓÑÅöÇÉÊìϤÕâ¸ö£¬·³Çé¸æÖªÒ»Ï£¬¸Ðл¡£ ²îµãÍüÁË£¬ÒòΪÕâÀﻹÊÇÓÃCOleSafeArrayÀ´½âÎöµÄ£¬ËùÒÔûÓõ½SafeArrayGetVartype£¬Õâ¸öº¯ÊýºÃÏóÒ²ÊÇmsdn ÖÐûÓеģ¬¿ÉÒÔÓÃËüÀ´ÅжÏÊÇ·ñÊÇÄãËùÐèÒªµÄVARTYPE£¬Ó¦¸ÃÊDZȽÏÓÐÓõġ£ VARTYPE vt;

SafeArrayGetVarType(psa, &vt);

ÕâÀïpsaΪSAFEARRAY*¡£

ÕâÒ»²½ºÜÐèҪһЩCOM»ù´¡£¬ÒòΪûÓÐÕâ¸ö»ù´¡µÄ»°£¬¿ÉÄÜ»áÓÐΪʲôҪ×öÕâ¸ö£¬ÓбØÒªÂð£¬Ö®ÀàµÄÒÉÎʵġ£Õâ»ØÎÒÃÇÒª¿´¿´Ë«½Ó¿Ú£¬ÎªMFCÉè¼ÆµÄ¿Ø¼þÌí¼ÓË«½Ó¿Ú£¨Ë«½Ó¿ÚÊÇʲô¾Í²»½âÊÍÁË£©¡£

ÕâÀï²Î¿¼ÁËmsdnÖеÄÀý×Óacdual£¬²¢ÇÒÓ¦ÓÃÁËÀý×ÓÀïÃæµÄһЩºê£¬Õâ¸öÀý×Ó¿ÉÒÔÖ±½ÓËÑË÷ msdnÕÒµ½£¬»¹ÓÐTN065: Dual-Interface Support for OLE Automation Servers²Î¿¼¡£ ÀÏÊÇÓÃÒ»¸öÀý×Ó£¬Ò²ÓÐЩÄåÁË£¬ÔÛÐÂÀ´Ò»Àý×Ó£¬TDual¿Ø¼þ ºÃ£¬¿ªÊ¼£º

1.н¨MFC¿Ø¼þ¹¤³Ì£¬ÕâÀïÌí¼ÓÁËÒ»¸öÊôÐÔ Hello£¨ÔڿؼþÉÏÏÔʾHelloÊôÐÔ¶ÔÓ¦µÄ×Ö·û´®£©£¬Ò»¸ö·½·¨SayHello£¬µ¯³öÒ»ÏûÏ¢¿ò£¬ÏÔʾ·½·¨²ÎÊýÖеÄ×Ö·û´®¡£

2.¸ÄÔì½Ó¿Ú£¬ Ìí¼ÓµÚ¶þ¸ö½Ó¿Ú

[ uuid(C3180013-EB23-4e8f-924C-38F5A201D3D8), helpstring(\ oleautomation, dual ]

interface ITDual : IDispatch {

[propput, id(1)] HRESULT Hello([in] BSTR newText); [propget, id(1)] HRESULT Hello([out, retval] BSTR* ret); [id(2)] HRESULT SayHello(BSTR strHello); }

Ë«½Ó¿ÚµÄ½Ó¿ÚÃèÊöÖбØÐëÓÐoleautomationºÍdualÊôÐÔ£¬¶øÇÒ½Ó¿Ú±ØÐëÅÉÉú×Ô IDispatch¡£ ÕâÀïµÄ½Ó¿Ú¶¨ÒåºÜÏóATLÖеÄIDL¶¨Ò壬Èç¹ûÓÃATLÉè¼Æ¹ý¿Ø¼þµÄ»°£¬Ó¦¸Ã²»Ä°ÉúµÄ£¬¾ßÌåµÄ¹æÔò¾Í²»ÂÞàÂÁË£¬Èç¹û²»Çå³þµÄ»°£¬Çë×ÔÐвéÕÒ×ÊÁÏÁË£¬´ó¼Ò¿ÉÒÔºÍMFCÖÐÔ­À´µÄ½Ó¿Ú¶¨Òå¶ÔÕÕһϣº properties:

// NOTE - ClassWizard will maintain property information here. // Use extreme caution when editing this section. //{{AFX_ODL_PROP(CTDualCtrl) [id(1)] BSTR Hello; //}}AFX_ODL_PROP methods:

// NOTE - ClassWizard will maintain method information here. // Use extreme caution when editing this section. //{{AFX_ODL_METHOD(CTDualCtrl) [id(2)] void SayHello(BSTR strHello); //}}AFX_ODL_METHOD

¶¨ÒåºÃÁËеĽӿںó£¬ÐèÒªÔÚcoclassÃèÊöÖÐÌí¼ÓнӿڵÄÒ»¸öÒýÓã¬ÈçÏ£º [ uuid(A1E75855-8561-4416-BE49-97B4D9A228E2), helpstring(\ coclass TDual {

// [default] dispinterface _DTDual;

// [default, source] dispinterface _DTDualEvents; [default] interface ITDual;

[default, source] dispinterface _DTDualEvents; dispinterface _DTDual; };

ÕâÀォȱʡµÄ½Ó¿ÚÉèÖÃΪÁËITDual¶ø²»ÊÇÔ­À´µÄdispinterface _DTDual¡£

3.¸ÄÔìºÃÁ˽ӿں󣬾ÍҪʵÏÖÕâ¸öеĽӿÚÁË¡£MFCʹÓÃǶÌ×ÀàÀ´ÊµÏÖÒ»¸ö½Ó¿Ú£¬µÃµ½Ç¶Ì×ÀàµÄ·½·¨ÊÇʹÓà BEGIN_INTERFACE_PART/END_INTERFACE_PARTºê¶Ô£¬½ÓמßÌåʵÏÖǶÌ×ÀàµÄÏàÓ¦½Ó¿Úº¯Êý£¨°üÀ¨IUnknownºÍ IDispatchµÄ½Ó¿Úº¯Êý£©¾Í¿ÉÒÔÁË¡£

ÕâÀïÓÃÁËacdulÀý×ÓÖж¨ÒåµÄBEGIN_DUAL_INTERFACE_PARTºÍ END_DUAL_INTERFACE_PARTºê¶ÔºÍDELEGATE_DUAL_INTERFACEºêÀ´¼ò»¯ÊµÏÖIUnknownºÍ IDispatchÖеĽӿں¯Êý¡£ÕâЩºêµÄ¶¨Ò彫ÔÚ×îºóÁгö¡£

ÔÚTDualCtl.hÖУ¬#include \Ìí¼ÓнӿÚPART£¬ÈçÏ£º // Event maps

//{{AFX_EVENT(CTDualCtrl) //}}AFX_EVENT

DECLARE_EVENT_MAP()

//´Ë´¦ÎªÌí¼Ó²¿·Ö public:

///////////////////////////////////////////////////////////////////////////// // Double Interface Part

DECLARE_INTERFACE_MAP()

BEGIN_DUAL_INTERFACE_PART(TDual, ITDual)

STDMETHOD(put_Hello)(THIS_ BSTR newText); STDMETHOD(get_Hello)(THIS_ BSTR FAR* ret); STDMETHOD(SayHello)(THIS_ BSTR strHello); END_DUAL_INTERFACE_PART(TDual)

ÔÚTDualCtl.cppÖÐ

///////////////////////////////////////////////////////////////////////////// // Control type information

static const DWORD BASED_CODE _dwTDualOleMisc = OLEMISC_ACTIVATEWHENVISIBLE | OLEMISC_SETCLIENTSITEFIRST | OLEMISC_INSIDEOUT |

OLEMISC_CANTLINKINSIDE | OLEMISC_RECOMPOSEONRESIZE;

IMPLEMENT_OLECTLTYPE(CTDualCtrl, IDS_TDUAL, _dwTDualOleMisc)

//Ìí¼ÓAddRef£¬QueryInterfaceµÈͨÓú¯ÊýµÄʵÏÖ DELEGATE_DUAL_INTERFACE(CTDualCtrl, TDual) ......

//ÕâÁ½¸öº¯ÊýÊÇÔ­À´Dispatch½Ó¿Ú·Ö·¢Ê±ÒªÓõ½µÄHelloÊôÐÔºÍSayHello·½·¨º¯Êý void CTDualCtrl::OnHelloChanged() {

// TODO: Add notification handler code InvalidateControl(); SetModifiedFlag(); }

void CTDualCtrl::SayHello(LPCTSTR strHello) {

// TODO: Add your dispatch handler code here AfxMessageBox(strHello);

ÁªÏµ¿Í·þ£º779662525#qq.com(#Ìæ»»Îª@)