Development of ActiveX controls based on MFC

Source: Internet
Author: User

ActiveX controls are reusable software components based on the Component Object Model (COM) and are widely used in desktop and Web applications. ActiveX control development under VC can be divided into three types, one is to directly use the com api for development, this is obviously very troublesomeProgramPersonnel requirements are also very high, so it is generally not considered; one is based on the traditional MFC, the basic functions of COM are encapsulated in several C ++ classes of MFC in an object-oriented way. developers can inherit these classes to obtain the functions supported by COM. MFC is familiar to the majority of VC programmers and is easy to learn. However, the disadvantage is that there are many things encapsulated by MFC, so the control developed by MFC is relatively large, therefore, it is suitable for developing desktop activexx controls, especially those with GUI interfaces. The third is based on ATL. ATL can be said to be a framework specially developed for com. It uses the C ++ template technology, you do not need to rely on a largeCodeModules are more suitable for Web application development.

This article introduces the second method, that is, the process of developing desktop visual controls using MFC, And the development environment is based on vc2005.

1.Create a Control Project

After opening vc2005, we need to create a project, select visual c ++-MFC on the left side of the new project page, select the MFC ActiveX Control on the right side, and fill in the solution and project name, for example, here, my project name is activexdemo1 and the solution name is activexdemo.

Then go to the control Wizard Page, and there is a runtime license on the second page of the Wizard. If this is selected, a license file will be generated when the control is generated, when using this control, other users must also attach this license. Here we keep the default status and do not select this license.

The next page is about the naming of each part of the project. You can customize it as needed. Here, we will not modify it by default.

On the next page, you can select the extension of the control based on and some basic features of the control. If the newly created control is based on a specific control, select the control name to be inherited from the created control. Otherwise, keep none. The additional functions in the lower part are selected based on actual needs, and you can place the cursor over the options. The function description is automatically displayed in the dynamic Prompt window. Click "finish". The Wizard will generate a new project based on your selection.

Go to the development environment. Let's take a look at the class view first.

The cactivexdemo1app is the main program module of the control. It defines functions such as the registration of the control (dllregisterserver) and deletion (dllunregisterserver, if necessary, we can define our own initialization and termination operation code in initinstance and exitinstance, which is generally the initialization and destruction of some resources.

Caxtivexdemo1ctrl is the control class. The control function we want to implement is basically implemented in this class.

It should be mentioned that the ondraw function of the parent class is rewritten in this class, and there are two codes:

PDC-> fillrect (rcbounds, cbrush: fromhandle (hbrush) getstockobject (white_brush )));

PDC-> ellipse (rcbounds );

That is, an elliptic is drawn on the control. In actual control development, you can modify and rewrite this function to draw the control interface.

Caxtivexdemo1proppage is a property page class that provides a dialog box for setting control properties during development.

Activexdemo1lib is a library node that provides the properties, methods, and interfaces of the control and events that may respond to the customer program. It is used when adding these functions of the control.

The cactivexdemo1app is the main program module of the control. It defines functions such as the registration of the control (dllregisterserver) and deletion (dllunregisterserver, if necessary, we can define our own initialization and termination operation code in initinstance and exitinstance, which is generally the initialization and destruction of some resources.

Caxtivexdemo1ctrl is the control class. The control function we want to implement is basically implemented in this class.

It should be mentioned that the ondraw function of the parent class is rewritten in this class, and there are two codes:

PDC-> fillrect (rcbounds, cbrush: fromhandle (hbrush) getstockobject (white_brush )));

PDC-> ellipse (rcbounds );

That is, an elliptic is drawn on the control. In actual control development, you can modify and rewrite this function to draw the control interface.

Caxtivexdemo1proppage is a property page class that provides a dialog box for setting control properties during development.

Activexdemo1lib is a library node that provides the properties, methods, and interfaces of the control and events that may respond to the customer program. It is used when adding these functions of the control.

Set project properties to set the configuration type to static library (. Lib)

2.Generate and test controls

