【问题标题】:WTL Adding a tooltip to a dynamically created buttonWTL 向动态创建的按钮添加工具提示
【发布时间】:2021-11-19 18:29:37
【问题描述】:

我一直在使用 Windows 模板库制作一个模态对话框,我需要在其中动态创建按钮并向它们添加工具提示。我似乎找不到正确的方法:


// CMyDialog.h
#pragma once
#include "stdafx.h"

class CMyDialog : public CDialogImpl<CIdleDialog> {

public:

    enum { IDD = IDD_IDLEDIALOG };

protected:

    BEGIN_MSG_MAP(CMyDialog)
    MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
    END_MSG_MAP()

    LRESULT OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam,
                         BOOL &bHandled)
    {
        CRect dialog_rect(0, 0, 600, 400);
        MoveWindow(&dialog_rect);
        CenterWindow();

        CButton btn;
        CRect btn_rect(10, 10, 200, 30);
        btn.Create(this->m_hWnd, btn_rect, L"Test Button",
                   WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | BS_FLAT, NULL,
                   BTN_ID_OFFSET + 1);

        CToolTipCtrl tooltip;
        tooltip.Create(this->m_hWnd, rcDefault, NULL,
                       TTS_BALLOON | TTS_NOPREFIX);

        TOOLINFO ti = {sizeof(ti)};
        ti.hwnd = this->m_hWnd;
        ti.uFlags = TTF_IDISHWND | TTF_SUBCLASS;
        ti.uId = (UINT_PTR)btn.m_hWnd;
        ti.lpszText = (LPWSTR)L"THIS IS A TOOLTIP";
        if (!tooltip.AddTool(&ti)) {
            ocdbg("Could not add tooltip to button.\n");
        }
        tooltip.Activate(TRUE);

        return TRUE;
    }
};

关于我如何运行此对话框:


// main.cpp
#include "stdafx.h"
#include "CMyDialog.h"

CAppModule _Module;

int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance,
                    _In_ PWSTR pCmdLine, _In_ int nCmdShow)
{
    AtlInitCommonControls(ICC_COOL_CLASSES | ICC_BAR_CLASSES);
    HRESULT h_res = _Module.Init(NULL, hInstance);

    {
        CMyDialog dialog;
        dialog.DoModal();
    }

    _Module.Term();
    return 0;
}

tooltip.AddTool(&amp;ti) 的调用返回0,表示失败。我假设这是因为该按钮不在我的 resource.h 文件中。有什么想法吗?

【问题讨论】:

  • CToolTipCtrl tooltip 不应该是临时的。它应该被声明为成员数据。
  • 另外,ti.hwnd 应该分配给btn.m_hWnd 而不是this-&gt;m_hWnd
  • @BarmakShemirani 我不认为这对这个案子很重要。当我将其设为数据成员时,没有任何变化。
  • @IInspectable ti.hwnd 成员是“包含该工具的窗口的句柄”。来自docs.microsoft.com/en-us/windows/win32/api/commctrl/…。你说的我试过了,但没有用。
  • 文档中的措辞很糟糕,真的。它是在请求时处理文本查找的窗口的句柄。由于您没有使用LPSTR_TEXTCALLBACK 值,因此ti.hwnd 值在很大程度上没有意义。

标签: c++ windows user-interface winapi wtl


【解决方案1】:

我已经按照这篇文章https://docs.microsoft.com/en-us/windows/win32/controls/cookbook-overview 解决了这个问题,并将其添加到我的对话框标题的顶部。

#pragma comment(linker,"\"/manifestdependency:type='win32' \
name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \
processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")

现在一切正常!

【讨论】:

  • 这应该不是必需的,因为自 comctl32.dll v5.80 以来已支持 TTS_BALLOON 样式。如果将ti.cbSize 更改为TTTOOLINFO_V1_SIZE 而不是sizeof(ti),则不需要comctl32.dll v6.0 依赖项。除非您使用较新的操作系统版本中引入的功能(您不是),否则您不需要使用完整的结构大小。当然,如果您的 UI 的其他方面需要视觉样式,那么请务必启用 v6.0 依赖项。
  • 我回去试试你说的。我实际上不再使用TTS_BALLOON,但它也没有以我当前的TTS_POPUP | TTS_NOPREFIX 样式显示。
  • @RemyLebeau 禁用 v6.0 依赖项并将ti.cbSize 设置为TTTOOLINFO_V1_SIZE 后,工具提示正常工作。谢谢!不过,我确实喜欢 v6.0 的按钮和工具提示的风格。将它们编辑成类似的风格会很费力吗?
  • 是的。因此,如果您喜欢/想要 6.0 的感觉,那么当然可以使用它。我只是指出,让工具提示正常工作并不严格需要 6.0。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-08-31
  • 2017-02-28
  • 1970-01-01
  • 1970-01-01
  • 2015-07-16
  • 2016-11-07
  • 1970-01-01
相关资源
最近更新 更多