【问题标题】:How to track focus changes between several TrackBars using WTL?如何使用 WTL 跟踪多个 TrackBar 之间的焦点变化?
【发布时间】:2012-02-04 16:14:25
【问题描述】:

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

到目前为止,我已经尝试过 MESSAGE_HANDLER(WM_SETFOCUS,函数) 以及一个 COMMAND_HANDLER(IDC_SLIDERn,WM_SETFOCUS,函数) 每个滑块都没有成功。

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

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

这可行,但有更优雅的方法吗?

【问题讨论】:

    标签: winapi focus atl wtl trackbar


    【解决方案1】:

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

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

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

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

    ...这听起来像您正在寻找的东西。显然 ATL 使用 NOTIFY_HANDLER 在消息映射中支持这些,类似于:

    NOTIFY_HANDLER(IDC_SLIDERn, NM_SETFOCUS, func)
    

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

    【讨论】:

      【解决方案2】:

      您不需要派生类,使用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(...) { }
      

      【讨论】:

        猜你喜欢
        • 2019-12-21
        • 2019-01-17
        • 2021-07-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-20
        • 1970-01-01
        相关资源
        最近更新 更多