Well, now we can generate this project first. Of course, at present, we only use a Control Project automatically generated by the system. There is no function, but it is just an empty framework.

After a few seconds, the project should be generated smoothly. The widget is automatically registered to the system. How can we test this control? Of course, you can create another project, such as a dialog box program. Right-click the Toolbox on the right of the dialog box and select an item from the menu.

Find the control we just generated from the COM component in the pop-up window and check it.

The control is displayed in the toolbox.

Drag the mouse to the dialog box to use this control.

In addition to this method, vs also provides a simple control testing tool. The tool in the Visual Studio menu has an ActiveX control test container.

Click the new control button in the toolbar.

In the insert control dialog box, find and select our control.

Then you can test the various functions of the control in this container.

3.Event

ActiveX controls use events to notify the container controls of certain events. Common examples of events include clicking controls, entering data on the keyboard, and changing the control status. When these operations occur, the control raises an event to remind the container.

MFC supports two types of events: common events and custom events. Common events are automatically handled by the colecontrol class. Custom events allow the control to notify the container when a specific operation of the control occurs. The internal status of the control is changed or a window message is received.

Common events

Common events are automatically triggered by the colecontrol class. Colecontrol contains predefined member functions that cause events caused by common operations. Some common operations implemented by colecontrol include clicking and double-clicking controls, Keyboard Events, and mouse button status changes.

To add common events, right-click the ActiveX control class in the Class View. For example, caxtivexdemo1ctrl is used in this example. Select Add event from the menu to open the Add event wizard.

In the Add event wizard, select click in the event name, that is, click the event, and add it to the control. Then select the third node under the database node in the Class View, that is, dactivexdemo1events. We can see the event we just added below.

Then generate a new control program. Let's take a look and test this new event.

Open the ActiveX control test container mentioned above, add the control, and click the control. The message bar below the program displays activexdemo1 control: click, this is the mouse event we added.

What does the control look like when it is used in the development environment? As mentioned above, create a dialog box project and place the control on the dialog box. Select this control. This click event exists in the control event in the Property Window. If you need to click the event in the control, click clickactivexdemo1ctrl1, add the required functions to the Event Response Function.

For example:

Void ctestmfcdlg: clickactivexdemo1ctrl1 ()

{

// Todo: add the message processing program code here

MessageBox (_ T ("Hi ."));

}

Compile and run the test program. Click the control position to bring up the MessageBox with the hi. character.

Custom events

The difference between custom events and common events is that custom events cannot be automatically triggered by the colecontrol class. A Custom Event identifies an operation determined by the Control developer as an event.

To add common events, right-click the ActiveX control class in the Class View. For example, caxtivexdemo1ctrl is used in this example. Select Add event from the menu to open the Add event wizard. Defines an event called myevent. An event can contain parameters. For example, we add a BSTR parameter MSG.

Return to the class view. The third node under the selected database node, namely _ dactivexdemo1events, is displayed below.

Select the control class in the Class View, that is, cactivexdemo1ctrl. A myevent function will also appear below.

Double-click this myevent to see the definition Code as follows:

Void myevent (bstr msg)

{

Fireevent (eventidmyevent, event_param (vts_pi1), MSG );

}

Here, this myevent (bstr msg) function is used to trigger the myevent event. What does it mean, that is to say, you can call this myevent (bstr msg) when you need to set a custom myevent in the control. The following is a combination of examples to see what is going on.

For example, we want the user to trigger this event when double-clicking the left button. Select the control class in the Class View, that is, cactivexdemo1ctrl, and find wm_lbuttondbclk in the message window to add the message processing function.

Modify the following in the message processing function:

Void cactivexdemo1ctrl: onlbuttondblclk (uint nflags, cpoint point)

{

// Todo: add the message processing program code and/or call the default value here

Myevent (_ T ("Hi, myevent ."));

Colecontrol: onlbuttondblclk (nflags, point );

}

In this way, every time you double-click the control, the custom myevent event will be triggered.

Then let's take a look at the test results.

