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

时间: 2025-01-02 05:00:56

COM应用总结(2/3) c++实例和部署的相关文章

MySQL单机多实例方案部署

MySQL单机多实例方案,是指在一台物理服务器上运行多个MySQL数据库实例. MySQL单机多实例的优点: 1.节省成本,减少服务器.IP.机柜的数量,总体运营成本低于单机单实例方案. 2.提升利用率,利用NUMA特性,对MySQL实例进行CPU绑定. 3.提升用户体验,大幅度提高IO响应时间,有助于提升用户的体验. MySQL多实例部署的具体实施 1.MySQL多实例目录的规划(数据目录配置文件目录) 实例1 数据路径: /home/mysql/data 配置文件路径: /usr/local

CentOS 6.5环境 MongoDB 3.2.8 单实例安装部署

本文是基于CentOS6.6操作系统上安装MongoDB3.2.8社区版.操作系统要求是64位,MongoDB要求下载64位版本.不建议生产环境部署单实例,可以部署集群,提高数据库的安全性.稳定性和可用性. 配置大内存页面redhat_transparent_hugepage参数设置为never. 先查看该参数值 # cat /sys/kernel/mm/redhat_transparent_hugepage/enabled [always] madvise never # cat /sys/k

MySQL多实例部署案例

昨天晚上在群中和一些网友聊到了MySQL多实例的话题,最早接触MySQL多实例还是在1年前,那会我刚步入运维行业,做过MySQL多实例的相关实验,在后来的工作中也很少用到多实例,一直就淡漠了它,昨天再次提及,故此再次重新整理下以前的笔记,参考一些大牛的观点,也参考我的好友贺总(尊称)的意见,特此写下这篇文章!废话不说,切入正题.... 在同一台物理服务器上部署多个实例,而多实例的部署方式简单,但是如何才能减少我们生产环境的维护成本,如何减少我们出错的机会,如何方便我们后续的迁移和清理等工作,以及

flex+java+BlazeDS部署tomcat7实现服务器推送实例不显示效果

问题描述 最近在研究flex和java,如何通过java服务端推送消息到flex客户端.网上查到使用BlazeDS,一步一步的完成实例,但是部署在Tomcat7后,运行实例没有效果,使用blazeds-turnkey-4.0.0.14931自带的tomcat就能够出现效果.我又试着下载一下新的tomcat6,将这个实例再次部署在tomcat6下,结果也可以实现实例效果.哪个大神可以指导一下,为什么部署在tomcat7下不显示效果. 解决方案 解决方案二: 解决方案三:BlazeDS的消息订阅机制

云服务器 ECS 安全:经典网络内网实例互通设置方法

经典网络内网实例互通设置方法 安全组是实例级别防火墙,为保障实例安全,设置安全组规则时要遵循"最小授权"原则,下面介绍四种安全的内网实例互通设置方法. 方法 1. 使用单 IP 地址授权 适用场景:适用于小规模实例间内网互通场景. 优点:以IP地址方式授权,安全组规则清晰,容易理解. 缺点:内网互通实例数量较多时,会受到安全组规则条数 100 条的限制,另外后期维护工作量比较大. 设置方法: 选择需要互通的实例,进入 本实例安全组. 选择需要配置安全组,单击 配置规则. 单击 内网入方

Redis启动多端口,运行多实例(转)

使用redis在同一台机器上,启用多个端口,实现多个实例,完成集群的模拟实现. 启动多实例 redis默认启动端口为6379,我们可以使用 --port 来指定多个端口,如下,在linux终端命令: redis-server & redis-server --port 6380 & redis-server --port 6381 & redis-server --port 6382 & 查看启动的redis实例: ps -ef | grep redis 使用实例 使用其中

MySQL多实例管理(mysqld_multi)

MySQL多实例管理(mysqld_multi)   官方文档:  https://dev.mysql.com/doc/refman/5.7/en/multiple-servers.htmlhttps://dev.mysql.com/doc/refman/5.5/en/mysqld-multi.html 1.MySQL多实例介绍 1.1.什么是MySQL多实例 MySQL多实例就是在一台机器上开启多个不同的服务端口(如:3306,3307),运行多个MySQL服务进程,通过不同的socket监听

传统大型企业平滑上云典型架构实践

      混合云构建是将企业本地数据中心资源与云资源的集成.对于大多数企业而言,为降低IT的成本和实现业务快速创新而采用云计算,在混合架构中是必然的选择.迁移老的应用和系统上云是有一定的时间和成本消耗,因此,选择一家能够帮助企业实施全面混合战略的云计算厂商,这对简化企业IT运营以及更轻松地实现业务目标至关重要.      企业对云的安全性要求优先级也是最高的,我们可以通过不同的云架构满足不同级别的安全要求,利用云计算的优势只需要给使用的服务付费,在保护云上资产安全的同时降低为安全消耗的成本.

EJB 3.0规范全新体验

规范 引言 期待以久的EJB3.0规范在最近发布了它的初稿.在本文中将对新的规范进行一个概要性的介绍,包括新增的元数据支持,EJBQL的修改,实体Bean模型访问bean上下文的新方法和运行时环境等等.作者还讨论了EJB在未来要作出的调整以及EJB3.0与其他开发规范之间的关系. 开始 无论如何由于EJB的复杂性使之在J2EE架构中的表现一直不是很好.EJB大概是J2EE架构中唯一一个没有兑现其能够简单开发并提高生产力的组建.EJB3.0规范正尝试在这方面作出努力以减轻其开发的复杂性.EJB3.