这是我学习com遇到的几个基本问题其解决
黄森堂(vcmfc)著
1.我用atl生成一个组件对象,我在com中使用idd_iencrypt,这个在哪里写义,是啥?guid?
答:idd_iencrypt是guid,也称作clsid,放到该项目的对象的xxx_i.c文件中。
2.s_ok,noerror等常量中定义在哪些文件上(偷一下懒)(vc6.0)。
答:winerror.h中
3.我在一个asp组件对象中有构造函数使用sysallocstring()分配内存在该对象的类变量,在dll release memory的时候,我要调用sysfreestring(),可是好像该对象没有析构函数,我在哪儿处理。
答:可以自己添个析构函数,在里面调用sysfreestring。或可以使用_bstr_t或ccombstr,就省得释放内存了。
4.bstr指针的内容如何拷贝到lpolestr指针上?
答:bstr是com使用的特殊字符串类型,它的开头是bstr所包含的字符串的字节长度,然后才是字符串,该字符串以null
结束,不过普通的字符串中间是不允许包含null的,但是bstr允许,因为它前面已经有该字符串的长度了。如果要在bstr和我们
所常见的字符串类型转换,一般不必自己转换,用_bstr_t类就可以。这也是微软所推荐的。比如要从bstr m_bstra 转为 char*
可以这样:
char* pstr;
pstr = (char*)_bstr_t(m_bstra);
很简单吧。
如果要从char* pstr转为bstr,这样作:
bstr m_bstra;
m_bstra = _bstr_t(pstr).copy();
其它类型转换我没试过,不过从char*转为
lpctsrt之类应该就不会太难了。
(注:看一看第9条,唉!,自已够笨的)
5.在com方法中能不能使用try...catch?
答:在com中可以用try,catch块,但在project->settings->c/c++->c++ language下要选中enable exception handling。如果你用try,catch块,可在catch块中可以这样写:error((bstr)e.description, iid_*, e.error())(e是_com_error)。
6.我的组件有一个方法encrypt,需要传入一个加密字符串,加密后将字符串返回给vb,在vb中我使用 s=jj.encrypt("数据"),那么我在com中该如何定义该方法?
答:返回值要是[out]属性,要想用以上方法使用,最后一个参数用[out,retval]bstr* pencryptstring,这将作为返回字符串。
完整定义如下:
[id(2), helpstring("加密")] hresult encrypt(bstr encryptstring,[out,retval]bstr *pencryptstring);]
7.我的属性为什么不能进行赋值?
我在组件里加一个属性key,可以get与put,在组件源程序中有get_key()与put_key(),get_key工作正常,可我的put_key不正常呀!,源程序如下:
stdmethodimp cencrypt::put_key(bstr newval)
{
m_pkey=newval;//m_pkey为类变量,如下定义:bstr m_pkey;
return s_ok;
}
答:m_pkey=sysallocstring(newval);
8.如何更改控件或组件的在注册时存放在注册表中的名称?

自已答:告诉你,不在.idl,在你的xxx.rgs文件中,全改了,是不是已经...,嘿嘿~~.
9.atl中ccombstr与_bstr_t的区别?嘿嘿~~,我现在才明白一点,高手莫笑。
答:
共同点:对于bstr到bstr,bstr到对象(ccombstr/_bstr_t),对象到bstr,两者之间没有什么区别,ccombstr与_bstr_t都能很好地管理处理bstr.
异同点:_bstr_t提供了bstr到char,wchar_t指针的处理,也就是说能把bstr的内容拷贝成char*,而ccombstr就没有这种功能。
10.ole_color与colorref,variant_bool与bool有何区别?
答:我是不知道,不过可以直接进行赋值。嘿嘿..,是不是太土吧!
以下是陆大虾的进课:
ole_color与colorref之间是有一定区别的。ole_color和colorref都是dword类型,但对于colorref来说,它的最高一个字节永远是0x00。即如果是红色,对于colorref来说是0x000000ff。而ole_color的最高一个字节有两种情况:0x80(也就是10000000,最高位是1)或0x00(也就是00000000,最高位是0)。当ole_color的最高位是0时,它与colorref是相同的,最后三个字节代表rgb,可以相互赋值。例如红色用ole_color来表示同样是0x000000ff。但当ole_color的最高位是1时,它的中间两个字节一定都是0x00,最后一个字节表示的是系统颜色索引值。例如系统定义菜单的颜色索引值是4,所以用ole_color来表示就是0x80000004。在vb中,如果你选中一个form,在它的属性页中你可以看到它的backcolor属性,你点击下拉框,就可以选择是使用调色板色还是系统色,调色板色就是对应了ole_color的高位为0的情况,系统色对应的是ole_color高位为1的情况。你试一下就知道是怎么回事了。
variant_bool和bool之间也有区别。bool为long,在bool中,ture为1,false为0。vairnat_bool为short,在variant_bool中,variant_true为-1(0xffff),variant_false为0(0x0000)。并且variant_bool是和vb中的boolean相同的,就像bstr和string的关系一样。所以,在自动化组件及控件中应该使用variant_bool。
11.如何知道该activex是在vb的设计时还是运行时?
答:判断run-mode和design-mode的方法是ccomcontrol::getambientusermode,你可以在msdn中找到这个函数的用法。
12.我的activex控件有一个属性algin,我想在vb中列出其属性值出现一个combobox来列出我定义的几个值?,有的枚举出来左边有图像,右边有文字说明,这是如何实现的?
答:简单的静态枚举直接在 idl 文件中定义枚举类型,把属性的类型定为枚举类型即可。动态枚举比较麻烦,主要涉及到 iperpropertybrowsingimpl<catlcontrolwin> 的下列方法:mappropertytopage, getpredfinedstrings, getpredefinedvalue, getdisplaystring。具体实现方法请参考《visual c++ 5 activex 编程指南》,jerry anderson 著,清华大学出版社。
以下简单的静态枚举的代码片段(以align属性说明):
//typedef enum tagfontalign{left=0,center=1,right=2}fontalign;(比较完整的如下)
typedef enum tagfontalign
{
[helpstring("left")]left=0,
[helpstring("center")]center=1,
[helpstring("right")]right=2,
}fontalign;
[propget, id(2), helpstring("对齐方式")] hresult align([out, retval] fontalign *pval);
[propput, id(2), helpstring("对齐方式")] hresult align([in] fontalign newval);
在接下来的接口定义中添加属性align时,属性的数据类型就填fontalign,其它操作照常。编译完以后,你就应该在vb project中的object browser中看到有这么一个枚举类型。在控件属性中选中align时,就会有个combo box让你选择fontalign中的一个值。
13.如何创建一个容器,像vb中的tabbed dialog容器,控件在它范围内移动?
答:这要靠控件容器实现 isimpleframesite 接口,在 msdn 中搜索 extending atl 3.0 control containment to help you write real-world containers。
14.在atl中使用其默认的font属性的话,会产生以下错误:
warning midl2039 : interface does not conform to [oleautomation] attribute
warning midl2039 : interface does not conform to [oleautomation] attribute
warning midl2039 : interface does not conform to [oleautomation] attribute
答:这可是困惑我n天,也不知道白了多少根头发,这是一个bug,在microsoft的knowledge的有这一个bug报告: