#17 ATL里设置默认属性、默认方法?
对于属性只要在.IDL文件中将其ID设为0就行了。如:
[propget, id(0), helpstring("property test")] HRESULT test([out, retval] short *pVal);
同理对于方法也生效。
#18 如何使某个参数可选择? HRESULT MyFunc([in]BSTR szName,[in, optional] VARIANT Param1, [out, optional] VARIANT Param2)
你在MyFunc程序中得检查Param1.vt是否为VT_EMPTY,如果是,用户未使用该参数。
#19 如何使用枚举类型?在你的IDL文件中加入如下相似的代码:
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中的一个值。
#20 OLE_COLOR与COLORREF的有区别吗?
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的情况。你试一下就知道是怎么回事了,详细请参看:MSDN/Platform SDK/Component Services/COM/Controls and Property Pages/Functions/OleTranslateColor的Remarks。
OLE_COLOR与COLORREF的转达换处理:在MFC中可有OLEControl::TranslateColor()来转达换,在ATL或其它地方可调用API:OleTranslateColor()来进行从OLE_COLOR到COLORREF的转换。返过来可用如下方法:OLE_COLOR ocConverted = (OLE_COLOR)clrBack;
同样,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。
#21 如何让我的控件输出数组?
参阅如下代码:
void CMyControl::GetArray( VARIANT FAR* pVariant )
{
//商业代码
int nCount = GetCount();
//定义维数
SAFEARRAYBOUND saBound[1];
//定义数组指针对性
SAFEARRAY* pSA;
saBound[0].cElements = nCount;
saBound[0].lLbound = 0;
//创建数组
pSA = SafeArrayCreate( VT_BSTR, 1, saBound );
for( long i = 0; i < nCount; i++ )
{
BSTR bstr;
//商业代码
bstr = GetItem( i ).AllocSysString();
//给数组赋值
SafeArrayPutElement( pSA, &i, bstr );
::SysFreeString( bstr );
}
// 初始化传递的参数
VariantInit( pVariant );
//设置返值的类型为数组
pVariant->vt = VT_ARRAY | VT_BSTR;
pVariant->parray = pSA;
}
Visual Basic 代码:
Dim t As Variant
Dim i as Integer
MyControl1.GetArray t
For i = 0 To MyControl1.Count - 1
ListBox.AddItem t( i )
Next i