0

我正在尝试使用 WTL 跟踪几个 TrackBars(又名滑块,都在同一个窗口内)之间的焦点变化。

到目前为止,我已经为每个滑块尝试了一个 MESSAGE_HANDLER(WM_SETFOCUS, func) 和一个 COMMAND_HANDLER(IDC_SLIDERn, WM_SETFOCUS, func) ,但没有成功。

msdn 上的 about trackbar controls 页面显示:“WM_SETFOCUS 重新绘制 trackbar 窗口。” ..

编辑:我现在已经从我自己的类中派生了滑块,在该类中我使用 MESSAGE_HANDLER 处理 WM_SETFOCUS 并通过将消息发布到父窗口并将 m_hWnd 作为 lParam 来通知父窗口,这样我就可以在父窗口中检查哪个滑块获得了焦点。

这行得通,但是有没有更优雅的方法来做到这一点?

4

2 回答 2

0

你不需要派生你的类,子类化CContainedWindowT就可以了。

BEGIN_MSG_MAP_EX(CDialog)
// ...
ALT_MSG_MAP(IDC_TRACKBAR)
    MSG_WM_SETFOCUS(OnControlSetFocus)
    MSG_WM_KILLFOCUS(OnControlKillFocus)
END_MSG_MAP()
// ...
CContainedWindowT<CTrackBarCtrl> m_TrackBar;
// ...
CDialog() :
    m_TitleListView(this, IDC_TRACKBAR)
// ...
LRESULT OnInitDialog(HWND, LPARAM)
{
    // ...
    ATLVERIFY(m_TrackBar.SubclassWindow(GetDlgItem(IDC_TRACKBAR)));
    // ...
// ...  
LRESULT OnControlSetFocus(...) { }
LRESULT OnControlKillFocus(...) { }
于 2012-02-04T21:45:58.447 回答
0

WM_SETFOCUS 被发送到获得焦点的特定窗口,而不是您发现的父窗口。

但是,您可以使用另一种技术来避免子类化;大多数控件(特别是“通用控件”,包括滑块)会在某些事件发生时向其父级发送 WM_NOTIFY,从而允许父级为一组子级处理这些事件。

在您的情况下,尝试在父窗口中侦听 WM_NOTIFY 消息,特别检查通知 ID 为NM_SETFOCUS的情况- 来自 MSDN:

通知控件的父窗口该控件已收到输入焦点。此通知代码以 WM_NOTIFY 消息的形式发送。

...这听起来像你在找什么。显然,ATL 使用NOTIFY_HANDLER在消息映射中支持这些,例如:

NOTIFY_HANDLER(IDC_SLIDERn, NM_SETFOCUS, func)

请注意,这是因为 Win32 通用控件支持这种通知转发。如果您要使用其他一些自定义控件,则可能不会收到这些通知,并且必须求助于子类化。但是对于普通控件,这是最简单的方法。

于 2012-02-04T21:59:42.663 回答