gpt4 book ai didi

c++ - 如何重新定义默认工具提示行为?

转载 作者:行者123 更新时间:2023-11-28 04:07:21 27 4
gpt4 key购买 nike

我创建了示例来检查 tooltip 控件。这是一个有点乱的程序,它创建窗口、按钮并为带有消息 qwerty 的按钮工具提示注册。每个 window/button/tooltip 窗口都添加了次要日志。

#include <windows.h>
#include <Windowsx.h>
#include <CommCtrl.h>
#include <string>
#include <map>

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
static HWND hwndTip = 0;
static HWND tool = 0;
WNDPROC old_tooltip_proc = 0;
WNDPROC old_button_proc = 0;

std::string GetLastErrorAsString()
{
//Get the error message, if any.
DWORD errorMessageID = ::GetLastError();
if (errorMessageID == 0)
return std::string(); //No error message has been recorded

LPSTR messageBuffer = nullptr;
size_t size = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, errorMessageID, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&messageBuffer, 0, NULL);

std::string message(messageBuffer, size);

//Free the buffer.
LocalFree(messageBuffer);

return message;
}

void log_msg(std::string prefix, UINT msg)
{
std::map<UINT, std::string> table
{
{WM_NCHITTEST, "WM_NCHITTEST"},
{TTM_WINDOWFROMPOINT, "TTM_WINDOWFROMPOINT"},
{WM_SETCURSOR, "WM_SETCURSOR"},
{WM_PAINT, "WM_PAINT"},
{WM_NCPAINT, "WM_NCPAINT"},
{WM_ERASEBKGND, "WM_ERASEBKGND"},
{WM_SHOWWINDOW, "WM_SHOWWINDOW"},
{WM_ACTIVATEAPP, "WM_ACTIVATEAPP"},
{WM_WINDOWPOSCHANGING, "WM_WINDOWPOSCHANGING"},
{WM_WINDOWPOSCHANGED, "WM_WINDOWPOSCHANGED"},
{WM_GETTEXT, "WM_GETTEXT"},
{WM_MOUSELEAVE , "WM_MOUSELEAVE"},
{WM_GETTEXTLENGTH, "WM_GETTEXTLENGTH"},
{WM_NCCALCSIZE, "WM_NCCALCSIZE"},
{WM_TIMER, "WM_TIMER"},
{WM_MOVE, "WM_MOVE"},
{WM_MOUSEMOVE, "WM_MOUSEMOVE"},
{WM_LBUTTONDOWN, "WM_LBUTTONDOWN"},
{TTM_RELAYEVENT, "TTM_RELAYEVENT"},
{SB_SETTEXTA, "SB_SETTEXTA"}
};
if (table.find(msg) == table.end())
{
OutputDebugString((prefix + " " + std::to_string(msg) + "\n").c_str());
return;
}
OutputDebugString((prefix + " " + table.at(msg) + "\n").c_str());
}

LRESULT CALLBACK tooltip_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
log_msg("TOOLTIP", message);
return CallWindowProc(old_tooltip_proc, hwnd, message, wParam, lParam);
}

LRESULT CALLBACK button_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
log_msg("BUTTON", message);
return CallWindowProc(old_button_proc, hwnd, message, wParam, lParam);
}


void createToolTip(HINSTANCE hInstance, HWND parent_window)
{
hwndTip = CreateWindowEx(WS_EX_TOPMOST, TOOLTIPS_CLASS, NULL,
WS_POPUP | TTS_ALWAYSTIP,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
parent_window, NULL, hInstance,
NULL);
old_tooltip_proc = (WNDPROC)SetWindowLongPtr(hwndTip, GWLP_WNDPROC, (LONG_PTR)tooltip_proc);
if (!hwndTip)
{
MessageBox(parent_window, "CreateWindowEx TOOLTIPS_CLASS failed", "ERROR", MB_OK);
return;
}
}

