How to obtain access to an ActiveX control from its property page

http://support.microsoft.com/kb/205670/en-us#top

There is a mistake in  step 8 In this article.It should include two header file :

#include "MyTestCtrl.h"
#include "CDMyTest.h"

but not :

#include "MyTestCtl.h"

http://support.microsoft.com/kb/205670/en-us#top

在这篇微软的文章中,第八步有个小错误,应该包含两个头文件:

#include "MyTestCtrl.h"
#include "CDMyTest.h"

而不是:

#include "MyTestCtl.h"

 

步骤总结如下:
(注意第八步的错误 
#include "MyTestCtrl.h"
#include "CDMyTest.h"
)

添加属性:

1.Generate a new MFC ActiveX control and specify the project name as MyTest. Accept all of the defaults for the control when prompted.
2.Add a new member function to the control. Name the function SayHello, with return type void. Add the following code to it:
void CMyTestCtrl::SayHello()
{
    AfxMessageBox("Hello"); //Add this statement.
}
					
3.Create a property:
In Visual C++ .NET
a. Open the Class View window and then open MyTestLib (this is the node that represents the IDL file for the project).
b. Right-click the subnode for the default dispinterface (_DMyTest), Add, and then click Add Property.
c. In the Add Property Wizard, set the property type to LONG and the property name to ControlPointer. For Implementation, click to select Get/Set methods.
d. Click Finish to generate the property.
In earlier versions of Visual C++
a. Click the Automation tab in the MFC ClassWizard dialog box, and then add a new property for the control of type LONG.
b. Set the External name field to ControlPointer, select Get/Set methods for Implementation, and then accept the rest of the settings.
4.Use the following code for the generated ControlPointer property methods:
long CMyTestCtrl::GetControlPointer() 
{
    return reinterpret_cast<long>(this);
}

void CMyTestCtrl::SetControlPointer(long /*nNewValue*/) 
{
    SetNotSupported();
}
					
5.Build the project to make the type library before proceeding.

添加新类:

6.Generate automation wrappers for the control:
In Visual C++ .NET
a. On the Project menu, click Add Class Project.
b. In the Add Class dialog box, click to select MFC Class from Typelib, and then click OK.
c. In the Add Class From Typelib Wizard, locate Add class from, and then click to select File.
d. Find the .tlb file that was generated for the control. The file is located in the Debug directory and is named MyTest.tlb. Use the selection arrows to move only the _DMyTest interface into the Generated classes pane. Note You must now change the Generated Classes class from the default CDMyTest to _DMyTest. This also changes the generated class names for the wrappers. The wizard prepends a 'C' to the generated wrapper classes, which may cause problems when you use some type libraries. Changing names is necessary for this type library to make the code match between Visual C++ .NET and earlier versions.
e. Click Finish to generate the wrapper header files.
In earlier versions of Visual C++
a. Click the Automation tab in the Class Wizard, click Add class, and then click From a type library.
b. Find the .tlb file that was generated for the control. It is located in the Debug directory and is named MyTest.tlb.
c. Select only the _DMyTest interface and click OK. The event interface is not needed.
7.Using the resource editor, add a button to the property page. Change the caption to Access all selected controls.

添加全局函数:

8.Add the control's header file after the other includes in the property page source file:
    #include "MyTestCtl.h"
					
9.Add a button click handler for the button by using the Class Wizard.
10.Add the following code in the button click handler function:
    void CMyTestPropPage::OnButton1() 
    {
        // Add this code:
        ULONG uNumControls;

        // Get the array of IDispatchs stored in the property page.
        LPDISPATCH *lpDispatchControls = GetObjectArray(&uNumControls);
 
        for (ULONG i = 0; i < uNumControls; i++)
        {
          CMyTestCtrl *pMyCtrl = GetControl(lpDispatchControls, i);
          if (pMyCtrl)
             pMyCtrl->SayHello();
        }
    }
					
11.Add the following global code method before the button click handler function:
    CMyTestCtrl* GetControl(LPDISPATCH *lpDispatchControls, ULONG iControlIndex)
    {
        CMyTestCtrl *pMyCtrl = NULL; 

        // Get the CCmdTarget object associated.
        pMyCtrl = (CMyTestCtrl*) CCmdTarget::FromIDispatch(lpDispatchControls[iControlIndex]);

        if (!pMyCtrl) // Above failed. Container must have aggregated the control.
        {
           long ControlPointer;

           _DMyTest control(lpDispatchControls[iControlIndex]);           

           // GetObjectArray() docs state must not release pointer.
           control.m_bAutoRelease = FALSE;
           ControlPointer = control.GetControlPointer();

           pMyCtrl = reinterpret_cast<CMyTestCtrl*>(ControlPointer);
        }

        return pMyCtrl;
    }
					
12.Build the project.
13.Test the project in Visual C++ ActiveX Test Container. You see the message box when you click the Access all selected controls button on the property page.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值