Develop ActiveX controls using MFC)

Source: Internet
Author: User

  Abstract:This article introduces the MFC development method of ActiveX controls in COM components, and describes how to customize and create inventory attributes, methods, event adding methods, and property pages. This allows you to master the basic MFC ActiveX development methods.

  Keywords:MFC; ActiveX control; COM

  Reading directory:

I. Preface
2. Establish an Engineering Framework
3. Add attributes, methods, and events
4. Implement attribute tables
5. Use ActiveX controls in the inclusion program
Vi. Summary

  Preface

ActiveX control is a COM component that implements a series of specific interfaces to make it more like a control in use and appearance. ActiveX controls involve almost all of the core technologies of COM and OLE, such as link objects, unified data transmission, OLE documents, property pages, permanent storage, and OLE automation.

As a basic interface unit, ActiveX controls must have their own properties and methods to provide functional services to programs with different characteristics and to package container programs, the attributes and methods are supported by the IDispatch interface of the automated service. In addition to attributes and methods, ActiveX controls also have a feature different from that of Automated Services-events. An event refers to a notification sent from a control to its inclusion program. Similar to a window control that sends a message to its owner, the ActiveX control notifies its package container by triggering an event. Events are triggered by calling the methods of automated objects through the IDispatch interface provided by the control package container. When designing ActiveX controls, consider the events that may occur in the controls and the events that the package container program will be interested in and include them. Unlike Automated Services, ActiveX controls have custom methods, attributes, and events (custom), and inventory (stock. Custom methods and attributes are common automated methods and attributes. Custom events are events with their own names and Dispatch IDs. The so-called inventory methods, attributes, and events are the "standard" methods, attributes, and events that use ActiveX controls to specify names and Dispatch IDs.

ActiveX controls can make COM components look and use the same as common window controls, and provide properties pages similar to setting Windows Standard control properties, this allows you to visually set the properties of ActiveX controls in the design phase of the package container program. ActiveX controls provide these functions to make it very convenient to use. The following section describes the development of ActiveX controls using MFC.
  Establish Engineering Framework

The "MFC ActiveX ControlWizard" Wizard allows you to easily create an MFC ActiveX Control Engineering Framework. Follow the default options to create the project structure shown in 1:


Figure 1 ActiveX control project structure created using the default options

The interfaces _ DSample68 and _ DSample68Events provide the attributes, methods, and possible events of the control to the client program. The global functions DllRegisterServer () and DllUnregisterServer () are used for registration and logout of controls in the registry. They do not need to be modified.

The application class inherits from the COleControlModule. The COleControlModule is derived from CWinApp and provides the function of initializing the control module. The base class of CSample68PropPage is COlePropertyPage, a derived class of the CDialog class. It is mainly responsible for displaying the user control attributes on the property page on the graphic interface. The control class CSample68Ctrl is an important class among these classes. Most of the substantive work is completed in this class. Its base class is COleControl, inherited from CWnd and c1_target, therefore, it can provide the same functions as the MFC window object and a series of event triggering functions and a distribution ing table for the control object, so that the ActiveX control can interact effectively with the container program in the same package. The derived classes of this class can send messages or trigger events to the control's package container when specific conditions are met to notify the package container program of some important events in the control. The distribution ing table is an important part of the table. It exposes the methods and Attributes provided by the control to the package container program. Figure 2 shows the role of the COleControl class in the control-to-package container communication. It can be seen that all the communication process between ActiveX Control and Its package container is completed by COleControl:


Figure 2 Role of COleControl in communication between ActiveX Control and package container

The control class reloads the OnDraw () function of the base class COleControl. The Wizard generates the following default code, which is used to draw an ellipse in the control's customer zone. In programming, we usually need to replace it:

Void CSample68Ctrl: OnDraw (
CDC * pdc, const CRect & rcBounds, const CRect & rcInvalid)
{
// Todo: Replace the following code with your own drawing code.
PDC-> fillrect (rcbounds, cbrush: fromhandle (hbrush) getstockobject (white_brush )));
PDC-> ellipse (rcbounds );
}


Figure 3 insert ActiveX Control


Figure 4 inserted control to be tested

After compiling the code generated by the wizard, ActiveX control with the extension ocx will be generated. ActiveX controls cannot run independently. They can only run in the package container program. Generally, the ActiveX Control Test Container tool attached with VC ++ is used to debug ActiveX controls for convenience. Right-click the client area of the test tool and select "Insert New Control…" in the pop-up menu... "Menu item, the dialog box shown in Figure 3 is displayed. The list box on the left lists all registered ActiveX controls in the current system, select the Control to be tested and insert it to the test program. You can test the Control methods, attributes, and events by using the menu items in the Control menu. In the split view below, the trace shows the debugging record (see figure 4 ).
  Add attributes, methods, and events


