不活动时提供鼠标交互

如果未立即激活控件,你可能仍希望它处理 WM_SETCURSOR 和 WM_MOUSEMOVE 消息,即使该控件没有自己的窗口。 这可以通过启用 IPointerInactive 接口(默认禁用)的 COleControl 的实现来完成。 (请参阅 ActiveX SDK,了解此接口的说明。)若要启用该接口,请在 COleControl::GetControlFlags 返回的标志集中包括 pointerInactive 标志:

DWORD CMyAxOptCtrl::GetControlFlags()
{
   DWORD dwFlags = COleControl::GetControlFlags();
// The control can receive mouse notifications when inactive.
dwFlags |= pointerInactive;
return dwFlags;
}

如果在使用 MFC ActiveX 控件向导创建控件时,选择了控件设置页上的“不活动时的鼠标指针通知”选项,则会自动生成用于包含此标志的代码。

启用 IPointerInactive 接口后,容器会将 WM_SETCURSOR 和 WM_MOUSEMOVE 消息委托给它。 在相应地调整鼠标坐标后,COleControlIPointerInactive 的实现将会在控件的消息映射中调度消息。 可以通过将对应的项添加到消息映射来处理普通窗口消息之类的消息。 在这些消息的处理程序中,应避免在使用 m_hWnd 成员变量(或使用它的任何成员函数)时不首先检查它的值是否不是 NULL。

你还可能希望非活动控件是 OLE 拖放操作的目标。 这需要在用户将对象拖动到控件上方时激活控件,以便可以将控件的窗口注册为放置目标。 若要在拖动过程中引发激活,请重写 COleControl::GetActivationPolicy,并返回 POINTERINACTIVE_ACTIVATEONDRAG 标志:

DWORD CMyAxOptCtrl::GetActivationPolicy()
{
   return POINTERINACTIVE_ACTIVATEONDRAG;
}

启用 IPointerInactive 接口通常意味着你希望控件能够随时处理鼠标消息。 若要在不支持 IPointerInactive 接口的容器中获取此行为,需要在可见时始终激活控件,这意味着控件应在其杂项标志中包含 OLEMISC_ACTIVATEWHENVISIBLE 标志。 但是,若要防止此标志在支持 IPointerInactive 的容器中生效,还可以指定 OLEMISC_IGNOREACTIVATEWHENVISIBLE 标志:

static const DWORD BASED_CODE _dwMyOleMisc =
OLEMISC_ACTIVATEWHENVISIBLE |
OLEMISC_IGNOREACTIVATEWHENVISIBLE |
OLEMISC_SETCLIENTSITEFIRST |
OLEMISC_INSIDEOUT |
OLEMISC_CANTLINKINSIDE |
OLEMISC_RECOMPOSEONRESIZE;

另请参阅

MFC ActiveX 控件:优化