应用程序控制
OLE 需要对应用程序及其对象进行广量的控制。 OLE 系统 DLL 必须能够自动启动和发布应用程序,协调其对象生成和修改,等等。 本主题中的函数可以满足这些要求。 除了由 OLE 系统 DLL 调用之外,这些函数有时也必须由应用程序调用。
应用程序控制
名称 | 描述 |
---|---|
AfxOleCanExitApp | 指示应用程序是否可以终止。 |
AfxOleGetMessageFilter | 检索应用程序的当前消息筛选器。 |
AfxOleGetUserCtrl | 检索当前用户控件标志。 |
AfxOleSetUserCtrl | 设置或清除用户控制标志。 |
AfxOleLockApp | 递增应用程序中活动对象数的框架全局计数。 |
AfxOleLockControl | 锁定指定控件的类工厂。 |
AfxOleUnlockApp | 递减应用程序中活动对象数的框架计数。 |
AfxOleUnlockControl | 解锁指定控件的类工厂。 |
AfxOleRegisterServerClass | 在 OLE 系统注册表中注册服务器。 |
AfxOleSetEditMenu | 实现 typename 对象命令的用户界面。 |
AfxOleCanExitApp
指示应用程序是否可以终止。
BOOL AFXAPI AfxOleCanExitApp();
返回值
如果应用程序退出,则为非零;否则为 0。
备注
如果存在对应用程序的对象的未处理引用,则应用程序不应终止。 全局函数 AfxOleLockApp
和 AfxOleUnlockApp
分别对应用程序对象引用计数器进行递增和递减。 当此计数器为非零时,应用程序不应终止。 如果计数器为非零,当用户从系统菜单选择“关闭”或从“文件”菜单选择“退出”时,应用程序的主窗口将会隐藏(不销毁)。 框架在 CFrameWnd::OnClose
中调用此函数。
示例
// Helper exit function for automation server
BOOL CMainFrame::CanExit()
{
if (AfxOleCanExitApp())
{
// No outstanding object counts - go ahead and exit
return TRUE;
}
else
{
// There are outstanding OLE object counts...
// hide app to give user impression that application has exited.
ShowWindow(SW_HIDE);
// take user out of control of the app
AfxOleSetUserCtrl(FALSE);
return FALSE;
}
}
要求
标头:afxdisp.h
AfxOleGetMessageFilter
检索应用程序的当前消息筛选器。
COleMessageFilter* AFXAPI AfxOleGetMessageFilter();
返回值
指向当前消息筛选器的指针。
注解
调用此函数可访问当前 COleMessageFilter
派生的对象,这与调用 AfxGetApp
来访问当前应用程序对象一样。
示例
COleMessageFilter *pFilter = AfxOleGetMessageFilter();
ASSERT_VALID(pFilter);
pFilter->BeginBusyState();
// do things requiring a busy state
pFilter->EndBusyState();
// Another example
//CWinApp-derived class
BOOL CCMFCAutomationApp::InitInstance()
{
CWinApp::InitInstance();
// Initialize OLE libraries
if (!AfxOleInit())
{
AfxMessageBox(IDP_OLE_INIT_FAILED);
return FALSE;
}
CWinThread *pThread = AfxGetThread();
if (pThread != NULL)
{
// Destroy message filter, thereby unregistering it.
delete pThread->m_pMessageFilter;
pThread->m_pMessageFilter = NULL;
// Create the new message filter object.
//CMyMessageFilter is derived from COleMessageFilter
pThread->m_pMessageFilter = new CMyMessageFilter;
ASSERT(AfxOleGetMessageFilter() != NULL);
// Register the new message filter object.
AfxOleGetMessageFilter()->Register();
}
//...
//...
//...
}
要求
标头:afxwin.h
AfxOleGetUserCtrl
检索当前用户控件标志。
BOOL AFXAPI AfxOleGetUserCtrl();
返回值
如果用户位于应用程序控件内,则不为零;否则为 0。
备注
如果用户已显式打开或创建新文档,则用户将位于应用程序控件内。 如果应用程序不是由 OLE 系统 DLL 启动的 - 换句话说,如果用户使用系统 Shell 启动了应用程序,则用户也将位于控件内。
要求
标头:afxdisp.h
AfxOleSetUserCtrl
设置或清除 AfxOleGetUserCtrl
参考中所说明的用户控制标志。
void AFXAPI AfxOleSetUserCtrl(BOOL bUserCtrl);
参数
bUserCtrl
指定是要设置还是清除用户控制标志。
备注
当用户创建或加载文档时,框架会调用此函数,但在通过间接操作(例如从容器应用程序中加载嵌入对象)加载或创建文档时,框架不会调用此函数。
如果应用程序中的其他操作应让用户控制应用程序,则调用此函数。
要求
标头:afxdisp.h
AfxOleLockApp
递增应用程序中活动对象数的框架全局计数。
void AFXAPI AfxOleLockApp();
备注
框架会保留应用程序中活动对象的计数。 AfxOleLockApp
和 AfxOleUnlockApp
函数分别递增和递减此计数。
当用户尝试关闭具有活动对象的应用程序(活动对象计数不为零的应用程序)时,框架会在用户的视图中隐藏应用程序,而不是完全关闭它。 AfxOleCanExitApp
函数指示应用程序是否可终止。
如果当客户端应用程序仍在使用任何公开 OLE 接口的对象时不应销毁该对象,则从该对象调用 AfxOleLockApp
。 另外,在调用构造函数中的 AfxOleLockApp
的任何对象的析构函数中调用 AfxOleUnlockApp
。 默认情况下,COleDocument
(和派生类)会自动锁定和解锁应用程序。
示例
// Below is a code sample from an Application Wizard-generated SDI
// Application with Automation support. The Application Wizard adds a
// dispatch interface to the document class. AfxOleLockApp() and
// AfxOleUnlockApp() respectively increment and decrement the
// application's object count. When the object count is equal to
// zero and if the user has not taken control of the application,
// the server is terminated.
CCMFCAutomationDoc::CCMFCAutomationDoc()
{
EnableAutomation();
AfxOleLockApp();
}
CCMFCAutomationDoc::~CCMFCAutomationDoc()
{
AfxOleUnlockApp();
}
要求
标头:afxdisp.h
AfxOleUnlockApp
递减应用程序中活动对象的框架计数。
void AFXAPI AfxOleUnlockApp();
备注
有关更多信息,请参阅 AfxOleLockApp
。
当活动对象数达到零时,将调用 AfxOleOnReleaseAllObjects
。
示例
请参阅 AfxOleLockApp 的示例。
要求
标头:afxdisp.h
AfxOleLockControl
锁定指定控件的类工厂,以便与此控件关联的动态创建的数据保留在内存中。
语法
BOOL AFXAPI AfxOleLockControl( REFCLSID clsid );
BOOL AFXAPI AfxOleLockControl( LPCTSTR lpszProgID );
参数
clsid
控件的唯一类 ID。
lpszProgID
控件的唯一程序 ID。
返回值
如果控件的类工厂成功锁定,则不为零;否则为 0。
注解
这可以明显加速控件的显示。 例如,一旦在对话框中创建控件并使用 AfxOleLockControl
锁定控件,则无需在每次显示或销毁对话框时创建和删除它。 如果用户反复打开并关闭对话框,则锁定控件可以显著提高性能。 准备销毁控件时,请调用 AfxOleUnlockControl
。
示例
// Starts and locks control's (Microsoft Calendar) class factory.
// Control will remain in memory for lifetime of
// application or until AfxOleUnlockControl() is called.
AfxOleLockControl(_T("MSCAL.Calendar"));
要求
标头:afxwin.h
AfxOleRegisterServerClass
使用此函数可在 OLE 系统注册表中注册服务器。
BOOL AFXAPI AfxOleRegisterServerClass(
REFCLSID clsid,
LPCTSTR lpszClassName,
LPCTSTR lpszShortTypeName,
LPCTSTR lpszLongTypeName,
OLE_APPTYPE nAppType = OAT_SERVER,
LPCTSTR* rglpszRegister = NULL,
LPCTSTR* rglpszOverwrite = NULL);
参数
clsid
对服务器的 OLE 类 ID 的引用。
lpszClassName
指向字符串的指针,该字符串包含服务器对象的类名。
lpszShortTypeName
指向字符串的指针,该字符串包含服务器对象类型的短名称,例如“Chart”。
lpszLongTypeName
指向字符串的指针,该字符串包含服务器对象类型的长名称,例如“Microsoft Excel 5.0 Chart”。
nAppType
取自 OLE_APPTYPE 枚举的值,用于指定 OLE 应用程序的类型。 可能的值如下:
OAT_INPLACE_SERVER:服务器具有完整的服务器用户界面。
OAT_SERVER:服务器仅支持嵌入。
OAT_CONTAINER:容器支持嵌入的链接。
OAT_DISPATCH_OBJECT:支持
IDispatch
的对象。
rglpszRegister
如果未找到项的现有值,则为指向表示要添加到 OLE 系统注册表的项和值的字符串的指针数组。
rglpszOverwrite
如果注册表包含给定项的现有值,则为指向表示要添加到 OLE 系统注册表的项和值的字符串的指针数组。
返回值
如果已成功注册服务器类,则返回非零值;否则返回 0。
备注
大多数应用程序可以使用 COleTemplateServer::Register
来注册应用程序的文档类型。 如果应用程序的系统注册表格式不适合典型模式,你可以使用 AfxOleRegisterServerClass
进行更多控制。
注册表由一组项和值组成。 rglpszRegister 和 rglpszOverwrite 参数是指向字符串的指针的数组,每个字符串由 NULL 字符 ('\0'
) 分隔的项和值组成。 其中每个字符串可以包含可替换的参数,这些参数的位置由字符序列 %1 到 %5 标记。
符号的填写方式如下:
符号 | 值 |
---|---|
1% | 类 ID,采用字符串格式 |
2% | 类名 |
%3 | 可执行文件的路径 |
4% | 短类型名称 |
%5 | 长类型名称 |
要求
标头:afxdisp.h
AfxOleSetEditMenu
实现 typename 对象命令的用户界面。
void AFXAPI AfxOleSetEditMenu(
COleClientItem* pClient,
CMenu* pMenu,
UINT iMenuItem,
UINT nIDVerbMin,
UINT nIDVerbMax = 0,
UINT nIDConvert = 0);
参数
pClient
指向客户端 OLE 项的指针。
pMenu
指向要更新的菜单对象的指针。
iMenuItem
要更新的菜单项的索引。
nIDVerbMin
对应于主要谓词的命令 ID。
nIDVerbMax
对应于最后一个谓词的命令 ID。
nIDConvert
“转换”菜单项的 ID。
备注
如果服务器仅识别一个主要谓词,则菜单项变为“谓词 typename 对象”,并在用户选择命令时发送 nIDVerbMin 命令。 如果服务器识别多个谓词,则菜单项变为“typename 对象”,并在用户选择命令时显示一个列出所有谓词的子菜单。 当用户从子菜单中选择谓词时,如果选择的是第一个谓词,则发送 nIDVerbMin,如果选择的是第二个谓词,则发送 nIDVerbMin + 1,依此类推。 默认的 COleDocument
实现会自动处理此功能。
必须在客户端的应用程序资源脚本 (.RC) 文件中包含以下语句:
#include <afxolecl.rc>
要求
标头:afxole.h
AfxOleUnlockControl
解锁指定控件的类工厂。
语法
BOOL AFXAPI AfxOleUnlockControl( REFCLSID clsid );
BOOL AFXAPI AfxOleUnlockControl( LPCTSTR lpszProgID );
参数
clsid
控件的唯一类 ID。
lpszProgID
控件的唯一程序 ID。
返回值
如果已成功解锁控件的类工厂,则返回非零值;否则返回 0。
备注
使用 AfxOleLockControl
锁定控件,因此动态创建的与控件关联的数据将保留在内存中。 这可以大幅加快控件的显示速度,因为不需要在每次显示控件时都创建和销毁控件。 准备销毁控件时,请调用 AfxOleUnlockControl
。
示例
// Unlock control's (Microsoft Calendar Control) class factory.
AfxOleUnlockControl(_T("MSCAL.Calendar"));
要求
标头:afxwin.h