COM初学者必看

1.我用ATL生成一个组件对象,我在COM中使用IDD_IEncrypt,这个在哪里写义,是啥?GUID

答:IDD_IEncryptGUID,也称作CLSID,放到该项目的对象的xxx_i.c文件中。

2.S_OK,NOERROR
等常量中定义在哪些文件上(偷一下懒)(VC6.0)。

答:winerror.h

3.
我在一个ASP组件对象中有构造函数使用SysAllocString()分配内存在该对象的类变量,在DLL Release memory的时候,我要调用SysFreeString(),可是好像该对象没有析构函数,我在哪儿处理。

答:可以自己添个析构函数,在里面调用SysFreeString。或可以使用_bstr_tCComBSTR,就省得释放内存了。

4.BSTR
指针的内容如何拷贝到LPOLESTR指针上?

答:BSTRCOM使用的特殊字符串类型,它的开头是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中可以用trycatch块,但在Project->Settings->C/C++->C++ Language下要选中Enable Exception Handling。如果你用trycatch块,可在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,可以getput,在组件源程序中有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的区别?嘿嘿~~,我现在才明白一点,高手莫笑。

答:

共同点:对于BSTRBSTRBSTR到对象(CComBSTR/_bstr_t),对象到BSTR,两者之间没有什么区别,CComBSTR_bstr_t都能很好地管理处理BSTR.

异同点:_bstr_t提供了BSTRchar,wchar_t指针的处理,也就是说能把BSTR的内容拷贝成char*,而CComBSTR就没有这种功能。

10.OLE_COLOR
COLORREF,VARIANT_BOOLBOOL有何区别?

答:我是不知道,不过可以直接进行赋值。嘿嘿..,是不是太土吧!

以下是陆大虾的进课:

OLE_COLOR
COLORREF之间是有一定区别的。OLE_COLORCOLORREF都是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之间也有区别。BOOLlong,在BOOL中,TURE1FALSE0VAIRNAT_BOOLshort,在VARIANT_BOOL中,VARIANT_TRUE-10xFFFF),VARIANT_FALSE00x0000)。并且VARIANT_BOOL是和VB中的Boolean相同的,就像BSTRString的关系一样。所以,在自动化组件及控件中应该使用VARIANT_BOOL

11.
如何知道该Activex是在VB的设计时还是运行时?

答:判断run-modedesign-mode的方法是CComControl::GetAmbientUserMode,你可以在MSDN中找到这个函数的用法。

12.
我的ActiveX控件有一个属性Algin,我想在VB中列出其属性值出现一个ComboBox来列出我定义的几个值?,有的枚举出来左边有图像,右边有文字说明,这是如何实现的?

答:简单的静态枚举直接在 IDL 文件中定义枚举类型,把属性的类型定为枚举类型即可。动态枚举比较麻烦,主要涉及到 IPerPropertyBrowsingImpl 的下列方法: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,在MicrosoftKnowLedge的有这一个BUG报告:

“BUG: MIDL2039 Warning with IFontDisp/IPictureDisp Parameter Type”

15.
ATL中产生的Active X中使用默认的Font属性的话,VB中的对象属性页中对其属性进行赋值,会产生一个错误:

“Invalid Properties Value”.

答:该属性在ATL产生后需要在作些设置才能用,在MicrosoftKnowLedge的有一篇文章:

Using Fonts in ATL Controls with NiceText.exe

16.
ATL中产生的Active X中使用默认的Font属性,在.IDL中产生默认接口定义,该如何使用该接口定义呢?

答:#include

IFont *piFont;

HRESULT hr;

HFONT hfont;



hr = m_pFont->QueryInterface(IID_IFont, (void **)&piFont);

if(SUCCEEDED(hr))

{

hr = piFont->get_hFont(&hfont);

}

lhxx
的小贡献

在程序中调用要动态分配内存或实例的COM时要注意要用指针的地址来进行参数传递:

... Sample(int **pInput)

{

*pInput = ...;

....

}

... Sample1( BSTR *pbstr)

{

*pbstr = (BSTR) malloc (.....);

....

}

如何打算学习ActiveX开发的话,这本书一定要看《Visual C++ 5 Active X编程指南》,学习COM一定要看《Inside COM,COM原理与应用》;还可参雨考我在CSDN的文档中心上发表的《COM错误处理》,嘿嘿~~,初学者看之有大补呀!,^_^.....

 

你可能感兴趣的:(技术文章)