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
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南