Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: WinAPI и системное программирование > Ручное создание BalloonTip для иконки в SystemTray


Автор: jungle 14.6.2009, 12:53
Пытаюсь реализовать отображение всплывающей подсказки в виде BalloonTip для иконки в системном трее. Для этого я не прибегаю к расширенной структуре TNotifyIconData, а использую ручное создание tooltip-окна. Это гарантирует мне отображение подсказки даже в том случае, если её показ блокируется через параметр в реестре. 

В Интернете достаточно материала на тему создания balloontip-ов для контролов – кнопок, едитбоксов и т.д., но нет для иконок в системном трее. 

Для ручного создания balloontip-а использую распространенный код:

Код

procedure ShowBalloonTip(CtrlHandle: HWND; Icon: integer; Title: pchar;
   Text: PWideChar;
   BackCL, TextCL: TColor);
const
   TTS_ALWAYSTIP = $01;
   TTS_BALLOON = $40;
   TTF_SUBCLASS = $0010;
   TTF_TRANSPARENT = $0100;
   TTM_ADDTOOL = $0400 + 50;
   TTM_SETTITLE = (WM_USER + 32);
   ICC_WIN95_CLASSES = $000000FF;
type
  TOOLINFO = packed record
    cbSize: Integer;
    uFlags: Integer;
    hwnd: THandle;
    uId: Integer;
    rect: TRect;
    hinst: THandle;
    lpszText: PWideChar;
    lParam: Integer;
  end;
var
  hWndTip: THandle;
  ti: TOOLINFO;
  hWnd: THandle;
begin
  hWnd := CtrlHandle;
  hWndTip := CreateWindowEx(WS_EX_TOPMOST,'tooltips_class32', nil,
  WS_POPUP or TTS_NOPREFIX or TTS_BALLOON or TTS_ALWAYSTIP,
  0, 0, 0, 0, hWnd, 0, HInstance, nil);
  if hWndTip <> 0 then begin
    ti.cbSize := SizeOf(ti);
    ti.uFlags := TTF_TRANSPARENT or TTF_SUBCLASS;
    ti.hwnd := hWnd;
    ti.lpszText := Text;
   // Windows.GetClientRect(hWnd, ti.rect);
    ti.rect:=Rect(0,0,16,16);
    SendMessage(hWndTip, TTM_SETTIPBKCOLOR, BackCL, 0);
    SendMessage(hWndTip, TTM_SETTIPTEXTCOLOR, TextCL, 0);
    SendMessage(hWndTip, TTM_ADDTOOL, 1, Integer(@ti));
    SendMessage(hWndTip, TTM_SETTITLE, Icon mod 4, Integer(Title));
  end;
end;


Подскажите, какой хэндл передать в процедуру ShowBalloonTip в качестве параметра CtrlHandle, чтобы отобразить подсказку над иконкой в трее?

Автор: Keeper89 14.6.2009, 13:56
Посмотрите вот http://delphikingdom.info/asp/answer.asp?IDAnswer=39600 ссылку, мне кажется это то, что вам нужно.

Автор: CodeMonkey 14.6.2009, 21:18
Я бы не рекомендовал вообще это делать по нескольким причинам:
1. http://www.delphikingdom.ru/asp/answer.asp?IDAnswer=42355.
2. http://transl-gunsmoker.blogspot.com/2009/01/blog-post_9405.html. Если пользователь выключил подсказки - значит он не хочет их видеть. А вы хотите плюнуть свой диалог ему в лицо. По этой причине, кстати, http://transl-gunsmoker.blogspot.com/2008/11/x.html.
3. http://transl-gunsmoker.blogspot.com/2009/02/blog-post_21.html. По краней мере их нужно делать отключаемыми или показывать только на время показа подсказки.

Автор: jungle 14.6.2009, 22:38
Видимо, я не совсем внятно сформулировал суть проблемы. Дело в том, что я просто хочу заменить стандартный hint значка в системной панели на tooltip (balloontip). Т.е. при наведении курсора мыши на значок появляется "балунтип". Мне это крайне необходимо, потому что в этом случае повышается информативность и эстетичность всплывающей подсказки. Всё что мне нужно, это каким-то образом получить хэндл значка для передачи в процедуру ShowBalloonTip.

Автор: Keeper89 15.6.2009, 02:11
Посмотрите еще вот http://www.swissdelphicenter.ch/torry/showcode.php?id=1164 и http://delphi.wikia.com/wiki/Shell_NotifyIcon_Example_1, с вашим кодом ничего не получилось.

Автор: Romikgy 15.6.2009, 09:17
Цитата(jungle @  14.6.2009,  21:38 Найти цитируемый пост)
это каким-то образом получить хэндл значка для передачи

передай хендл основной формы

Автор: Keeper89 15.6.2009, 10:36
Цитата(Romikgy @  15.6.2009,  10:17 Найти цитируемый пост)
передай хендл основной формы 

Не работает, ни хендл основной формы, ни хендл картинки в трее. У меня, по крайней мере.

Автор: jungle 15.6.2009, 12:20
Keeper89, спасибо за ссылки! К сожалению, в обоих примерах используется структура NotifyIconData для автоматического создания стандартного "балунтипа". В моём случае необходимо самому создавать окно класса tooltips_class32. Повторюсь, код, который я процитировал выше рабочий, если передать Handle кнопки, например.

Автор: Keeper89 15.6.2009, 12:26
Цитата(jungle @  15.6.2009,  13:20 Найти цитируемый пост)
Повторюсь, код, который я процитировал выше рабочий, если передать Handle кнопки, например. 

Я понял, еще вчера сам попробовал. Но как уже я сказал для трея не работает, ни хендл основной формы, ни хендл картинки в трее, уже весь Интернет перерыл.

Автор: CodeMonkey 15.6.2009, 12:56
http://transl-gunsmoker.blogspot.com/2008/12/blog-post_01.html
Зачем вам это нужно? Делать свою программу кривой только по той причине, что балун-подсказка выглядит "красивше" прямоугольника?

Автор: jungle 15.6.2009, 13:59
Keeper89, в исходниках компонента CoolTrayIcon нашел очень любопытный комментарий в коде функции:

Код

function TCoolTrayIcon.GetClientIconPos(X, Y: Integer): TPoint;
// Return the cursor position inside the tray icon
const
  IconBorder = 1;
//  IconSize = 16;
var
  H: HWND;
  P: TPoint;
  IconSize: Integer;
begin
{ The CoolTrayIcon.Handle property is not the window handle of the tray icon.
  We can find the window handle via WindowFromPoint when the mouse is over
  the tray icon. (It can probably be found via GetWindowLong as well).

  BTW: The parent of the tray icon is the TASKBAR - not the traybar, which
  contains the tray icons and the clock. The traybar seems to be a canvas,
  not a real window (?). }

  // Get the icon size
  IconSize := GetSystemMetrics(SM_CYCAPTION) - 3;

  P.X := X;
  P.Y := Y;
  H := WindowFromPoint(P);
  { Convert current cursor X,Y coordinates to tray client coordinates.
    Add borders to tray icon size in the calculations. }
  Windows.ScreenToClient(H, P);
  P.X := (P.X mod ((IconBorder*2)+IconSize)) -1;
  P.Y := (P.Y mod ((IconBorder*2)+IconSize)) -1;
  Result := P;
end;

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)