Create controls for multiple containers-License and signature

Source: Internet
Author: User
Even an ole-Compliant Control may occasionally behave differently in different ActiveX containers. Failure to adapt to the differences between containers will seriously affect the application of controls in some containers, and even make the controls completely unavailable in some containers.

This article discusses how to adapt to container-related requirements when using Visual C ++ to create controls, especially the policies that must be executed when developing ActiveX controls for a large scope of use. For example, how to solve problems such as license, thread, content validation, and keyboard event response.

1. ActiveX Controls

Before discussing the differences between containers (which complicate the development of ActiveX controls for multiple containers), it is necessary to review what ActiveX controls are and how they are created.

ActiveX controls can be viewed as COM objects that implement standard Ole interfaces. All controls must be ultimately positioned in a container, such as Visual Basic, Visual C ++, and IE browsers. Containers use standard Ole interfaces to negotiate with controls. For example, a container can create, customize, and store controls for future use. All interactions between containers and ActiveX controls are performed through standard Ole interfaces. Therefore, ActiveX controls follow the "black box" concept. In addition to its external interfaces, the control user does not need to know its internal working process. As long as the development tool (container) andProgramming LanguageUnderstand and use standard Ole interfaces to use ActiveX controls in multiple containers. Of course, this is just a theory. In practice, no two containers are the same, and developers must grasp the differences between them.

To create an ActiveX control, select a development tool. There are many tools available, from VB to Delphi to vj ++. This article discusses how to create a control based on VC ++. With VC ++, you can get faster execution speed and more control over the creation process, as well as support for platform sdks and APIs to the maximum extent. VC ++ provides the MFC ActiveX Control Wizard to simplify the creation of ActiveX controls. This wizard guides you through every step of creating the control shell. The first question raised by the Wizard is whether permission is required.

Ii. License controls

The control operation has two different environments: runtime and design time. A license control contains several interfaces used to design a time limit for certain accesses. Users without proper permission can only use the control in the runtime environment, rather than in the design environment. If you plan to use controls within the enterprise, the internet, or the Local intranet, the license is generally avoided. However, if you are selling commercial products or planning to limit the ability to access controls during design, you should take advantage of the benefits of the license.

