1

Тема: AHK: Как создавать подсказки для элементов GUI?

Собственно как например при наведении курсора на "красный крестик" вывести подсказку "Сохранить и выйти", вместо стандартного "Закрыть", и желательно с меньшей задержкой?

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

2

Re: AHK: Как создавать подсказки для элементов GUI?

Может пригодиться: AHK. Отключение кнопки закрытия окна [X].

3

Re: AHK: Как создавать подсказки для элементов GUI?

Что-то не дошло, где там хоть намёк на создание подсказки...

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

4

Re: AHK: Как создавать подсказки для элементов GUI?

Можно отключить кнопку "закрыть" [X] и создать свою кнопку "сохранить и выйти". Как-то ещё можно создать кнопку прямо в заголовке.

Если нужны подсказки просто к элементам управления (не системное меню), то это будет ещё проще.

5

Re: AHK: Как создавать подсказки для элементов GUI?

Как-то ещё можно создать кнопку прямо в заголовке.
...
Если нужны подсказки просто к элементам управления (не системное меню), то это будет ещё проще.

А как?

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

6

Re: AHK: Как создавать подсказки для элементов GUI?

Можно поискать. Чем дальше в лес, тем больше дров.

7

Re: AHK: Как создавать подсказки для элементов GUI?

Искал, но примеры на дельфи и С++ для нуба, как об стенку горохом.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

8

Re: AHK: Как создавать подсказки для элементов GUI?

Можно создать окно вообще без заголовка, нарисовать кнопки (и, если необходимо, заголовок) самостоятельно.

9

Re: AHK: Как создавать подсказки для элементов GUI?

У меня на Win7 вот так работает:

global WM_NCMOUSELEAVE := 0x2A2, WM_NCMOUSEMOVE := 0xA0, HTCLOSE := 20
      , HWINEVENTHOOK, HookProcAdr, EVENT_OBJECT_SHOW := 0x8002

Gui, Show, w300 h200

HookProcAdr := RegisterCallback("HookProc", "F" )
OnMessage(WM_NCMOUSEMOVE, "MonitorMessage")
OnMessage(WM_NCMOUSELEAVE, "MonitorMessage")
return

GuiClose:
   ExitApp

MonitorMessage(wp, lp, msg)
{
   if (msg = WM_NCMOUSEMOVE)
   {
      if (wp = HTCLOSE)
      {
         if !HWINEVENTHOOK
         {
            HWINEVENTHOOK := API_SetWinEventHook(EVENT_OBJECT_SHOW, EVENT_OBJECT_SHOW, 0, HookProcAdr, 0,0,0)
            ToolTip Сохранить и выйти,,, 10
         }
      }
      else
      {
         DllCall("UnhookWinEvent", Ptr, HWINEVENTHOOK), HWINEVENTHOOK := ""
         ToolTip,,,, 10
      }
   }
   else if (msg = WM_NCMOUSELEAVE)
   {
      DllCall("UnhookWinEvent", Ptr, HWINEVENTHOOK), HWINEVENTHOOK := ""
      ToolTip,,,, 10
   }
}

HookProc(hWinEventHook, event, hwnd, idObject, idChild, dwEventThread, dwmsEventTime)
{
   WinGetClass, Class, ahk_id %hwnd%
   if (Class = "#32774")
      WinClose, ahk_id %hwnd%
}

