Win32 API. Урок 27. Тултип-контрол

Дата публикации 27 май 2002

Win32 API. Урок 27. Тултип-контрол — Архив WASM.RU

Мы изучим контроль tooltip. Что это такое, как его создать и как им пользоваться.

Сырец довнлоад здесь.

ТЕОРИЯ

Тултип - это маленькая прямоугольное окно, которое отображается, когда курсор мыши находится над какой-то определенной областью. Окно тултипа содержит текст, заданный программистом. В этом отношении тултип играет ту же роль, что и окно статуса, но оно исчезает, когда пользователь кликает или убирает курсор мыши из заданной области. Вы, вероятно, знакомы с тултипами, ассоциированные с кнопками тулбара. Эти "тултипы" - одно из удобств, предоставляемых тулбаром. Если вам нужны тултипы для других окон/контролов, вам необходимо создать собственный тултип контрол.

Теперь, когда вы знаете, что такое тултип, давайте перейдем к тому, как мы можем создать и использовать его. Ниже расписаны шаги:

  • Создать тултип-контрол функцией CreateWindowEx.
  • Определить регион, в котором он будет отслеживать передвижения мыши.
  • Передать регион тултип-контролу.
  • Передавать сообщения от мыши в указанном регионе тултип-контролу (этот шаг зависит от заданных флагов).

Ниже мы детально проанализируем каждый шаг.

Создание тултипа

Тултип - это common control. Поэтому вам необходимо где-нибудь в программе вызвать функцию InitCommonControls, чтобы MASM подлинковал к выходнуму экзешнику comctl32.dll. Вы создаете тултип с помощью CreateWindowEx. Это будет выглядеть примерно так:

Код (Text):
  1.  
  2.        .data
  3.        TooltipClassName db "Tooltips_class32",0
  4.        .code
  5.        .....
  6.        invoke InitCommonControls
  7.        invoke CreateWindowEx, NULL, addr TooltipClassName, NULL,
  8.        TIS_ALWAYSTIP, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
  9.        CW_USEDEFAULT, NULL, NULL, hInstance, NULL

Обратите внимание на стиль окна: TIS_ALWAYSTIP. Этот стиль указывает, что тултип будет показываться, когда курсор мыши будет находиться над заданной областью вне зависимости от статуса окна. То есть, если вы будете использовать этот флга, тултип будет появляться (когда курсор мыши будет находиться над определенной областью), даже если окно, с которым ассоциирован тултип, неактивно.

Вам не нужно задавать слили WS_POPUP и WS_EX_TOOLWINDOW, потому что тултип определяет их автомтически. Вам также не нужно указывать координаты, ширину и высоту тултипа: он сам рассчитывает свои характеристики, поэтому в качестве всех четырех параметров мы указывает CW_USEDEFAULT. Оставшиеся параметры не играют роли.

Определение tool'ов

Тултип создается, но не отображается сразу. Нам нужно, чтобы он отображался только над определенной областью. Теперь пришло время задать ее. Мы называем такую область 'tool'. Tool - это прямоугольная область клиентской части окна, в пределах которой тултип будет отслеживать передвижение мыши. Прямоугольная область может покрывать всю клиентскую часть окна или только некоторую долю от нее. Поэтому мы можем поделить 'tool' на два типа: один - это, когда в качестве tool'а выступает целая клиентская область окна, а другой - прямоугольная часть клиентскойобласти окна. Оба типа нходят свое применение. Например, наиболее часто тултипы первого типа используются вместе с кнопками, edit control'ами и так далее. Вам не нужно указывать координаты и размерность tool'а: предполагается, что будет задействована вся клиентская область. Tool'ы второго типа полезны, когда вы хотите поделить клиенскую часть окна на несколько регионов без использования дочерних окон. В этом случае вам будет необходимо задать координату верхнего левого угла, ширину и высоту tool'а.

Вы определяете характеристики tool'а в структуре TOOLINFO, которая имеет следующее определение:

Код (Text):
  1.  
  2.        TOOLINFO STRUCT
  3.          cbSize             DWORD      ?
  4.          uFlags             DWORD      ?
  5.          hWnd  *            DWORD      ?
  6.          uId                DWORD      ?
  7.          rect               RECT      
  8.          hInst *            DWORD      ?
  9.          lpszText           DWORD      ?
  10.          lParam             LPARAM     ?
  11.        TOOLINFO*ENDS
  • cbSize - размер структуры TOOLINFO. Вы должны заполнить этот параметр. Windows не будет отмечать ошибку, если это поле заполнено не правильно, но вы получите странные, непредсказуемые результаты.
  • uFlags - битовые флаги определяют характеристики tool'а.
    • TTF_IDISHWND - "ID - это hWnd". Если вы укажете этот флаг, вы должны заполнить параметр uId хэндлом окна, который вы хотите использовать. Если вы не укажете этот флаг, это будет означать, что вы хотите использовать второй тип tool'а. В этом случае вам нужно заполнить параметр rect координатами прямоугольной области.
    • TTF_CENTERTIP - обычно окно тултипа появляется справа и ниже курсора мыши. Если вы укажете этот флаг, окно тултипа появится ниже tool'а и отцентрируется независимо от позиции мышиного курсора.
    • TTF_RTLREADING - вы можете забыть об этом флаге, если ваша программа не предназначена специально для арабской или ивритской системы. Этот флаг отображает текст тултипа справла налево. Не работает под другими системами.
    • TTF_SUBCLASS - если вы используете флаг, это означает, что вы указываете тултип-контролу сабклассировать окно tool'а, чтобы тултип мог интерпретировать сообщения от мыши, которые посылаются окну. Этот флаг очень удобен. Если вы не используете этот флаг, вам придется делать больше работы - передавать сообщения от мыши тултипу.
  • hWnd - Хэндл окна, который содержит tool. Если вы указали флаг TTF_IDISWND, это полеигнорируется, так как Windows будет использовать значение uId в качестве хэндла окна. Вам нужно заполнить это поле, если:
    • Вы не устанавливали флаг TTF_IDISHWND
    • Вы указываете значение LPSTR_TEXTCALLBACK в параметре lpszText. Это значение указывает тултипу, что когда ему необходимо отобразить свое окно, он дожен уведомить об этом окно, которое содержит tool. Это вид динамического обновления текста тултипа. Если вы хотите изменять динамически текст тултипа, вам следует LPSTR_TEXTCALLBACK в качестве значения LPSTR_TEXTCALLBACK. Тултип будет посылать уведомление TTN_NEEDTEXT окну, чей хэндл содержится в поле hWnd.
  • uId - это поле может иметь одно из двух значений, в зависимости от того, содержит ли uFlags флаг IIF_IDISHWND.
    • Определяемое приложением ID tool'а, если флаг TTF_IDISHWND. Так как это означает, что вы используете tool, покрывающее только часть клиентской области, то логично, что вы можете именть несколько tool'ов на одной клиенской области (без пересечений). Тултип-контрол должен иметь какой-то путь отличать их друг от друга. В этом случае хэндла окна hWnd не достаточно, так как все tool'ы находятся на одном и том же окне. Определяемые приложением ID служат именно для этой цели. ID может быть любым значением, главное, чтобы оно было уникально по отношению к другим ID.
    • Хэндл окна, чья клиенская область полностью используется в качестве tool'а, если указан флаг TTF_IDISHWND. Вы можее удивиться. почем это поле используется для хранения хэндла окна, если есть hWnd? Ответ следующий: поле hWnd уже может быть заполнено, если в параметре lpszText указано значение LPSTR_TEXTCALLBACK. Окно, которое ответственно за предоставление текста тултипа, и окно, которое содержит tool, могут быть не одним и тем же.
  • rect - структура RECT, которая указывает размерность tool'а. Эта структура определяет прямоугольник относительного верхнего левого угла клиентской области окна, указанного в параметре hWnd. То есть, вы должжны заполнить эту структуру, если вы хотите указать tool, который покрывает только часть клиентской области. Тултип-контрол проигнорирует это поле, если вы укажете флаг TTF_IDISHWND (вы хотите использовать в качестве tool'а целое окно).
  • hInst - это хэндл процесса, содержащий ресурс строки, которая будет использована в качестве текста, если значение lpszText равно ID строкового ресурса. Это может вас несколько смутить. Прочтите сначала описание параметра lpszText, и вы поймете, для чего используется это поле. Тултип-контрол игнорирует это поле, если lpszText не содержит ID ресурса.
  • lpszText - это поле имеет несколько значений:
    • Если вы укажете в этом поле значение LPSTR_TEXTCALLBACK, тултип будет посылать уведомительное сообщение TTN_NEEDTEXT окну, которое идентифицируется хэндлом поля hWnd, чтобы то предоставило тултипу текстовую строку. Это наиболее динамичный метод обновления текста тултипа: вы можете менять его каждый раз, когда отображается окно тултипа.
    • Если вы укажете в этом поле ID строкового ресурса, тултип, когда ему потребуется отобразить текст в своем окне, будет искать строку в таблице строк процесса, заданного параметром hInst. Тултип-контрол идентифицирует ID ресурса следующим образом: так как ID ресурса - это 16-битное значение, верхнее слово этого поля всегда будет равно нулю. Этот метод полезен, если вы хотите портировать вашу программу на другие языки. Так как строковый ресурс определен в файле определения ресурсов, вам не нужно модифицировать исходный код. Вам только нужно изменить таблицу строк и текст тултипа изменится без риска внесения ошибок в программу.
    • Если значение в этом поле не равно LPSTR_TEXTCALLBACK и верхнее слово не равно нулю, тултип-контрол интерпретирует значение как указатель на текстовую строку, которая будет использована в качестве текста тултипа. Этот метод самый простой, но наименее гибкий.

Резюме: вы должны заполнить структуру TOOLINFO и передать ее тултипу. Эта структура задаст характерситики tool'а.

Регистрация tool'а

После того, как вы заполнили структуру TOOLINFO, вы должны передать ее тултипу. Тултип может обслуживать много tool'ов, поэтому обычно одно тултипа хватает на все окно. Чтобы зарегистрировать tool, вы посылаете тултипу сообщение TTM_ADDTOOL. wParam не используется, а lParam должен содержать адрес структуры TOOLINFO.

Код (Text):
  1.  
  2.        .data?
  3.        ti TOOLINFO
  4.        .......
  5.        .code
  6.        .......
  7.        <fill the TOOLINFO structure>
  8.        .......
  9.        invoke SendMessage, hwndTooltip, TTM_ADDTOOL, NULL, addr ti

SendMessage возвратит TRUE, если tool был успешно зарегистрирован тултипом или FALSE в обратном случае. Вы можете удалить tool сообщением TTM_DELTOOL.

Передача сообщений от мыши тултипу

Когда вышеописанные шаги выполнены, тултип имеет всю необходимую информацию о том, в какой области он должен отслеживать сообщения мыши и какой текст он должен отображать. Единственное, что отстутсвует - это триггер. Подумайте: область, указанная в качестве tool'а находитится на клиенсткой части другого окна. Как может тултип перехватить сообщения от мыши для этого окна? Необходимо, чтобы он мог измерить количество времени, которое курсор мыши находится над tool'ом, чтобы вовремя отобразить окно тултипа. Есть два метода, чтобы достичь этой цели, один требует помощи со стороны окна, которое tool, а другой этого не требует.

Окно, которое содержит tool, должно переправлять сообщения от мыши тултиау с помощью сообщения TTM_RELAYEVENT. lParam должен содержать адрес структуры MSG, содержающую сообщение от мыши. Тултип обрабатывает только следующие сообщения от мыши:

  • WM_LBUTTONDOWN
  • WM_MOUSEMOVE
  • WM_LBUTTONUP
  • WM_RBUTTONDOWN
  • WM_MBUTTONDOWN
  • WM_RBUTTONUP
  • WM_MBUTTONUP

Все другие сообщения игнорируются. Таким образом, в процедуре окна, содержащего tool, должен быть обработчик вроде следующего:

Код (Text):
  1.  
  2.    WndProc proc hWnd:DWORD, uMsg:DWORD, wParam:DWORD, lParam:DWORD
  3.    .......
  4.       if uMsg==WM_CREATE
  5.            .............
  6.        elseif uMsg==WM_LBUTTONDOWN || uMsg==WM_MOUSEMOVE || \
  7.               uMsg==WM_LBUTTONUP || uMsg==WM_RBUTTONDOWN || \
  8.               uMsg==WM_MBUTTONDOWN || uMsg==WM_RBUTTONUP || \
  9.               uMsg==WM_MBUTTONUP
  10.            invoke SendMessage, hwndTooltip, TTM_RELAYEVENT, NULL, addr msg
  11.            ..........

Вы можете указать флаг TTF_SUBCLASS в параметре uFlags структуры TOOLINFO. Этот флаг указывает тултипу сабклассировать окно, которое содержит tool, чтобы перехватывать сообщения от мыши без участия сабклассированного окна. Этот метод проще использовать и он требует меньше усилий, так как тултип берет всю обработку сообщений на себя.

Вот и все. Теперь ваш тултип полностью функционален. Есть несколько полезных тултиповых сообщений, о которых вас следует знать.

  • TTM_ACTIVATE - если вы хотите включать/выключать контрол динамически, это сообщение для вас. Если wParam равен TRUE, тултип включается, если wParam равен FALSE, тултип выкючается. Тултип включается автоматически, как только он был создан, поэтому вам не надо посылать сообщение, чтобы активировать его.
  • TTM_GETTOOLINFO и TTM_SETTOOLINFO. Если вы хотите получить/изменить значения в структуре TOOLINFO после того, как она была отправлена тултипу, используйте данное сообщение. Вам потребуется указать tool, чьи характериситики вы хотите изменить, с помощью верных uId и hWnd. Если вы хотите изменить только параметр rect, используйте сообщение TTM_NEWTOOLRECT. Если вам нужно только изменить текст тултипа, используйте TTM_UPDATATIPTEXT.
  • TTM_SETDELAYTIME. С помощью этого сообщения вы можете задать временную задержку, которую будет использовать тултип.

ПРИМЕР

Следующий пример - это простое диалоговое окно с двумя кнопками. Клиентская область диалогового окна поделена на 4 области: верняя левая, верхняя правая, нижняя левая и нижняя правая. Каждая область указана как tool с собственным текстом. Две кнопки также имеют свои собственные тексты подсказок.

Код (Text):
  1.  
  2.        .386
  3.        .model flat,stdcall
  4.        option casemap:none
  5.        include \masm32\include\windows.inc
  6.        include \masm32\include\kernel32.inc
  7.        include \masm32\include\user32.inc
  8.        include \masm32\include\comctl32.inc
  9.        includelib \masm32\lib\comctl32.lib
  10.        includelib \masm32\lib\user32.lib
  11.        includelib \masm32\lib\kernel32.lib
  12.        DlgProc proto :DWORD,:DWORD,:DWORD,:DWORD
  13.        EnumChild proto :DWORD,:DWORD
  14.        SetDlgToolArea proto :DWORD,:DWORD,:DWORD,:DWORD,:DWORD
  15.        .const
  16.        IDD_MAINDIALOG equ 101
  17.        .data
  18.        ToolTipsClassName db "Tooltips_class32",0
  19.        MainDialogText1 db "This is the upper left area of the dialog",0
  20.        MainDialogText2 db "This is the upper right area of the dialog",0
  21.        MainDialogText3 db "This is the lower left area of the dialog",0
  22.        MainDialogText4 db "This is the lower right area of the dialog",0
  23.        .data?
  24.        hwndTool dd ?
  25.        hInstance dd ?
  26.        .code
  27.        start:
  28.            invoke GetModuleHandle,NULL
  29.            mov hInstance,eax
  30.            invoke DialogBoxParam,hInstance,IDD_MAINDIALOG,NULL,addr
  31.        DlgProc,NULL
  32.            invoke ExitProcess,eax
  33.  
  34.  
  35.        DlgProc proc hDlg:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD
  36.            LOCAL ti:TOOLINFO
  37.            LOCAL id:DWORD
  38.            LOCAL rect:RECT
  39.            .if uMsg==WM_INITDIALOG
  40.                invoke InitCommonControls
  41.                invoke CreateWindowEx,NULL,ADDR ToolTipsClassName,NULL,\
  42.                    TTS_ALWAYSTIP,CW_USEDEFAULT,\
  43.                    CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,\
  44.                    hInstance,NULL
  45.                mov hwndTool,eax
  46.                mov id,0
  47.                mov ti.cbSize,sizeof TOOLINFO
  48.                mov ti.uFlags,TTF_SUBCLASS
  49.                push hDlg
  50.                pop ti.hWnd
  51.                invoke GetWindowRect,hDlg,addr rect
  52.                invoke SetDlgToolArea,hDlg,addr ti,addr
  53.        MainDialogText1,id,addr rect
  54.                inc id
  55.                invoke SetDlgToolArea,hDlg,addr ti,addr
  56.        MainDialogText2,id,addr rect
  57.                inc id
  58.                invoke SetDlgToolArea,hDlg,addr ti,addr
  59.        MainDialogText3,id,addr rect
  60.                inc id
  61.                invoke SetDlgToolArea,hDlg,addr ti,addr
  62.        MainDialogText4,id,addr rect
  63.                invoke EnumChildWindows,hDlg,addr EnumChild,addr ti
  64.            .elseif uMsg==WM_CLOSE
  65.                invoke EndDialog,hDlg,NULL
  66.            .else
  67.                mov eax,FALSE
  68.                ret
  69.            .endif
  70.            mov eax,TRUE
  71.            ret
  72.        DlgProc endp
  73.  
  74.        EnumChild proc uses edi hwndChild:DWORD,lParam:DWORD
  75.            LOCAL buffer[256]:BYTE
  76.            mov edi,lParam
  77.            assume edi:ptr TOOLINFO
  78.            push hwndChild
  79.            pop [edi].uId
  80.            or [edi].uFlags,TTF_IDISHWND
  81.            invoke GetWindowText,hwndChild,addr buffer,255
  82.            lea eax,buffer
  83.            mov [edi].lpszText,eax
  84.            invoke SendMessage,hwndTool,TTM_ADDTOOL,NULL,edi
  85.            assume edi:nothing
  86.            ret
  87.        EnumChild endp
  88.  
  89.  
  90.        SetDlgToolArea proc uses edi esi
  91.        hDlg:DWORD,lpti:DWORD,lpText:DWORD,id:DWORD,lprect:DWORD
  92.            mov edi,lpti
  93.            mov esi,lprect
  94.            assume esi:ptr RECT
  95.            assume edi:ptr TOOLINFO
  96.            .if id==0
  97.                mov [edi].rect.left,0
  98.                mov [edi].rect.top,0
  99.                mov eax,[esi].right
  100.                sub eax,[esi].left
  101.                shr eax,1
  102.                mov [edi].rect.right,eax
  103.                mov eax,[esi].bottom
  104.                sub eax,[esi].top
  105.                shr eax,1
  106.                mov [edi].rect.bottom,eax
  107.            .elseif id==1
  108.                mov eax,[esi].right
  109.                sub eax,[esi].left
  110.                shr eax,1
  111.                inc eax
  112.                mov [edi].rect.left,eax
  113.                mov [edi].rect.top,0
  114.                mov eax,[esi].right
  115.                sub eax,[esi].left
  116.                mov [edi].rect.right,eax
  117.                mov eax,[esi].bottom
  118.                sub eax,[esi].top
  119.                mov [edi].rect.bottom,eax
  120.            .elseif id==2
  121.                mov [edi].rect.left,0
  122.                mov eax,[esi].bottom
  123.                sub eax,[esi].top
  124.                shr eax,1
  125.                inc eax
  126.                mov [edi].rect.top,eax
  127.                mov eax,[esi].right
  128.                sub eax,[esi].left
  129.                shr eax,1
  130.                mov [edi].rect.right,eax
  131.                mov eax,[esi].bottom
  132.                sub eax,[esi].top
  133.                mov [edi].rect.bottom,eax
  134.            .else
  135.                mov eax,[esi].right
  136.                sub eax,[esi].left
  137.                shr eax,1
  138.                inc eax
  139.                mov [edi].rect.left,eax
  140.                mov eax,[esi].bottom
  141.                sub eax,[esi].top
  142.                shr eax,1
  143.                inc eax
  144.                mov [edi].rect.top,eax
  145.                mov eax,[esi].right
  146.                sub eax,[esi].left
  147.                mov [edi].rect.right,eax
  148.                mov eax,[esi].bottom
  149.                sub eax,[esi].top
  150.                mov [edi].rect.bottom,eax
  151.            .endif
  152.            push lpText
  153.            pop [edi].lpszText
  154.            invoke SendMessage,hwndTool,TTM_ADDTOOL,NULL,lpti
  155.            assume edi:nothing
  156.            assume esi:nothing
  157.            ret
  158.        SetDlgToolArea endp
  159.        end start

АНАЛИЗ

После того, как создано основное диалоговое окно, мы создает тултип-контрол функцией CreateWindowsEx.

Код (Text):
  1.  
  2.        invoke InitCommonControls
  3.        invoke CreateWindowEx,NULL,ADDR ToolTipsClassName,NULL,\
  4.               TTS_ALWAYSTIP,CW_USEDEFAULT,\
  5.               CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,\
  6.               hInstance,NULL
  7.        mov hwndTool,eax

После этого мы переходим к определению четырех tool'ов для каждого угла диалогового окна.

Код (Text):
  1.  
  2.        mov id,0        ; used as the tool ID
  3.        mov ti.cbSize,sizeof TOOLINFO
  4.        mov ti.uFlags,TTF_SUBCLASS   ; tell the tooltip control to subclass the dialog window.
  5.        push hDlg
  6.        pop ti.hWnd    ; handle to the window that contains the tool
  7.        invoke GetWindowRect,hDlg,addr rect   ; получаем размерность клиентской
  8.                                              ; области
  9.        invoke SetDlgToolArea,hDlg,addr ti,addr MainDialogText1,id,addr rect

Мы инициализируем члены структуры TOOLINFO. Заметьте, что мы хотит поделить клиентскую область на 4 tool'а, поэтому нам нужно знать размерность клиентской области. Это то, для чего мы вызываем GetWindowsRect. Мы не хотим передавать сообщения мыши тултипу, поэтому мы указываем флга TIF_SUBCLASS.

SetDlgToolArea - это функция, которая высчитывает координаты прямоугольной области каждого tool'а и регистрирует tool в тултипе. Я не хочу вдаваься в подробности относительно этого, достаточно сказать, что она делит клиентскую область на 4 области с одними и теми же размерами. Затем она посылает сообщение TTN_ADDTOOL тултипу, передавая адрес структуры TOOLINFO в lParam.

Код (Text):
  1.  
  2.        invoke SendMessage,hwndTool,TTM_ADDTOOL,NULL,lpti

После того, как все 4 tool'а зарегистрированы, мы можем перейти к кнопкам на диалоговом окне. Мы можем обрабатывать каждую кнопку с помоью ее ID, но это утомительно. Вместо этого мы используем EnumChildWindows API, чтобы перечислить все контролы на диалоговом окне и затем зарегистрировать для каждого из них подсказку. EnumChildWindows имеет следующий синтаксис:

Код (Text):
  1.  
  2.        EnumChildWindows proto hWnd:DWORD, lpEnumFunc:DWORD, lParam:DWORD

hWnd - хэндл родительского окна. lpEnumFunc - адрес функции EnumChildProc, которая будет вызываться для каждого перечисленного контрола. lParam - заданное приложением значение, которое будет передано EnumChildProc. У этой функции следующее определение:

Код (Text):
  1.  
  2.        EnumChildProc proto hwndChild:DWORD, lParam:DWORD

hwndChild - хэндл контрола, найденного EnumChildWindows. lParam - это тоже значение, что вы передали EnumChildWindow. В нашем примере мы вызываем EnumChildWindows следующим образом:

Код (Text):
  1.  
  2.        invoke EnumChildWindows,hDlg,addr EnumChild,addr ti

Мы передаем адрес структуры TOOLINFO в параметре lParam, потому что мы будем регистрировать подсказки для каждого дочерний контрол в функции EnumChild. Если мы не будем использовать данный метода, нам придется объявить глобальную переменную, чтобы предотвратить баги.

Когда мы вызываем EnumchildWindows, Windows перечислит дочерние конролы нашего диалогового окна и вызовет для каждого из ни фукнцию Enumchild. То есть, если наше диалоговое окно имеет два контрола, EnumChild будет вызван дважды.

Функция EnumChild заполнит соответствующие поля структуры TOOLINFO и зарегестрирует tool.

Код (Text):
  1.  
  2.        EnumChild proc uses edi hwndChild:DWORD,lParam:DWORD
  3.            LOCAL buffer[256]:BYTE
  4.            mov edi,lParam
  5.            assume edi:ptr TOOLINFO
  6.            push hwndChild
  7.            pop [edi].uId   ; we use the whole client area of the control as the tool
  8.            or [edi].uFlags,TTF_IDISHWND
  9.            invoke GetWindowText,hwndChild,addr buffer,255
  10.            lea eax,buffer    ; use the window text as the tooltip text
  11.            mov [edi].lpszText,eax
  12.            invoke SendMessage,hwndTool,TTM_ADDTOOL,NULL,edi
  13.            assume edi:nothing
  14.            ret
  15.        EnumChild endp

Заметьте, что в этом случае мы используем другой тип tool'ов, покрывающий всю клиентскую область окна. Поэтому нам нужно заполнить поле uID хэндлом окна, которое содержит tool. Также мы указываем флаг TTF_IDISHWND в параметре uFlags. © Iczelion, пер. Aquila


0 1.735
archive

archive
New Member

Регистрация:
27 фев 2017
Публикаций:
532