質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

91.25%

  • MFC

    89questions

    MFC (Microsoft Fouondation Class)とは、MicrosoftがVC++用に開発したWindows用アプリケーションのフレームワークです。

  • Visual C++

    87questions

    Microsoft Visual C++はWindowsのCとC++の統合開発環境(IDE)であり、コンパイラやデバッガを含んでいます。

項目のツールチップ表示後に、キーボードでアイテムを選択しなおすと、ツールチップ表示が一瞬表示してすぐ消えてしまう。

受付中

回答 1

投稿

  • 評価
  • クリップ 1
  • VIEW 26

samusaku

score 26

前提・実現したいこと

以前、こちらで皆様にツールチップ表示方法について教えていただき、実現できました。
ですが、キーボードの上下押下してアイテムを選択しなおすと、ツールチップが表示したと思ったら、すぐ消えてしまう現象になり、
解決できなく困っております。
キーボードの上下で項目を選択しなおしても、ツールチップ表示がすぐに消えなくなる方法がわからず困っております。
ソースを記載いたしますので、有識者の皆様のご教授いただければと幸いです。

発生手順
1.項目にマウスを合わせる。
2.ツールチップが表示される。
→5秒ほどで表示が消える。(正常)
3.手順2に続いて、キーボードの上下を押下してアイテムを選択しなおす。
4.ツールチップが表示される。
→一瞬表示してすぐ消える。(問題)

※手順3でキーボード左右押下や別キーを押下した場合は、ツールチップが一瞬で消えず、5秒ほどで消えます。
→アイテム選択しなおした場合のみ発生いたします。

OK現象

イメージ説明

NG現象

イメージ説明

上記の画像の動作は以下のソースコードで実現しております。

該当のソースコード

ツールチップ表示クラス CListCtrlEx(h/cpp)

CListCtrlEx.hの実装
------------------------------------------------------------------------------------
class CListCtrlEx : public CListCtrl
{
    DECLARE_DYNCREATE(CListCtrlEx)

// コンストラクタ
public:
    // コンストラクタ
    CListCtrlEx();

    // デストラクタ
    virtual ~CListCtrlEx();

//    void SetDispTooltipColumn(int nColumn);

protected:
    afx_msg void OnToolTipText(NMHDR* pNMHDR, LRESULT* pResult);

    DECLARE_MESSAGE_MAP()
private:
};
------------------------------------------------------------------------------------

CListCtrlEx.h.cppの実装
------------------------------------------------------------------------------------

#include "stdafx.h"
#include "CListCtrlEx.h"


IMPLEMENT_DYNAMIC(CListCtrlEx, CListCtrl)

// コンストラクタ
CListCtrlEx::CListCtrlEx()
{
}

// デストラクタ
CListCtrlEx::~CListCtrlEx()
{
}

BEGIN_MESSAGE_MAP(CListCtrlEx, CListCtrl)
    ON_NOTIFY(TTN_NEEDTEXTA, 0, OnToolTipText)
    ON_NOTIFY(TTN_NEEDTEXTW, 0, OnToolTipText)
END_MESSAGE_MAP()


// ツールチップ
void CListCtrlEx::OnToolTipText(NMHDR* pNMHDR, LRESULT* pResult)
{
    // マウス位置座標からクライアント座標に変換
    CPoint pt(GetMessagePos());
    ScreenToClient(&pt);

    LVHITTESTINFO lvhti;
    ::ZeroMemory(&lvhti, sizeof(lvhti));    //構造体初期化
    lvhti.pt = pt;

    // マウス位置の行と列を取得する
    ListView_SubItemHitTest(m_hWnd, &lvhti);
    int nRow    = lvhti.iItem;        //行
    int nColumn    = lvhti.iSubItem;    //列

    if( NULL != pNMHDR ) {
      TOOLTIPTEXT* pToolTipText = (TOOLTIPTEXT*)pNMHDR;
      CString stToolTip = _T("");
      if( ((nRow != -1) && (nColumn != -1)) ) {
        // ツールチップ表示対象列の場合、リストの文字列を取得する
        stToolTip = GetItemText(nRow, nColumn);
        // ツールチップ表示文字列設定
        (void)lstrcpyn(pToolTipText->szText, stToolTip, (stToolTip.GetLength() + 1) );
      }
    }
}
------------------------------------------------------------------------------------

以下はダイアログ画面にリスト表示(ListCtrlを用いて実現)をするクラスです(DispToolTipDlg.h/cpp)

DispToolTipDlg.hの実装
------------------------------------------------------------------------------------
// DispToolTipDlg.h : ヘッダー ファイル
#pragma once
#include "afxcmn.h"
#include "CListCtrlEx.h"

