Как отслеживать изменения фокуса между несколькими трекбарами с помощью WTL? - PullRequest
0 голосов
/ 04 февраля 2012

Я пытаюсь отслеживать изменения фокуса между несколькими трекбарами (так называемые ползунки, все в одном и том же окне), используя WTL.

До сих пор я пробовал MESSAGE_HANDLER (WM_SETFOCUS, func), а также одинCOMMAND_HANDLER (IDC_SLIDERn, WM_SETFOCUS, func) для каждого ползунка без успеха.

Страница управления трекбаром в msdn гласит: «WM_SETFOCUS перерисовывает окно трекбар»...

edit: теперь я получил ползунки из своего собственного класса, где я обрабатываю WM_SETFOCUS с помощью MESSAGE_HANDLER и уведомляю родительское окно, отправляя ему сообщение с m_hWnd как lParam, чтобы я мог проверить в родительском, какой слайдерПолучил фокус.

Это работает, но есть ли более элегантный способ сделать это?

Ответы [ 2 ]

0 голосов
/ 05 февраля 2012

WM_SETFOCUS отправляется в конкретное окно, которое получает фокус, а не к родителю, как вы обнаружили.

Однако есть альтернативный метод, который вы можете использовать, чтобы избежать создания подклассов; большинство элементов управления (в частности, «общие элементы управления», включающие ползунки) отправляют WM_NOTIFY своему родителю при возникновении определенных событий, что позволяет родителю обрабатывать эти события для коллекции дочерних элементов.

В вашем случае попробуйте прослушать сообщение WM_NOTIFY в родительском окне, в частности, проверить случай, когда идентификатор уведомления равен NM_SETFOCUS - из MSDN:

Уведомляет родительское окно элемента управления о том, что элемент управления получил фокус ввода. Этот код уведомления отправляется в виде сообщения WM_NOTIFY.

... звучит как то, что вы ищете. Очевидно, ATL поддерживает их в карте сообщений, используя NOTIFY_HANDLER , что-то вроде:

NOTIFY_HANDLER(IDC_SLIDERn, NM_SETFOCUS, func)

Обратите внимание, что это работает, потому что Win32 Common Controls поддерживает такой вид пересылки уведомлений; если бы вы использовали вместо этого какой-то другой пользовательский элемент управления, вы можете не получать эти уведомления и должны были бы прибегнуть к созданию подклассов. Но для общего контроля это самый простой способ сделать это.

0 голосов
/ 05 февраля 2012

Вам не нужно выводить свой класс, подклассы с 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(...) { }
...