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


    晚上在博客堂读完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(E389AD6C-4FB6-47AF-B03A-A5A5C6B2B820), 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));

    from:http://blog.csdn.net/phinecos/article/details/4611934

  • 相关阅读:
    递归方程(续)
    递推方程
    协方差简单介绍
    排列组合
    牛顿法
    jquery常用方法总结
    RegExp的test()方法
    localStorage用法总结
    正则表达式
    登录页面按回车键实现登陆效果
  • 原文地址:https://www.cnblogs.com/lidabo/p/2942081.html
Copyright © 2020-2023  润新知