API_SetWinEventHook(eventMin, eventMax, hmodWinEventProc, lpfnWinEventProc, idProcess, idThread, dwFlags)
{
   return DllCall("SetWinEventHook" , UInt, eventMin
                                    , UInt, eventMax
                                    , Ptr, hmodWinEventProc
                                    , Ptr, lpfnWinEventProc
                                    , UInt, idProcess
                                    , UInt, idThread
                                    , UInt, dwFlags, Ptr)
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

10

Re: AHK: Как создавать подсказки для элементов GUI?

teadrinker
То что надо.
Спасибо Вам.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

11

Re: AHK: Как создавать подсказки для элементов GUI?

ypppu пишет:

Можно создать окно вообще без заголовка, нарисовать кнопки (и, если необходимо, заголовок) самостоятельно.

А как к кнопке сделать появляющуюся подсказку?

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

12

Re: AHK: Как создавать подсказки для элементов GUI?

serzh82saratov пишет:

А как к кнопке сделать появляющуюся подсказку?

global WM_NCMOUSELEAVE := 0x2A2, WM_NCMOUSEMOVE := 0xA0, WM_MOUSEMOVE := 0x200, WM_MOUSELEAVE := 0x2A3
      , HTCLOSE := 20, HWINEVENTHOOK, HookProcAdr, EVENT_OBJECT_SHOW := 0x8002, hButton

Gui, Add, Button, x230 y167 w60 h23 hwndhButton, OK
Gui, Show, w300 h200

HookProcAdr := RegisterCallback("HookProc", "F" )
OnMessage(WM_NCMOUSEMOVE, "MonitorMessage")
OnMessage(WM_NCMOUSELEAVE, "MonitorMessage")
OnMessage(WM_MOUSEMOVE, "MonitorMessage")
OnMessage(WM_MOUSELEAVE, "MonitorMessage")
return

GuiClose:
   ExitApp

MonitorMessage(wp, lp, msg, hwnd)
{
   static ToolTip
   if (msg = WM_NCMOUSEMOVE)
   {
      if (wp = HTCLOSE)
      {
         if !HWINEVENTHOOK
            ToolTipShow("Сохранить и выйти", 10)
      }
      else if HWINEVENTHOOK
         ToolTipDestroy(10)
   }
   else if (HWINEVENTHOOK && msg = WM_NCMOUSELEAVE)
      ToolTipDestroy(10)
      
   if (msg = WM_MOUSEMOVE && hwnd = hButton && !ToolTip)
      ToolTip, Подсказка для кнопки,,, % ToolTip := 9
   else if (ToolTip && (hwnd != hButton || msg = WM_MOUSELEAVE))
      ToolTip, % ToolTip := "",,, 9
}

ToolTipShow(Text, N)
{
   HWINEVENTHOOK := SetWinEventHook(EVENT_OBJECT_SHOW, EVENT_OBJECT_SHOW, 0, HookProcAdr, 0,0,0)
   ToolTip, % Text,,, N
}

ToolTipDestroy(N)
{
   DllCall("UnhookWinEvent", Ptr, HWINEVENTHOOK), HWINEVENTHOOK := ""
   ToolTip,,,, N
}

HookProc(hWinEventHook, event, hwnd, idObject, idChild, dwEventThread, dwmsEventTime)
{
   WinGetClass, Class, ahk_id %hwnd%
   if (Class = "#32774")
      WinClose, ahk_id %hwnd%
}

SetWinEventHook(eventMin, eventMax, hmodWinEventProc, lpfnWinEventProc, idProcess, idThread, dwFlags)
{
   return DllCall("SetWinEventHook" , UInt, eventMin
                                    , UInt, eventMax
                                    , Ptr, hmodWinEventProc
                                    , Ptr, lpfnWinEventProc
                                    , UInt, idProcess
                                    , UInt, idThread
                                    , UInt, dwFlags, Ptr)
}

Надо ещё проверить, не остаётся ли ToolTip, если резко убрать курсор с кнопки за пределы окна. Если остаётся, нужно ещё дополнительно убивать с помощью таймера. Но у меня, вроде, нормально и так.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

13

Re: AHK: Как создавать подсказки для элементов GUI?

Вроде всё хорошо работает. Единственно не дошло как ещё одну кнопку с подсказкой добавить.

global WM_NCMOUSELEAVE := 0x2A2, WM_NCMOUSEMOVE := 0xA0, WM_MOUSEMOVE := 0x200, WM_MOUSELEAVE := 0x2A3
      , HTCLOSE := 20, HWINEVENTHOOK, HookProcAdr, EVENT_OBJECT_SHOW := 0x8002, hButton

Gui, Add, Button, x230 y167 w60 h23 hwndhButton, OK
Gui, Add, Button, x2  y1  w60 h23 hwndhButton1, OK
Gui, Show, w300 h200

HookProcAdr := RegisterCallback("HookProc", "F" )
OnMessage(WM_NCMOUSEMOVE, "MonitorMessage")
OnMessage(WM_NCMOUSELEAVE, "MonitorMessage")
OnMessage(WM_MOUSEMOVE, "MonitorMessage")
OnMessage(WM_MOUSELEAVE, "MonitorMessage")
return
 

MonitorMessage(wp, lp, msg, hwnd)
{
   static ToolTip
   if (msg = WM_NCMOUSEMOVE)
   {
      if (wp = HTCLOSE)
      {
         if !HWINEVENTHOOK
            ToolTipShow("Сохранить и выйти", 10)
      }
      else if HWINEVENTHOOK
         ToolTipDestroy(10)
   }
   else if (HWINEVENTHOOK && msg = WM_NCMOUSELEAVE)
      ToolTipDestroy(10)
      
   if (msg = WM_MOUSEMOVE && hwnd = hButton && !ToolTip)
      ToolTip, Подсказка для кнопки,,, % ToolTip := 9     ;%  
   else if (msg = WM_MOUSEMOVE && hwnd = hButton1 && !ToolTip)
      ToolTip, Подсказка для кнопки 1,,, % ToolTip := 9   ;%  
   else if (ToolTip && (hwnd != hButton || msg = WM_MOUSELEAVE))      
      ToolTip, % ToolTip := "",,, 9   ;%  
}

ToolTipShow(Text, N)
{
   HWINEVENTHOOK := API_SetWinEventHook(EVENT_OBJECT_SHOW, EVENT_OBJECT_SHOW, 0, HookProcAdr, 0,0,0)
   ToolTip, % Text,,, N  ;%  
}

ToolTipDestroy(N)
{
   DllCall("UnhookWinEvent", Ptr, HWINEVENTHOOK), HWINEVENTHOOK := ""
   ToolTip,,,, N
}

HookProc(hWinEventHook, event, hwnd, idObject, idChild, dwEventThread, dwmsEventTime)
{
   WinGetClass, Class, ahk_id %hwnd%
   if (Class = "#32774")
      WinClose, ahk_id %hwnd%
}

API_SetWinEventHook(eventMin, eventMax, hmodWinEventProc, lpfnWinEventProc, idProcess, idThread, dwFlags)
{
   return DllCall("SetWinEventHook" , UInt, eventMin
                                    , UInt, eventMax
                                    , Ptr, hmodWinEventProc
                                    , Ptr, lpfnWinEventProc
                                    , UInt, idProcess
                                    , UInt, idThread
                                    , UInt, dwFlags, Ptr)
}
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

14

Re: AHK: Как создавать подсказки для элементов GUI?

Лучше будет, если разделить мониторинг для кнопки системного меню и остальных. Кроме того, всем ToolTip'ам можно присвоить один и тот же номер, ведь они не могут показываться параллельно.

global WM_NCMOUSELEAVE := 0x2A2, WM_NCMOUSEMOVE := 0xA0, WM_MOUSEMOVE := 0x200, WM_MOUSELEAVE := 0x2A3
      , HTCLOSE := 20, HWINEVENTHOOK, HookProcAdr, EVENT_OBJECT_SHOW := 0x8002, hButton1, hButton2

Gui, Add, Button, x165  y167  w60 h23 hwndhButton1, Cancel
Gui, Add, Button, x230 y167 w60 h23 hwndhButton2, OK
Gui, Show, w300 h200

HookProcAdr := RegisterCallback("HookProc", "F" )
OnMessage(WM_NCMOUSEMOVE, "NonClientAreaMessages")
OnMessage(WM_NCMOUSELEAVE, "NonClientAreaMessages")
OnMessage(WM_MOUSEMOVE, "ClientAreaMessages")
OnMessage(WM_MOUSELEAVE, "ClientAreaMessages")
return

GuiClose:
   ExitApp

NonClientAreaMessages(wp, lp, msg, hwnd)
{
   if (msg = WM_NCMOUSEMOVE)
   {
      if (wp = HTCLOSE)
      {
         if !HWINEVENTHOOK
            ToolTipShow("Подсказка для кнопки Close", 1)
      }
      else if HWINEVENTHOOK
         ToolTipDestroy(1)
   }
   else if (HWINEVENTHOOK && msg = WM_NCMOUSELEAVE)
      ToolTipDestroy(1)
}

ClientAreaMessages(wp, lp, msg, hwnd)
{
   static ToolTipExist
   if (msg = WM_MOUSEMOVE)
   {
      if (hwnd = hButton1 && !ToolTipExist)
         ToolTip, Подсказка для кнопки Cancel,,, % ToolTipExist := 1
      else if (hwnd = hButton2 && !ToolTipExist)
         ToolTip, Подсказка для кнопки OK,,, % ToolTipExist := 1
      else if (hwnd !~= (hButton1 "|" hButton2) && ToolTipExist)
         ToolTip, % ToolTipExist := "",,, 1
   }
   else if (msg = WM_MOUSELEAVE)
      ToolTip, % ToolTipExist := "",,, 1
}
   

ToolTipShow(Text, N)
{
   HWINEVENTHOOK := SetWinEventHook(EVENT_OBJECT_SHOW, EVENT_OBJECT_SHOW, 0, HookProcAdr, 0,0,0)
   ToolTip, % Text,,, N
}

ToolTipDestroy(N)
{
   DllCall("UnhookWinEvent", Ptr, HWINEVENTHOOK), HWINEVENTHOOK := ""
   ToolTip,,,, N
}

HookProc(hWinEventHook, event, hwnd, idObject, idChild, dwEventThread, dwmsEventTime)
{
   WinGetClass, Class, ahk_id %hwnd%
   if (Class = "#32774")
      WinHide, ahk_id %hwnd%
}

SetWinEventHook(eventMin, eventMax, hmodWinEventProc, lpfnWinEventProc, idProcess, idThread, dwFlags)
{
   return DllCall("SetWinEventHook" , UInt, eventMin
                                    , UInt, eventMax
                                    , Ptr, hmodWinEventProc
                                    , Ptr, lpfnWinEventProc
                                    , UInt, idProcess
                                    , UInt, idThread
                                    , UInt, dwFlags, Ptr)
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

15

Re: AHK: Как создавать подсказки для элементов GUI?

Немного отредактировал предыдущий код.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

16

Re: AHK: Как создавать подсказки для элементов GUI?

И ещё в функции HookProc() лучше использовать WinHide вместо WinClose, иначе системная подсказка вообще больше не появится в этой сессии ни над каким объектом.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

17

Re: AHK: Как создавать подсказки для элементов GUI?

И ещё в функции HookProc() лучше использовать WinHide вместо WinClose, иначе системная подсказка вообще больше не появится в этой сессии ни над каким объектом.

А я правильно понимаю, что HookProc гасит системную подсказку "Закрыть"? Что-то тяжело даётся понимание кода, полное незнание WinApi вводит в ступор.
Попытался сам сделать задуманное:

+ открыть спойлер

global PrControl 
    , Help_OK := "Подсказка для кнопки OK" 
    , Help_Cancel := "Подсказка для кнопки Cancel"
    , Help_NC_20 := "Подсказка для кнопки Закрыть" 
    , Help_NC_8 := "Подсказка для кнопки Свернуть"
    
Gui, Add, Button, y100, Cancel
Gui, Add, Button, x+20 yp wp, OK
Gui, Show 

OnMessage(0x200, "WM_MOUSEMOVE")
OnMessage(0xA0, "WM_NCMOUSEMOVE")
OnMessage(0x2A2, "MOUSELEAVE")
return 

MOUSELEAVE() {  
    ToolTip % PrControl := ""
}

WM_MOUSEMOVE() {  
    If (A_GuiControl <> PrControl)
    {
        PrControl := A_GuiControl
        ToolTip, % Help_%PrControl% 
    }     
}

WM_NCMOUSEMOVE(wp) { 
    If (PrControl <> "NC_" wp)
    {
        PrControl := "NC_" wp
        ToolTip, % Help_%PrControl%           
    }           
}

GuiClose:
   ExitApp

на сравнении, хотел бы понять хотя-бы функциональные различия.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

18

Re: AHK: Как создавать подсказки для элементов GUI?

serzh82saratov пишет:

А я правильно понимаю, что HookProc гасит системную подсказку "Закрыть"?

Правильно.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

19

Re: AHK: Как создавать подсказки для элементов GUI?

teadrinker
Для меня там всё очень сложно. А возможно-ли просто при старте убить нужные системные подсказки?

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

20

Re: AHK: Как создавать подсказки для элементов GUI?

Только так же через хук, т. к. убить данное окно можно наверняка только при его появлении, у меня иначе не вышло.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder