ATL问题集(精典整理1)

/*此文是将网上的一些文章,自已遇到的问题进行整理,有些是翻译,所有只供学习讨论,如有版权还归原作者――作者:王卫星csdnid:wangweixing2000*/

#32如何动态创建ocx

答:看下面代码

#include <atlbase.h>

 CComModule _Module;

#include <atlcom.h>

#include <atlwin.h>

#pragma comment(lib,"atl")

 

CComQIPtr<IWebBrowser2> m_spBrowser;

CAxWindow content_wnd;

......

if(  _tcslen(m_tcHtmlFileName) > 0 )

{

RECT rc;

GetClientRect( &rc );

if(m_spBrowser==NULL)

{

LPOLESTR pstrbrowserid;

StringFromCLSID(IID_IWebBrowser2,&pstrbrowserid);

_bstr_t bstrbrowser(pstrbrowserid);

CoTaskMemFree(pstrbrowserid);

if(content_wnd.IsWindow())

content_wnd.DestroyWindow();

content_wnd.Create( m_hWnd, rc, LPCTSTR(bstrbrowser), WS_CHILD&brvbar;WS_VISIBLE&brvbar;WS_HSCROLL&brvbar;WS_VSCROLL );//create a browser control

HRESULT hrbrowser;

hrbrowser = content_wnd.QueryControl( IID_IWebBrowser2, reinterpret_cast<void**>(&m_spBrowser) );

}

 

#33如何获取窗体上ocx的接口指针?

解决方法:

CWindow::GetDlgControl()

CAxWindow中的QueryControl

拿上面的例子:

hrbrowser = content_wnd.QueryControl( IID_IWebBrowser2, reinterpret_cast<void**>(&m_spBrowser) );

 

#34如何调整控件的大小

要调整控件大小,只需使用标准的 MoveWindow SetWindowPos API(或它们的 CWindow 包装)调整宿主窗口的大小即可。为响应收到的窗口消息,宿主对象自动调整控件大小以填充宿主窗口。

 

#35 #import Java com组件后生成的.tlh文件中的汉字“参数”问题

解决办法:

1、先保存好这个tlh文件的时间戳

2、打开.tlh文件,手动把"参数"改称"var"

3、然后保存文件,并手动把时间戳改回1种保存的时间辍

f5-----ok

 

#36如何使用IStream

我以前写的代码:

void bufStorageWrite()

{

CoInitialize(NULL);

IStream *pStream = NULL;

HRESULThr = S_OK;

HGLOBAL hGLobal =  GlobalAlloc(GMEM_FIXED,SIZE_T(nCount*sizeof(Coord3D)));

::CreateStreamOnHGlobal(hGLobal,true,&pStream);

if(pStream)

{

DWORD dwData[2] = {1,0};

Coord3D coord = {1,2,3,4};

clock_t t1 = clock();

for(int i=0; i<nCount; i++)

{

pStream->Write(&coord,sizeof(Coord3D),NULL);//(&dwData, 2*sizeof(DWORD), NULL);

}

clock_t t2 = clock();

cout<<_T("bufStorageWrite WriteTime ")<<t2-t1<<endl;

 

pStream->Release();

}

 

CoUninitialize();

}

 

#37如何操作DATE类型?

看看下面代码,加上#include <atlconv.h>

void CVarUseDlg::OnDate()

{

       VARIANT timeSelection;

       COleDateTime timeNow;

       DATE curDate;

       HRESULT hr;

       //获取当前时间.

       timeNow = COleDateTime::GetCurrentTime();

      

       //设置一个时间给VARIANT

       timeSelection.vt = VT_DATE;

       timeSelection.date = timeNow.m_dt;

      

       //Convert Variant into string using Variant Change Type.

       hr = VariantChangeType(&timeSelection, &timeSelection, 0, VT_BSTR);

       CString sCurTime(timeSelection.bstrVal);

      

      

       //Get Time as System Time.

       SYSTEMTIME mySysTime;

       timeNow.GetAsSystemTime(mySysTime);

      

       //Use COleDateTime functionality to get change SYSTEMTIME into DATE.

       COleDateTime pastTime(mySysTime);

       curDate = pastTime.m_dt;

 

 

       //Use COldeDateTime Format command to get date as CString.

       LPCTSTR format = _T("%X %z");  //Current time and time zone.

       //Note see "strftime" help for valid formating strings.  

       CString sTime = pastTime.Format(format);

 

}

 

#38我用VB写了一个DLL,用VC怎么调用啊?

#import "your.dll" no_namespace前加上下面这句:

#import "msvbvm60.dll" no_namespace rename("EOF", "EndOfFile") rename("RGB","ColorRGB")

使用VB来开发控件的时候,需要将VB的虚拟机装上去

msvbvm60VB做的控件都要用到的一个DLL

 

#39 那怎么发布使用了dllActivex呢?  

1、如果需要创建cab文件,首先需要Cabarc或者Makecab,它们随着Cabinet  SDK的安装就有了,Cabinet  SDK的下载地址是http://msdn.microsoft.com/workshop/management/cab/cabdl.asp  
Cabarc
可以创建、查看或者解出cab里面的文件,而Makecab则只可以用来创建cab文件。
 
2
、制作cab文件时需要将所有的相关文件都包含进去,可以通过DependsVC自带的)检查需要的文件。使用inf文件将这些东西都写进去。
 
