【发布时间】:2020-11-01 19:11:59
【问题描述】:
在一个 Win32 / C++ 应用程序中,在 64 位 Windows 7 下运行,使用 Visual Studio 16.7.7,我想在主(也是唯一的)窗口中实现跟踪工具提示。按照Microsoft SDK documentation 中的示例,跟踪似乎可以工作,但工具提示窗口本身并没有出现。
我已经使用调试器验证了工具提示已激活和停用,正在发生预期的鼠标跟踪,TTM_TRACKPOSITION 消息中的屏幕坐标正确,并且文本正常。该应用程序是 Unicode,我检查了结构是 Unicode 版本,并且初始化了公共控件,并且链接了当前版本的公共控件库。根据 Spy++,工具提示窗口具有 WS_EX_TOPMOST 和 WS_EX_TOOLWINDOW 扩展样式。
需要进行哪些更改才能显示工具提示?
这是我正在使用的代码:
全局变量:
HINSTANCE hInst;
HWND hWnd;
HWND hwndTT;
WCHAR ttText[12];
TOOLINFO toolTipInfo;
BOOL trackingMouse;
初始化:
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
hInst = hInstance; // Store instance handle in our global variable
hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr);
if (!hWnd)
{
return FALSE;
}
// Set up for mouse tracking (tooltips)
INITCOMMONCONTROLSEX icc;
icc.dwSize = sizeof(INITCOMMONCONTROLSEX);
icc.dwICC = ICC_BAR_CLASSES;
BOOL ok=InitCommonControlsEx(&icc);
trackingMouse = FALSE;//
WCHAR nullString[15] = { L"After create" };
hwndTT = CreateTrackingToolTip(0 /*toolID*/, hWnd, nullString);
...
HWND CreateTrackingToolTip(int toolID, HWND hWndParent, WCHAR* pText)
{
// Create a tooltip.
HWND h = CreateWindowEx(WS_EX_TOPMOST, TOOLTIPS_CLASS, NULL,
WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
hWndParent, NULL, hInst, NULL);
if(!h)
{
return NULL;
}
// Set up the tool information. In this case, the "tool" is the entire parent window.
memset(&toolTipInfo, 0, sizeof(TOOLINFO));
toolTipInfo.cbSize = sizeof(TOOLINFO);
toolTipInfo.uFlags = TTF_IDISHWND | TTF_TRACK | TTF_ABSOLUTE;
toolTipInfo.hwnd = hWndParent;
toolTipInfo.hinst = hInst;
toolTipInfo.lpszText = pText;
toolTipInfo.uId = (UINT_PTR)hWndParent;
GetClientRect(hWndParent, &toolTipInfo.rect);
// Associate the tooltip with the tool window.
SendMessage(h, TTM_ADDTOOL, 0, (LPARAM)(LPTOOLINFO)&toolTipInfo);
return h;
}
窗口程序:
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_MOUSELEAVE: // The mouse pointer has left our window. Deactivate the tooltip.
SendMessage(hwndTT, TTM_TRACKACTIVATE, (WPARAM)FALSE, (LPARAM)&toolTipInfo);
trackingMouse = FALSE;
TRACE(L"\nDeactivate tooltip");
return FALSE;
case WM_MOUSEMOVE:
static int oldX, oldY;
int newX, newY;
if(!trackingMouse) // The mouse has just entered the window.
{ // Request notification when the mouse leaves.
TRACKMOUSEEVENT tme = { sizeof(TRACKMOUSEEVENT) };
tme.hwndTrack = hWnd;
tme.dwFlags = TME_LEAVE;
BOOL ok=TrackMouseEvent(&tme);
// Activate the tooltip.
SendMessage(hwndTT, TTM_TRACKACTIVATE, (WPARAM)TRUE, (LPARAM)&toolTipInfo);
trackingMouse = TRUE;
TRACE(L"\nActivate tooltip");
}
newX = GET_X_LPARAM(lParam); newY = GET_Y_LPARAM(lParam);
// Make sure the mouse has actually moved. The presence of the tooltip
// causes Windows to send the message continuously.
if((newX != oldX) || (newY != oldY))
{
oldX = newX; oldY = newY;
// Update the text.
swprintf_s(ttText, ARRAYSIZE(ttText), L"%d, %d", newX, newY);
toolTipInfo.lpszText = ttText;
SendMessage(hwndTT, TTM_SETTOOLINFO, 0, (LPARAM)&toolTipInfo);
// Position the tooltip. The coordinates are adjusted so that the tooltip does not overlap the mouse pointer.
POINT pt = { newX, newY };
ClientToScreen(hWnd, &pt);
SendMessage(hwndTT, TTM_TRACKPOSITION, 0, (LPARAM)MAKELONG(pt.x + 10, pt.y - 20));
}
return FALSE;
...
【问题讨论】:
-
先尝试通过发送
TTM_ACTIVATE消息(将wParam设置为TRUE)来启用控件。 -
@Jonathan Potter:在 TTM_ADDTOOL 之后发送 TTM_ACTIVATE 不会改变任何东西。工具提示仍未出现。
-
奇怪的解决方案;据我所知,跟踪工具提示不仅仅是 comctrl v6 的一个功能。