Open the ActiveX control test container, add the control, and double-click the control to see what appears in the message box?

Because double-click is a two-click event, two events are displayed at the same time.

Activexdemo1 control: myevent {MSG = 72}

Activexdemo1 control: Click

Open the test project and a myevent event is added to the control event of the control.

Add a processing function myeventactivexdemo1ctrl1 (lpctstr MSG) for this event. MSG is the msg parameter when we define the event. In the preceding definition, we pass "Hi, myevent. "string message. Now let's see if it looks like this. In the myeventactivexdemo1ctrl1 function, a MessageBox is displayed, and the msg parameter is printed out.

Void ctestmfcdlg: myeventactivexdemo1ctrl1 (lpctstr MSG)

{

// Todo: add the message processing program code here

MessageBox (MSG );

}

Note that you need to comment out the clickactivexdemo1ctrl1 processing function of the Click Event defined in the preceding common events. After compiling and running the program, double-click the control to bring up the HI, myevent. dialog box. That is to say, because the double-click operation triggers the myevent event we define, and then calls the myevent processing function.

4.Method

The method is some function functions that the control opens to users, similar to C ++ class functions. There are two types of control methods. One is a common method, which is provided by the parent colecontrol. Custom methods are defined by developers to provide users with custom functions.

Common Methods

Colecontrol supports two common methods: doclick and refresh. Refresh is called by the control user to immediately update the control's appearance. The call of doclick is used to trigger the control's click event.

To add common methods, open the library node in the class view. In this example, the activexdemo1lib node is used. Select the second node, that is, _ dactivexdemo1 in this example. Right-click the node and select Add method to open the add method wizard.

Select the common method to be added in the method name. For example, doclick.

Select _ dactivexdemo1 in the Class View and you will see the common method we just added below. At the same time, you can also see an aboutbox method here, which is automatically added to us by the system. The function is to display an about window, this window can be found and edited under dialog in the project resource view.

Verify the newly added method. Open the ActiveX control test container, add the control, and click the red box on the toolbar, that is, the call method.

Select the added doclick method from the method name in the call method pair window, and then click call. Do you still remember what doclick is doing ?, By the way, it will trigger the click event. We have added the click event as a common event, now, calling doclick is to trigger the click event we added above, so activexdemo1 control: click is displayed in the message box of the Main Window of the test container.

So what is the effect in the development environment?

Well, go back to the test project. We first add a button to the form, called doclick. We will call the doclick method by clicking it.

To facilitate the operation, we first add a bound object variable to the control just added to the dialog box. Right-click the control and select Add variable.

Add the control variable bound to this control in the Add member variable wizard, for example, m_activexdemo.

Then, double-click the button added to the form, that is, add the button and click the event function, add a line of code as follows, that is, call the doclick method of the control.

Void ctew.fcdlg: onbnclickedbutton1 ()

{

// Todo: add the control notification handler code here

M_activexdemo.doclick ();

}

Finally, compile and run the test program and click the doclick button. The hi. dialog box is displayed. This means that the mouse click event of the control is triggered by executing the doclick method of the control object. Therefore, the event processing function clickactivexdemo1ctrl1 added in the common Events section is executed.

Custom Method

The difference between a custom method and a common method is that a custom method is not implemented by colecontrol. It must be implemented for each custom method added to the control.

To add a custom method, open the library node in the class view. In this example, the activexdemo1lib node is used. Select the second node, that is, _ dactivexdemo1 in this example. Right-click the node and select Add method to open the add method wizard.

Add the name, return value, and parameters of the method to be customized in the add method wizard.

Note that there is an internal name. By default, it is the same as the method name above, but you can also change it to another name. This internal name is the function name of the method in the control class, for example, if our method is named mythod, select the second node under the library interface in the class view. The mymethod method just defined will appear below.

The cactivexdemo1ctrl control class is selected. The method name defined in this class is the internal name mymethodinner specified above.

The specific function of the method is implemented in this internal function. For example, we define mymethodinner as follows:

