0

WTL を使用して、複数のトラックバー (別名、すべて同じウィンドウ内のスライダー) 間のフォーカスの変化を追跡しようとしています。

これまでのところ、スライダーごとに MESSAGE_HANDLER(WM_SETFOCUS, func) と 1 つの COMMAND_HANDLER(IDC_SLIDERn, WM_SETFOCUS, func) を試しましたが、成功しませんでした。

msdn のトラックバー コントロールについてのページには、「WM_SETFOCUS はトラックバー ウィンドウを再描画します」と書かれています。..

編集: MESSAGE_HANDLER で WM_SETFOCUS を処理する独自のクラスからスライダーを派生させ、m_hWnd を lParam としてメッセージを投稿して親ウィンドウに通知することで、どのスライダーがフォーカスを得たかを親で確認できるようになりました。

これは機能しますが、これを行うためのよりエレガントな方法はありますか?

4

2 に答える 2

0

あなたが発見したように、WM_SETFOCUSは親ではなく、フォーカスを取得する特定のウィンドウに送信されます。

ただし、サブクラス化を回避するために使用できる代替手法があります。ほとんどのコントロール (具体的には、スライダーを含む「共通コントロール」) は、特定のイベントが発生したときに親に WM_NOTIFY を送信し、親が子のコレクションに対してこれらのイベントを処理できるようにします。

あなたの場合、親ウィンドウで WM_NOTIFY メッセージをリッスンしてみてください。具体的には、通知 ID がNM_SETFOCUSの場合を確認してください- MSDN から:

コントロールが入力フォーカスを受け取ったことをコントロールの親ウィンドウに通知します。この通知コードは、WM_NOTIFY メッセージの形式で送信されます。

...探しているもののように聞こえます。どうやら ATL は、次のようなNOTIFY_HANDLERを使用してメッセージ マップでこれらをサポートしているようです。

NOTIFY_HANDLER(IDC_SLIDERn, NM_SETFOCUS, func)

Win32 Common Controls がこの種の通知転送をサポートしているため、これが機能することに注意してください。代わりに他のカスタム コントロールを使用すると、これらの通知を受け取ることができず、サブクラス化に頼る必要があります。しかし、一般的なコントロールの場合、これが最も簡単な方法です。

于 2012-02-04T21:59:42.663 に答える
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 に答える