CodeFx:一站式微软开发技术解决方案

COM组件和ActiveX控件示例

数据访问示例

库示例

 

进程间通信示例 

 

花了2个小时粗略阅读了代码,记录下学习心得:

1)先来说ActiveX这条线,它里面使用了ATL(这里有2种实现,进程内和进程外)MFC,C#,VB四种技术来实现。功能就是四点:一个返回字符串的HelloWorld方法,一个float类型的属性FloatProperty,一个返回进程号和线程号的GetProcessThreadID方法,一个FloatPropertyChanging事件。

2)授权支持是 ActiveX 控件的一项可选功能,它使您得以控制能使用或分发该控件的人。(请参见MFC ActiveX 控件:授权 ActiveX 控件》)。

头文件的修改     

“ActiveX 控件向导将下列代码放置在控件头文件中。声明了 factory 对象的两个成员函数,其中一个成员函数验证控件 .LIC 文件是否存在,而另一个成员函数则对包含该控件的应用程序中使用的许可证密钥进行检索:

  
  
  
  
  1. BEGIN_OLEFACTORY(CMFCActiveXCtrl)        // Class factory and guid  
  2.     virtual BOOL VerifyUserLicense();  
  3.     virtual BOOL GetLicenseKey(DWORD, BSTR FAR*);  
  4. END_OLEFACTORY(CMFCActiveXCtrl) 

实现文件的修改

“ActiveX 控件向导将下面两条语句放置在控件实现文件中,以声明许可文件名和许可字符串:

 

  
  
  
  
  1. static const TCHAR BASED_CODE _szLicFileName[] =   
  2.    _T("License.lic");  
  3. static const WCHAR BASED_CODE _szLicString[] =  
  4.    L"Copyright (c) 2000 "

注意:如果以任何方式修改 szLicString,则必须也修改控件 .LIC 文件的第一行,否则授权将无法正确运行。
“ActiveX 控件向导”将下列代码放置在控件实现文件中,以定义控件类的 VerifyUserLicense 函数和 GetLicenseKey 函数:

 

  
  
  
  
  1. // CMFCActiveXCtrl::CMFCActiveXCtrlFactory::VerifyUserLicense -  
  2. // Checks for existence of a user license  
  3.  
  4. BOOL CMFCActiveXCtrl::CMFCActiveXCtrlFactory::VerifyUserLicense()  
  5. {  
  6.     return AfxVerifyLicFile(AfxGetInstanceHandle(), _szLicFileName,  
  7.         _szLicString);  
  8. }  
  9.  
  10. // CMFCActiveXCtrl::CMFCActiveXCtrlFactory::GetLicenseKey -  
  11. // Returns a runtime licensing key  
  12. BOOL CMFCActiveXCtrl::CMFCActiveXCtrlFactory::GetLicenseKey(DWORD dwReserved,  
  13.     BSTR FAR* pbstrKey)  
  14. {  
  15.     if (pbstrKey == NULL)  
  16.         return FALSE;  
  17.     *pbstrKey = SysAllocString(_szLicString);  
  18.     return (*pbstrKey != NULL);  

最后,“ActiveX 控件向导修改控件项目 .IDL 文件。将关键字 licensed 添加到控件的 coclass 声明中,如下例所示:

  
  
  
  
  1. uuid(E389AD6C-4FB6-47AF-B03A-A5A5C6B2B820), licensed,  
  2.   helpstring("MFCActiveX Control"), control ]  
  3. coclass MFCActiveX 

   3)作者封装了一个方法AutoWrap来调用COM组件公开出来的属性或方法。

 

  
  
  
  
  1. HRESULT AutoWrap(int autoType, VARIANT *pvResult, IDispatch *pDisp,   
  2.                  LPOLESTR ptName, int cArgs)   
  3. {  
  4.     // Begin variable-argument list  
  5.     va_list marker;  
  6.     va_start(marker, cArgs);  
  7.     if (!pDisp)   
  8.     {  
  9.         _putts(_T("NULL IDispatch passed to AutoWrap()"));  
  10.         _exit(0);  
  11.     }  
  12.     // Variables used  
  13.     DISPPARAMS dp = { NULL, NULL, 0, 0 };  
  14.     DISPID dispidNamed = DISPID_PROPERTYPUT;  
  15.     DISPID dispID;  
  16.     HRESULT hr;  
  17.     char szName[200];  
  18.       
  19.     // Convert down to ANSI  
  20.     WideCharToMultiByte(CP_ACP, 0, ptName, -1, szName, 256, NULL, NULL);  
  21.       
  22.     // Get DISPID for name passed  
  23.     hr = pDisp->GetIDsOfNames(IID_NULL, &ptName, 1, LOCALE_USER_DEFAULT,  
  24.         &dispID);  
  25.     if (FAILED(hr))  
  26.     {  
  27.         _tprintf(_T(  
  28.             "IDispatch::GetIDsOfNames(\"%s\") failed w/err 0x%08lx\n" 
  29.             ), szName, hr);  
  30.         return hr;  
  31.     }  
  32.       
  33.     // Allocate memory for arguments  
  34.     VARIANT *pArgs = new VARIANT[cArgs+1];  
  35.     // Extract arguments  
  36.     for(int i=0; i<cArgs; i++)   
  37.     {  
  38.         pArgs[i] = va_arg(marker, VARIANT);  
  39.     }  
  40.       
  41.     // Build DISPPARAMS  
  42.     dp.cArgs = cArgs;  
  43.     dp.rgvarg = pArgs;  
  44.       
  45.     // Handle special-case for property-puts  
  46.     if (autoType & DISPATCH_PROPERTYPUT)  
  47.     {  
  48.         dp.cNamedArgs = 1;  
  49.         dp.rgdispidNamedArgs = &dispidNamed;  
  50.     }  
  51.       
  52.     // Make the call  
  53.     hr = pDisp->Invoke(dispID, IID_NULL, LOCALE_SYSTEM_DEFAULT,  
  54.         autoType, &dp, pvResult, NULL, NULL);  
  55.     if (FAILED(hr))   
  56.     {  
  57.         _tprintf(_T(  
  58.             "IDispatch::Invoke(\"%s\"=%08lx) failed w/err 0x%08lx\n" 
  59.             ), szName, dispID, hr);  
  60.         return hr;  
  61.     }  
  62.  
  63.     // End variable-argument section  
  64.     va_end(marker);  
  65.       
  66.     delete[] pArgs;  
  67.       
  68.     return hr;  

4)DLL的延迟加载使得我们不需要使用LoadLibrary和GetProcAddress。这样的好处是直到程序调用DLL中的函数时才加载此DLL。

  
  
  
  
  1. #include <Delayimp.h> 

  卸载延迟加载的DLL的代码:

  
  
  
  
  1. PCSTR pszDll = "CppDllExport.dll";  
  2.  _tprintf(_T("__FUnloadDelayLoadedDLL2 => %d\n"),  
  3.  __FUnloadDelayLoadedDLL2(pszDll)); 

 

你可能感兴趣的:(技术,微软,方案,一站式,CodeFx)