Void cactivexdemo1ctrl: mymethodinner (lpctstr MSG)

{

Afx_manage_state (afxgetstaticmodulestate ());

// Todo: add the scheduling handler code here

MessageBox (MSG );

}

In other words, a message dialog box is displayed, and the message content is the string passed in the parameter.

Then let's test the effect. First, test the ActiveX control container and open the call method window. In the method name, we can see that we have set a mymethod, sorry, we will see the defined msg parameter in the parameter area, select it, and enter the value you want to pass to the parameter in the following parameter values, such as hello, and then click set value, click "call". The mymethodinner is executed, that is, the Hello message window is displayed.

Then let's take a look at the effects when using controls for development.

Back to the test project, remember the doclick button. I still use this button, but it is a little bit of a problem, because we didn't have this custom method when binding control variables for this control, therefore, if this method is not found in the control class definition generated during binding, the test will fail. To save trouble, we can simply create a project, add controls, bind control variables as mentioned above, and write the following code in the doclick click event:

Void ct1dlg: onbnclickedbutton1 ()

{

// Todo: add the control notification handler code here

M_activexdemo.mymethod (_ T ("This is mymethod ."));

}

Compile and execute the command. Click the doclick button and you will see the this is mymethod message box.

5.Attribute

Property is a data member exposed to all containers in the ActiveX control. Similar to events and methods, it can also be divided into common attributes and custom attributes.

Common attributes

Common attributes are implemented by the colecontrol class. The colecontrol class contains predefined member functions that support General Properties of controls. Some common attributes include the title of the control, the foreground color, and the background color.

To add common attributes, open the library node in the class view. In this example, the activexdemo1lib node is used. Select the second node, that is, _ dactivexdemo1 in this example. Right-click the node and select Add attribute to open the Add attribute wizard. Select the Common Implementation type and select the attribute to be added under the attribute name. For example, here we select caption.

Then, you can see the newly added attribute in the Class View.

This caption is the caption attribute in the control property window when we use the control for development.

In the development environment, we can use getcaption and setcaption of the control variable to obtain and set this property of the control.

For example, the following changes are made to the Click Event function of the doclick button in the test project:

Void ct1dlg: onbnclickedbutton1 ()

{

// Todo: add the control notification handler code here

MessageBox (m_activexdemo.getcaption ());

M_activexdemo.setcaption (_ T ("change "));

MessageBox (m_activexdemo.getcaption ());

}

In this way, the control's caption name dialog box is displayed when you click the doclick button. Then, modify the name and display the modified name in the pop-up dialog box.

In the ActiveX control test container, open the call method window. In the method name, we can see the caption (proput) and caption (proget) methods, that is, it corresponds to the above setcaption and getcaption. Here, you can also try to modify the content of the caption and obtain the modified value.

Custom Attributes

The difference between Custom Attributes and common attributes is that custom attributes are not implemented by the colecontrol class. Custom properties are used to publish a state or appearance of an ActiveX control to a programmer who uses the control.

To add a custom attribute, open the library node in the class view. In this example, the activexdemo1lib node is used. Select the second node, that is, _ dactivexdemo1 in this example. Right-click the node and select Add attribute to open the Add attribute wizard. The custom attributes include the member variables and the get/set method.

Member variable attributes

Let's take a look at the attributes of member variables. Select the attribute type as needed and enter the attribute name. The variable name and notification function are automatically filled in. If you are not satisfied with the default name, you can manually modify the two names.

The variable name is used as a member variable of the control class to store the control attributes. For example, the control class in the selected class view, that is, cactivexdemo1ctrl, the m_myprop1 member variable is shown below.

The use of such custom attributes is similar to that of common attributes. In the ActiveX control test container, methods such as myprop1 (proput) and myprop1 (proget) are available for calling during testing, during development, attributes will also appear in the Properties window of the control. In the program, you can also get and set the attribute values through getmyprop1 and setmyprop1.

The notification function is a function triggered when this attribute is modified. Is defined as a member function in the control class.

