You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WTL为动态创建的按钮添加ToolTip时AddTool调用失败如何解决

WTL模态对话框动态按钮添加Tooltip失败问题解决

错误原因

你猜测的「动态创建的按钮未定义在resource.h」不成立,动态创建的控件无需在resource.h中注册,实际错误如下:

  • 控件与Tooltip对象生命周期错误:CButton、CToolTipCtrl都是OnInitDialog内的局部栈变量,函数执行结束后对象就会被析构,WTL窗口类析构时会自动销毁绑定的窗口句柄,导致Tooltip绑定的目标按钮不存在,AddTool自然失败。
  • 公共控件初始化不全:wWinMain中调用AtlInitCommonControls时仅注册了工具栏、冷却栏类,未注册Tooltip所需的控件类。
  • 类定义参数错误:CMyDialog继承CDialogImpl时模板参数误写为CIdleDialog,会导致消息映射、窗口绑定等基础逻辑异常。

解决步骤

  1. 将CButton、CToolTipCtrl改为CMyDialog的成员变量,延长对象生命周期和对话框保持一致。
  2. 修正CDialogImpl的模板参数为当前类CMyDialog。
  3. 补充Tooltip控件的注册参数。
  4. 增加鼠标消息转发逻辑,保证Tooltip能正常捕获鼠标事件触发提示。

修正后的代码

CMyDialog.h

#pragma once
#include "stdafx.h"

class CMyDialog : public CDialogImpl<CMyDialog> {
public:
    enum { IDD = IDD_IDLEDIALOG };
    // 移为成员变量
    CButton m_btn;
    CToolTipCtrl m_tooltip;

protected:
    BEGIN_MSG_MAP(CMyDialog)
    MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
    // 增加鼠标消息转发
    MESSAGE_HANDLER(WM_MOUSEMOVE, OnMouseMove)
    END_MSG_MAP()

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

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

        m_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)m_btn.m_hWnd;
        ti.lpszText = (LPWSTR)L"THIS IS A TOOLTIP";
        if (!m_tooltip.AddTool(&ti)) {
            ocdbg("Could not add tooltip to button.\n");
        }
        m_tooltip.Activate(TRUE);

        return TRUE;
    }

    LRESULT OnMouseMove(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
    {
        MSG msg = { m_hWnd, uMsg, wParam, lParam };
        m_tooltip.RelayEvent(&msg);
        bHandled = FALSE;
        return 0;
    }
};

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)
{
    // 补充Tooltip所需的ICC_TOOLTIP_CLASSES,或者直接用ICC_WIN95_CLASSES包含所有常用控件
    AtlInitCommonControls(ICC_COOL_CLASSES | ICC_BAR_CLASSES | ICC_TOOLTIP_CLASSES);
    HRESULT h_res = _Module.Init(NULL, hInstance);

    {
        CMyDialog dialog;
        dialog.DoModal();
    }

    _Module.Term();
    return 0;
}

内容的提问来源于stack exchange,提问作者big54mac

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 06:24:05