Самопальный System Tray Tooltip как?

Тема в разделе "WASM.WIN32", создана пользователем Codeblight, 31 дек 2006.

  1. Codeblight

    Codeblight New Member

    Публикаций:
    0
    Регистрация:
    17 окт 2005
    Сообщения:
    60
    Адрес:
    Russia
    Думаю тут все знают как добавить иконку своей программы в SystemTray, а так же Tooltip и т.п. ... Моя программа должна показывать статистику при наведении на иконку. Все бы хорошо, но даже в версии Shell 5.0 размер текста тултипа 128 байт, мне же надо около 256-512 байт.

    1. С 256 можно сделать Ballon, однако он мне не нужен, т.к. не исчезает, когда я мышку убираю с иконки (грубо говоря его надо кликом закрывать или ждать пока он пропадет сам, что напрягает).
    2. Создать Tooltip обычный можно на окне своей программы и, если не ошибаюсь, при флажке TTF_ABSOLUTE показывать его ориентируясь относительно координат экрана... Однако я не могу определить координаты иконки в трее...
    3. Показывать тултип где-то рядом около трея на WM_MOUSEMOVE конечно можно, но там нет WM_MOUSELEAVE - т.ч. я не смогу узнать когда его убирать ;(


    Вообщем если не сложно - поделитесь идеями, как реализовать в трее тултип с текстом больше 128 символов. Желательно чтобы это работало на win2k и выше и пропадало, когда я убираю мышку со значка.
     
  2. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    Создавать своё окно, схожее на тултип (с его системными цветами) и показывать.

    Это почему? Твоему окну должно приходить это сообщение.
     
  3. Codeblight

    Codeblight New Member

    Публикаций:
    0
    Регистрация:
    17 окт 2005
    Сообщения:
    60
    Адрес:
    Russia
    не должно вовсе, т.к. TrackMouseEvent некуда прикручивать ...
     
  4. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    Почему некуда? Имеется ввиду
    .
     
  5. Codeblight

    Codeblight New Member

    Публикаций:
    0
    Регистрация:
    17 окт 2005
    Сообщения:
    60
    Адрес:
    Russia
    Ну да, вот окно свое я создам. Далее его надо показать. когда ? ок - SystemTray пошлет мне MouseMove - я покажу окно тултипа, далее я убираю мышку с иконки в System Tray и окно остается висеть, т.к. оно никогда не узнает что я уже убрал мышку. Проветить что мышка не на иконке я не могу (не знаю как).
     
  6. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    А, убирать с трея, а не с окна. Ну, проги делают закрытие по таймауту, если не задержать мышь над самим окном. А узнать, не ушла ли мышь с трея - можно периодически опрашивать координаты курсора и сравнивать с теми, что получены от трея сначала.
     
  7. atorn

    atorn New Member

    Публикаций:
    0
    Регистрация:
    14 дек 2006
    Сообщения:
    64
    Зачем? Лучше WindowFromPoint и GetWindowText.
     
  8. Codeblight

    Codeblight New Member

    Публикаций:
    0
    Регистрация:
    17 окт 2005
    Сообщения:
    60
    Адрес:
    Russia
    На самом деле трей делает примернотак:
    1. на маус мув ставит таймер 1-2 сек и запоминает на каком элементе курсор
    2. по срабатыванию таймера убивает таймер, проверяет положение курсора - если он там то кажет хинт
    -

    просто показывать и тупо убирать по таймеру не то, т.к. когда я со значка курсор убираю - хинт нормальный сразу пропадает. Проверять по координатам можно, только учитывать надо не 1 пиксел а размер иконки... Тупо добавить до размера иконки тоже можно, но есть риск скажем тыкнуть в крайний пиксел иконки и потом свести на соседнюю - а прога че будет при этом думать - неясно ;(
    Опять же с показом вообще идиотизм получается - двигаешь просто быстро мышкой через все иконки - если без таймера делать - то у проги моей будет тупо хинт выскакивать ;)
     
  9. Codeblight

    Codeblight New Member

    Публикаций:
    0
    Регистрация:
    17 окт 2005
    Сообщения:
    60
    Адрес:
    Russia
    Ну это то понятно, но зачем мне GetWindowText + разве значки в трее это окна ? )) как тогда я буду угадвать какое из них мое ? :)
     
  10. atorn

    atorn New Member

    Публикаций:
    0
    Регистрация:
    14 дек 2006
    Сообщения:
    64
    Codeblight
    Можно добавить в угол иконки точку нестандартного цвета, и найти её (GetPixel). Так найдёшь координаты.
     
  11. Codeblight

    Codeblight New Member

    Публикаций:
    0
    Регистрация:
    17 окт 2005
    Сообщения:
    60
    Адрес:
    Russia
    я должен искать точки нестандартного цвета на экране ?) вы затраты то попробуйте представить - не оч быстрая затея точки перебирать :derisive: Может есть какие-нибудь более простые варианты ? :) Возможно есть у кого идеи как стандартный Balloon сделать автозакрывающимся или подобные ?
     
  12. GMax

    GMax Member

    Публикаций:
    0
    Регистрация:
    3 июл 2006
    Сообщения:
    218
    ИМХО что-то подобное делает ReGet в момент окончания загрузки файла. Но как делает не знаю.
    Была идея посмотреть но не как время не найду, там ASProtect и Delphi т.е. геморрой гарантирован.
    А вообще вопрос интересный.
     
  13. Demon666

    Demon666 New Member

    Публикаций:
    0
    Регистрация:
    19 май 2006
    Сообщения:
    99
    Код (Text):
    1. WM_NOTIFY
    2. TTN_NEEDTEXT
    3. typedef struct { // ttt  
    4.     NMHDR     hdr;
    5.     LPTSTR    lpszText;
    6.     char      szText[80];
    7.     HINSTANCE hinst;
    8.     UINT      uFlags;
    9. } TOOLTIPTEXT, FAR *LPTOOLTIPTEXT;
    Хм… помниться давно, когда кодил, lpszText позволял более 2000 сиволов выводить на ToolTips
    hInst->NULL lpszText->указатель на строку с теми символами
    на компе где-то исходник валялся, но умну много пива выпил и искать лень
    а вообще учимся читать MSDN
    что здесь написано в топе единственное про таймер правильно сказываеццо
    ну ладно мож после праздников рассола попью, да если трабл не разрешиться помогу
    с НГ братья по разуму!
     
  14. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine
    Ставьте таймер при отображении псевдотултипа и каждые n миллисекунд проверяйте положение курсора мыши. Также постоянно нужно вычислять координаты значка в трее, т.к. значки могут двигаться. Сверяете потом координаты курсора с координатами значка в трее и при выходе за пределы значка закрываетесь и прибиваете таймер. Координаты значков можно вычислить используя соовщение TB_GETBUTTONSIZE.
     
  15. ViCooper

    ViCooper Victor

    Публикаций:
    0
    Регистрация:
    11 дек 2006
    Сообщения:
    26
    С Новым Годом!
    После того как получишь WM_MOUSEMOVE ( или че там у тя, для отображения инфы ) лепи SetForegroundWindow(i'm трей), далее все сообщения которые ты хочеш иметь - БУДУТ.
    Собственно об этом ( и об фсех проблеммах типа: "нет сообщений" ) MSDN так и говорит.
     
  16. Codeblight

    Codeblight New Member

    Публикаций:
    0
    Регистрация:
    17 окт 2005
    Сообщения:
    60
    Адрес:
    Russia
    Все бы ничего, но это для обычных тултипов. WM_NOTIFY не летит в приложение когда я по SystemTray мышом вожу ;(

    помоему это размер оно возвращает, вообще они на другую строку могут переноситься если широкую панель задач делаешь.

    откуда такая уверенность ? чтобы некоторые сообщения иметь - их надо регистрировать. WM_MOUSE_LEAVE из таких.
     
  17. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine
    Codeblight
    Имея координаты и размеры трея и размеры каждой кнопки, можно вычислить координаты кнопок.

    Всё это нужно учитывать.
     
  18. Demon666

    Demon666 New Member

    Публикаций:
    0
    Регистрация:
    19 май 2006
    Сообщения:
    99
    гы-гы.
    Вообще-то имелось в виду совсем другое не твое окно а ToolbarWindow32(system tray) гы-гы.
    Конкретнее:
    Вот сорс (MASM32)
    Прошу не пинать сорс писался на коленках за ~30 минут
    Что делает, при запуске появиться окно
    после его сворачивания появляется иконка в трее
    при наведении на эту иконку появляется ToolTips(Balloon)
    на нем много-много символов гы-гы
    удалить ToolTips можно с помощью вызова меню правой кнопкой мыши и также убить иконку в system tray`е
    вам только остается догадаться, как удалить ToolTips по таймеру и когда уберется с иконки курсор хе-хе
    интересно кто все-таки первый догадается, как это сделать…

    Код (Text):
    1. .586
    2. .model flat,stdcall
    3. option casemap:none
    4. include windows.inc
    5. include user32.inc
    6. include kernel32.inc
    7. include shell32.inc
    8. includelib user32.lib
    9. includelib kernel32.lib
    10. includelib shell32.lib
    11.  
    12. m2m  MACRO M1,M2
    13.     push M2
    14.     pop  M1
    15. ENDM
    16.  
    17. WM_SHELLNOTIFY equ WM_USER+5
    18. IDI_TRAY equ 0
    19. IDM_RESTORE equ 1000
    20. IDM_EXIT    equ 1010
    21. WinMain PROTO :DWORD,:DWORD,:DWORD,:DWORD
    22.  
    23. .data
    24. ClassName   db "TrayIconWinClass",0
    25. AppName         db "TrayIcon Demo",0
    26. RestoreString   db "&Kill ToolTips",0
    27. ExitString      db "E&xit Program",0
    28. TOOLTIPS_CLASS db "tooltips_class32",0
    29. szToolTipsCaption db "Info",0
    30. szBuffer db "Можно добавить в угол иконки точку нестандартного цвета, и найти её (GetPixel). Так найдёшь координаты."
    31. szBuffer1 db "попробуйте представить - не оч быстрая затея точки перебирать ;-) Может есть какие-нибудь более простые варианты ? :) Возможно есть у кого идеи как стандартный Balloon сделать автозакрывающимся или подобные ?",0
    32.  
    33. .data?
    34. hInstance   dd ?
    35. note NOTIFYICONDATA <>
    36. hPopupMenu  dd ?
    37. hToolTips dd ?
    38. hToolBar dd ?
    39. ;szBuffer db 2048 dup (?)
    40.  
    41. .code
    42. start:
    43.     invoke GetModuleHandle, NULL
    44.     mov    hInstance,eax
    45.     invoke WinMain, hInstance,NULL,NULL, SW_SHOWDEFAULT
    46.     invoke ExitProcess,eax
    47.  
    48. WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
    49.     LOCAL wc:WNDCLASSEX
    50.     LOCAL msg:MSG
    51.     LOCAL hwnd:HWND
    52.     mov   wc.cbSize,SIZEOF WNDCLASSEX
    53.     mov   wc.style, CS_HREDRAW or CS_VREDRAW or CS_DBLCLKS
    54.     mov   wc.lpfnWndProc, OFFSET WndProc
    55.     mov   wc.cbClsExtra,NULL
    56.     mov   wc.cbWndExtra,NULL
    57.     push  hInst
    58.     pop   wc.hInstance
    59.     mov   wc.hbrBackground,COLOR_APPWORKSPACE
    60.     mov   wc.lpszMenuName,NULL
    61.     mov   wc.lpszClassName,OFFSET ClassName
    62.     invoke LoadIcon,NULL,IDI_APPLICATION
    63.     mov   wc.hIcon,eax
    64.     mov   wc.hIconSm,eax
    65.     invoke LoadCursor,NULL,IDC_ARROW
    66.     mov   wc.hCursor,eax
    67.     invoke RegisterClassEx, addr wc
    68.     invoke CreateWindowEx,WS_EX_CLIENTEDGE,ADDR ClassName,ADDR AppName,\
    69.            WS_OVERLAPPED+WS_CAPTION+WS_SYSMENU+WS_MINIMIZEBOX+WS_MAXIMIZEBOX+WS_VISIBLE,CW_USEDEFAULT,\
    70.            CW_USEDEFAULT,350,200,NULL,NULL,\
    71.            hInst,NULL
    72.     mov   hwnd,eax
    73.     .while TRUE
    74.         invoke GetMessage, ADDR msg,NULL,0,0
    75.         .BREAK .IF (!eax)
    76.         invoke TranslateMessage, ADDR msg
    77.         invoke DispatchMessage, ADDR msg
    78.     .endw
    79.     mov eax,msg.wParam
    80.     ret
    81. WinMain endp
    82.  
    83. WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
    84.     LOCAL point:POINT
    85.     LOCAL toolinfo:TOOLINFO
    86.     .if uMsg==WM_CREATE
    87.         invoke CreatePopupMenu
    88.         mov hPopupMenu,eax
    89.         invoke AppendMenu,hPopupMenu,MF_STRING,IDM_RESTORE,addr RestoreString
    90.         invoke AppendMenu,hPopupMenu,MF_STRING,IDM_EXIT,addr ExitString
    91.     .elseif uMsg==WM_DESTROY
    92.         invoke PostQuitMessage,NULL
    93.     .elseif uMsg==WM_SIZE
    94.         .if wParam==SIZE_MINIMIZED
    95.             mov note.cbSize,sizeof NOTIFYICONDATA
    96.             push hWnd
    97.             pop note.hwnd
    98.             mov note.uID,IDI_TRAY
    99.             mov note.uFlags,NIF_ICON+NIF_MESSAGE
    100.             mov note.uCallbackMessage,WM_SHELLNOTIFY
    101.             invoke LoadIcon,NULL,IDI_WINLOGO
    102.             mov note.hIcon,eax
    103.             invoke lstrcpy,addr note.szTip,addr AppName
    104.             invoke ShowWindow,hWnd,SW_HIDE
    105.             invoke Shell_NotifyIcon,NIM_ADD,addr note
    106.         .endif
    107.     .elseif uMsg==WM_COMMAND
    108.         .if lParam==0
    109.             mov eax,wParam
    110.             .if ax==IDM_EXIT
    111.                 invoke Shell_NotifyIcon,NIM_DELETE,addr note
    112.                 invoke DestroyWindow,hWnd
    113.             .elseif ax==IDM_RESTORE
    114.                 mov toolinfo.cbSize,SIZEOF TOOLINFO
    115.                 mov toolinfo.uFlags,TTF_IDISHWND or TTF_TRACK
    116.                 m2m toolinfo.hWnd,NULL
    117.                 m2m toolinfo.uId,hToolBar
    118.                 mov toolinfo.hInst,NULL
    119.                 invoke SendMessage,hToolTips,TTM_TRACKACTIVATE,FALSE,ADDR toolinfo
    120.                 invoke DestroyWindow,hToolTips
    121.                 mov hToolTips,0
    122.             .endif
    123.         .endif
    124.     .elseif uMsg==WM_SHELLNOTIFY
    125.         .if wParam==IDI_TRAY
    126.             .if lParam==WM_RBUTTONDOWN
    127.                 invoke GetCursorPos,addr point
    128.                 invoke TrackPopupMenu,hPopupMenu,TPM_RIGHTALIGN,point.x,point.y,NULL,hWnd,NULL
    129.             .elseif lParam==WM_MOUSEMOVE
    130.                 .if hToolTips==0
    131.                     invoke MessageBeep,10
    132.                     invoke GetCursorPos,ADDR point
    133.                     invoke WindowFromPoint,point.x,point.y
    134.                     mov hToolBar,eax
    135.                     invoke CreateWindowEx,WS_EX_TOPMOST,ADDR TOOLTIPS_CLASS,NULL,TTS_ALWAYSTIP or TTS_BALLOON,CW_USEDEFAULT, CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,hWnd,NULL,hInstance,NULL
    136.                     mov hToolTips,eax
    137.                     mov toolinfo.cbSize,SIZEOF TOOLINFO
    138.                     mov toolinfo.uFlags,TTF_IDISHWND or TTF_TRACK
    139.                     m2m toolinfo.hWnd,NULL
    140.                     m2m toolinfo.uId,hToolBar
    141.                     mov toolinfo.hInst,NULL
    142.                     mov toolinfo.lpszText,OFFSET szBuffer
    143.                     invoke SendMessage,hToolTips,TTM_ADDTOOL,0,ADDR toolinfo
    144.                     invoke SendMessage,hToolTips,TTM_SETMAXTIPWIDTH,0,500
    145.                     invoke SendMessage,hToolTips,TTM_SETTITLE,1,ADDR szToolTipsCaption
    146.                     mov ecx,point.y
    147.                     shl ecx,10h
    148.                     mov eax,point.x
    149.                     or ecx,eax
    150.                     invoke SendMessage,hToolTips,TTM_TRACKPOSITION,0,ecx
    151.                     invoke SendMessage,hToolTips,TTM_TRACKACTIVATE,TRUE,ADDR toolinfo
    152.                 .endif
    153.             .endif
    154.         .endif
    155.     .else
    156.         invoke DefWindowProc,hWnd,uMsg,wParam,lParam       
    157.         ret
    158.     .endif
    159.     xor eax,eax
    160.     ret
    161. WndProc endp
    162.  
    163. end start
     
  19. Codeblight

    Codeblight New Member

    Публикаций:
    0
    Регистрация:
    17 окт 2005
    Сообщения:
    60
    Адрес:
    Russia
    Получить инфу о кнопке, над которой курсор расположен через сообщение нельзя, т.к. адресное пространство не моё, можно конечно инжектнуть эксплорер, но авиры и фаровалы ругаться будут ;( Вчера пробовал - эксплорер падает... После 3х часового танца с бубном от больших тултипов решил пока отказаться ;) Спасибо всем за идеи, позже вернусь к вопросу ;)
     
  20. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine
    Codeblight
    Смотря какое сообщение. Если не нужно передавать указатели, то никуда инжектиться не надо. К примеру, TB_GETBUTTONSIZE прекрасно обрабатывается и без инжекта.