Using VS2010 Develop ActiveX Control in MFC Project
2012-11-18 16:55
447 查看
1.Create MFC Project
Step1:Open VS 2010 and create a MFC ActiveX Control project named “GetSystemTime”. Then click OK.
![](http://img.my.csdn.net/uploads/201211/18/1353225082_3703.png)
Step2:In Control Settings tab keep the following item checked. Then click Finish.
![](http://img.my.csdn.net/uploads/201211/18/1353225350_2620.png)
The VS2010 will create the necessary framework files for you.
![](http://img.my.csdn.net/uploads/201211/18/1353225763_5238.png)
Step3:Configure project properties. Open property pages and switch to "General" tab, then set "Use of MFC item" to "Use MFC in a Static Library" and click OK.
![](http://img.my.csdn.net/uploads/201211/18/1353226433_5073.png)
2.Add method and implement the control
Step1:Switch to “Class View”. Expand "GetSystemTimeLib" and find "_DGetSystemTime". Right click it to select Add->Add Method.
![](http://img.my.csdn.net/uploads/201211/18/1353227574_3726.png)
Step2: In the Add Method Wizard select Return type "BSTR" and type Method name "GetLocalTime" then click Finish.
![](http://img.my.csdn.net/uploads/201211/18/1353227824_3852.png)
Step3:Switch to “Solution View”. Find “GetSystemTimeCtrl.cpp” file and open it.
![](http://img.my.csdn.net/uploads/201211/18/1353228300_1954.png)
Step4:In the code view, you will find that the VS2010 has added a method named "GetLocalTime" for us.
![](http://img.my.csdn.net/uploads/201211/18/1353228495_2534.png)
Step5:Implement the code and build the project. You will find a "GetSystemTime.ocx" file in the debug folder.
![](http://img.my.csdn.net/uploads/201211/18/1353229179_9942.png)
2.Implement the safety interface
Microsoft support link:How to mark MFC ActiveX controls as Safe for Scripting and Initialization
SUMMARY:
By default, MFC ActiveX controls are not marked as Safe for Scripting and Safe for Initialization. This becomes apparent when the control is run in
the Internet Explorer with the security level set to medium or high. In either of these modes, warnings may be displayed that the control's data is not safe or that the control may not be safe for scripts to use.
There are two methods that a control can use to eliminate these errors. The first involves the control implementing the IObjectSafety interface and is
useful for controls that would like to change their behavior and become "safe" if run in the context of an Internet Browser. The second involves modifying the control's DllRegisterServer function to mark the control "safe" in the registry. This article covers
the second of these methods. The first method, implementing the IObjectSafety interface, is covered in the Internet Client SDK.
Please keep in mind that a control should only be marked as safe if it is, in fact, safe. Please refer to the Internet Client SDK documentation for a description
of this. See "Safe Initialization and Scripting for ActiveX Controls" under the Component Development Section.
Note This article does not cover how to
mark a control safe for downloading. For more information on code download and code signing, please refer to the Internet Client SDK.
MORE INFORMATION:
Follow these steps to mark your MFC ActiveX Control as Safe for Scripting and Safe for Initializing:
Implement the CreateComponentCategory and RegisterCLSIDInCategory helper functions by adding the following cathelp.h and cathelp.cpp files to your project.
Modify the DllRegisterServer to mark the control as safe. Locate the implementation of DllRegisterServer in a .cpp file in your project. You will need to add several things to this .cpp file. Include the
file that implements CreateComponentCategory and RegisterCLSIDInCategory:
Define the GUID associated with the safety component categories:
Define the GUID associated with your control. For simplicity, you can borrow the GUID from theIMPLEMENT_OLECREATE_EX macro in the main .cpp file for the control. Adjust the format slightly so that it looks like the following:
To mark your control as both Safe for Scripting and Initialization, modify the DllRegisterServer function as follows:
You would not normally modify the DllUnregisterServer function for these two reasons:
You would not want to remove a component category because other controls may be using it.
Although there is an UnRegisterCLSIDInCategory function defined, by default DllUnregisterServer removes the control's entry from the registry entirely. Therefore, removing the category from the control's
registration is of little use.
After compiling and registering your control, you should find the following entries in the registry:
Step1:Open VS 2010 and create a MFC ActiveX Control project named “GetSystemTime”. Then click OK.
![](http://img.my.csdn.net/uploads/201211/18/1353225082_3703.png)
Step2:In Control Settings tab keep the following item checked. Then click Finish.
![](http://img.my.csdn.net/uploads/201211/18/1353225350_2620.png)
The VS2010 will create the necessary framework files for you.
![](http://img.my.csdn.net/uploads/201211/18/1353225763_5238.png)
Step3:Configure project properties. Open property pages and switch to "General" tab, then set "Use of MFC item" to "Use MFC in a Static Library" and click OK.
![](http://img.my.csdn.net/uploads/201211/18/1353226433_5073.png)
2.Add method and implement the control
Step1:Switch to “Class View”. Expand "GetSystemTimeLib" and find "_DGetSystemTime". Right click it to select Add->Add Method.
![](http://img.my.csdn.net/uploads/201211/18/1353227574_3726.png)
Step2: In the Add Method Wizard select Return type "BSTR" and type Method name "GetLocalTime" then click Finish.
![](http://img.my.csdn.net/uploads/201211/18/1353227824_3852.png)
Step3:Switch to “Solution View”. Find “GetSystemTimeCtrl.cpp” file and open it.
![](http://img.my.csdn.net/uploads/201211/18/1353228300_1954.png)
Step4:In the code view, you will find that the VS2010 has added a method named "GetLocalTime" for us.
![](http://img.my.csdn.net/uploads/201211/18/1353228495_2534.png)
Step5:Implement the code and build the project. You will find a "GetSystemTime.ocx" file in the debug folder.
BSTR CGetSystemTimeCtrl::GetLocalTime(void) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); CString strResult; // TODO: Add your dispatch handler code here time_t t; t=time(NULL); //get system time strResult = ctime(&t); return strResult.AllocSysString(); }
![](http://img.my.csdn.net/uploads/201211/18/1353229179_9942.png)
2.Implement the safety interface
Microsoft support link:How to mark MFC ActiveX controls as Safe for Scripting and Initialization
SUMMARY:
By default, MFC ActiveX controls are not marked as Safe for Scripting and Safe for Initialization. This becomes apparent when the control is run in
the Internet Explorer with the security level set to medium or high. In either of these modes, warnings may be displayed that the control's data is not safe or that the control may not be safe for scripts to use.
There are two methods that a control can use to eliminate these errors. The first involves the control implementing the IObjectSafety interface and is
useful for controls that would like to change their behavior and become "safe" if run in the context of an Internet Browser. The second involves modifying the control's DllRegisterServer function to mark the control "safe" in the registry. This article covers
the second of these methods. The first method, implementing the IObjectSafety interface, is covered in the Internet Client SDK.
Please keep in mind that a control should only be marked as safe if it is, in fact, safe. Please refer to the Internet Client SDK documentation for a description
of this. See "Safe Initialization and Scripting for ActiveX Controls" under the Component Development Section.
Note This article does not cover how to
mark a control safe for downloading. For more information on code download and code signing, please refer to the Internet Client SDK.
MORE INFORMATION:
Follow these steps to mark your MFC ActiveX Control as Safe for Scripting and Safe for Initializing:
Implement the CreateComponentCategory and RegisterCLSIDInCategory helper functions by adding the following cathelp.h and cathelp.cpp files to your project.
Cathelp.h
#include "comcat.h" // Helper function to create a component category and associated // description HRESULT CreateComponentCategory(CATID catid, WCHAR* catDescription); // Helper function to register a CLSID as belonging to a component // category HRESULT RegisterCLSIDInCategory(REFCLSID clsid, CATID catid);
Cathelp.cpp
#include "comcat.h" // Helper function to create a component category and associated // description HRESULT CreateComponentCategory(CATID catid, WCHAR* catDescription) { ICatRegister* pcr = NULL ; HRESULT hr = S_OK ; hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr, NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (void**)&pcr); if (FAILED(hr)) return hr; // Make sure the HKCR\Component Categories\{..catid...} // key is registered CATEGORYINFO catinfo; catinfo.catid = catid; catinfo.lcid = 0x0409 ; // english // Make sure the provided description is not too long. // Only copy the first 127 characters if it is int len = wcslen(catDescription); if (len>127) len = 127; wcsncpy(catinfo.szDescription, catDescription, len); // Make sure the description is null terminated catinfo.szDescription[len] = '\0'; hr = pcr->RegisterCategories(1, &catinfo); pcr->Release(); return hr; } // Helper function to register a CLSID as belonging to a component // category HRESULT RegisterCLSIDInCategory(REFCLSID clsid, CATID catid) { // Register your component categories information. ICatRegister* pcr = NULL ; HRESULT hr = S_OK ; hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr, NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (void**)&pcr); if (SUCCEEDED(hr)) { // Register this category as being "implemented" by // the class. CATID rgcatid[1] ; rgcatid[0] = catid; hr = pcr->RegisterClassImplCategories(clsid, 1, rgcatid); } if (pcr != NULL) pcr->Release(); return hr; }
Modify the DllRegisterServer to mark the control as safe. Locate the implementation of DllRegisterServer in a .cpp file in your project. You will need to add several things to this .cpp file. Include the
file that implements CreateComponentCategory and RegisterCLSIDInCategory:
#include "CatHelp.h"
Define the GUID associated with the safety component categories:
const CATID CATID_SafeForScripting = {0x7dd95801,0x9882,0x11cf,{0x9f,0xa9,0x00,0xaa,0x00,0x6c,0x42,0xc4}}; const CATID CATID_SafeForInitializing = {0x7dd95802,0x9882,0x11cf,{0x9f,0xa9,0x00,0xaa,0x00,0x6c,0x42,0xc4}};
Define the GUID associated with your control. For simplicity, you can borrow the GUID from theIMPLEMENT_OLECREATE_EX macro in the main .cpp file for the control. Adjust the format slightly so that it looks like the following:
const GUID CDECL BASED_CODE _ctlid = { 0x43bd9e45, 0x328f, 0x11d0, { 0xa6, 0xb9, 0x0, 0xaa, 0x0, 0xa7, 0xf, 0xc2 } };
To mark your control as both Safe for Scripting and Initialization, modify the DllRegisterServer function as follows:
STDAPI DllRegisterServer(void) { AFX_MANAGE_STATE(_afxModuleAddrThis); if (!AfxOleRegisterTypeLib(AfxGetInstanceHandle(), _tlid)) return ResultFromScode(SELFREG_E_TYPELIB); if (!COleObjectFactoryEx::UpdateRegistryAll(TRUE)) return ResultFromScode(SELFREG_E_CLASS); if (FAILED( CreateComponentCategory( CATID_SafeForScripting, L"Controls that are safely scriptable") )) return ResultFromScode(SELFREG_E_CLASS); if (FAILED( CreateComponentCategory( CATID_SafeForInitializing, L"Controls safely initializable from persistent data") )) return ResultFromScode(SELFREG_E_CLASS); if (FAILED( RegisterCLSIDInCategory( _ctlid, CATID_SafeForScripting) )) return ResultFromScode(SELFREG_E_CLASS); if (FAILED( RegisterCLSIDInCategory( _ctlid, CATID_SafeForInitializing) )) return ResultFromScode(SELFREG_E_CLASS); return NOERROR; }
You would not normally modify the DllUnregisterServer function for these two reasons:
You would not want to remove a component category because other controls may be using it.
Although there is an UnRegisterCLSIDInCategory function defined, by default DllUnregisterServer removes the control's entry from the registry entirely. Therefore, removing the category from the control's
registration is of little use.
After compiling and registering your control, you should find the following entries in the registry:
HKEY_CLASSES_ROOT\Component Categories\{7DD95801-9882-11CF-9FA9-00AA006C42C4} HKEY_CLASSES_ROOT\Component Categories\{7DD95802-9882-11CF-9FA9-00AA006C42C4} HKEY_CLASSES_ROOT\CLSID\{"your controls GUID"}\Implemented Categories\{7DD95801-9882-11CF-9FA9-00AA006C42C4} HKEY_CLASSES_ROOT\CLSID\{"your controls GUID"}\Implemented Categories\{7DD95802-9882-11CF-9FA9-00AA006C42C4}
相关文章推荐
- Using VS2010 Develop ActiveX Control in MFC Project
- Develop and Deploy ActiveX Control in C#
- Subversion Version Control: Using The Subversion Version Control System in Development Projects
- How to start a second thread in an MFC-based ActiveX control to fire events in Visual C++
- Using GDI+ in a Single Document MFC Project to Rotate, Zoom, and Constraint an Image
- MFC Ocx: Using ActiveX Controls in Nondialog Windows
- Using VS2010 Develop ActiveX Control in Windows Form Control Libarary
- Using VS2010 Develop ActiveX Control in Windows Form Control Libarary
- How to enumerate the system fonts in the combobox control using VC++ - 用VC++如何在ComboBox控件中枚举系统字体
- Using Keyboard Interface Control in Windows
- VS2010 The project file ' ' has been renamed or is no longer in the solution
- Some of the Best Open Source Project's in VC++ & MFC
- VS2010/MFC编程入门之三十三(常用控件:标签控件Tab Control 下)
- WEB项目使用远程桌面,Embedding the Remote Desktop ActiveX Control in a Web Page
- Maven: Problem: Using Jedis in maven project
- Using Timers in MFC Applications
- Using ActiveX in IE
- Using extjs calendar control (DateField) in ASP.NET
- How to keep Z-order of a control in MFC dialog?
- 使用VS2010开发ActiveX(MFC)控件(3)——添加接口及WEB调用