Figure 5 adding a property


Figure 6 Add a method

You can add inventory and custom properties, methods, and events of ActiveX controls. Add properties and methods to the Automation page of the MFC ClassWizard dialog box and click "Add Property... "And" Add Method... "The add attribute and add method dialog box shown in Figure 5 and figure 6 is displayed. For inventory attributes and methods, you can directly select from the drop-down list of the External name combo box. The Implementation item is automatically set to Stock. Adding custom attributes and methods is the same as adding attributes and methods to interfaces in an Automation Object. the odl file and control class generate the corresponding code. The following shows some distribution ing Code implemented in the control class:

......
// Dispatch maps
// {Afx_dispatch (csample68ctrl)
Cstring m_message;
Afx_msg void onmessagechanged ();
Afx_msg short getxpos ();
Afx_msg void setxpos (short nnewvalue );
Afx_msg short getypos ();
Afx_msg void setypos (short nnewvalue );
Afx_msg short messagelen ();
//} Afx_dispatch
Declare_dispatch_map ()
// Dispatch and event IDS
Public:
Enum {
// {Afx_disp_id (csample68ctrl)
Dispidmessage = 1l,
Dispidxpos = 2L,
DispidYPos = 3L,
DispidMessageLen = 4L,
//} AFX_DISP_ID
};
......
BEGIN_DISPATCH_MAP (CSample68Ctrl, COleControl)
// {AFX_DISPATCH_MAP (CSample68Ctrl)
Disp_property_policy (CSample68Ctrl, "Message", m_message, OnMessageChanged, VT_BSTR)
DISP_PROPERTY_EX (CSample68Ctrl, "XPos", GetXPos, SetXPos, VT_I2)
DISP_PROPERTY_EX (CSample68Ctrl, "YPos", GetYPos, SetYPos, VT_I2)
DISP_FUNCTION (CSample68Ctrl, "MessageLen", MessageLen, VT_I2, VTS_NONE)
DISP_STOCKPROP_BACKCOLOR ()
DISP_STOCKPROP_CAPTION ()
DISP_STOCKPROP_FORECOLOR ()
//} AFX_DISPATCH_MAP
END_DISPATCH_MAP ()
......

A custom method MessageLen () and three inventory attributes BackColor, Caption, and ForeColor are added to indicate the background color, title, and foreground color of the control, respectively), two custom properties XPos and YPos obtained in Get/Set mode, and a custom property Message implemented in the form of member variables. These Custom Attributes indicate the x and y coordinates of the string and the content to be displayed. For properties obtained using the Get/Set method, you should add corresponding member functions to them in the control class and modify the implementation process of their Get and Set member functions:

Short m_nYPos;
Short m_nXPos;
......
Short CSample68Ctrl: GetXPos ()
{
Return m_nXPos;
}
Void CSample68Ctrl: SetXPos (short nNewValue)
{
M_nXPos = nNewValue;
SetModifiedFlag ();
}
Short CSample68Ctrl: GetYPos ()
{
Return m_nYPos;
}
Void CSample68Ctrl: SetYPos (short nNewValue)
{
M_nYPos = nNewValue;
SetModifiedFlag ();
}

For the attribute Message created as a member variable, the wizard also generates a Message response function:

Void CSample68Ctrl: OnMessageChanged ()
{
SetModifiedFlag ();
}

The OnMessageChanged () function is called as long as the value of this attribute is changed.

To enable the preceding property settings, such as the background color and foreground color, to be physically associated with the control, you need to replace the code generated by the wizard in the OnDraw () function of the control class. For example, the following code sets the property added previously as the parameter value and displays a string of characters in the control:

// Set the paint brush with the background color
CBrush Brush (TranslateColor (GetBackColor ()));
// Set the font color with the foreground color
Pdc-> SetTextColor (TranslateColor (GetForeColor ()));
// Draw the background
Pdc-> FillRect (rcBounds, & Brush );
// Set the font background to transparent
Pdc-> SetBkMode (TRANSPARENT );
// Display characters
Pdc-> TextOut (m_nXPos, m_nYPos, m_message );

In order to make the effect immediately displayed on the control after the attribute settings are changed, InvalidateControl () should be called in the function implementation related to the attribute settings to update the display of the control.

