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);