Отображение подсказок MF C для элементов управления, вложенных в другой элемент управления - PullRequest
1 голос
/ 27 марта 2020

По некоторым причинам у меня есть родительское окно. Это окно содержит нормальные элементы управления. Но также требуются дочерние элементы управления, в которых снова есть элементы управления. Реальное приложение более сложное. В реальной версии я также использую WS_EX_CONTROLPARENT, чтобы разрешить навигацию в диалоге между вложенными элементами управления.

Для простоты я создал диалоговое базовое приложение. В нем есть обычный элемент редактирования и элемент управления stati c с элементом управления для редактирования. Я только что создал элемент управления редактирования внутри своего кода.

Я включил подсказки. Нормальным способом. Подсказки отображаются для кнопок и обычного элемента управления редактированием. Но элемент управления внутри stati c не показывает всплывающую подсказку.

Как получить подсказки инструментов для вложенных элементов управления внутри моего обработчика?

Вот код для CPP.

// ToolTipTestDlg.cpp : implementation file
#include "pch.h"
#include "framework.h"
#include "ToolTipTest.h"
#include "ToolTipTestDlg.h"
#include "afxdialogex.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

// CToolTipTestDlg dialog

CToolTipTestDlg::CToolTipTestDlg(CWnd* pParent /*=nullptr*/)
    : CDialogEx(IDD_TOOLTIPTEST_DIALOG, pParent)
{
    EnableToolTips();
}

void CToolTipTestDlg::DoDataExchange(CDataExchange* pDX)
{
    CDialogEx::DoDataExchange(pDX);
    DDX_Control(pDX, IDC_CONTAINER, m_container);
}

BEGIN_MESSAGE_MAP(CToolTipTestDlg, CDialogEx)
    ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTW, 0, 0xFFFF, OnToolTipText)
END_MESSAGE_MAP()

// CToolTipTestDlg message handlers

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

    m_edit1.Create(WS_CHILD | WS_BORDER | WS_VISIBLE, CRect(10, 10, 110, 30), this, 1);
    m_edit2.Create(WS_CHILD | WS_BORDER | WS_VISIBLE, CRect(10, 10, 110, 30), &m_container, 1);

    return TRUE;  // return TRUE  unless you set the focus to a control
}

BOOL CToolTipTestDlg::OnToolTipText(UINT nId, NMHDR* pNMHDR, LRESULT* pResult)
{
    // For all keyboard messages we need to know the target of the message
    ASSERT(pNMHDR->code == TTN_NEEDTEXTA || pNMHDR->code == TTN_NEEDTEXTW);
    TOOLTIPTEXTW* pTTTW = reinterpret_cast<NMTTDISPINFO*>(pNMHDR);

    CString strTipText = _T("Test");
    wcsncpy_s(pTTTW->szText, _countof(pTTTW->szText), CT2W(strTipText), _countof(pTTTW->szText));

    *pResult = 0;
    return TRUE;    // message was handled
}

Заголовочный файл:

// ToolTipTestDlg.h : header file

#pragma once

// CToolTipTestDlg dialog
class CToolTipTestDlg : public CDialogEx
{
// Construction
public:
    CToolTipTestDlg(CWnd* pParent = nullptr);   // standard constructor

// Dialog Data
#ifdef AFX_DESIGN_TIME
    enum { IDD = IDD_TOOLTIPTEST_DIALOG };
#endif

    CEdit m_edit1, m_edit2;
    CStatic m_container;

protected:
    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support

// Implementation
protected:
    // Generated message map functions
    virtual BOOL OnInitDialog();
    DECLARE_MESSAGE_MAP()
    afx_msg BOOL OnToolTipText(UINT, NMHDR* pNMHDR, LRESULT* pResult);
};

И файл R C с контейнером:

/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//

IDD_TOOLTIPTEST_DIALOG DIALOGEX 0, 0, 321, 96
STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_THICKFRAME
EXSTYLE WS_EX_APPWINDOW
FONT 8, "MS Shell Dlg", 0, 0, 0x1
BEGIN
    DEFPUSHBUTTON   "OK",IDOK,79,75,50,14
    PUSHBUTTON      "Cancel",IDCANCEL,134,75,50,14
    LTEXT           " ",IDC_CONTAINER,7,39,168,25,SS_NOTIFY
END

1 Ответ

2 голосов
/ 30 марта 2020

Мое исследование показало, что эта реализация всплывающей подсказки MF C предназначена только для элементов управления, которые являются непосредственными дочерними элементами для элемента управления, который называется EnabledToolTips.

Я нашел решение, которое работает. Возможно, он не самый лучший, но его легко реализовать.

Я использую собственный класс-контейнер (в моем коде реального мира этот класс уже существует)

class CStaticContainer : public CStatic
{

public:
DECLARE_MESSAGE_MAP()
    afx_msg BOOL OnToolTipText(UINT, NMHDR* pNMHDR, LRESULT* pResult);
};

Я убедился, что это Класс контейнера используется и подклассирует существующий CStati c (здесь код для примера в классе диалога):

// In the dialog class 
CStaticContainer m_container;

...
void CToolTipTestDlg::DoDataExchange(CDataExchange* pDX)
{
    CDialogEx::DoDataExchange(pDX);
    DDX_Control(pDX, IDC_CONTAINER, m_container);
}

Я также включил подсказки для контейнера в OnInitDialog.

m_container.EnableToolTips();

Для класса контейнера я добавил обработчик TTN_NEEDTEXT. Он просто пересылает сообщение внешнему родителю.

BEGIN_MESSAGE_MAP(CStaticContainer, CStatic)
    ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTW, 0, 0xFFFF, OnToolTipText)
END_MESSAGE_MAP()

BOOL CStaticContainer::OnToolTipText(UINT nId, NMHDR* pNMHDR, LRESULT* pResult)
{
    GetParent()->SendMessage(WM_NOTIFY, nId, reinterpret_cast<LPARAM>(pNMHDR));
    return TRUE;    // message was handled
}

Теперь всплывающие подсказки отображаются для всех элементов управления.

...