• COM应用总结(2/3) c++实例和部署


    接着把这个总结继续。

    实例

    以常用的HTML文档的处理为例,深入地描述一下COM的使用,其他的类别使用类同(如Office的编程对象)

    首先工程包含

    #include <mshtml.h>

    具体的代码如下:

    //以DOM对象的形式遍历HTML文档
    int WalkTree(CComPtr<IHTMLDOMNode> domNode)
    {
        ASSERT(domNode!=NULL);

        long type;
        CComBSTR tag;
        if(domNode->get_nodeType(&type)==S_OK)
        {
            switch(type)
            {
            case 1://MSXML::NODE_ELEMENT:
                {
                    // Get the element name and set the tag name...
                    if(SUCCEEDED(domNode->get_nodeName(&tag)) )
                    {
                        ///查到 <a ... 这样的元素                    if(wcscmp(tag.m_str, L"A")==0)
                        {
                            CComPtr<IDispatch> pDisp;
                            domNode->get_attributes(&pDisp);

                            CComQIPtr<IHTMLAttributeCollection, &IID_IHTMLAttributeCollection> pAttrs;
                            pAttrs = pDisp;
                            pDisp = NULL;

                            long l;
                            COleVariant index;
                            index.vt = VT_I4;
                            pAttrs->get_length(&l);
                            for (long i = 0; i < l; i++)
                            {
                                pDisp = NULL;
                                index.lVal = i;
                                pAttrs->item(index, &pDisp);

                                ///查询接口 也可用 CComQIPtr
                                CComPtr<IHTMLDOMAttribute> phref;
                                if(SUCCEEDED(pDisp->QueryInterface(IID_IHTMLDOMAttribute, (void**)&phref)) )
                                {
                                    VARIANT_BOOL vbSpecified;
                                    phref->get_specified(&vbSpecified);
                                    if(VARIANT_TRUE==vbSpecified)
                                    {
                                        CComBSTR text;
                                        if(SUCCEEDED(phref->get_nodeName(&text)) )
                                        {
                                            ///You can do...
                                        }

                                        COleVariant v;
                                        if(SUCCEEDED(phref->get_nodeValue(&v)) )
                                        {
                                            ///You can do...
                                        }
                                    }
                                }
                            }
                        }
                    }           

                    CComPtr<IHTMLDOMNode> pChild;
                    if(domNode->get_firstChild(&pChild)==S_OK)
                    {
                        // If we have children, loop through and handle each one...
                        if (pChild)
                        {
                            // Recurse for all the children of this tag...
                            CComPtr<IHTMLDOMNode> domChild;
                            while (pChild)
                            {
                                WalkTree(pChild);

                                domChild=NULL;
                                domChild=pChild;
                                pChild=NULL;
                                domChild->get_nextSibling(&pChild);
                            }
                        }
                    }
                    break;
                }
            case 3://MSXML::NODE_TEXT:
                {
                    COleVariant val;
                    if(domNode->get_nodeValue(&val)==S_OK)
                    {
                        ///You can do...
                    }
                }
                break;
            }
        }

        return 0;
    }

    void CBrowserDomDlg::OnBnClickedOk()
    {
        CComPtr<IDispatch> pDisp;
        pDisp = m_Web.get_Document();

        CComQIPtr<IHTMLDocument2, &IID_IHTMLDocument2> pHTML;
        pHTML = pDisp;

        ///可以查看HTML的 title内容
        CComBSTR bstrTitle;
        if(pHTML!=NULL && pHTML->get_title(&bstrTitle)==S_OK)
        {
            //title is
        }

        CComPtr<IHTMLElementCollection> pElems;
        HRESULT hr;

        pHTML->get_all(&pElems);
        if(pElems==NULL) return;
        long l;
        if(!SUCCEEDED(pElems->get_length(&l)) )
            return;

        //遍历元素找到BODY节点
        CComPtr<IHTMLElement> htmlBody;   
        COleVariant index;
        for(int i=0;i<l;i++)
        {
            CComPtr<IDispatch> pChild;

            index.vt = VT_I4;
            index.lVal = i;

            hr=pElems->item(index,index ,&pChild);
            htmlBody=NULL;
            if(SUCCEEDED(hr) && SUCCEEDED(pChild.QueryInterface(&htmlBody)) && htmlBody!=NULL)
            {
                CComBSTR name;
                hr=htmlBody->get_tagName(&name);
                if(wcscmp(name.m_str, L"BODY")==0)
                    break;
            }
        }

        if(htmlBody==NULL) return;

        CComPtr<IHTMLDOMNode>pDOM;
        htmlBody->QueryInterface(&pDOM);

        if(pDOM==NULL) return;

        WalkTree(pDOM);
    }

    还有我们在应用中常用的ADO数据存取的方式:

    #import   "C:\Program   Files\common   files\system\ado\msado15.dll "   no_namespace   rename( "EOF ", "EndOfFile ")   rename( "BOF ", "FirstOfFile ")

    _RecordsetPtr   m_pRs;

    具体的操作和以上的例子类似

    部署

    一般的COM组件都是C++开发的[因为现在.net提供了更好的实现形式,单纯使用COM的时机少了很多],部署时只要注意对应的MFC库和ATL库的设置即可

    部署有两个形式[在项目编译选项设置]

    静态链接

    把MFC和ATL静态链接到组件中

    [减少了部署的麻烦,组件的大小比动态连接大]

    如项目就一个COM组件,那这种形式最好

    动态连接

    此时部署有两个方法:

    1、 安装对应版本的MFC和ATL发行库[VS就包含]

    2、 把Microsoft.VC**.CRT Microsoft.VC**.MFC Microsoft.VC**.ATL 这些需要的目录和其中的文件放在和组件库相同的地方即可

    全部的实例代码参见:

    http://cid-56b433ad3d1871e3.office.live.com/self.aspx/.Public/ComTutorial.zip

  • 相关阅读:
    Scala for the Impatients---(1)Basics
    2.2 Markov Chain
    2.1 Monte Carlo Integration
    1.2 Sampling From Non-standard Distribution
    1.1 Built-in Distributions In Matlab
    Design Pattern -- Builder
    Java Dynamic proxy
    The Difference Between Keypoints and Descriptors
    gcc -l option vs. -L option: The difference
    Stationarity and Independence of Data
  • 原文地址:https://www.cnblogs.com/2018/p/1800763.html
Copyright © 2020-2023  润新知