3
inf搞法:inf文件描述cab中所有的ocxdll文件,inf通过一些命名区域来提供需要的信息。
 
 
怎么写
inf  
最开始一般是[Version]区:
 
eg:  [Version]  
       signature="$XXXX$"  
       AdvancedINF=2.0  
接下来就是最重要的[Add.Code]区:
 
eg:  [Add.Code]  
       Ctrl1.dll=C1Section  
       Ctrl2.dll=Ctrl2.dll  
前面是要下载的文件名,后面是对应这个文件的区域名,可以是任何名字,不过一般都是和文件的名字相同,这样方便维护。还有需要注意是在[Add.Code]区出现的文件要根据依赖性进行排序,例如前面说的ctrl1.dll要依赖于ctrl2.dll,则ctrl2.dll要出现在ctrl1.dll的前面。因为安装时是按照相反的顺序进行的,也就是说先安装ctrl2.dll,然后才是ctrl1.dll,哧哧,记清楚了,不要搞反了。
 
再接下来是各个文件的区域了
 
[Ctrl1.dll]  
file-win32-x86=thiscab  
RegisterServer=yes  
clsid={.....}  
DestDir=    
FileVersion=1,0,0,0  
[Ctrl1.dll]
区域中的第一个file值告诉ie到哪里去得到这个dllfile一共包括三个部分,第一部分是file,这个永远都是这样的(至少目前来说);第二部分告诉声明支持的OSwin32表示windowsmac就是苹果MAC  OX了;第三部分是CPU类型,比如说x86  ppc  (Power  PC)  mips或者alpha了。
 
file
的值可以取三个一个URLignorethiscab,如果是URL则说明到URL所在的位置去下;如果是ignore说明对于这种OSCPU,不需要下载这个文件(ctrl1.dll);如果是thiscab很明显就在当前的cab文件中了。
 
接下来是RegisterServer,可以取两个值yesno,如果为yes则说明ie要注册该dll,如果是no就不必了;
 
再下来是DestDir,它的值是dll将要存到本地硬盘的位置,如果它的值是10,则将dll放到/Windows或者/WinNT下;如果是11,则放到/Windows/System或者
 
/WinNT/System32
下;如果是空(就是没有值)则会放到/Windows或者/WinNT下的Downloaded  Program  Files目录下;
 
最后是FileVersion,这个就比较明显了,说明了ctrl1.dll的版本号。
 
有时候我们使用VB来开发控件的时候,需要将VB的虚拟机装上去,它需要一些其它的说明的,简单地讲一下吧:
 
[Add.Code]中增加一项MSVBVM60.DLL=MSVBVM60.DLL(以VB6为例)下面是
 
MSVBVM60.DLL
区域:
 
[MSVBVM60.DLL]  
           hook=MSVBVM60.cab_Installer  
           FileVersion=6,0,81,76  
FileVersion
很明显,是版本号,就不再说发,就说说hook吧。
 
hook
区域是在安装的时候需要执行的区域,它分为两种,一种是有条件的,另外一种是无条件的,无条件的hook区域是必须执行的,反之则根据条件判断是否执行。以[Setup  Hooks]标记的区域是无条件区域,如下所示
 
[Setup  Hooks]  
       hookname=section-name  
 
[section-name]  
run=%EXTRACT_DIR%/setup.exe  
无条件区域常用来通过一个inf文件执行一个安装程序,这就是我们在资源管理器右键点击一个inf文件时在执行安装这样的菜单的原因了
 
