Using ActiveX Controls with MFC

來源:互聯網
上載者:User
Using ActiveX Controls with MFCContents
  • Introduction.
  • Creating a Wrapper for the ActiveX Control.
  • Responding to ActiveX Events.
  • Serializing
Introduction

You may use ActiveX controls in Visual C++ just as you would any other control such as a Button or an Edit box. You may have created these controls yourself or they may have been written by someone else. You do not need the source code.

Creating a Wrapper for the ActiveX Control.

Open the Project in which you intend to use an ActiveX control.

Project | Add To Project | Components and Controls. You will be taken to the Gallery where you may choose from Registered ActiveX Controls. Choose the Control from the list and click Insert. You will be asked to choose the Control from a list (usually one) and to confirm the names of the wrapper files which will be created. I advise suffixing the class name and file names with 'wrapper' to avoid confusion with the actual C++ files which define the control.

A new 'wrapper' class will be added to your Project. This class inherits from CWnd and is otherwise quite simple.

You may use this class as if it were any other windows control such as a button or an edit box. A new 'OCX' button will be added to the Controls palette for use on Dialogs or you may use the Create method of the wrapper class to create the ActiveX controls dynamically. (See Creating ActiveX controls with MFC for an example of this).

Of course if you are developing a system of interacting ActiveX controls you will find yourself having to re-create this wrapper class whenever you change the specification of the ActiveX control. Do so by removing the files from the file view (highlight and press delete), and by deleting the actual files in your project folder. You needn't worry about doing this as long as you have put the word wrapper in the name of the wrapper classes. Then use the Gallery to add the wrapper again.

Responding to ActiveX Events.

The Classwizard Message Maps tab helps you to easily add handlers for the events fired by ActiveX controls if you have placed one of those controls on a dialog resource. However, most useful ActiveX controls will create and position their child controls dynamically so ClassWizard will not be able to detect them. We must therefore resort to entering the macros ourselves. Remember that if you're not sure what the macro should look like for your particular control, you can put an ActiveX control on a dialog and create a Message Map for its events. Just be careful to remove the entries after you have used them to see the form they should take.

Firstly, create an IDR resource symbol for your control. Use View | View Resource Symbols. You should use this resource symbol when creating the control wrapper.

e.g.

m_SubSectionWrapper.Create( _T("SUB"), WS_CHILD | WS_VISIBLE, tempRect, this, IDR_SUBSECTION);

MFC controls capture ActiveX Events by using an 'Events Sink' which is basically just an extension of the regular message map. You must declare the Events Sink map inside the regular message map declarations in the declaration (.h) file. e.g.

// Message maps//{{AFX_MSG(CSubSectionCtrl)afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);DECLARE_EVENTSINK_MAP()//}}AFX_MSGDECLARE_MESSAGE_MAP()

Add the Event Sinks Map near the start of the definition (.cpp) file, before the regular BEGIN_MESSAGE_MAP section, as follows:

BEGIN_EVENTSINK_MAP(CSubContainerCtrl, COleControl)     //{{AFX_EVENTSINK_MAP(CSubContainerCtrl)     ON_EVENT(CSubContainerCtrl, IDR_SUBSECTION, 1 /* ResizeControls */, OnResizeColumns, VTS_NONE)     //}}AFX_EVENTSINK_MAPEND_EVENTSINK_MAP()

The BEGIN_EVENTSINK_MAP macro takes the container's Class name, then the base class name as parameters. The container's class name is used again in the AFX_EVENTSINK_MAP macro and the ON_EVENT macro.

The ON_EVENT macro needs the ID number of the ActiveX Event, which you can get from the ODL file, the OLE/COM Object viewer, or by creating an example handler using the classwizard as mentioned above. The final parameter is a space-separated list of parameter types for the event. Again, if you are not sure which types to use here, you could create an example using a dialog and the classwizard.

Next, declare the handler in the declaration (.h) file.

//{{AFX_MSG(CSubSectionCtrl)afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);afx_msg void OnResizeColumns();DECLARE_EVENTSINK_MAP()//}}AFX_MSGDECLARE_MESSAGE_MAP()

Then just write the definition for your handler. e.g.

void CSubContainerCtrl::OnResizeColumns() {    ...} 
Serializing.

If you are using the MFC Document/View architecture with Compound Document support then the controls which you add will be persisted automatically.

The issue of serializing ActiveX controls which are used by other ActiveX controls is generally avoided in the documentation because it is not straightforward. In theory it can be done by using the PX_Blob macro, a temporary file archive, and a call to one of the control's COM methods. However I have yet to see a working example of this, though it is obvious that Microsoft have managed it in their own applications.

Alternatively, you may extract the properties of the ActiveX control (assuming they are directly available as COM properties) and serialize those values.

Copyright Murray Cumming. Verbatim copying and distribution of this entire article is permitted in any medium, provided this notice is preserved.

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.