You can compile the program and Test it in the ActiveX Control Test Container tool. After the control is inserted, use "Invoke Methods... "The Dialog Box 7 is displayed. In the Method Name combo box, you can select the attributes and methods to be tested. The property tests are described as ProgGet and ProgSet to indicate that the property value is obtained and set. In the Parameter editing box, enter the Parameter to be set and its corresponding Parameter type. Click the SetValue button to add the Parameter value to the Parameter list box, finally, click the Invoke button to apply the Set Properties in the control and execute the specified method. For methods with Return values, the execution results are displayed in the Return edit box. If an Exception occurs, the Exception error message is displayed in the Exception edit box. Figure 8 shows the Property setting control interface.


Figure 7 test attributes and Methods


Figure 8 controls with properties set

To Add control properties, go to the ActiveX Events page of the MFC ClassWizard dialog box and click "Add Event... The "Add Event" Event Add dialog box shown in "button" appears. Similar to adding methods and properties, you can enter a Custom Event name in the External name combo box or select an inventory event from the drop-down list. The Implementation item automatically sets the Stock or Custom option based on the event type to be added. The ActiveX Control notifies the container program of a specific event by adding events. Inventory events are mostly Keyboard Events and mouse events, which are automatically handled by the COleControl. For custom events. necessary Code such as the event ing table is added to the odl file and control class (included in the Code). Developers must compile their own code to determine the conditions under which the event should be triggered.


Figure 9 Add an event

Dispinterface _ DSample68Events
{
Properties:
// Event interface has no properties
Methods:
// NOTE-ClassWizard will maintain event information here.
// Use extreme caution when editing this section.
// {AFX_ODL_EVENT (CSample68Ctrl)
[Id (1)] void MsgOut ();
//} AFX_ODL_EVENT
};
......
// Event maps
// {AFX_EVENT (CSample68Ctrl)
Void FireMsgOut ()
{FireEvent (eventidMsgOut, EVENT_PARAM (VTS_NONE ));}
//} AFX_EVENT
DECLARE_EVENT_MAP ()
// Dispatch and event IDs
Public:
Enum {
// {Afx_disp_id (csample68ctrl)
......
Eventidmsgout = 1l,
//} Afx_disp_id
};
......
Begin_event_map (csample68ctrl, colecontrol)
// {Afx_event_map (csample68ctrl)
Event_custom ("msgout", firemsgout, vts_none)
//} Afx_event_map
End_event_map ()

The above Code adds a custom MsgOut event, which can be triggered by calling FireMsgOut. Next, modify the OnMessageChanged () Message response function of the Message attribute. This function is called whenever the Message attribute content is changed. In this function, call the previously added MessageLen () method to determine the length of the modified Message attribute. When the length is greater than 10, FireMsgOut () is called to trigger the MsgOut event:

Void csample68ctrl: onmessagechanged ()
{
Invalidatecontrol ();
If (messagelen ()> = 10)
Firemsgout ();
Setmodifiedflag ();
}


Figure 10 select the event to be logged

When you use ActiveX Control Test Container to Test the newly added event, you must first use the "Logging... "Menu item 10 is displayed, and the Events to be tracked are selected from the" Events "property page. When the content of the Message attribute is set to more than 10 characters in the Invoke Methods dialog box, the split view at the bottom of the Program Framework records the MsgOut event triggered by the control (11 ).


Figure 11 test the event
  Implementation Attribute Table

Attribute Table is a unique technology of ActiveX controls. It can provide a visual human-machine interaction interface when the package container program is in the design stage, you can also set the Custom Attributes and inventory attributes of the control. When you use the Wizard to generate a program framework, an empty property page is generated to manage custom properties. In code, you can use the control class to maintain the property page ID table in the file:

Begin_proppageids (csample68ctrl, 1)
Proppageid (csample68proppage: guid)
End_proppageids (csample68ctrl)

The csample68proppage class is derived from colepropertypage, and the base class of colepropertypage is cdialog. Therefore, it is not difficult to find that csample68proppage is similar to the normal dialog box class. You can add interaction controls related to custom properties to the default property page in the resource view as in the processing dialog box, and bind these controls with class member variables through classwizard. However, the difference is that when binding a member variable, it also needs to establish a correspondence relationship with the corresponding property in the control. 12. In the optional property name combo box, enter a custom property name or directly select an inventory property name from the drop-down list. The classwizard wizard displays the dodataexchange () add the binding Code of controls, variables, and attributes to the function:

