[C#]CodeFx:一站式微软开发技术解决方案

转载:http://www.cnblogs.com/phinecos/archive/2009/03/04/1403450.html    
晚上在博客堂读完VSTO
写的一篇文章,介绍了CodePlex上面的一个项目,叫做All-In-One Code Framework,代号CodeFx简单的说,就是收集了几乎所有常见的微软开发技术的示例项目,将其打包到这个框架里,而且还使用多各种不同的语言进行实现。比如创建一个ActiveX控件和COM组件,CodeFx里面使用ATLMFCVBC#来实现同样的功能。

适合新手入门,也可以作为一份模板供经验丰富的开发者使用,可节省大量的时间。官方网站上给出了框架的基本结构,如下图所示:

COM组件和ActiveX控件示例

 

数据访问示例

库示例

进程间通信示例 

 

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

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

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

头文件的修改     

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

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

 

实现文件的修改

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

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

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

// CMFCActiveXCtrl::CMFCActiveXCtrlFactory::VerifyUserLicense –
// Checks for existence of a user license

BOOL CMFCActiveXCtrl::CMFCActiveXCtrlFactory::VerifyUserLicense()
{
    
return AfxVerifyLicFile(AfxGetInstanceHandle(), _szLicFileName,
        _szLicString);
}
// CMFCActiveXCtrl::CMFCActiveXCtrlFactory::GetLicenseKey –
// Returns a runtime licensing key
BOOL CMFCActiveXCtrl::CMFCActiveXCtrlFactory::GetLicenseKey(DWORD dwReserved,
    BSTR FAR
* pbstrKey)
{
    
if (pbstrKey == NULL)
        
return FALSE;
    
*pbstrKey = SysAllocString(_szLicString);
    
return (*pbstrKey != NULL);
}

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

    [ uuid(E389AD6C4FB647AFB03AA5A5C6B2B820), licensed,
      helpstring(
"MFCActiveX Control"), control ]
    coclass MFCActiveX

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

HRESULT AutoWrap(int autoType, VARIANT *pvResult, IDispatch *pDisp, 
                 LPOLESTR ptName, 
int cArgs
{
    
// Begin variable-argument list
    va_list marker;
    va_start(marker, cArgs);
    
if (!pDisp) 
    {
        _putts(_T(
"NULL IDispatch passed to AutoWrap()"));
        _exit(
0);
    }
    
// Variables used
    DISPPARAMS dp = { NULL, NULL, 00 };
    DISPID dispidNamed 
= DISPID_PROPERTYPUT;
    DISPID dispID;
    HRESULT hr;
    
char szName[200];
    
    
// Convert down to ANSI
    WideCharToMultiByte(CP_ACP, 0, ptName, 1, szName, 256, NULL, NULL);
    
    
// Get DISPID for name passed
    hr = pDisp->GetIDsOfNames(IID_NULL, &ptName, 1, LOCALE_USER_DEFAULT,
        
&dispID);
    
if (FAILED(hr))
    {
        _tprintf(_T(
            
"IDispatch::GetIDsOfNames(\"%s\") failed w/err 0x%08lx\n"
            ), szName, hr);
        
return hr;
    }
    
    
// Allocate memory for arguments
    VARIANT *pArgs = new VARIANT[cArgs+1];
    
// Extract arguments
    for(int i=0; i<cArgs; i++
    {
        pArgs[i] 
= va_arg(marker, VARIANT);
    }
    
    
// Build DISPPARAMS
    dp.cArgs = cArgs;
    dp.rgvarg 
= pArgs;
    
    
// Handle special-case for property-puts
    if (autoType & DISPATCH_PROPERTYPUT)
    {
        dp.cNamedArgs 
= 1;
        dp.rgdispidNamedArgs 
= &dispidNamed;
    }
    
    
// Make the call
    hr = pDisp->Invoke(dispID, IID_NULL, LOCALE_SYSTEM_DEFAULT,
        autoType, 
&dp, pvResult, NULL, NULL);
    
if (FAILED(hr)) 
    {
        _tprintf(_T(
            
"IDispatch::Invoke(\"%s\"=%08lx) failed w/err 0x%08lx\n"
            ), szName, dispID, hr);
        
return hr;
    }
    
// End variable-argument section
    va_end(marker);
    
    delete[] pArgs;
    
    
return hr;
}

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

#include <Delayimp.h>

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

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

posted on 2009-03-04 23:15 Phinecos(洞庭散人)

赞(0) 打赏
分享到: 更多 (0)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