CTreeCtrlで選択でフォーカスが外れた時も、選択している状態を残したい

[戻る]
takeno 2005/05/25(水) 19:37:49
VC++6.0 MFC WinXP sp2

初心者です。
CTreeCtrlを利用したツリーを選択するダイアログを作成しています。
そのダイアログにはコンボボックスも作成しています。
Treeを選択している時は、青色で選択している事がすぐわかるのですが、
コンボボックスにマウスを移したときに、
Treeには選択しているという青色が表示されません。

青色をずっと残しておくにはどうすればよいですか。

シャノン 2005/05/25(水) 20:04:01
TVS_SHOWSELALWAYS について調べてみてください。

takeno 2005/05/25(水) 20:52:58
シャノン様
下記の様に設定致しました。
しかし、表示は変化ありません。

何がおかしいのでしょうか?

CTreeCtrl& m_Tree = GetTreeCtrl();
m_Tree.ModifyStyle(NULL,TVS_HASLINES | TVS_SHOWSELALWAYS);

Blue 2005/05/26(木) 02:01:29
TVS_SHOWSELALWAYSを指定
(Tree Control のプロパティのスタイルで"選択を常に表示")しても、
>青色をずっと残しておくにはどうすればよいですか。
とならず、グレーになってしまいます。

その色を変える(グレー→選択状態の色)のがわからなかったので、
ツリーコントロールのNM_KILLFOCUSを使って、以下のようにしてみたら
うまくいきました。

ちなみにツリーコントロールのIDは IDC_TREE1 です。

void CTreeDlg::OnKillfocusTree1(NMHDR* pNMHDR, LRESULT* pResult) 
{
    // TODO: この位置にコントロール通知ハンドラ用のコードを追加してください
    // ツリーコントロールを取得
    CTreeCtrl* pTree = ( CTreeCtrl* )this->GetDlgItem( IDC_TREE1 );
    // 描画用のデバイス コンテキスト
    CClientDC  dc( pTree );

    // ツリーコントロールのフォントを設定
    CFont* pOldFont = dc.SelectObject( pTree->GetFont() );

    // 選択中のアイテムのハンドルを取得
    HTREEITEM  hItem = pTree->GetSelectedItem();

    // アイテムのテキストを取得
    CString strText  = pTree->GetItemText( hItem );
    // アイテムの外接四角形を取得
    CRect rect;
    pTree->GetItemRect( hItem, &rect, TRUE );

    // 背景色と文字色を設定
    dc.SetBkColor( ::GetSysColor( COLOR_HIGHLIGHT ) );
    dc.SetTextColor( ::GetSysColor( COLOR_HIGHLIGHTTEXT ) );

    // テキストを描写
    dc.TextOut( rect.left + 2, rect.top + 1, strText );

    // フォントを元に戻す
    dc.SelectObject( pOldFont );

    *pResult = 0;
}

環境 WinXp Pro SP2, VC++6.0 Stand SP6
参考サイト
http://www.alpha-net.ne.jp/users2/uk413/vc/VCT_TVcolor.html

なんかもっと楽ちんな方法がありそう。

Blue 2005/05/26(木) 02:11:43
あれ?よくみたらダイアログじゃない?
>CTreeCtrl& m_Tree = GetTreeCtrl();
GetTreeCtrlで戻り値がCTreeCtrl&ってことはCTreeViewでしょうか?

どっちにしろ処理的にはあまり変わりないですけど。

シャノン 2005/05/26(木) 13:09:05
カスタムドローとか。
なんかアイテム選択の切り替えが重い。改良の余地ありだな。

void CTreeDlg::OnNMCustomDrawTree1(NMHDR *pNMHDR, LRESULT *pResult)
{
    LPNMTVCUSTOMDRAW pNMTVCD = reinterpret_cast<LPNMTVCUSTOMDRAW>(pNMCD);
    switch( pNMTVCD->nmcd.dwDrawStage )
    {
    case CDDS_PREPAINT:
        *pResult = CDRF_NOTIFYITEMDRAW;
        return;

    case CDDS_ITEMPREPAINT:
        if( pNMTVCD->nmcd.uItemState & CDIS_SELECTED )
        {
            pNMTVCD->clrTextBk = GetSysColor( COLOR_HIGHLIGHT );
            pNMTVCD->clrText = GetSysColor( 
COLOR_HIGHLIGHTTEXT );
            *pResult = CDRF_NEWFONT;
            return;
        }

    default:
        break;
    }

    *pResult = CDRF_DODEFAULT;

}

シャノン 2005/05/26(木) 13:14:38
ちょっと軽くなった

case CDDS_ITEMPREPAINT:
    if( GetFocus()->m_hWnd != this->m_Tree1.m_hWnd )
    {
        if( pNMTVCD->nmcd.uItemState & CDIS_SELECTED )
        {
            pNMTVCD->clrTextBk = GetSysColor( COLOR_HIGHLIGHT );
            pNMTVCD->clrText = GetSysColor( 
COLOR_HIGHLIGHTTEXT );

            *pResult = CDRF_NEWFONT;
        }
    }

Blue 2005/05/27(金) 00:23:33
>   if( GetFocus()->m_hWnd != this->m_Tree1.m_hWnd )
を
if ( !GetFocus() || ( GetFocus()->m_hWnd != m_Tree1.m_hWnd ) )
とするとダイアログからフォーカスを失っても、選択状態の色になります。
(そのままコピペしたらGetFocus()で落ちる)

# まぁ私の最初のやつは長いしそれも考慮してないですからねw

Blue 2005/05/27(金) 00:26:15
>(そのままコピペしたらGetFocus()で落ちる)
まちがえたコメントを書いてしまいました。。。orz

>>   if( GetFocus()->m_hWnd != this->m_Tree1.m_hWnd )
のままコピペするとGetFocus()のところで落ちてしまうので、
>if ( !GetFocus() || ( GetFocus()->m_hWnd != m_Tree1.m_hWnd ) )
としたのでした。

シャノン 2005/05/27(金) 00:52:14
>>   if( GetFocus()->m_hWnd != this->m_Tree1.m_hWnd )
> のままコピペするとGetFocus()のところで落ちてしまうので、

む、俺んトコじゃ落ちなかったけどなぁ。
GetFocus()->GetSafeHwnd() だと大丈夫かも?

Blue 2005/05/27(金) 01:00:35
落ちるときは、
ダイアログ内にフォーカスがない場合、
つまり最小化や他のウィンドウにフォーカスがある時です。
(GetFocus()がNULLのとき)

古いスレッドには追加発言できません。