For example, if we write the following code in this function:

Void cactivexdemo1ctrl: onmyprop1changed (void)

{

Afx_manage_state (afxgetstaticmodulestate ());

// Todo: add the property handler code here

MessageBox (_ T ("myprop1 changed ."));

Setmodifiedflag ();

}

Then, in the ActiveX control test container, call myprop1 (propput) to modify the property value. This dialog box is displayed. Similarly, if you modify the property value in the property window during development or modify the property value in the code, this notification function will be triggered, and a dialog box in our code will pop up.

GET/SetMethod attributes

To add a GET/Set Method property, select the get/Set Method in the Implementation type in the Add properties wizard window and specify the property type and name. The wizard automatically fills in the get and set functions, you can also specify custom parameters.

Then, the getmyprop2 (void) and setmyprop2 (lpctstr newval) functions are displayed in the definition of the control class, which are used to obtain and set the attribute values respectively. However, if you look at the code of these two functions, these two automatically generated functions do not actually implement the function of obtaining and setting attribute values. These are only two frameworks, basically, nothing is done. If you call these two functions in the ActiveX control test container, there will be no response, so we need to manually define the specific functions of the function.

For example, we can add a member variable to the control class to store our property values. Since this property defines the BSTR type, we can declare the added member variable as cstring m_myprop2, modify getmyprop2 (void) and setmyprop2 (lpctstr newval) as follows:

BSTR cactivexdemo1ctrl: getmyprop2 (void)

{

Afx_manage_state (afxgetstaticmodulestate ());

Cstring strresult (m_myprop2 );

// Todo: add the scheduling handler code here

Return strresult. allocsysstring ();

}

Void cactivexdemo1ctrl: setmyprop2 (lpctstr newval)

{

Afx_manage_state (afxgetstaticmodulestate ());

// Todo: add the property handler code here

M_myprop2 = newval;

Setmodifiedflag ();

}

In the ActiveX control test container, call setmyprop2 to assign values to the attribute, and then use getmyprop2 to return the newly assigned attribute value.

In addition, when defining this attribute, the parameter list is left blank. The default result is the above setmyprop2 and getmyprop2 functions, if other parameters are added to the parameter list, the newly added parameters are added to the parameter list of the two functions. For example, if we add a BSTR property myprop3 and add a long Arg parameter to the parameter list, the two functions will be getmyprop3 (long Arg) and setmyprop3 (long Arg, BSTR newval ).

6.Property page

The properties page allows ActiveX Control users to view and modify ActiveX control properties. You can access these properties by calling the Control Properties dialog box. This dialog box contains one or more property pages. These property pages provide a custom graphical interface for viewing and editing control properties.

Use default property page

After the ActiveX control project is created, the system automatically adds an attribute page class for us, which is cactivexdemo1proppage. At the same time, there will be a property page dialog box resource in the dialog box resource, which is idd_proppage_activexdemo1.

Click the property button on the toolbar in the ActiveX control test container. The property page dialog box is displayed.

For example. Of course there is nothing above.

If you are using the control for development, you can click the property page button in the Properties window after selecting the control to open this property page, developers can set the properties of the control in the pop-up properties page.

To modify the property of a control on the property page, you must place some controls on the property page to modify the property value. For example, if we have added a caption attribute, we need to provide the function of modifying this attribute on the attribute page. Generally, we need to use a text input box. In this way, we place an edit control in the dialog box on the property page and set the ID to idc_edit_caption. Then, bind a variable to the Edit Control. Right-click the Edit Control, add the variable, and open

Add a new variable in the Add member variable wizard and set it to m_caption. Set the type to value here. Because the attribute is a string, the variable type also uses cstring.

