在对工具提示对象执行 TTM_ADDTOOL 时传递两个 HWND 句柄有什么意义?
What's the sense passing two HWND handles when doing TTM_ADDTOOL to a tooltip object?
在this MSDN代码示例中:
// Description:
// Creates a tooltip for an item in a dialog box.
// Parameters:
// idTool - identifier of an dialog box item.
// nDlg - window handle of the dialog box.
// pszText - string to use as the tooltip text.
// Returns:
// The handle to the tooltip.
//
HWND CreateToolTip(int toolID, HWND hDlg, PTSTR pszText)
{
if (!toolID || !hDlg || !pszText)
{
return FALSE;
}
// Get the window of the tool.
HWND hwndTool = GetDlgItem(hDlg, toolID);
// Create the tooltip. g_hInst is the global instance handle.
HWND hwndTip = CreateWindowEx(NULL, TOOLTIPS_CLASS, NULL,
WS_POPUP |TTS_ALWAYSTIP | TTS_BALLOON,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
hDlg, NULL,
g_hInst, NULL);
if (!hwndTool || !hwndTip)
{
return (HWND)NULL;
}
// Associate the tooltip with the tool.
TOOLINFO toolInfo = { 0 };
toolInfo.cbSize = sizeof(toolInfo);
toolInfo.hwnd = hDlg; // first HWND
toolInfo.uFlags = TTF_IDISHWND | TTF_SUBCLASS;
toolInfo.uId = (UINT_PTR)hwndTool; // second HWND
toolInfo.lpszText = pszText;
SendMessage(hwndTip, TTM_ADDTOOL, 0, (LPARAM)&toolInfo);
return hwndTip;
}
我们将TTM_ADDTOOL
操作与两个HWND句柄相关联,一个是Dialogbox(hDlg),另一个是对话框内部的控件。我试过,发现注释掉 toolInfo.hwnd = hDlg;
仍然可以在鼠标悬停在 toolID 控件上时显示工具提示。
那么传递两个HWND句柄有什么意义呢?在其他情况下是必须的还是有用的?
当您将 lpszText 字段设置为 LPSTR_TEXTCALLBACK 时,也会使用 TOOLINFO 结构中的 hwnd。当工具提示需要文本时,它会发送一个 TTN_GETDISPINFO notification through a WM_NOTIFY message to that hwnd. That message's LPARAM will then be a pointer to a NMTTDISPINFO 结构,然后您可以使用该结构来设置工具提示的文本。以防工具提示的文本需要更改。
除了接受的答案中解释的原因外,在通知hwnd时,rect成员使用此句柄后面window的客户区作为其坐标的基础。
当 hwnd 未使用或指向无效句柄时,rect 成员为 screen-relative,这可能会导致意外行为。所以,除非你想做一些非常具体的事情来考虑桌面,否则无论何时你想使用 rect,你都需要在 hwnd 中提供一个有效的句柄。
我在任何地方都找不到这个解释。我对使用此句柄和 rect 成员的观察使我明白它们以这种方式相关。
在this MSDN代码示例中:
// Description:
// Creates a tooltip for an item in a dialog box.
// Parameters:
// idTool - identifier of an dialog box item.
// nDlg - window handle of the dialog box.
// pszText - string to use as the tooltip text.
// Returns:
// The handle to the tooltip.
//
HWND CreateToolTip(int toolID, HWND hDlg, PTSTR pszText)
{
if (!toolID || !hDlg || !pszText)
{
return FALSE;
}
// Get the window of the tool.
HWND hwndTool = GetDlgItem(hDlg, toolID);
// Create the tooltip. g_hInst is the global instance handle.
HWND hwndTip = CreateWindowEx(NULL, TOOLTIPS_CLASS, NULL,
WS_POPUP |TTS_ALWAYSTIP | TTS_BALLOON,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
hDlg, NULL,
g_hInst, NULL);
if (!hwndTool || !hwndTip)
{
return (HWND)NULL;
}
// Associate the tooltip with the tool.
TOOLINFO toolInfo = { 0 };
toolInfo.cbSize = sizeof(toolInfo);
toolInfo.hwnd = hDlg; // first HWND
toolInfo.uFlags = TTF_IDISHWND | TTF_SUBCLASS;
toolInfo.uId = (UINT_PTR)hwndTool; // second HWND
toolInfo.lpszText = pszText;
SendMessage(hwndTip, TTM_ADDTOOL, 0, (LPARAM)&toolInfo);
return hwndTip;
}
我们将TTM_ADDTOOL
操作与两个HWND句柄相关联,一个是Dialogbox(hDlg),另一个是对话框内部的控件。我试过,发现注释掉 toolInfo.hwnd = hDlg;
仍然可以在鼠标悬停在 toolID 控件上时显示工具提示。
那么传递两个HWND句柄有什么意义呢?在其他情况下是必须的还是有用的?
当您将 lpszText 字段设置为 LPSTR_TEXTCALLBACK 时,也会使用 TOOLINFO 结构中的 hwnd。当工具提示需要文本时,它会发送一个 TTN_GETDISPINFO notification through a WM_NOTIFY message to that hwnd. That message's LPARAM will then be a pointer to a NMTTDISPINFO 结构,然后您可以使用该结构来设置工具提示的文本。以防工具提示的文本需要更改。
除了接受的答案中解释的原因外,在通知hwnd时,rect成员使用此句柄后面window的客户区作为其坐标的基础。
当 hwnd 未使用或指向无效句柄时,rect 成员为 screen-relative,这可能会导致意外行为。所以,除非你想做一些非常具体的事情来考虑桌面,否则无论何时你想使用 rect,你都需要在 hwnd 中提供一个有效的句柄。
我在任何地方都找不到这个解释。我对使用此句柄和 rect 成员的观察使我明白它们以这种方式相关。