TOOLINFO get_tool_info(HWND tool)
{
TOOLINFO g_toolItem = { 0 };
g_toolItem.cbSize = sizeof(g_toolItem);
g_toolItem.uFlags = TTF_IDISHWND | TTF_SUBCLASS;
g_toolItem.hwnd = GetParent(tool);
g_toolItem.uId = (UINT_PTR)tool;
g_toolItem.hinst = NULL;
g_toolItem.lpszText = LPSTR_TEXTCALLBACK;
return g_toolItem;
}

void register_tool(HWND _tool)
{
std::string f("qwerty");
TOOLINFO toolinfo = get_tool_info(_tool);
toolinfo.lpszText = const_cast<char*>(f.c_str());
if (SendMessage(hwndTip, TTM_ADDTOOL, 0, (LPARAM)&toolinfo) == FALSE)
{
MessageBox(toolinfo.hwnd, "TTM_ADDTOOL failed", "ERROR", MB_OK);
return;
}
tool = _tool;
}

void unregister_tool(HWND tool)
{
TOOLINFO toolinfo = get_tool_info(tool);
SendMessage(hwndTip, TTM_DELTOOL, 0, (LPARAM)&toolinfo);
}

HWND createButton(HWND parent_window)
{
auto handle = CreateWindow(TEXT("button"), TEXT("Hellooooooooooooooooooooooooooooo"),
WS_VISIBLE | WS_CHILD,
10, 10, 800, 250,
parent_window, NULL, NULL, NULL);
old_button_proc = (WNDPROC)SetWindowLongPtr(handle, GWLP_WNDPROC, (LONG_PTR)button_proc);
return handle;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
INITCOMMONCONTROLSEX ic;
ic.dwSize = sizeof(INITCOMMONCONTROLSEX);
ic.dwICC = ICC_TAB_CLASSES;
InitCommonControlsEx(&ic);
static TCHAR szAppName[] = TEXT("ToolTipApplication");
HWND hwnd;
MSG msg;
WNDCLASS wndclass;
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = szAppName;
if (!RegisterClass(&wndclass))
{
MessageBox(NULL, TEXT("This program requires Windows NT!"),
szAppName, MB_ICONERROR);
return 0;
}
hwnd = CreateWindow(szAppName, // window class name
TEXT("The Hello Program"), // window caption
WS_OVERLAPPEDWINDOW, // window style
CW_USEDEFAULT, // initial x position
CW_USEDEFAULT, // initial y position
CW_USEDEFAULT, // initial x size
CW_USEDEFAULT, // initial y size
NULL, // parent window handle
NULL, // window menu handle
hInstance, // program instance handle
NULL); // creation parameters
HWND button = createButton(hwnd);
createToolTip(hInstance, ::GetDesktopWindow());
register_tool(button);
ShowWindow(hwnd, iCmdShow);
UpdateWindow(hwnd);
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
log_msg("window", message);
return DefWindowProc(hwnd, message, wParam, lParam);
}

工具提示工作正常,但我想替换默认行为。如果将鼠标悬停在按钮上,将显示工具提示。但是当我在工具提示处快速移动光标时,工具提示将消失。我想禁用这种消失。系统托盘中的工具提示类似于此行为。如果将鼠标悬停在工具提示上,它不会同时消失。类似的东西:

enter image description here

附言我试图重新定义 TTM_RELAYEVENT 消息的处理,但没有给出任何结果。

最佳答案

添加TTF_TRANSPARENT

TTF_TRANSPARENT: Causes the tooltip control to forward mouse event messages to the parent window. This is limited to mouse events that occur within the bounds of the tooltip window.

代码:

TOOLINFO get_tool_info(HWND tool)
{
TOOLINFO g_toolItem = { 0 };
g_toolItem.cbSize = sizeof(g_toolItem);
g_toolItem.uFlags = TTF_IDISHWND | TTF_SUBCLASS | TTF_TRANSPARENT;
g_toolItem.hwnd = GetParent(tool);
g_toolItem.uId = (UINT_PTR)tool;
g_toolItem.hinst = NULL;
g_toolItem.lpszText = LPSTR_TEXTCALLBACK;
return g_toolItem;
}

关于c++ - 如何重新定义默认工具提示行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58486641/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com