Консультация № 183867
13.08.2011, 13:03
89.10 руб.
0 3 1
Здравствуйте!
Подскажите пожалуйста как отобразить всплывающую подсказку при наведении курсора на заголовок listview?
событие mousemove не вызывается при "езде" над хедером. Программа написана на с++ builder

Обсуждение

Неизвестный
15.08.2011, 07:50
общий
Добрый день!

Если речь идёт именно о SysListView32 или WC_LISTVIEW, то можно сделать так:

- привязать тултип к регионам колонок заголовка(listview header)
- сделать обработчик нотификаций в родительском окне, чтобы обновлять тултип для изменённого заголовка(listview header)

Немного комментариев по коду из приложения:

Я для простоты сделал маленький проект в Win32API, без родительского окна для листвью, чтоб было меньше кода. Т.о. там листвью сам является основным окном.
Поэтому я сделал перехват обработчика, чтобы ловить нотификации WM_NOTIFY.
Если листвью будет лежать на диалоге, то этого делать не надо, а нотификации надо ловить прямо в диалоге, соответсвенно.
Ещё там один момент, который я не написал в коде - я не чищу тултипы перед добавлением, а так же не отслеживаю появление/удаление колонок в процессе работы, но, предположу, что NM_CUSTOMDRAW прилетить в обоих случаях.

В приложении проект для MS VC 6.0 и собранный пример, release-сборка.
Сам код - HeaderList.cpp, можно лекго перенести в любую среду разработки, только первую директиву #include "stdafx.h" убрать
Прикрепленные файлы:
8b86b179a90cb859195d117f22f021e0.zip
Неизвестный
15.08.2011, 07:56
общий
это ответ
Здравствуйте, Sov!


Ещё раз дублирую свой код сюда, так как не туда нажал для ответа

Приложение:
#include <tchar.h>
#include <stdio.h>

// в билдере, скорее всего не понадобится
#pragma comment(lib, "ComCtl32.lib")

#include "CommCtrl.h"

// DATA
WNDPROC wndProcNative = NULL;
HWND hTip = NULL;

// прикрепляет тултип ко всем колонкам
void RefreshTips(HWND hListHeader)
{
RECT rc;
GetClientRect (hListHeader, &rc);

TCHAR szText[32] = TEXT("");

TOOLINFO ti;
ti.cbSize = sizeof(TOOLINFO);
ti.uFlags = TTF_SUBCLASS;
ti.hwnd = hListHeader;
ti.hinst = GetModuleHandle(NULL);
ti.lpszText = szText;

int iCount = Header_GetItemCount(hListHeader);
for (int i=0; i<iCount; i++)
{
ti.uId = i;
_stprintf(szText, TEXT("Hello, header #%d"), i+1);

Header_GetItemRect(hListHeader, i, &rc);

ti.rect.left = rc.left;
ti.rect.top = rc.top;
ti.rect.right = rc.right;
ti.rect.bottom = rc.bottom;

SendMessage(hTip, TTM_ADDTOOL, 0, (LPARAM) (LPTOOLINFO) &ti);
}
}

// в своём проекте вместо этого обработку перенести в обработчик окна-родителя для листа

LRESULT CALLBACK ListProc(HWND hList, UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message)
{
case WM_NOTIFY:
{
NMHDR *hdr = (NMHDR *)lParam;
if(hdr->hwndFrom == ListView_GetHeader(hList))
{
if(hdr->code == NM_CUSTOMDRAW)
RefreshTips(ListView_GetHeader(hList));
}
}
break;
}
if(wndProcNative)
return CallWindowProc(wndProcNative, hList, message, wParam, lParam);
else
return DefWindowProc(hList, message, wParam, lParam);
}

int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
INITCOMMONCONTROLSEX iccx;
iccx.dwSize = sizeof INITCOMMONCONTROLSEX;
iccx.dwICC = ICC_LISTVIEW_CLASSES|ICC_TREEVIEW_CLASSES;
InitCommonControlsEx(&iccx);

// LISTVIEW
HWND hList = CreateWindow(WC_LISTVIEW, TEXT("List View with Header"), WS_VISIBLE|WS_OVERLAPPEDWINDOW|LVS_REPORT, 100, 100, 300, 200, NULL, 0, GetModuleHandle(NULL), 0);
if(!hList)
return 0;
ListView_SetExtendedListViewStyleEx(hList,LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES,LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES);

// LISTVIEW - COLUMNS
LVCOLUMN lvc;
lvc.mask = LVCF_TEXT|LVCF_WIDTH;
lvc.cx = 120;
lvc.pszText = TEXT("Header 1");
SendMessage(hList, LVM_INSERTCOLUMN,0,(long)&lvc);
lvc.cx = 170;
lvc.pszText = TEXT("Header 2");
SendMessage(hList, LVM_INSERTCOLUMN,1,(long)&lvc);

// LISTVIEW - PROC
wndProcNative = (WNDPROC)SetWindowLong(hList, GWL_WNDPROC, (LONG)ListProc);

// TOOLTIP
hTip = CreateWindow(TOOLTIPS_CLASS, NULL, WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, ListView_GetHeader(hList), 0, GetModuleHandle(NULL), 0);
SetWindowPos(hTip, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);

RefreshTips(ListView_GetHeader(hList));

// MSG LOOP
MSG msg;
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage (&msg);
DispatchMessage(&msg);
if(!IsWindow(hList))
break;
}

return 0;
}
Прикрепленные файлы:
Неизвестный
15.08.2011, 08:17
общий
15.08.2011, 08:18
Здравствуйте, Sov!

Установите свойство ShowHint в значение true, а метод MouseMove опишите как показано ниже:

void __fastcall TForm1::ListView1MouseMove(TObject *Sender, TShiftState Shift, int X, int Y)
{
//Получаем координаты заголовка
TListItem *pListItem = ListView1->GetItemAt(X, Y);
//Всплывающая подсказка - заголовок
if(pListItem) ListView1->Hint = pListItem->Caption;
}

При наведении на заголовок будет возникать всплывающая подсказка с заголовком.
Форма ответа