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

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

ただいまの
回答率

90.84%

  • MFC

    109questions

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

  • Visual C++

    107questions

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

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

解決済

回答 1

投稿

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

samusaku

score 28

前提・実現したいこと

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

発生手順
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

checkベストアンサー

0

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

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

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

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

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

  • ただいまの回答率 90.84%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

  • 解決済

    [c]一つのデータでカラム数が変わるデータの読み込み

    質問失礼します。プログラム初心者です。 以下のような〜〜〜.datを fp1 = fopen(fname1,"r"); while((ret = fscanf(fp1,"%d %d

  • 解決済

    シーザー暗号についての問題

    シーザー暗号についての質問です 大文字を3字ずらす小文字を5字ずらすというプログラムを作っています。 ぶち当たった壁が大文字は3字ずらすことは可能なのですが小文字を5字ずらすことが

  • 受付中

    プログラムを見やすく改良したい

    正常に動くプルグラムを見やすく改良したい。 具体的に教えていただければありがたいです。セグメンテーションフォルトでベスト7まで表示して停止します。173行あたりだと思うのですが、よ

  • 受付中

    c言語 文字列を逆順にして出力する

    発生している問題・エラーメッセージ 文字列を逆順にする関数を作成したのですが最後の文字の入れ替えができません。少しいじるとコアダンプと出てしまいます。どなたか解決法を教えてください

  • 解決済

    C++ スライシングについて

    C++のスライシングについて教えてください。 スライシングが起こる例などを教えていただければと思います

  • 解決済

    C言語でファイルを読み込み、一部の要素を取り出すコードのエラー

    前提・実現したいこと c言語でテキストファイルを読み込み、行としてではなく、各要素を読み込んで3列目と4列目だけ出力しようとしています。以下がコード作成のために参考にしているサイト

  • 解決済

    string空白ありで何個目かの文字列を取り出す

    空白ありで何個かの文字列を受け取り 何個目かの文字列を表示したいのですが 思い通りに動きません 条件は受け取る文字列はわからない例"okada saitou kimura is

  • 解決済

    マルチバイト文字のchar*をvector<char*>に変換したい

     前提・実現したいこと マルチバイト文字が格納されているchar*型の文字列をvector<char*>に変換したいです。 char* String = "abcあいうえお"

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

  • MFC

    109questions

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

  • Visual C++

    107questions

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

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