本文介绍与开发 ActiveX 控件相关的高级主题。 这些包括:
重要
ActiveX 是一项不推荐用于新开发的旧技术。 有关取代 ActiveX 的新式技术的详细信息,请参阅 ActiveX 控件。
在 ActiveX 控件中使用数据库类
由于 ActiveX 控件类是类库的一部分,因此可以应用相同的过程和规则,以便在标准 MFC 应用程序中使用数据库类来开发使用 MFC 数据库类的 ActiveX 控件。
有关 MFC 数据库类的一般概述,请参阅 MFC 数据库类(DAO 和 ODBC)。 本文介绍了 MFC ODBC 类和 MFC DAO 类,并指导你详细了解这两个类。
注释
DAO 通过 Office 2013 获得支持。 DAO 3.6 是最终版本,它被视为已过时。 Visual C++ 环境和向导不支持 DAO(尽管包含 DAO 类,但仍可使用它们)。 Microsoft建议对新项目使用 OLE DB 模板 或 ODBC 和 MFC 。 应仅在维护现有应用程序时使用 DAO。
实现参数化属性
参数化属性(有时称为属性数组)是一种将值的同质集合公开为控件的单个属性的方法。 例如,可以使用参数化属性将数组或字典公开为属性。 在 Visual Basic 中,使用数组表示法访问此类属性:
x = o.Array(2, 3) ' gets element of 2D array
o.Array(2, 3) = 7 ' sets element of 2D array
使用“添加属性向导”实现参数化属性。 添加属性向导通过添加一对 Get/Set 函数来实现该属性,这些函数允许控件用户使用上述表示法或标准方式访问该属性。
与方法和属性类似,参数化属性还限制允许的参数数。 对于参数化属性,限制为 15 个参数(保留一个用于存储属性值的参数)。
以下过程添加一个名为 Array 的参数化属性,该属性可作为整数的二维数组进行访问。
使用“添加属性向导”添加参数化属性
加载控件的项目。
在类视图中,展开控件的库节点。
右键单击控件(库节点的第二个节点)的接口节点以打开快捷菜单。
在快捷菜单中,单击“ 添加 ”,然后单击“ 添加属性”。
在 “属性名称 ”框中,键入
Array
。在 “属性类型” 框中,选择
short
。对于 实现 类型,请单击 “获取/设置方法”。
在 “获取函数 ”和 “设置函数” 框中,键入 Get 和 Set Functions 的唯一名称或接受默认名称。
使用参数名称和参数类型控件添加名为 row(类型 short)的参数。
添加名为 column ( 类型 short)的第二个参数。
单击“完成”。
添加属性向导所做的更改
添加自定义属性时,“添加属性向导”会更改控件类标头(。H) 和实现 (.CPP) 文件。
以下行将添加到控件类。H 文件:
SHORT GetArray(SHORT row, SHORT column);
void SetArray(SHORT row, SHORT column, SHORT newVal);
此代码声明两个调用 GetArray
的函数, SetArray
允许用户在访问属性时请求特定的行和列。
此外,“添加属性向导”将以下行添加到控件调度映射(位于控件类实现中)。CPP) 文件:
DISP_PROPERTY_PARAM_ID(CMyAxUICtrl, "Array", dispidArray, GetArray, SetArray, VT_I2, VTS_I2 VTS_I2)
最后,将函数的GetArray
SetArray
实现添加到末尾。CPP 文件。 在大多数情况下,将修改 Get 函数以返回属性的值。 Set 函数通常包含应在属性更改之前或之后执行的代码。
若要使此属性很有用,可以在类型控件 short
类中声明二维数组成员变量,以存储参数化属性的值。 然后,可以修改 Get 函数以返回存储在正确行和列的值,如参数指示,并修改 Set 函数以更新行和列参数引用的值。
处理 ActiveX 控件中的错误
如果控件中出现错误条件,可能需要将错误报告给控件容器。 报告错误有两种方法,具体取决于发生错误的情况。 如果错误发生在属性的 Get 或 Set 函数中,或者在 OLE 自动化方法的实现中发生,控件应调用 COleControl::ThrowError,该作会向控件用户发出错误信号。 如果错误发生在任何其他时间,该控件应调用 COleControl::FireError,这会触发库存错误事件。
若要指示发生的错误类型,控件必须向或传递FireError
错误代码ThrowError
。 错误代码是具有 32 位值的 OLE 状态代码。 如果可能,请从 OLECTL 中定义的标准代码集中选择错误代码。H 头文件。 下表汇总了这些代码。
ActiveX 控件错误代码
错误 | DESCRIPTION |
---|---|
CTL_E_ILLEGALFUNCTIONCALL | 非法函数调用 |
CTL_E_OVERFLOW | 溢出 |
CTL_E_OUTOFMEMORY | 内存不足 |
CTL_E_DIVISIONBYZERO | 被零除 |
CTL_E_OUTOFSTRINGSPACE | 字符串空间不足 |
CTL_E_OUTOFSTACKSPACE | 堆栈空间不足 |
CTL_E_BADFILENAMEORNUMBER | 文件名或数字错误 |
CTL_E_FILENOTFOUND | 找不到文件 |
CTL_E_BADFILEMODE | 文件模式错误 |
CTL_E_FILEALREADYOPEN | 文件已打开 |
CTL_E_DEVICEIOERROR | 设备 I/O 错误 |
CTL_E_FILEALREADYEXISTS | 文件已存在 |
CTL_E_BADRECORDLENGTH | 错误的记录长度 |
CTL_E_DISKFULL | 磁盘已满 |
CTL_E_BADRECORDNUMBER | 错误的记录编号 |
CTL_E_BADFILENAME | 文件名错误 |
CTL_E_TOOMANYFILES | 文件过多 |
CTL_E_DEVICEUNAVAILABLE | 设备不可用 |
CTL_E_PERMISSIONDENIED | 权限被拒绝 |
CTL_E_DISKNOTREADY | 磁盘未就绪 |
CTL_E_PATHFILEACCESSERROR | 路径/文件访问错误 |
CTL_E_PATHNOTFOUND | 找不到路径 |
CTL_E_INVALIDPATTERNSTRING | 无效的模式字符串 |
CTL_E_INVALIDUSEOFNULL | NULL 的使用无效 |
CTL_E_INVALIDFILEFORMAT | 文件格式无效 |
CTL_E_INVALIDPROPERTYVALUE | 属性值无效 |
CTL_E_INVALIDPROPERTYARRAYINDEX | 属性数组索引无效 |
CTL_E_SETNOTSUPPORTEDATRUNTIME | 运行时不支持设置。 |
CTL_E_SETNOTSUPPORTED | 不支持 Set 语句(只读属性) |
CTL_E_NEEDPROPERTYARRAYINDEX | 需要属性数组索引 |
CTL_E_SETNOTPERMITTED | 不允许进行设置 |
CTL_E_GETNOTSUPPORTEDATRUNTIME | 运行时不支持 Get 语句 |
CTL_E_GETNOTSUPPORTED | 不支持 Get(只写属性) |
CTL_E_PROPERTYNOTFOUND | 找不到属性 |
CTL_E_INVALIDCLIPBOARDFORMAT | 剪贴板格式无效 |
CTL_E_INVALIDPICTURE | 图片无效 |
CTL_E_PRINTERERROR | 打印机错误 |
CTL_E_CANTSAVEFILETOTEMP | 无法将文件保存到 TEMP |
CTL_E_SEARCHTEXTNOTFOUND | 找不到搜索文本 |
CTL_E_REPLACEMENTSTOOLONG | 替换内容太长 |
如有必要,请使用 CUSTOM_CTL_SCODE 宏为某个标准代码未涵盖的条件定义自定义错误代码。 此宏的参数应为介于 1000 和 32767 之间的整数(包括 32767)。 例如:
#define MYCTL_E_SPECIALERROR CUSTOM_CTL_SCODE(1000)
如果要创建 ActiveX 控件来替换现有的 VBX 控件,请使用 VBX 控件用来确保错误代码兼容的相同数值定义 ActiveX 控件错误代码。
处理控件中的特殊键
在某些情况下,你可能希望以特殊方式处理某些击键组合;例如,在多行文本框控件中按下 ENTER 键时插入新行,或者在按下方向键 ID 时在一组编辑控件之间移动。
如果 ActiveX 控件的基类是 COleControl
,则可以重写 CWnd::P reTranslateMessage 来处理消息,然后容器处理它们。 使用此方法时,如果处理替代PreTranslateMessage
中的消息,请始终返回 TRUE。
下面的代码示例演示了处理与方向键相关的任何消息的可能方法。
BOOL CMyAxUICtrl::PreTranslateMessage(MSG* pMsg)
{
BOOL bHandleNow = FALSE;
switch (pMsg->message)
{
case WM_KEYDOWN:
switch (pMsg->wParam)
{
case VK_UP:
case VK_DOWN:
case VK_LEFT:
case VK_RIGHT:
bHandleNow = TRUE;
break;
}
if (bHandleNow)
{
OnKeyDown((UINT)pMsg->wParam, LOWORD(pMsg->lParam), HIWORD(pMsg->lParam));
}
break;
}
return bHandleNow;
}
有关处理 ActiveX 控件的键盘接口的详细信息,请参阅 ActiveX SDK 文档。
访问运行时不可见的对话控件
可以创建没有用户界面且在运行时不可见的对话框控件。 如果在运行时 ActiveX 控件中添加一个不可见控件,并使用 CWnd::GetDlgItem 访问控件,该控件将无法正常工作。 相反,应使用以下方法之一来获取表示控件的对象:
使用“添加成员变量向导”,选择 “控件变量 ”,然后选择控件的 ID。 输入成员变量名称,并选择控件的包装类作为 控件类型。
-或-
将局部变量和子类声明为对话框项。 插入类似于以下内容的代码(
CMyCtrl
是包装类,IDC_MYCTRL1是控件的 ID):CCirc myCirc; myCirc.SubclassDlgItem(IDC_CIRCCTRL2, this); // ... use myCirc ... myCirc.UnsubclassWindow();