If you select to license a control, the control wizard automatically adds the necessary interfaces and creates a customizable license file (LIC ). The remaining work that must be done is to modify the variables in the main document (such as myprojectctl. cpp. Please modify the license file to make it conform to the license key:

Static const tchar based_code

_ Szlicfilename [] = _ T ("control. Lic ");

Static const wchar based_code

_ Szlicstring [] = "my unique validation string ";

After the license file is available, development tools often buffer the license key of the control in the project. If the license file itself is no longer available, the applicationProgramUse the buffered license key verification control. This is feasible in the desktop environment, but there is no built-in mechanism in the Internet (and intranet) environment to securely buffer this license information through HTML.

There are two ways to solve this problem. First, you can use Microsoft's lpk_tool.exe tool, which is part of the Microsoft Internet client SDK. Lpk_tool.exe can convert license files into encrypted files referenced in HTML documents. Ie can extract license information from the LPK file when instantiating a control that requires a license:

The second method requires a custom control's license verification routine. For example, it can ask whether the container is in the design or running mode. The colecontrol class inherited by the Control contains the member function ambientusermode, which returns true when the control is in design mode.

However, not all containers respond to this query (including ie browsers ). In this case, ambientusermode always returns true; in other words, it always assumes that the control is in design mode. If the container responds to the query incorrectly, you can write a function to force the control to think that it is in running mode, so as to avoid this restriction:

Bool cctrl: optimisticambientusermode (){

Bool busermode;

If (! Getambientproperty (

Dispid_ambient_usermode,

Vt_bool, & busermode ))

Busermode = true;

// Run mode if the container does not answer

Return busermode ;}

Iii. Thread model and Resource Sharing

Microsoft's two thread models, single-thread and unit models, also complicate the use of controls in multiple containers. A single-threaded control executes all objects in a single thread. A unit-threaded control can execute an object in any thread at any time.

In some cases, you may need to render specific resources so that all instances of the control can access them. For example, if multiple instances of the control perform many database operations, you need to create a single, shared database connection for all instances, instead of creating a separate connection for each instance (in other cases, there is only one available resource, such as the device context or port ).

There is a major problem to be solved when sharing resources in the unit model thread environment. For example, two threads can try to use the same resource at the same time. This may cause data errors or other unexpected results. So how can containers know that the control is a unit model thread safe? When the class factory (Class Object) calls updateregistry, the control writes data to the Registry. When the control is thread-safe

Afxregapartmentthreading notification container:

Bool cctrl: c3ctrlfactory: updateregistry (

Bool bregister ){

If (bregister)

Return

Afxoleregistercontrolclass (

AfxGetInstanceHandle (),

M_clsid, m_lpszprogid,

Ids_myctl, idb_myctl,

Afxregapartmentthreading,

_ Dwmyctlolemisc, _ tlid,

_ Wvermajor, _ wverminor );

Else

Return

Afxoleunregisterclass (m_clsid,

M_lpszprogid );}

It seems that the problem can be solved by changing the value to 0 (marking the control's non-unit model Security. If you want to support the control in as many containers as possible, you must make the control support the unit model thread. This is because some development environment containers such as VJ ++ require controls to support unit model threads. In addition, the Unit model thread enables IE to use ActiveX controls more efficiently when creating new windows.

Using semaphores to avoid two threads accessing the critical zone at the same time can solve the problem caused by data sharing (or unique resources) between instances (and threads. Similarly, you can avoid restricted resources by creating a resource pool. For example, the control can select a connection from the database connection pool to obtain available connections when accessing the database without affecting other threads.

Iv. Support Content Inspection

Many customizable controls allow users to check their content. This test is generally executed when the user finishes editing a control and moves the focus. When the input focus is lost, Windows sends the wm_killfocus message to the control. Generally, the control should provide an opportunity for all programmers who use it to respond to this important event. Some development tools, such as VB, can automatically provide events when the control gets or loses focus. However, some containers cannot. Therefore, a more secure approach is to add custom events to ensure that programmers are always given the opportunity to respond to these events.

In VC ++, you can use classwizard to add custom events that execute the check when the focus is lost to the control. Press Ctrl + W to start classwizard, and then click the ActiveX events property page and add event button. Next, enter "ctlostfocus" as the external name, and the internal name is automatically set to firectlostfocus. Because this event does not require parameters, ignore the parameter table and click OK. The message maps attribute page is displayed. Select wm_killfocus from the available message list and click Add function. In this case, classwizard adds a message processing function to the control. Click the edit code button to go to the editing page:

Void cctrl: onkillfocus (cwnd *

Pnewwnd ){

Colecontrol: onkillfocus (_

Pnewwnd );

Firectlostfocus ();}

No matter what container, you can add the inspection function for the control through the above steps.

The same steps can be used to add the wm_setfocus message processing process and firectlgotfocus event.

5. Respond to keyboard and mouse events

Many controls require users to use the arrow keys to change the display, such as moving between texts as a blinking line of the insertion point, or moving within the container for better positioning accuracy. However, sometimes the container uses the same button, for example, ie uses the downward arrow to scroll the HTML document. In this case, the control does not respond to the arrow when getting the focus.

The pretranslatemessage function that overwrites the cwnd class can regain control of the arrow keys (and other keys) controlled by the container object. You only need to monitor the wm_keydown message and filter out the required events. Then, when you need to respond to a button, call onkeydown and return true.

If an ActiveX control is used in an MDI window while another window partially hides the MDI window, another problem may occur: clicking the ActiveX control does not move the MDI window to the very beginning (that is, activating ). This is because the MDI window does not know the user's mouse-Click Event on the ActiveX control, so it cannot respond and set itself as an activity window.

This problem can be solved if you can let the parent window (here refers to the MDI window) Know the click event on the ActiveX control. A simple method is to send the WM _ parentnotify message to the parent window to notify the mouse to click the event. The WM _ parentnotify message is sent when the control is created, destroyed, or when you press the mouse key on the control. By setting an appropriate extended style bit, you can ensure that the message is sent when you press the mouse key. First, override the precreatewindow virtual function of the control. The createstruct parameter passed to this function contains the dwexstyle Member, which can be used to check or modify the extended style bit used to create the control:

Bool cctrl: precreatewindow (createstruct & CS ){

CS. dwexstyle & =

~ Ws_ex_noparentnotify;

Return

Colecontrol: precreatewindow (CS );}

This modification causes the user to send the wm_parentnotify message during the default mouse processing of the widget when the mouse key is pressed. The parent window can use this opportunity to activate itself.

6. Use Constants

Another container-related problem involves constant processing. Ole controls often have properties with enumeration values. For example, a property called scrollbars uses the following enumeration values, which must be defined in the part Class Library:

Typedef Enum {

Sbnone = 0,

Sbutomatic = 1,

Sbalwayson = 2,} ctlscrollbarconstants;

However, not all containers can read these enumeration definitions for development environments (such as VBScript ). As a control developer, You can provide an additional file to define the values of these constants in different development environments, or provide additional methods to obtain these enumerated quantities. For the latter, you can add a method corresponding to the enumeration volume in the control.

For example, you can add three methods: sbnone, sbutomatic, and sbalwayson. Their return values correspond to the enumerated quantity respectively:

Short cctrl: sbnone (){

Return 0 ;}

Short cctrl: sbutomatic (){

Return 1 ;}

Short cctrl: sbalwayson (){

Return 2 ;}

On this basis, you can use these methods to set the attributes of scrollbars in any development environment (container:

CTL. scrollbars = CTL. sbutomatic

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.