// CDispToolTipDlg ダイアログ
class CDispToolTipDlg : public CDialogEx
{
// コンストラクション
public:
    CDispToolTipDlg(CWnd* pParent = NULL);    // 標準コンストラクター

// ダイアログ データ
#ifdef AFX_DESIGN_TIME
    enum { IDD = IDD_DISPTOOLTIP_DIALOG };
#endif
    protected:
    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV サポート
protected:
    HICON m_hIcon;

    // 生成された、メッセージ割り当て関数
    virtual BOOL OnInitDialog();
    afx_msg void OnPaint();
    afx_msg HCURSOR OnQueryDragIcon();
    DECLARE_MESSAGE_MAP()
private:
    CListCtrlEx m_listCtrl;
    void ListInit(void);
    void ListInsertItem(void);


DispToolTipDlg.hの実装
------------------------------------------------------------------------------------
#include "stdafx.h"
#include "DispToolTip.h"
#include "DispToolTipDlg.h"
#include "afxdialogex.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CDispToolTipDlg ダイアログ

void CDispToolTipDlg::DoDataExchange(CDataExchange* pDX)
{
    CDialogEx::DoDataExchange(pDX);
    DDX_Control(pDX, IDC_LIST1, m_listCtrl);
}

BOOL CDispToolTipDlg::OnInitDialog()
{
    CDialogEx::OnInitDialog();

    // このダイアログのアイコンを設定します。アプリケーションのメイン ウィンドウがダイアログでない場合、
    //  Framework は、この設定を自動的に行います。
    SetIcon(m_hIcon, TRUE);            // 大きいアイコンの設定
    SetIcon(m_hIcon, FALSE);        // 小さいアイコンの設定

    // TODO: 初期化をここに追加します。
    // リスト項目設定
    ListInit();
    // アイテム挿入
    ListInsertItem();

    return TRUE;  // フォーカスをコントロールに設定した場合を除き、TRUE を返します。
}

void CDispToolTipDlg::ListInit(void)
{
    // 項目タイトル追加
    LVCOLUMN    lvc;
    int         i;
    TCHAR       caption[][16] = { _T("Test1"), _T("Test2"), _T("Test3") };
    const int   clmNum = sizeof caption / sizeof caption[0];

    lvc.mask = LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
    for (i = 0; i < clmNum; i++)
    {
     lvc.iSubItem = i;
     lvc.pszText = caption[i];
     lvc.cx = 100;
     if (m_listCtrl.InsertColumn(i, &lvc) == -1) {
      break;
     }
     }
}

// リストアイテム挿入
void CDispToolTipDlg::ListInsertItem(void)
{
    struct
    {
     TCHAR    test1[32];
     int      test2;
     int      test3;
    } item[] =
    {
     { _T("sample1"), 10, 100 },
     { _T("sample2"), 20, 200 },
     { _T("sample3"), 30, 300 }
    };

    const int    itemNum = sizeof item / sizeof item[0];
    LVITEM       lvi;
    CString      str;
    int          i, index = 0;

    for (i = 0; i < itemNum; i++)
    {
        lvi.mask = LVIF_TEXT;
        lvi.iItem = i;
        lvi.iSubItem = 0;
        lvi.pszText = item[i].test1;
        index = m_listCtrl.InsertItem(&lvi);

        str.Format(_T("%d"), item[i].test2);
        lvi.iItem = index;
        lvi.iSubItem = 1;
        lvi.pszText = const_cast<LPTSTR>(static_cast<LPCTSTR>(str));
        m_listCtrl.SetItem(&lvi);

        str.Format(_T("%d"), item[i].test3);
        lvi.iItem = index;
        lvi.iSubItem = 2;
        lvi.pszText = const_cast<LPTSTR>(static_cast<LPCTSTR>(str));
        m_listCtrl.SetItem(&lvi);
    }
}
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

0

推測ですが、マウスが指し示している位置と実際の選択位置が違うのですぐに消えるのか、または、キー入力が有ったからということで消しているかのどれかでしょうね。

CToolTipCtrlクラスを使っていると思うんですが、これを派生させて自分独自の仕様を盛り込むくらいしか思いつきませんが、そこまでCToolTipCtrlクラスが外向けに公開しているかどうかにかかって来ると思います。

ところで、すぐに消えてなにかまずいことでもあるんでしょうか?
もっと作ろうとしているプログラムの本来の仕様の部分に注力したほうが良いのでは?と思いますが・・・。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

ただいまの回答率

91.25%

関連した質問

同じタグがついた質問を見る

  • MFC

    89questions

    MFC (Microsoft Fouondation Class)とは、MicrosoftがVC++用に開発したWindows用アプリケーションのフレームワークです。

  • Visual C++

    87questions

    Microsoft Visual C++はWindowsのCとC++の統合開発環境(IDE)であり、コンパイラやデバッガを含んでいます。

  • トップ
  • Visual C++に関する質問
  • 項目のツールチップ表示後に、キーボードでアイテムを選択しなおすと、ツールチップ表示が一瞬表示してすぐ消えてしまう。