ie下载了一个cab文件,如果文件中没有[Add.Code],则处理[Setup  Hooks]区域,运行run所指定程序,哧哧,上面就是setup.exe
 
条件区域则为在一定条件下执行,前面为MSVBVM60.DLL指定的hook区域就是一个条件区域,如果在MSVBVM60.DLL指定的CLSID或者version不能满足需要而且没有file这个命名值,则执行hook所指定的区域。
 
[MSVBVM60.cab_Installer]  
file-win32-x86=http://activex.microsoft.com/controls/vb6/VBRun60.cab  
run=%EXTRACT_DIR%/VBRun60.exe  
上面[MSVBVM60.cab_Installer]是一个hook区域,它也包含了一个file,指定一个URL,表示MSVBVM60.DLL可以从这个URL下载得到;run则说明了执行哪一个文件
 
这里有必要说明一下的是,MS对一些常用的
Redistributable  Microsoft  DLLs  
可以通过指定CODEBASE属性为http://activex.microsoft.com/controls,这样在cab文件中就中需要包含这些文件,在计算机上有一个文件redist.txt上面的dll就是
Redistributable  Microsoft  DLLs  
 
 
创建一个cab文件:
 
cabarc  N  ctrl1.cab  ctrl1.inf  ctrl1.dll  
N
表示要创建一个新的文件,ctrl1.cab是创建的文件名,ctrl1.infcabinf,后而是需要加到cab里的文件,可以使用通配符。
 
然后就可以将cab文件放到网页上了
 
<OBJECT  ID="Ctrl1Obj"  
               CLASSID="clsid:....................................."  
               CODEBASE="http://server.com/ctrl1.cab#version=8,0,0,5007">  
</OBJECT>  
这里也在一个version,不过这里的version是指控件的version,而inf里的是文件的version
 
 
 
制作电子签名:  
首先从下面的网址下载制作签名的工具SignCode,地址是
 
http://msdn.microsoft.com/workshop/gallery/tools/authenticode/authcode.asp  
从签名授权中心如VeriSign或者你的局域网上运行的
Microsoft  Certificate    
Server
授权服务器得到一个certificate,在申请授权的过程你会得到一个私钥。
 
也可以使用MakeCert.exeCert2Spc.exe创建的私钥进行测试,方法是首先使用MakeCert创建一个X.509certificate.cer文件)
 
       MakeCert  -sv  MyKey.pvk  n  "CN=My  Software  Company"  MyCert.cer  
然后利用Cert2Spc.cer文件转换成为PKCS  #7软件发布Certificate(.spc文件)
 
       Cert2Spc  MyCert.cer  MyCert.spc  
利用你下载的SignCode对你的cab文件进行电子签名
 
       SignCode  -spc  MyCert.spc  -v  MyKey.pvk  -t  http://  
               timestamp.verisign.com/scripts/timstamp.dll  ctrl1.cab  
SignCode
还可以指定一些其它的参数,就不说了,太长了,哧哧。
 
虽然可以利用测试的.cer.spc文件,但是在发布的时候,必须申请。
 
 
其实东西在SDK中都有说明,不过都是E文的,慢慢看就没有什么发
 
---------------------------------------------------------------  
 
再补充一点,如果只是测试,你可以SignCode时回车,根据提示一步步往下选,命令行参数又臭又长,还经常出错,这样会节省不少你的时间
 
---------------------------------------------------------------  
 
这是因为ocx关联了你的两个dll,在系统调用ocx中的注册函数是需要调用你的dll但系统无法找到,所以加载ocx失败造成注册失败
 
 
解决的办法是在cab的安装文件里把dll安装到系统的目录下,或者动态加载dll,或者指定加载dll的目录

 

#40 如何在应用程序中判断DLLCOM)已注册?  
 
读注册表/HKEY_CLASSES_ROOT/APPID,看你的DLL是否注册,  

代码如下:

HKEY  valueKey;  
 if  (ERROR_SUCCESS!=RegOpenKeyEx(HKEY_CLASSES_ROOT,  
                       "?????",0,KEY_READ,&valueKey))    
 {           //?????
为类ID,"CLSID//{3B5B0834-5D5D-46C9-AFC9-FD746EDCC272}"  
         //
未注册成功  
       return;  
  }  
  else  
             //
已经注册成功

 转贴请注明出处!