Then let's take a look at a dodataexchange function in the property page class. This function is automatically called by the system to exchange data between controls and member variables. Since we just bound the Edit Control to the m_caption variable, we have written such a ddx_text (PDX, idc_edit_caption, m_caption) in dodataexchange );, this statement implements data exchange between the m_caption and edit controls. However, the Control Caption attribute cannot be automatically obtained from the value entered in the edit control. An operation is required, namely, ddp_text (PDX, idc_edit_caption, m_caption, _ T ("caption");, so that the caption property is bound to the m_caption variable on the property page. Every time we modify the edit control content in the property page, you can modify the control caption.

Then the complete dodataexchange function should be like the following.

Void cactivexdemo1proppage: dodataexchange (cdataexchange * PDX)

{

Ddx_text (PDX, idc_edit_caption, m_caption );

Ddp_text (PDX, idc_edit_caption, m_caption, _ T ("caption "));

Ddp_postprocessing (PDX );

}

In addition, note that ddp_postprocessing is the code automatically generated by the system. This sentence must be placed behind ddx_text and ddp_text. Otherwise, you cannot bind the control property to the control on the property page. So far, we can modify the caption attribute on this property page at design time without modifying it through program code.

Add other custom property pages

By default, there is only one property page. If you need to set too many properties, you need to add a custom property page.

The method for adding a property page is as follows: Open the resource view of Vs and add a new dialog resource.

Here we select idd_ole_proppage_small. Of course we can also select large. Specify idd_ole_proppage_small for this new resource ID.

Then you need to create an association class for this resource. This association class should be the MFC class, set the class name to cproppage1, and the base class to the colepropertypage. Select the resource ID of the newly added dialog box.

Open the CPP file of the control class cactivexdemo1ctrl and find the macro description section of the property page.

Begin_proppageids (cactivexdemo1ctrl, 1)

Proppageid (cactivexdemo1proppage: guid)

End_proppageids (cactivexdemo1ctrl)

Add the new property page and add one to the property page count.

// Todo: add more property pages as needed. Please remember to increase the Count!

Begin_proppageids (cactivexdemo1ctrl, 2)

Proppageid (cactivexdemo1proppage: guid)

Proppageid (cproppage1: guid)

End_proppageids (cactivexdemo1ctrl)

In this way, the newly added property page is appended to the control. Then, you can open the property page of the control to see an additional property page.

Common property page

In addition to customizing property pages as needed, the system also provides developers with premade common property pages, such as color and font. MFC provides three common property pages used with ActiveX Controls: clsid_ccolorproppage, clsid_cfontproppage, and clsid_cpictureproppage. These pages display user interfaces with common colors, fonts, and image attributes.

To merge these property pages into the control, you only need to add their IDs to the code of the attribute page ID array of the initialization control. That is, modify the proppageids declaration in the CPP file of the class control cactivexdemo1ctrl to the following form. As in the custom property page, you also need to increase the property page count.

// Todo: add more property pages as needed. Please remember to increase the Count!

Begin_proppageids (cactivexdemo1ctrl, 3)

Proppageid (cactivexdemo1proppage: guid)

Proppageid (cproppage1: guid)

Proppageid (clsid_ccolorproppage)

End_proppageids (cactivexdemo1ctrl)

In this way, a color property page is added to the property page. However, to use this property page, you need to add several common attributes. For example, you want to use this property page to set the backcolor and forecolor attributes, add a backcolor and a forecolor attribute by referring to the methods in the common attributes section. compile and generate the control and click Properties in the toolbar in the ActiveX control test container.

In the pop-up attribute window, you can see the settings of these two attributes.

To use the color attribute, call the colecontrol: translatecolor member function. The parameter of this function is the color attribute value and the optional color palette handle. The returned value is a colorref value, which can be passed to the GDI function, such as settextcolor and createsolidbrush. The following example shows how to use these two color attributes when creating a widget.

Cbrush bkbrush (translatecolor (getbackcolor ()));

Colorref clrfore = translatecolor (getforecolor ());

PDC-> fillrect (rcbounds, & bkbrush );

PDC-> settextcolor (clrfore );

PDC-> drawtext (internalgettext (),-1, rcbounds, dt_singleline | dt_center | dt_vcenter );

Related Article

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.