Even if it is a conformityOLE standard controls 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 and usesHow to meet container-related requirements when creating controls in Visual C ++, especially when developing ActiveX controls for a wide range of use. For example, how to solve problems such as license, thread, content validation, and keyboard event response.
I. AboutActiveX Control
Before discussing the differences between containers (this difference makes it possible to develop for multiple containersActiveX control is complicated), it is necessary to review what is ActiveX Control and Its creation process.
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. Capacity
AndAll interactions between ActiveX controls are performed through standard OLE interfaces. Therefore, ActiveX controls follow the concept of "black box. In addition to its external interfaces, the control user does not need to know its internal working process. As long as development tools (containers) and programming languages understand and use standard
OLE interface, ActiveX control can be used in a variety of containers. Of course, this is just a theory. In practice, no two containers are the same, and developers must grasp the differences between them.
CreateActiveX control starts with selecting development tools. 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,You can use controls on the Internet or local Intranet to avoid using a license. 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 custom 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 application uses the buffered license key verification control. This is feasible in the desktop environment, but inThere 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 useMicrosoft is a tool named lpk_tool.exe, which is a part of 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. Class inherited by the control (COleControl) contains the member function AmbientUserMode, which returns TRUE when the control is in design mode.
However, not all containers respond to this query (includingIE browser ). 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? Call in the class factory (Class Object)The control writes data to the Registry during UpdateRegistry. When the control is thread-safe
AfxRegApartmentT