已标记关键词 清除标记
相关推荐
中文名: 深入解析ATL(第2版) 原名: ATL Internals, 2nd Edition Working with ATL 8 别名: ATL 作者: (美)塔瓦瑞斯译者: 赖仪灵 曹雨田 资源格式: PDF 版本: 扫描版 出版社: 电子工业出版社书号: 9787121049859发行时间: 2007年11月01日 地区: 大陆 语言: 简体中文 简介: 编辑推荐 ATL的发明人Jim Springfield亲自作序推荐。   四位顶尖的Windows编程专家倾力合作,绝对经典再现。   COM、ATL开发人员的必备宝典。   深入分析ATL实现COM内幕细节,展示COM应用中的各类漂亮技巧。   ATL的经典指南现已更新到ATL 8和VisuaI Studio 2005:   四位顶尖的Windows编程专家在本书中系统地揭示了ATL的内部工作原理,他们解释了ATL是 如何工作的,以及为什么要以这样的方式工作。通过本书,客户端开发人员可以掌握ATL中的窗口、COM控件、MFC集成、Web服务代理生成等资源。服务端编程人员可以应用ATL的全COM服务器和对象服务、高吞吐量、高并发Web应用程序和服务的广泛支持。每个Windows开发人员都将从本书中学到强大的方法来增加应用程序的灵活性、减少负载、最大化程序的透明度和可控性。   ·通过图表、示例代码和ATL的内部实现代码来揭密ATL的内部原理。   ·遍历向导以简化在普通应用程序中的ATL开发。   ·掌握C++、COM和ATL中的字符串使用技巧。   ·利用ATL的智能类型:CComPtr、CComQIPtr、CComBSTR和CComVariant。   ·理解并正确实现IUnknown。   ·创建能从COM服务器中暴露COM对象的粘合代码。   ·使用Canned Interface实现来支持对象的永久性、COM集合、枚举器和连接点。   ·使用ATL窗口类和控件建立独立的应用程序和UI组件。   ·使用ATL Servet开发可以运行在微软IIS上的Web应用程序。 虽然.NET系统从1998年才开始其发展进程。但它已经使很多开发人员的编程发生了革命性的变化,并在未来几年将持续得到改进。但是,COM编程(和 ATL)也依然非常有活力,对Microsoft内外的很多开发人员都非常重要。本书的第2版,与第1版一样,提供了您所需要的信息,使我们在这些技术上的投资也将获得最大的回报。                        ——Jim Springfield,ATL发明人 虽然ATL比较精深,但是这本书的讲解非常通俗易懂,语言比较简练,条理非常清楚。即使在读完这本书之后,它仍然可以作为参考书指导我们的开发和学习工作。我想,这就是好书的价值所在吧。            ——潘爱民,经典畅销书《深入解析Windows操作系统,第4版》译者 内容简介 本书主要介绍了ATL技术的原理、内部实现和应用技巧,由当今4 位顶尖的 Windows技术专家联合撰写。全书内容丰富,深入浅出,主要涵盖了ATL内部架构和实现方法、运用向导简化ATL开发、C++/COM/ATL中字符串的使用技巧、理解并正确实现IUnknown、充分利用ATL提供的Smart Types、撰写能够暴露COM服务器上COM对象的粘合代码、利用Canned Interface实现来支持对象持久化/COM群集/枚举、利用ATL Windows类建构独立的应用程序和UI组件等的技术内容。本书适合于广大Windows开发人员阅读参考,是ATL开发人员的必备权威参考书籍。 作者简介 Christopher Tavares,目前在微软工作,是模式与实践方面的专家。有着超过25年的编程经验,涉及的平台从Sinclair ZX-81到多CPU信号处理硬件。 目录: 第2版序 第1版序 前言 致谢 关于作者 联系博文视点 第1章 你好,ATL 1.1 什么是ATL 1.2 创建COM服务器 1.3 插入COM类 1.4 添加属性和方法 1.5 实现附加接口 1.6 脚本支持 1.7 添加永久性 1.8 添加和激发事件 1.9 使用窗口 1.10 COM控件 1.11 容纳控件 1.12 ATL Server Web项目 1.13 总结 第2章 字符串和文本 2.1 字符串数据类型、转换类和辅助函数 2.2 智能BSTR类CComBSTR 2.3 CComBSTR类 2.4 CString类 2.5 总结 第3章 ATL智能类型 3.1 智能VARIANT类CComVariant 3.2 智能SAFEARRAY类CComSafeArray 3.3 智能指针类CComPtr和CComQIP
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页