Какой смысл передавать два дескриптора HWND при выполнении TTM_ADDTOOL для объекта всплывающей подсказки?

В этом примере кода 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, один из которых является диалоговым окном (hDlg), а другой является элементом управления внутри диалогового окна. Я попытался и обнаружил, что при комментировании toolInfo.hwnd = hDlg; всплывающая подсказка все еще может отображаться при наведении указателя мыши на элемент управления toolID.

Тогда какой смысл передавать два дескриптора HWND? Это обязательно или полезно в других случаях?


person Jimm Chen    schedule 14.11.2015    source источник
comment
На самом деле вы не использовали два дескриптора окна, вы просто установили id подсказки. Это может пригодиться позже, когда вам нужно будет динамически генерировать текст всплывающей подсказки. Вы получаете флаг и идентификатор обратно в уведомлениях TTN_GETDISPINFO и TTN_NEEDTEXT.   -  person Hans Passant    schedule 14.11.2015
comment
@HansPassant: «ID» на самом деле является HWND при использовании флага TTF_IDISHWND (что делает рассматриваемый код).   -  person IInspectable    schedule 14.11.2015
comment
Конечно. И уведомление также передает флаг обратно, чтобы обработчик сообщений знал, что у него есть допустимый дескриптор окна. Операционная система не заботится о том, какой идентификатор вы используете.   -  person Hans Passant    schedule 14.11.2015


Ответы (1)


hwnd в структуре TOOLINFO также используется, когда вы устанавливаете для поля lpszText значение LPSTR_TEXTCALLBACK. Когда всплывающей подсказке требуется текст, она отправляет TTN_GETDISPINFO через сообщение WM_NOTIFY на этот hwnd. LPARAM этого сообщения будет указателем на NMTTDISPINFO, которую затем можно использовать для установки текста всплывающей подсказки. Хорошо, если текст всплывающей подсказки нужно изменить.

person Daren Coffey    schedule 14.11.2015
comment
Вы правы, и страница MSDN (msdn.microsoft.com/en-us/library/windows/desktop/) говорит об этом явно и немного расплывчато. Три раза перечитал, чтобы понять. Таким образом, один HWND предназначен для идентификации горячей области (называемой инструментом), другой HWND используется в качестве средства обратного вызова уведомлений - на случай, если вам нужно это уведомление. - person Jimm Chen; 14.11.2015