如果未立即激活控件,你可能仍希望它处理WM_SETCURSOR和WM_MOUSEMOVE消息,即使该控件没有自己的窗口。 这可以通过启用 COleControl
默认禁用的接口的实现 IPointerInactive
来实现。 (有关此接口的说明,请参阅 ActiveX SDK 。若要启用它,请在 COleControl::GetControlFlags 返回的标志集中包括指针非活动标志:
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消息委托给它。
COleControl
在适当调整鼠标坐标后,通过控件的消息映射调度消息的实现 IPointerInactive
。 通过将相应的条目添加到消息映射,可以像普通窗口消息一样处理这些消息。 在这些消息的处理程序中,避免使用 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;