Void csample68proppage: dodataexchange (cdataexchange * PDX)
{
// {Afx_data_map (csample68proppage)
Ddp_text (PDX, idc_message, m_smessage, _ T ("message "));
Ddx_text (PDX, idc_message, m_smessage );
Ddp_text (PDX, idc_title, m_scaption, _ T ("caption "));
Ddx_text (PDX, idc_title, m_scaption );
Ddp_text (PDX, idc_xpos, m_nxpos, _ T ("xpos "));
Ddx_text (PDX, idc_xpos, m_nxpos );
Ddp_text (PDX, idc_ypos, m_nypos, _ T ("ypos "));
Ddx_text (PDX, idc_ypos, m_nypos );
//} Afx_data_map
Ddp_postprocessing (PDX );
}


Figure 12 binding of member variables, controls, and attributes

The visualization settings of custom properties are only implemented on the default properties page generated by the wizard. Although you can also use the same method to set inventory properties, you can use the inventory property page ID to directly use the inventory property page for maintenance. For example, for the inventory attributes backcolor and forecolor, you can set them through the inventory attribute page with the ID number clsid_ccolorproppage. You must modify begin_proppageids () when adding it to the attribute page ID table () macro property page count; otherwise, the system will crash:

Begin_proppageids (csample68ctrl, 2)
Proppageid (csample68proppage: guid)
Proppageid (clsid_ccolorproppage)
End_proppageids (csample68ctrl)

Continue to Test the Control in ActiveX Control Test Container, insert it, and select "Properties…" in the "Edit" menu... "Menu item, the attribute table shown in Figure 13 is displayed. This property table has three property pages, the first of which is the custom property page you just edited, and the second property page (14) this is the color property page specified by CLSID_CcolorPropPage (inventory property page). The last property page is the extended property page automatically added by the wizard. After setting the corresponding attribute in the Attribute Table, click "Apply" to allow the control to use the new attribute. This is the same as the function completed in the "Invoke Methods" dialog box, but it is much more convenient. In the design phase of the package container program, this attribute table is also used to complete the interaction between the control and the customer's attribute settings.


Figure 13 properties table of the control


Figure 14 color attribute page
  Use ActiveX controls in inclusion programs

For the ActiveX control package container program, you do not need to write a specific package container program framework like using the OLE Document Server or ActiveX Document Server Object, add the control directly to the project and create it in the dialog box to use it.

In the "Add To Project" menu under the "Project" menu, the "Components and Controls... The "sub-menu item opens a" Components and Controls Gallery "dialog box, enters the Registered ActiveX Controls directory, selects the ActiveX Control created earlier, and adds it to the project. The wizard adds a packaging class for this ActiveX control in the project, and adds an icon to the "Controls" toolbar to indicate this control. You can place it in the dialog box resources like using other standard controls and modify its default properties. In addition, you can dynamically change the property settings of the control by using the member functions of the control packaging class in the program. For example, the following code uses the packaging Class Object m_ctrlTest to dynamically set the XPos, YPos, and Message attributes of the control during the program running:

// Update the display
Updatedata ();
// Dynamically change the message attribute of the control
M_ctrltest.setmessage (m_sinput );
// Set the display Coordinate
M_ctrltest.setxpos (10 );
M_ctrltest.setypos (10 );


Figure 15 add an Event Response Function

In the resource view, right-click the ActiveX control placed on the dialog box and select "Events... "Menu item, the dialog box shown in 15 is displayed, and the events provided by the control are displayed in the list box on the left, double-click an event to add corresponding event processing functions and event ing tables to the package container program. You can also handle the event in response to the control:

Begin_eventsink_map (csample69dlg, cdialog)
// {Afx_eventsink_map (csample69dlg)
On_event (csample69dlg, idc_sample68ctrl1, 1/* msgout */, onmsgoutsample68ctrl1, vts_none)
//} Afx_eventsink_map
End_eventsink_map ()
......
Void csample69dlg: onmsgoutsample68ctrl1 ()
{
// Obtain the number of input characters
Int nnum = m_ctrltest.messagelen ();
// Echo information
M_sinput.format ("too many characters are entered. A total of % d characters are entered.", nnum );
// Display information
Updatedata (false );
}

From the process of using ActiveX controls, we can see that there is no big difference between ActiveX controls and standard controls, through the packaging class, the use of control attributes and methods in the customer program can be as simple as using the common MFC class. In addition, the Create () method is also provided in the control packaging class, so that the control can be dynamically created during the program running.

  Summary

Although ActiveX controls are technically integrated into many excellent technologies of COM and OLE, MFC provides powerful support for ActiveX controls, this makes the development of ActiveX controls very easy. However, to deeply understand ActiveX control technology, we also need to have a basic concept for some basic technologies. The purpose of this article is not to introduce how to compile an ActiveX control, by analyzing the control creation process, you can gain a new understanding of ActiveX control development. The code described in this article is compiled by Microsoft Visual C ++ 2000 under Windows 6.0 Professional.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

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.