1

Тема: AHK: Изменить размер шрифта TOOLTIP

Возможно ли изменить размер  шрифта  именно tooltip ?
Пример
Tooltip, info, ; размер шрифта.
Или какимто другим образом.
Пытался найти по справкам но безуспешно.
Спасибо зарание !

Win10 x64

2

Re: AHK: Изменить размер шрифта TOOLTIP

Свойства всплывающей подсказки задаются в системе:

rundll32.exe shell32.dll Control_RunDLL desk.cpl,desc,

3

Re: AHK: Изменить размер шрифта TOOLTIP

Понял спасибо!

Win10 x64

4

Re: AHK: Изменить размер шрифта TOOLTIP

Шрифт конкретного окна ToolTip можно и скриптом задать, только придётся создавать его вручную через winapi, а не командой.

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

5

Re: AHK: Изменить размер шрифта TOOLTIP

Пример:

myTrayTip := new ToolTip({ text: "Модифицированный TrayTip"
                         , title: "AutoHotkey"
                         , CloseButton: true
                         , Icon: 1              ; 1 — Info, 2 — Warning, 3 — Error, n > 3 — предполагается hIcon
                         , TrayTip: true
                         , FontSize: 18
                         , FontName: "Verdana" })

myToolTip := new ToolTip({ text: "Это модифицированный ToolTip.           `nОн сейчас прозрачен для кликов мыши."
                         , title: "AutoHotkey"
                         , Icon: 2
                         , transparent: true    ; если true — окно прозрачно для мыши
                         , BallonTip: true      ; BalloonTip — это ToolTip с хвостиком
                         , FontSize: 28
                         , FontName: "Times New Roman"
                         , FontStyle: "italic" })
Sleep, 2500
myToolTip.Hide()  ; скрываем
myToolTip.SetText("Можно менять текст`nи расположение")  ; меняем текст
Sleep, 500

myToolTip.Show(50, 50)  ; показываем в координатах x = 50, y = 50
Sleep, 2000

myToolTip.Hide()
myToolTip.SetText("I'm near the mouse cursor!")
Sleep, 500

myToolTip.Show()  ; без координат — в районе курсора
Sleep, 2500

myToolTip := ""   ; уничтожаем ToolTip

myTrayTip.SetText("Goodbye!")
Sleep, 1000
myTrayTip := ""
ExitApp

class ToolTip {
   __New( options )  {
/*
Возможные опции:
   text, title
   icon (1: Info, 2: Warning; 3: Error; n > 3: предполагается hIcon)
   CloseButton (true или false)
   transparent (true или false)
   x, y — координаты, если не указаны, ToolTip появится вблизи курсора
   BallonTip (BalloonTip — это ToolTip с хвостиком, true или false)
   TrayTip — будет показан BalloonTip у иконки скрипта в трее, параметры x, y, и BalloonTip игнорируются
   FontName, FontSize
   FontStyle (bold, italic, underline, strikeout в любом сочетании через пробел)
*/
      for k, v in options
         this[k] := v
      ((this.icon || this.CloseButton) && this.title = "") && this.title := " "
      this._CreateToolTip()
      this.Show()
   }
   
   _CreateToolTip()  {
      static WS_POPUP := 0x80000000, WS_EX_TOPMOST := 8, WS_EX_TRANSPARENT := 0x20
           , TTS_NOPREFIX := 2, TTS_ALWAYSTIP := 1, TTS_BALLOON := 0x40, TTS_CLOSE := 0x80
           , TTF_TRACK := 0x20, TTF_ABSOLUTE := 0x80, WM_GETFONT := 0x31
           , mult := A_IsUnicode ? 2 : 1, szTI := A_PtrSize = 4 ? 48 : 72, szLF := 28 + 32 * mult
           , LOGPIXELSY := 90, ANTIALIASED_QUALITY := 4
           , styles := { bold: {value: 700, offset: 16, size: "Int"}
                       , italic: {value: 1, offset: 20, size: "Char"}
                       , underline: {value: 1, offset: 21, size: "Char"}
                       , strikeout: {value: 1, offset: 22, size: "Char"} }
     
      VarSetCapacity(TOOLINFO, szTI, 0)
      this.pTI := &TOOLINFO
      NumPut(szTI, TOOLINFO)
      (this.TrayTip && this.BallonTip := true)
      NumPut(TTF_TRACK|(this.BallonTip ? 0 : TTF_ABSOLUTE), &TOOLINFO + 4)
      
      this.hwnd := DllCall("CreateWindowEx", UInt, WS_EX_TOPMOST|(this.transparent ? WS_EX_TRANSPARENT : 0)
        , Str, "tooltips_class32", Str, ""
        , UInt, WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP | (this.CloseButton ? TTS_CLOSE : 0) | (this.BallonTip ? TTS_BALLOON : 0)
        , Int, 0, Int, 0, Int, 0, Int, 0, Ptr, 0, Ptr, 0, Ptr, 0, Ptr, 0)
      
      hPrevFont := this._SendMessage(WM_GETFONT)
      VarSetCapacity(LOGFONT, szLF, 0)
      DllCall("GetObject", Ptr, hPrevFont, Int, szLF, Ptr, &LOGFONT)
      DllCall("DeleteObject", Ptr, hPrevFont)
      
      if this.FontSize  {
         hDC := DllCall("GetDC", Ptr, this.hwnd, Ptr)
         height := -DllCall("MulDiv", Int, this.FontSize, Int, DllCall("GetDeviceCaps", Ptr, hDC, Int, LOGPIXELSY), Int, 72)
         DllCall("ReleaseDC", Ptr, this.hwnd, Ptr, hDC)
         NumPut(height, LOGFONT, "Int")
      }
      FontStyle := this.FontStyle
      Loop, parse, FontStyle, %A_Space%
         if obj := styles[A_LoopField]
            NumPut(obj.value, &LOGFONT + obj.offset, obj.size)

      (this.FontSize > 24 && NumPut(ANTIALIASED_QUALITY, &LOGFONT + 26, "Char"))
      this.FontName && StrPut(this.FontName, &LOGFONT + 28, StrLen(this.FontName) * mult, A_IsUnicode ? "UTF-16" : "CP0")
      this.hFont := DllCall("CreateFontIndirect", Ptr, &LOGFONT, Ptr)
      this._SetInfo()
   }
   
   _SetInfo()  {
      static WM_USER := 0x400, WM_SETFONT := 0x30
           , TTM_ADDTOOL := WM_USER + (A_IsUnicode ? 50 : 4)
           , TTM_SETTITLE := WM_USER + (A_IsUnicode ? 33 : 32)
      
      this._SendMessage(WM_SETFONT, this.hFont, 1)
      this._SendMessage(TTM_ADDTOOL, 0, this.pTI)
      this._SendMessage(TTM_SETTITLE, this.icon, &(t := this.title))
      this.SetText(this.text)
   }
   
   SetText(text)  {
      static WM_USER := 0x400, TTM_UPDATETIPTEXT := WM_USER + (A_IsUnicode ? 57 : 12)
      NumPut(&text, this.pTI + (A_PtrSize = 4 ? 36 : 48))
      this._SendMessage(TTM_UPDATETIPTEXT, 0, this.pTI)
   }
   
   Show(x := "", y := "")  {
      static WM_USER := 0x400, TTM_TRACKACTIVATE := WM_USER + 17, TTM_TRACKPOSITION := WM_USER + 18
      
      if this.TrayTip
         this._GetTrayIconCoords(xTT, yTT)
      else  {
         xTT := x, yTT := y
         (xTT = "" && xTT := this.x)
         (yTT = "" && yTT := this.y)
      
         if (xTT = "" || yTT = "") {
            CoordMode, Mouse
            MouseGetPos, xm, ym
            (xTT = "" && xTT := xm + 10)
            (yTT = "" && yTT := ym + 10)
         }
      }
      this._SendMessage(TTM_TRACKPOSITION, 0, xTT|(yTT<<16))
      this._SendMessage(TTM_TRACKACTIVATE, 1, this.pTI)
      
      if this.BallonTip
         xMax := A_ScreenWidth, yMax := A_ScreenHeight
      else  {
         WinGetPos,,, W, H, % "ahk_id" this.hwnd
         xMax := A_ScreenWidth - W - 10
         yMax := A_ScreenHeight - H - 10
      }
      
      if (xTT > xMax || yTT > yMax)  {
         (xTT > xMax && xTT := xMax)
         (yTT > yMax && yTT := yMax)
         this._SendMessage(TTM_TRACKPOSITION, 0, xTT|(yTT<<16))
      }
   }
   
   Hide()  {
      static WM_USER := 0x400, TTM_TRACKACTIVATE := WM_USER + 17
      this._SendMessage(TTM_TRACKACTIVATE, 0, this.pTI)
   }
   
   _SendMessage(msg, wp := 0, lp := 0)  {
      Return DllCall("SendMessage", Ptr, this.hwnd, UInt, msg, Ptr, wp, Ptr, lp, Ptr)
   }
   
   _GetTrayIconCoords(ByRef x, ByRef y)  {
      static WM_USER := 0x400, TB_BUTTONCOUNT := WM_USER + 24, TB_GETBUTTON := WM_USER + 23, TB_GETITEMRECT := WM_USER + 29
           , PtrSize := A_Is64bitOS ? 8 : 4, szTBBUTTON := 8 + PtrSize*3, szTRAYDATA := 16 + PtrSize*2
         
      ControlGet, hTray, hwnd,, ToolbarWindow321, ahk_class Shell_TrayWnd
      WinWait, ahk_id %hTray%
      WinGet, PID, PID
      WinGetPos, xTB, yTB
      
      if !IsObject(RemoteBuff := new RemoteBuffer(PID, szTBBUTTON))  {
         x := xTB, y := yTB
         MsgBox, % "Не удалось создать удалённый буфер`nОшибка " A_LastError
         Return
      }
      SendMessage, TB_BUTTONCOUNT
      Loop % ErrorLevel  {
         SendMessage, TB_GETBUTTON, A_Index - 1, RemoteBuff.ptr
         pTBBUTTON := RemoteBuff.Read(szTBBUTTON)
         pTRAYDATA := RemoteBuff.Read(szTRAYDATA, NumGet(pTBBUTTON + 8 + PtrSize) - RemoteBuff.ptr)
         hWnd := NumGet(pTRAYDATA + 0, PtrSize = 4 ? "UInt" : "UInt64")
         if (hWnd = A_ScriptHwnd)  {
            SendMessage, TB_GETITEMRECT, A_Index - 1, RemoteBuff.ptr
            pRECT := RemoteBuff.Read(16)
            x := NumGet(pRECT + 0, "Int") + xTB + 5, y := NumGet(pRECT + 4, "Int") + yTB + 5
            break
         }
      }
      RemoteBuff := "", ((x = "" || y = "") && x := xTB, y := yTB)
   }
   
   __Delete()  {
      DllCall("DeleteObject", Ptr, this.hFont)
      DllCall("DestroyWindow", Ptr, this.hwnd)
   }
}

Class RemoteBuffer
{
   __New(PID, size)  {
      static PROCESS_VM_OPERATION := 0x8, PROCESS_VM_WRITE := 0x20, PROCESS_VM_READ := 0x10
         , MEM_COMMIT := 0x1000, PAGE_READWRITE := 0x4
         
      if !(this.hProc := DllCall("OpenProcess", UInt, PROCESS_VM_OPERATION|PROCESS_VM_READ|PROCESS_VM_WRITE, Int, 0, UInt, PID, Ptr))
         Return
      
      if !(this.ptr := DllCall("VirtualAllocEx", UInt, this.hProc, UInt, 0, UInt, size, UInt, MEM_COMMIT, UInt, PAGE_READWRITE, Ptr))
         Return, "", DllCall("CloseHandle", Ptr, this.hProc)
   }
   
   __Delete()  {
      DllCall("VirtualFreeEx", Ptr, this.hProc, Ptr, this.ptr, UInt, 0, UInt, MEM_RELEASE := 0x8000)
      DllCall("CloseHandle", Ptr, this.hProc)
   }
   
   Read(size, offset = 0)  {
      static LocalBuff
      VarSetCapacity(LocalBuff, size, 0)
      if !DllCall("ReadProcessMemory", Ptr, this.hProc, Ptr, this.ptr + offset, Ptr, &LocalBuff, UInt, size, UInt, 0)
         Return, 0, DllCall("MessageBox", Ptr, 0, Str, "Не удалось прочитать данные`nОшибка """ A_LastError """", Str, "", UInt, 0)
      
      VarSetCapacity(LocalBuff, -1)
      Return &LocalBuff
   }
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

6

Re: AHK: Изменить размер шрифта TOOLTIP

Нужная штука, думаю в коллекции самое место. Добавить ещё опцию через сколько миллисекунд скрыть.

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

7

Re: AHK: Изменить размер шрифта TOOLTIP

Здесь есть проблема с TrayTip. Я использую недокументированную структуру TRAYDATA для получения hWnd связанного с иконкой окна, а в Windows 10 она, вроде, уже не работает, нужно другой способ искать.

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

8

Re: AHK: Изменить размер шрифта TOOLTIP

Ну уже ToolTip штука нужная, а про TrayTip написать что он довеском тут, с ограничениями.
Или просто ToolTip выложить, раз везде работает.

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

9

Re: AHK: Изменить размер шрифта TOOLTIP

serzh82saratov пишет:

Добавить ещё опцию через сколько миллисекунд скрыть.

Кстати, тоже интересный вопрос. А как можно запрограммировать удаление экземпляра объекта изнутри конструктора?
Первой мыслью было создать таймер на метод __Delete(). Но в этом случае окно-то удаляется, но сам объект в памяти остаётся. Пример:

#Persistent
myToolTip := new ToolTip({ FontSize: 30
                         , text: "Я буду виден 3 секунды"
                         , time: 3000 })
Sleep, 4000
ExitApp

class ToolTip {
   __New( options )  {
/*
Возможные опции:
   text, title
   icon (1: Info, 2: Warning; 3: Error; n > 3: предполагается hIcon)
   CloseButton (true или false)
   transparent (true или false)
   x, y — координаты, если не указаны, ToolTip появится вблизи курсора
   BallonTip (BalloonTip — это ToolTip с хвостиком, true или false)
   TrayTip — будет показан BalloonTip у иконки скрипта в трее, параметры x, y, и BalloonTip игнорируются
   FontName, FontSize
   FontStyle (bold, italic, underline, strikeout в любом сочетании через пробел)
   time — время, через которое ToolTip будет уничтожен
*/
      for k, v in options
         this[k] := v
      ((this.icon || this.CloseButton) && this.title = "") && this.title := " "
      this._CreateToolTip()
      this.Show()
   }
   
   _CreateToolTip()  {
      static WS_POPUP := 0x80000000, WS_EX_TOPMOST := 8, WS_EX_TRANSPARENT := 0x20
           , TTS_NOPREFIX := 2, TTS_ALWAYSTIP := 1, TTS_BALLOON := 0x40, TTS_CLOSE := 0x80
           , TTF_TRACK := 0x20, TTF_ABSOLUTE := 0x80, WM_GETFONT := 0x31
           , mult := A_IsUnicode ? 2 : 1, szTI := A_PtrSize = 4 ? 48 : 72, szLF := 28 + 32 * mult
           , LOGPIXELSY := 90, ANTIALIASED_QUALITY := 4
           , styles := { bold: {value: 700, offset: 16, size: "Int"}
                       , italic: {value: 1, offset: 20, size: "Char"}
                       , underline: {value: 1, offset: 21, size: "Char"}
                       , strikeout: {value: 1, offset: 22, size: "Char"} }
     
      VarSetCapacity(TOOLINFO, szTI, 0)
      this.pTI := &TOOLINFO
      NumPut(szTI, TOOLINFO)
      (this.TrayTip && this.BallonTip := true)
      NumPut(TTF_TRACK|(this.BallonTip ? 0 : TTF_ABSOLUTE), &TOOLINFO + 4)
      
      this.hwnd := DllCall("CreateWindowEx", UInt, WS_EX_TOPMOST|(this.transparent ? WS_EX_TRANSPARENT : 0)
        , Str, "tooltips_class32", Str, ""
        , UInt, WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP | (this.CloseButton ? TTS_CLOSE : 0) | (this.BallonTip ? TTS_BALLOON : 0)
        , Int, 0, Int, 0, Int, 0, Int, 0, Ptr, 0, Ptr, 0, Ptr, 0, Ptr, 0)
      
      hPrevFont := this._SendMessage(WM_GETFONT)
      VarSetCapacity(LOGFONT, szLF, 0)
      DllCall("GetObject", Ptr, hPrevFont, Int, szLF, Ptr, &LOGFONT)
      DllCall("DeleteObject", Ptr, hPrevFont)
      
      if this.FontSize  {
         hDC := DllCall("GetDC", Ptr, this.hwnd, Ptr)
         height := -DllCall("MulDiv", Int, this.FontSize, Int, DllCall("GetDeviceCaps", Ptr, hDC, Int, LOGPIXELSY), Int, 72)
         DllCall("ReleaseDC", Ptr, this.hwnd, Ptr, hDC)
         NumPut(height, LOGFONT, "Int")
      }
      FontStyle := this.FontStyle
      Loop, parse, FontStyle, %A_Space%
         if obj := styles[A_LoopField]
            NumPut(obj.value, &LOGFONT + obj.offset, obj.size)

      (this.FontSize > 24 && NumPut(ANTIALIASED_QUALITY, &LOGFONT + 26, "Char"))
      this.FontName && StrPut(this.FontName, &LOGFONT + 28, StrLen(this.FontName) * mult, A_IsUnicode ? "UTF-16" : "CP0")
      this.hFont := DllCall("CreateFontIndirect", Ptr, &LOGFONT, Ptr)
      if this.time  {
         timer := ObjBindMethod(this, "__Delete")
         SetTimer % timer, % "-" . this.time
      }
      this._SetInfo()
   }
   
   _SetInfo()  {
      static WM_USER := 0x400, WM_SETFONT := 0x30
           , TTM_ADDTOOL := WM_USER + (A_IsUnicode ? 50 : 4)
           , TTM_SETTITLE := WM_USER + (A_IsUnicode ? 33 : 32)
      
      this._SendMessage(WM_SETFONT, this.hFont, 1)
      this._SendMessage(TTM_ADDTOOL, 0, this.pTI)
      this._SendMessage(TTM_SETTITLE, this.icon, &(t := this.title))
      this.SetText(this.text)
   }
   
   SetText(text)  {
      static WM_USER := 0x400, TTM_UPDATETIPTEXT := WM_USER + (A_IsUnicode ? 57 : 12)
      NumPut(&text, this.pTI + (A_PtrSize = 4 ? 36 : 48))
      this._SendMessage(TTM_UPDATETIPTEXT, 0, this.pTI)
   }
   
   Show(x := "", y := "")  {
      static WM_USER := 0x400, TTM_TRACKACTIVATE := WM_USER + 17, TTM_TRACKPOSITION := WM_USER + 18
      
      if this.TrayTip
         this._GetTrayIconCoords(xTT, yTT)
      else  {
         xTT := x, yTT := y
         (xTT = "" && xTT := this.x)
         (yTT = "" && yTT := this.y)
      
         if (xTT = "" || yTT = "") {
            CoordMode, Mouse
            MouseGetPos, xm, ym
            (xTT = "" && xTT := xm + 10)
            (yTT = "" && yTT := ym + 10)
         }
      }
      this._SendMessage(TTM_TRACKPOSITION, 0, xTT|(yTT<<16))
      this._SendMessage(TTM_TRACKACTIVATE, 1, this.pTI)
      
      if this.BallonTip
         xMax := A_ScreenWidth, yMax := A_ScreenHeight
      else  {
         WinGetPos,,, W, H, % "ahk_id" this.hwnd
         xMax := A_ScreenWidth - W - 10
         yMax := A_ScreenHeight - H - 10
      }
      
      if (xTT > xMax || yTT > yMax)  {
         (xTT > xMax && xTT := xMax)
         (yTT > yMax && yTT := yMax)
         this._SendMessage(TTM_TRACKPOSITION, 0, xTT|(yTT<<16))
      }
   }
   
   Hide()  {
      static WM_USER := 0x400, TTM_TRACKACTIVATE := WM_USER + 17
      this._SendMessage(TTM_TRACKACTIVATE, 0, this.pTI)
   }
   
   _SendMessage(msg, wp := 0, lp := 0)  {
      Return DllCall("SendMessage", Ptr, this.hwnd, UInt, msg, Ptr, wp, Ptr, lp, Ptr)
   }
   
   _GetTrayIconCoords(ByRef x, ByRef y)  {
      static WM_USER := 0x400, TB_BUTTONCOUNT := WM_USER + 24, TB_GETBUTTON := WM_USER + 23, TB_GETITEMRECT := WM_USER + 29
           , PtrSize := A_Is64bitOS ? 8 : 4, szTBBUTTON := 8 + PtrSize*3, szHWND := PtrSize
         
      ControlGet, hTray, hwnd,, ToolbarWindow321, ahk_class Shell_TrayWnd
      WinWait, ahk_id %hTray%
      WinGet, PID, PID
      WinGetPos, xTB, yTB
      
      if !IsObject(RemoteBuff := new RemoteBuffer(PID, szTBBUTTON))  {
         x := xTB, y := yTB
         MsgBox, % "Не удалось создать удалённый буфер`nОшибка " A_LastError
         Return
      }
      SendMessage, TB_BUTTONCOUNT
      Loop % ErrorLevel  {
         SendMessage, TB_GETBUTTON, A_Index - 1, RemoteBuff.ptr
         pTBBUTTON := RemoteBuff.Read(szTBBUTTON)
         pHWND := RemoteBuff.Read(szHWND, NumGet(pTBBUTTON + 8 + PtrSize) - RemoteBuff.ptr)
         hWnd := NumGet(pHWND + 0, PtrSize = 4 ? "UInt" : "UInt64")
         if (hWnd = A_ScriptHwnd)  {
            SendMessage, TB_GETITEMRECT, A_Index - 1, RemoteBuff.ptr
            pRECT := RemoteBuff.Read(16)
            x := NumGet(pRECT + 0, "Int") + xTB + 5, y := NumGet(pRECT + 4, "Int") + yTB + 5
            break
         }
      }
      RemoteBuff := "", ((x = "" || y = "") && x := xTB, y := yTB)
   }
   
   __Delete()  {
      SoundBeep
      DllCall("DeleteObject", Ptr, this.hFont)
      DllCall("DestroyWindow", Ptr, this.hwnd)
   }
}

Class RemoteBuffer
{
   __New(PID, size)  {
      static PROCESS_VM_OPERATION := 0x8, PROCESS_VM_WRITE := 0x20, PROCESS_VM_READ := 0x10
         , MEM_COMMIT := 0x1000, PAGE_READWRITE := 0x4
         
      if !(this.hProc := DllCall("OpenProcess", UInt, PROCESS_VM_OPERATION|PROCESS_VM_READ|PROCESS_VM_WRITE, Int, 0, UInt, PID, Ptr))
         Return
      
      if !(this.ptr := DllCall("VirtualAllocEx", UInt, this.hProc, UInt, 0, UInt, size, UInt, MEM_COMMIT, UInt, PAGE_READWRITE, Ptr))
         Return, "", DllCall("CloseHandle", Ptr, this.hProc)
   }
   
   __Delete()  {
      DllCall("VirtualFreeEx", Ptr, this.hProc, Ptr, this.ptr, UInt, 0, UInt, MEM_RELEASE := 0x8000)
      DllCall("CloseHandle", Ptr, this.hProc)
   }
   
   Read(size, offset = 0)  {
      static LocalBuff
      VarSetCapacity(LocalBuff, size, 0)
      if !DllCall("ReadProcessMemory", Ptr, this.hProc, Ptr, this.ptr + offset, Ptr, &LocalBuff, UInt, size, UInt, 0)
         Return, 0, DllCall("MessageBox", Ptr, 0, Str, "Не удалось прочитать данные`nОшибка """ A_LastError """", Str, "", UInt, 0)
      
      VarSetCapacity(LocalBuff, -1)
      Return &LocalBuff
   }
}

В метод __Delete() включён SoundBeep для демонстрации. Как видно, он срабатывает два раза — один, когда уничтожается окно, второй, когда завершается скрипт. Получается как-то некрасиво.

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

10

Re: AHK: Изменить размер шрифта TOOLTIP

Вот вариант от lexikos:
https://autohotkey.com/boards/viewtopic … amp;t=4777

11

Re: AHK: Изменить размер шрифта TOOLTIP

Классный! Он просто изменяет обычный ToolTip. Но с TrayTip не работает. И таким способом нельзя сделать его прозрачным для кликов, будет перехватывать фокус. И BalloonTip не сделать.

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

12

Re: AHK: Изменить размер шрифта TOOLTIP

teadrinker пишет:

как можно запрограммировать удаление экземпляра объекта изнутри конструктора?

Удалось решить.

myTrayTip := new ToolTip({ text: "Модифицированный TrayTip"
                         , title: "Стандартная иконка «Info»"
                         , CloseButton: true
                         , Icon: 1              ; 1 — Info, 2 — Warning, 3 — Error, n > 3 — предполагается hIcon
                         , TrayTip: true
                         , FontSize: 18
                         , FontName: "Verdana" })

myToolTip := new ToolTip({ text: "Это модифицированный ToolTip `nОн прозрачен для кликов мыши."
                         , title: "Кастомная иконка"
                         , Icon: hIcon := CreateIconFromBase64(GetIcon(), 32)
                         , transparent: true    ; если true — окно прозрачно для мыши
                         , BallonTip: true      ; BalloonTip — это ToolTip с хвостиком
                         , FontSize: 28
                         , FontName: "Times New Roman"
                         , FontStyle: "italic" })
                         
ColoredTip:= new ToolTip({ text: "  Я исчезну через 7 сек  "
                         , x: A_ScreenWidth
                         , y: 0
                         , BallonTip: true
                         , title: "  Я цветной ToolTip!"
                         , TextColor: "Navy"
                         , BackColor: 0xFFA500
                         , FontName: "Comic Sans MS"
                         , FontSize: 25
                         , TimeOut: 7000 })  ; будет автоматически удалён через 7000 мс
                         
oTimer := Func("Timer").Bind(ColoredTip)
SetTimer, % oTimer, 1000
Sleep, 2500
myToolTip.Hide()  ; скрываем
myToolTip.SetText("Можно менять текст`nи расположение")  ; меняем текст
Sleep, 500

myToolTip.Show(50, 50)  ; показываем в координатах x = 50, y = 50
Sleep, 2000

myToolTip.Hide()
myToolTip.SetText("I'm near the mouse cursor!")
Sleep, 500

myToolTip.Show()  ; без координат — в районе курсора
Sleep, 2500

myToolTip := ""   ; уничтожаем ToolTip, это можно было сделать автоматически, указав TimeOut

myTrayTip.SetText("Goodbye!")
Sleep, 1000
myTrayTip := ""
ExitApp

class ToolTip {
   __New( options )  {
/*
Возможные опции:
   text, title
   icon (1: Info, 2: Warning; 3: Error; n > 3: предполагается hIcon)
   CloseButton (true или false)
   transparent (true или false)
   x, y — координаты, если не указаны, ToolTip появится вблизи курсора
   BallonTip (BalloonTip — это ToolTip с хвостиком, true или false)
   TrayTip — будет показан BalloonTip у иконки скрипта в трее, параметры x, y, и BalloonTip игнорируются
   FontName, FontSize
   FontStyle (bold, italic, underline, strikeout в любом сочетании через пробел)
   BackColor — цвет фона
   TextColor — цвет текста
   TimeOut — время, через которое ToolTip будет уничтожен
*/
      for k, v in options
         this[k] := v
      ((this.icon || this.CloseButton) && this.title = "") && this.title := " "
      this._CreateToolTip()
      this.Show()
   }
   
   _CreateToolTip()  {
      static WS_POPUP := 0x80000000, WS_EX_TOPMOST := 8, WS_EX_TRANSPARENT := 0x20
           , TTS_NOPREFIX := 2, TTS_ALWAYSTIP := 1, TTS_BALLOON := 0x40, TTS_CLOSE := 0x80
           , TTF_TRACK := 0x20, TTF_ABSOLUTE := 0x80, szTI := A_PtrSize = 4 ? 48 : 72
     
      VarSetCapacity(TOOLINFO, szTI, 0)
      this.pTI := &TOOLINFO
      NumPut(szTI, TOOLINFO)
      (this.TrayTip && this.BallonTip := true)
      NumPut(TTF_TRACK|(this.BallonTip ? 0 : TTF_ABSOLUTE), &TOOLINFO + 4)
      
      this.hwnd := DllCall("CreateWindowEx", UInt, WS_EX_TOPMOST|(this.transparent ? WS_EX_TRANSPARENT : 0)
        , Str, "tooltips_class32", Str, ""
        , UInt, WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP | (this.CloseButton ? TTS_CLOSE : 0) | (this.BallonTip ? TTS_BALLOON : 0)
        , Int, 0, Int, 0, Int, 0, Int, 0, Ptr, 0, Ptr, 0, Ptr, 0, Ptr, 0)
        
      if (this.FontName || this.FontSize || this.FontStyle)
         this._SetFont()
      
      if (this.TextColor != "" || this.BackColor != "")
         this._SetColor()
      
      this._SetInfo()

      if this.TimeOut  {
         timer := ObjBindMethod(this, "_Destroy")
         SetTimer % timer, % "-" . this.TimeOut
      }
   }
   
   _SetFont()  {
      static WM_GETFONT := 0x31, mult := A_IsUnicode ? 2 : 1, szLF := 28 + 32 * mult
           , LOGPIXELSY := 90, ANTIALIASED_QUALITY := 4
           , styles := { bold: {value: 700, offset: 16, size: "Int"}
                       , italic: {value: 1, offset: 20, size: "Char"}
                       , underline: {value: 1, offset: 21, size: "Char"}
                       , strikeout: {value: 1, offset: 22, size: "Char"} }
                       
      hPrevFont := this._SendMessage(WM_GETFONT)
      VarSetCapacity(LOGFONT, szLF, 0)
      DllCall("GetObject", Ptr, hPrevFont, Int, szLF, Ptr, &LOGFONT)
      DllCall("DeleteObject", Ptr, hPrevFont)
      
      if this.FontSize  {
         hDC := DllCall("GetDC", Ptr, this.hwnd, Ptr)
         height := -DllCall("MulDiv", Int, this.FontSize, Int, DllCall("GetDeviceCaps", Ptr, hDC, Int, LOGPIXELSY), Int, 72)
         DllCall("ReleaseDC", Ptr, this.hwnd, Ptr, hDC)
         NumPut(height, LOGFONT, "Int")
      }
      FontStyle := this.FontStyle
      Loop, parse, FontStyle, %A_Space%
         if obj := styles[A_LoopField]
            NumPut(obj.value, &LOGFONT + obj.offset, obj.size)

      (this.FontSize > 24 && NumPut(ANTIALIASED_QUALITY, &LOGFONT + 26, "Char"))
      this.FontName && StrPut(this.FontName, &LOGFONT + 28, StrLen(this.FontName) * mult, A_IsUnicode ? "UTF-16" : "CP0")
      this.hFont := DllCall("CreateFontIndirect", Ptr, &LOGFONT, Ptr)
   }
   
   _SetColor()  {
      static WM_USER := 0x400, TTM_SETTIPBKCOLOR := WM_USER + 19, TTM_SETTIPTEXTCOLOR := WM_USER + 20
      
      VarSetCapacity(empty, 2, 0)
      DllCall("UxTheme\SetWindowTheme", Ptr, this.hwnd, Ptr, 0, Ptr, &empty)   
      ( this.TextColor != "" && this._SendMessage(TTM_SETTIPTEXTCOLOR, this._GetColor(this.TextColor)) )
      ( this.BackColor != "" && this._SendMessage(TTM_SETTIPBKCOLOR, this._GetColor(this.BackColor)) )
   }
   
   _GetColor(color)  {
      static WS_CHILD := 0x40000000, WM_CTLCOLORSTATIC := 0x138
      
      Gui, New, +hwndhGui +%WS_CHILD%
      Gui, Color, % color + 0 = "" ? color : Format("{:x}", color)
      Gui, Add, Text, hwndhText
      hdc := DllCall("GetDC", Ptr, hText, Ptr)
      SendMessage, WM_CTLCOLORSTATIC, hdc, hText,, ahk_id %hGui%
      clr := DllCall("GetBkColor", Ptr, hdc)
      DllCall("ReleaseDC", Ptr, hText, Ptr, hdc)
      Gui, Destroy
      Return clr
   }
   
   _SetInfo()  {
      static WM_USER := 0x400, WM_SETFONT := 0x30
           , TTM_ADDTOOL := WM_USER + (A_IsUnicode ? 50 : 4)
           , TTM_SETTITLE := WM_USER + (A_IsUnicode ? 33 : 32)
      
      this._SendMessage(WM_SETFONT, this.hFont, 1)
      this._SendMessage(TTM_ADDTOOL, 0, this.pTI)
      this._SendMessage(TTM_SETTITLE, this.icon, &(t := this.title))
      this.SetText(this.text)
   }
   
   SetText(text)  {
      static WM_USER := 0x400, TTM_UPDATETIPTEXT := WM_USER + (A_IsUnicode ? 57 : 12)
      NumPut(&text, this.pTI + (A_PtrSize = 4 ? 36 : 48))
      this._SendMessage(TTM_UPDATETIPTEXT, 0, this.pTI)
   }
   
   Show(x := "", y := "")  {
      static WM_USER := 0x400, TTM_TRACKACTIVATE := WM_USER + 17, TTM_TRACKPOSITION := WM_USER + 18
      
      if this.TrayTip
         this._GetTrayIconCoords(xTT, yTT)
      else  {
         xTT := x, yTT := y
         (xTT = "" && xTT := this.x)
         (yTT = "" && yTT := this.y)
      
         if (xTT = "" || yTT = "") {
            CoordMode, Mouse
            MouseGetPos, xm, ym
            (xTT = "" && xTT := xm + 10)
            (yTT = "" && yTT := ym + 10)
         }
      }
      this._SendMessage(TTM_TRACKPOSITION, 0, xTT|(yTT<<16))
      this._SendMessage(TTM_TRACKACTIVATE, 1, this.pTI)
      
      if this.BallonTip
         xMax := A_ScreenWidth, yMax := A_ScreenHeight
      else  {
         WinGetPos,,, W, H, % "ahk_id" this.hwnd
         xMax := A_ScreenWidth - W - 10
         yMax := A_ScreenHeight - H - 10
      }
      
      if (xTT > xMax || yTT > yMax)  {
         (xTT > xMax && xTT := xMax)
         (yTT > yMax && yTT := yMax)
         this._SendMessage(TTM_TRACKPOSITION, 0, xTT|(yTT<<16))
      }
   }
   
   Hide()  {
      static WM_USER := 0x400, TTM_TRACKACTIVATE := WM_USER + 17
      this._SendMessage(TTM_TRACKACTIVATE, 0, this.pTI)
   }
   
   _SendMessage(msg, wp := 0, lp := 0)  {
      Return DllCall("SendMessage", Ptr, this.hwnd, UInt, msg, Ptr, wp, Ptr, lp, Ptr)
   }
   
   _GetTrayIconCoords(ByRef x, ByRef y)  {
      static WM_USER := 0x400, TB_BUTTONCOUNT := WM_USER + 24, TB_GETBUTTON := WM_USER + 23, TB_GETITEMRECT := WM_USER + 29
           , PtrSize := A_Is64bitOS ? 8 : 4, szTBBUTTON := 8 + PtrSize*3, szHWND := PtrSize
         
      ControlGet, hTray, hwnd,, ToolbarWindow321, ahk_class Shell_TrayWnd
      WinWait, ahk_id %hTray%
      WinGet, PID, PID
      WinGetPos, xTB, yTB
      
      if !IsObject(RemoteBuff := new RemoteBuffer(PID, szTBBUTTON))  {
         x := xTB, y := yTB
         MsgBox, % "Не удалось создать удалённый буфер`nОшибка " A_LastError
         Return
      }
      SendMessage, TB_BUTTONCOUNT
      Loop % ErrorLevel  {
         SendMessage, TB_GETBUTTON, A_Index - 1, RemoteBuff.ptr
         pTBBUTTON := RemoteBuff.Read(szTBBUTTON)
         pHWND := RemoteBuff.Read(szHWND, NumGet(pTBBUTTON + 8 + PtrSize) - RemoteBuff.ptr)
         hWnd := NumGet(pHWND + 0, PtrSize = 4 ? "UInt" : "UInt64")
         if (hWnd = A_ScriptHwnd)  {
            SendMessage, TB_GETITEMRECT, A_Index - 1, RemoteBuff.ptr
            pRECT := RemoteBuff.Read(16)
            x := NumGet(pRECT + 0, "Int") + xTB + 5, y := NumGet(pRECT + 4, "Int") + yTB + 5
            break
         }
      }
      RemoteBuff := "", ((x = "" || y = "") && x := xTB, y := yTB)
   }
   
   _Destroy()  {
      this.__Delete()
      this.SetCapacity(0)
      this.base := ""
   }
   
   __Delete()  {
      (this.hFont && DllCall("DeleteObject", Ptr, this.hFont))
      (this.Icon > 3 && DllCall("DestroyIcon", Ptr, this.Icon))
      DllCall("DestroyWindow", Ptr, this.hwnd)
   }
}

Class RemoteBuffer
{
   __New(PID, size)  {
      static PROCESS_VM_OPERATION := 0x8, PROCESS_VM_WRITE := 0x20, PROCESS_VM_READ := 0x10
         , MEM_COMMIT := 0x1000, PAGE_READWRITE := 0x4
         
      if !(this.hProc := DllCall("OpenProcess", UInt, PROCESS_VM_OPERATION|PROCESS_VM_READ|PROCESS_VM_WRITE, Int, 0, UInt, PID, Ptr))
         Return
      
      if !(this.ptr := DllCall("VirtualAllocEx", UInt, this.hProc, UInt, 0, UInt, size, UInt, MEM_COMMIT, UInt, PAGE_READWRITE, Ptr))
         Return, "", DllCall("CloseHandle", Ptr, this.hProc)
   }
   
   __Delete()  {
      DllCall("VirtualFreeEx", Ptr, this.hProc, Ptr, this.ptr, UInt, 0, UInt, MEM_RELEASE := 0x8000)
      DllCall("CloseHandle", Ptr, this.hProc)
   }
   
   Read(size, offset = 0)  {
      static LocalBuff
      VarSetCapacity(LocalBuff, size, 0)
      if !DllCall("ReadProcessMemory", Ptr, this.hProc, Ptr, this.ptr + offset, Ptr, &LocalBuff, UInt, size, UInt, 0)
         Return, 0, DllCall("MessageBox", Ptr, 0, Str, "Не удалось прочитать данные`nОшибка """ A_LastError """", Str, "", UInt, 0)
      
      VarSetCapacity(LocalBuff, -1)
      Return &LocalBuff
   }
}

Timer(oTip)  {
   static i := 0
   oTip.SetText("  Я исчезну через " (7 - ++i) " сек  ")
   if (i = 7)
      SetTimer,, Delete
}

CreateIconFromBase64(StringBASE64, Size)
{
   StringBase64ToData(StringBASE64, IconData)
   Return DllCall("CreateIconFromResourceEx", Ptr, &IconData + 4
      , UInt, NumGet(&IconData, "UInt"), UInt, true, UInt, 0x30000, Int, Size, Int, Size, UInt, 0)
}
   
StringBase64ToData(StringBase64, ByRef OutData)
{
   DllCall("Crypt32.dll\CryptStringToBinary", Ptr, &StringBase64 
      , UInt, StrLen(StringBase64), UInt, CRYPT_STRING_BASE64 := 1, UInt, 0, UIntP, Bytes, UIntP, 0, UIntP, 0)

   VarSetCapacity(OutData, Bytes) 
   DllCall("Crypt32.dll\CryptStringToBinary", Ptr, &StringBase64 
      , UInt, StrLen(StringBase64), UInt, CRYPT_STRING_BASE64, Str, OutData, UIntP, Bytes, UIntP, 0, UIntP, 0)
   Return Bytes
}

GetIcon()  {
   Icon32 = 
   (RTrim Join
      qBAAACgAAAAgAAAAQAAAAAEAIAAAAAAAgBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
      FRgjABMXIQATFyEAFBchABMXIQAVGCMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
      AAAAABUYIwAAAAAAAAAAAAAAAAIAAAAAAAAAABUYIwAVGCMAExchABMXIRQUFyETExchABUYIwAVGCMAAAAAAAAAAAAAAAACAAAAAAAAAAAVGCMAAAAAAAAAAAAAAAAA
      AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFRgjABQXIgAUFyIAFBciABMXIQATFyEAFRgjABUYIwIUFyIAFBciqxQXIqoUFyIAFRgjAhUYIwAUFyIA
      FBgiABQXIgATFyIAExciABUYIwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVGCMAFBciABQXIhAUFiFCExgiABMWIQAAAAAA
      FRgjAxUYIwAVFiO4ExghuBUYIwAVGCMDAAAAABQXIgATGiIAExchQhMYIhATGCIAFRgjAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
      AAAAABUYIwEUFyIAFBchMhQXIv8TFyFDFBciABUXIwIVGCMCFRgjABUXI7sUGCK7FRgjABUYIwIUFyMCFBciABQXIkMUFyL/FBchMhQXIgAVGCMBAAAAAAAAAAAAAAAA
      AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFRgjABUXIgEVFyIAFBciuRQXItoVGSICFRgiARUYIwMUFyIBFBcinRMXIp0UFyIBFRgjAxUYIgEVGCIC
      FBci2hQXIroVFyIAFRciARUYIwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFRgjAAAAAAAAAAAAAAAAAgAAAAEVGCMAFBgjARQXIgAUFyIkFBci/xQXImEUFyIC
      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
      FBci2xQXIrcUGCMAFBgjARUYIwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVGCMBFRciABUXIjIUFyL/FBciQxQXIgAUFyMC
      FRgjAxUYIwAVFyO7FBgiuxUYIwAVGCMDFRgiAhQXIgAUFiFFFBci/xQXIjEUFyIAFRgjAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
      AAAAABUYIwAUFyIAFBciEBQXIkITGCYAFRQiAAAAAAAVGCMDFRgjABUWI7gTGCG4FRgjABUYIwMAAAAAExYgABQVHgATFiFDFBYiEBQWIgAVGCMAAAAAAAAAAAAAAAAA
      AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFRgjABQXIgAUFyEAFBciABQXJAAVFSIAFRgjABUYIwIVFyIAFBciqxQXIqoVFyIAFRgjAhUYIwATFiEA
      FBYgABMXIgAUFyIAFBciABUYIwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVGCMAAAAAAAAAAAAAAAACAAAAAAAAAAAVGCMA
      FRgjABUWIQAUFyEVFRYiFBUWIQAVGCMAFRgjAAAAAAAAAAAAAAAAAgAAAAAAAAAAFRgjAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
      AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVGCMAFRciABQXIgAVFiIAFRYiABUYIwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
      AAAAAAAAAAAAAAAA/////////////n////5///++ff//nnn//8/z///f+//38A/v8eAHj/jAAx//gAH//wAB//8AAP//AAD/wwAAw8MAAMP/AAD//wAA//+AAf//gAH/
      +MADH/HgB4/38A/v///////P8///nnn//759///+f////n////////////8=
   )
   Return Icon32
}

У кого есть возможность запустить на Windows 10, протестируте пожалуйста, появляется ли TrayTip вблизи иконки скрипта в трее, или в стороне от неё.

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

13

Re: AHK: Изменить размер шрифта TOOLTIP

А чем это лучше?

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

14 (изменено: Alectric, 2016-12-10 10:55:40)

Re: AHK: Изменить размер шрифта TOOLTIP

teadrinker пишет:

У кого есть возможность запустить на Windows 10

Попробовал запустить:

Не удалось прочитать данные
Ошибка "299"

После нажатия "Ок" всё работает.

Post's attachments

Desktop.zip 452.18 kb, 9 downloads since 2016-12-10 

You don't have the permssions to download the attachments of this post.
Win 10 x64
AHK v1.1.33.02
                       Справка тебе в помощь.

15

Re: AHK: Изменить размер шрифта TOOLTIP

У меня на 10 такое же сообщение в начале. Ни одно из окошек вблизи иконки не появляется.

16

Re: AHK: Изменить размер шрифта TOOLTIP

Спасибо. А на десятке определяется hwnd трея с помощью кода:

ControlGet, hTray, hwnd,, ToolbarWindow321, ahk_class Shell_TrayWnd
MsgBox % hTray

? И как определяется, если нет?

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

17

Re: AHK: Изменить размер шрифта TOOLTIP

Да, определяется. По кр. мере что-то этот код возвращает.

---------------------------
E00C0A0E363002A9.AHK
---------------------------
0x100de
---------------------------
ОК   
---------------------------

18

Re: AHK: Изменить размер шрифта TOOLTIP

YMP, так может глянешь, что там за проблема на десятке? В моём коде метод  _GetTrayIconCoords(). Логика такая:
находим хэндл трея (контрол ToolbarWindow321 в окне Shell_TrayWnd);
каждой кнопке поочерёдно отправляем сообщение TB_GETBUTTON, получаем (через удалённый буфер) структуру TBBUTTON, там по смещению 8 + PtrSize (где PtrSize := A_Is64bitOS ? 8 : 4) пойнтер структуры, которая в семёрке выглядит так:

typedef TRAYDATA
{
IntPtr hwnd;
uint uID;
uint uCallbackMessage;
uint Reserved;
uint Reserved2;
IntPtr hIcon;
}

Структура недокументирована и на десятке может быть организована по-другому. Нужно получить hwnd и сравнить его с A_ScriptHwnd скрипта, чтоб понять, принадлежит ли иконка скрипту. Ошибка, которая возникает на десятке при чтении буфера — ERROR_PARTIAL_COPY. Такое может быть, когда 32-битным скриптом пытаешься читать 64-битное значение, но здесь, вроде, не в этом дело.

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

19

Re: AHK: Изменить размер шрифта TOOLTIP

Хорошо, попробую разобраться.

20

Re: AHK: Изменить размер шрифта TOOLTIP

Указатель на TRAYDATA, получаемый из TBBUTTON, равен 0.

21

Re: AHK: Изменить размер шрифта TOOLTIP

Печально! А хэндл трея точно правильно определяется? TB_BUTTONCOUNT правильное значение возвращает?

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

22

Re: AHK: Изменить размер шрифта TOOLTIP

Вот код нашёл: Tray Icon Windows 10. Можно с его помощью соотнести иконку с процессом и получить её координаты?

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

23

Re: AHK: Изменить размер шрифта TOOLTIP

А, кажись нашёл, в чём дело. Тут надо ToolbarWindow323 использовать, тогда работает. TB_BUTTONCOUNT возвращает число тех иконок, которые не скрыты.

Если открыть окошко со скрытыми иконками, оно определяется, как ToolbarWindow321. Но когда в скрипте было это значение, то TB_BUTTONCOUNT возвращало 1, хотя там несколько иконок у меня.

24

Re: AHK: Изменить размер шрифта TOOLTIP

Ага, отлично. А вот таким способом на десятке однозначно нельзя определить?

WinGet, hWnd,, ahk_class Shell_TrayWnd
for k, v in ["TrayNotifyWnd", "SysPager", "ToolbarWindow32"]
   hToolbar := DllCall("FindWindowEx", Ptr, k = 1 ? hWnd : hToolbar, Ptr, 0, Str, v, UInt, 0, Ptr)

; для сравнения:
ControlGet, hTray, hwnd,, ToolbarWindow323, ahk_class Shell_TrayWnd

MsgBox, % Format("{:#x}", hToolbar) "`n" hTray

Если нельзя, то как-нибудь подобно можно, чтобы не зависеть от порядкового номера?

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

25

Re: AHK: Изменить размер шрифта TOOLTIP

Одно и то же находит.

---------------------------
E00C0F04070E0019.AHK
---------------------------
0x100f2
0x100f2
---------------------------
ОК   
---------------------------

26

Re: AHK: Изменить размер шрифта TOOLTIP

myTrayTip := new ToolTip({ text: "Модифицированный TrayTip"
                         , title: "Стандартная иконка «Info»"
                         , CloseButton: true
                         , Icon: 1              ; 1 — Info, 2 — Warning, 3 — Error, n > 3 — предполагается hIcon
                         , TrayTip: true
                         , FontSize: 18
                         , FontName: "Verdana" })

myToolTip := new ToolTip({ text: "Это модифицированный ToolTip `nОн прозрачен для кликов мыши."
                         , title: "Кастомная иконка"
                         , Icon: hIcon := CreateIconFromBase64(GetIcon(), 32)
                         , transparent: true    ; если true — окно прозрачно для мыши
                         , BallonTip: true      ; BalloonTip — это ToolTip с хвостиком
                         , FontSize: 28
                         , FontName: "Times New Roman"
                         , FontStyle: "italic" })
                         
ColoredTip:= new ToolTip({ text: "  Я исчезну через 7 сек  "
                         , x: A_ScreenWidth
                         , y: 0
                         , BallonTip: true
                         , title: "  Я цветной ToolTip!"
                         , TextColor: "Navy"
                         , BackColor: 0xFFA500
                         , FontName: "Comic Sans MS"
                         , FontSize: 25
                         , TimeOut: 7000 })  ; будет автоматически удалён через 7000 мс
                         
oTimer := Func("Timer").Bind(ColoredTip)
SetTimer, % oTimer, 1000
Sleep, 2500
myToolTip.Hide()  ; скрываем
myToolTip.SetText("Можно менять текст`nи расположение")  ; меняем текст
Sleep, 500

myToolTip.Show(50, 50)  ; показываем в координатах x = 50, y = 50
Sleep, 2000

myToolTip.Hide()
myToolTip.SetText("I'm near the mouse cursor!")
Sleep, 500

myToolTip.Show()  ; без координат — в районе курсора
Sleep, 2500

myToolTip := ""   ; уничтожаем ToolTip, это можно было сделать автоматически, указав TimeOut

myTrayTip.SetText("Goodbye!")
Sleep, 1000
myTrayTip := ""
ExitApp

class ToolTip {
   __New( options )  {
/*
Возможные опции:
   text, title
   icon (1: Info, 2: Warning; 3: Error; n > 3: предполагается hIcon)
   CloseButton (true или false)
   transparent (true или false)
   x, y — координаты, если не указаны, ToolTip появится вблизи курсора
   BallonTip (BalloonTip — это ToolTip с хвостиком, true или false)
   TrayTip — будет показан BalloonTip у иконки скрипта в трее, параметры x, y, и BalloonTip игнорируются
   FontName, FontSize
   FontStyle (bold, italic, underline, strikeout в любом сочетании через пробел)
   BackColor — цвет фона
   TextColor — цвет текста
   TimeOut — время, через которое ToolTip будет уничтожен
*/
      for k, v in options
         this[k] := v
      ((this.icon || this.CloseButton) && this.title = "") && this.title := " "
      this._CreateToolTip()
      this.Show()
   }
   
   _CreateToolTip()  {
      static WS_POPUP := 0x80000000, WS_EX_TOPMOST := 8, WS_EX_TRANSPARENT := 0x20
           , TTS_NOPREFIX := 2, TTS_ALWAYSTIP := 1, TTS_BALLOON := 0x40, TTS_CLOSE := 0x80
           , TTF_TRACK := 0x20, TTF_ABSOLUTE := 0x80, szTI := A_PtrSize = 4 ? 48 : 72
     
      VarSetCapacity(TOOLINFO, szTI, 0)
      this.pTI := &TOOLINFO
      NumPut(szTI, TOOLINFO)
      (this.TrayTip && this.BallonTip := true)
      NumPut(TTF_TRACK|(this.BallonTip ? 0 : TTF_ABSOLUTE), &TOOLINFO + 4)
      
      this.hwnd := DllCall("CreateWindowEx", UInt, WS_EX_TOPMOST|(this.transparent ? WS_EX_TRANSPARENT : 0)
        , Str, "tooltips_class32", Str, ""
        , UInt, WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP | (this.CloseButton ? TTS_CLOSE : 0) | (this.BallonTip ? TTS_BALLOON : 0)
        , Int, 0, Int, 0, Int, 0, Int, 0, Ptr, 0, Ptr, 0, Ptr, 0, Ptr, 0)
        
      if (this.FontName || this.FontSize || this.FontStyle)
         this._SetFont()
      
      if (this.TextColor != "" || this.BackColor != "")
         this._SetColor()
      
      this._SetInfo()

      if this.TimeOut  {
         timer := ObjBindMethod(this, "_Destroy")
         SetTimer % timer, % "-" . this.TimeOut
      }
   }
   
   _SetFont()  {
      static WM_GETFONT := 0x31, mult := A_IsUnicode ? 2 : 1, szLF := 28 + 32 * mult
           , LOGPIXELSY := 90, ANTIALIASED_QUALITY := 4
           , styles := { bold: {value: 700, offset: 16, size: "Int"}
                       , italic: {value: 1, offset: 20, size: "Char"}
                       , underline: {value: 1, offset: 21, size: "Char"}
                       , strikeout: {value: 1, offset: 22, size: "Char"} }
                       
      hPrevFont := this._SendMessage(WM_GETFONT)
      VarSetCapacity(LOGFONT, szLF, 0)
      DllCall("GetObject", Ptr, hPrevFont, Int, szLF, Ptr, &LOGFONT)
      DllCall("DeleteObject", Ptr, hPrevFont)
      
      if this.FontSize  {
         hDC := DllCall("GetDC", Ptr, this.hwnd, Ptr)
         height := -DllCall("MulDiv", Int, this.FontSize, Int, DllCall("GetDeviceCaps", Ptr, hDC, Int, LOGPIXELSY), Int, 72)
         DllCall("ReleaseDC", Ptr, this.hwnd, Ptr, hDC)
         NumPut(height, LOGFONT, "Int")
      }
      FontStyle := this.FontStyle
      Loop, parse, FontStyle, %A_Space%
         if obj := styles[A_LoopField]
            NumPut(obj.value, &LOGFONT + obj.offset, obj.size)

      (this.FontSize > 24 && NumPut(ANTIALIASED_QUALITY, &LOGFONT + 26, "Char"))
      this.FontName && StrPut(this.FontName, &LOGFONT + 28, StrLen(this.FontName) * mult, A_IsUnicode ? "UTF-16" : "CP0")
      this.hFont := DllCall("CreateFontIndirect", Ptr, &LOGFONT, Ptr)
   }
   
   _SetColor()  {
      static WM_USER := 0x400, TTM_SETTIPBKCOLOR := WM_USER + 19, TTM_SETTIPTEXTCOLOR := WM_USER + 20
      
      VarSetCapacity(empty, 2, 0)
      DllCall("UxTheme\SetWindowTheme", Ptr, this.hwnd, Ptr, 0, Ptr, &empty)   
      ( this.TextColor != "" && this._SendMessage(TTM_SETTIPTEXTCOLOR, this._GetColor(this.TextColor)) )
      ( this.BackColor != "" && this._SendMessage(TTM_SETTIPBKCOLOR, this._GetColor(this.BackColor)) )
   }
   
   _GetColor(color)  {
      static WS_CHILD := 0x40000000, WM_CTLCOLORSTATIC := 0x138
      
      Gui, New, +hwndhGui +%WS_CHILD%
      Gui, Color, % color + 0 = "" ? color : Format("{:x}", color)
      Gui, Add, Text, hwndhText
      hdc := DllCall("GetDC", Ptr, hText, Ptr)
      SendMessage, WM_CTLCOLORSTATIC, hdc, hText,, ahk_id %hGui%
      clr := DllCall("GetBkColor", Ptr, hdc)
      DllCall("ReleaseDC", Ptr, hText, Ptr, hdc)
      Gui, Destroy
      Return clr
   }
   
   _SetInfo()  {
      static WM_USER := 0x400, WM_SETFONT := 0x30
           , TTM_ADDTOOL := WM_USER + (A_IsUnicode ? 50 : 4)
           , TTM_SETTITLE := WM_USER + (A_IsUnicode ? 33 : 32)
      
      this._SendMessage(WM_SETFONT, this.hFont, 1)
      this._SendMessage(TTM_ADDTOOL, 0, this.pTI)
      this._SendMessage(TTM_SETTITLE, this.icon, &(t := this.title))
      this.SetText(this.text)
   }
   
   SetText(text)  {
      static WM_USER := 0x400, TTM_UPDATETIPTEXT := WM_USER + (A_IsUnicode ? 57 : 12)
      NumPut(&text, this.pTI + (A_PtrSize = 4 ? 36 : 48))
      this._SendMessage(TTM_UPDATETIPTEXT, 0, this.pTI)
   }
   
   Show(x := "", y := "")  {
      static WM_USER := 0x400, TTM_TRACKACTIVATE := WM_USER + 17, TTM_TRACKPOSITION := WM_USER + 18
      
      if this.TrayTip
         this._GetTrayIconCoords(xTT, yTT)
      else  {
         xTT := x, yTT := y
         (xTT = "" && xTT := this.x)
         (yTT = "" && yTT := this.y)
      
         if (xTT = "" || yTT = "") {
            CoordMode, Mouse
            MouseGetPos, xm, ym
            (xTT = "" && xTT := xm + 10)
            (yTT = "" && yTT := ym + 10)
         }
      }
      this._SendMessage(TTM_TRACKPOSITION, 0, xTT|(yTT<<16))
      this._SendMessage(TTM_TRACKACTIVATE, 1, this.pTI)
      
      if this.BallonTip
         xMax := A_ScreenWidth, yMax := A_ScreenHeight
      else  {
         WinGetPos,,, W, H, % "ahk_id" this.hwnd
         xMax := A_ScreenWidth - W - 10
         yMax := A_ScreenHeight - H - 10
      }
      
      if (xTT > xMax || yTT > yMax)  {
         (xTT > xMax && xTT := xMax)
         (yTT > yMax && yTT := yMax)
         this._SendMessage(TTM_TRACKPOSITION, 0, xTT|(yTT<<16))
      }
   }
   
   Hide()  {
      static WM_USER := 0x400, TTM_TRACKACTIVATE := WM_USER + 17
      this._SendMessage(TTM_TRACKACTIVATE, 0, this.pTI)
   }
   
   _SendMessage(msg, wp := 0, lp := 0)  {
      Return DllCall("SendMessage", Ptr, this.hwnd, UInt, msg, Ptr, wp, Ptr, lp, Ptr)
   }
   
   _GetTrayIconCoords(ByRef x, ByRef y)  {
      static WM_USER := 0x400, TB_BUTTONCOUNT := WM_USER + 24, TB_GETBUTTON := WM_USER + 23, TB_GETITEMRECT := WM_USER + 29
           , PtrSize := A_Is64bitOS ? 8 : 4, szTBBUTTON := 8 + PtrSize*3, szHWND := PtrSize
         
      for k, v in ["TrayNotifyWnd", "SysPager", "ToolbarWindow32"]
         hTray := DllCall("FindWindowEx", Ptr, k = 1 ? WinExist("ahk_class Shell_TrayWnd") : hTray, Ptr, 0, Str, v, UInt, 0, Ptr)
      WinWait, ahk_id %hTray%
      WinGet, PID, PID
      WinGetPos, xTB, yTB
      
      if !IsObject(RemoteBuff := new RemoteBuffer(PID, szTBBUTTON))  {
         x := xTB, y := yTB
         MsgBox, % "Не удалось создать удалённый буфер`nОшибка " A_LastError
         Return
      }
      SendMessage, TB_BUTTONCOUNT
      Loop % ErrorLevel  {
         SendMessage, TB_GETBUTTON, A_Index - 1, RemoteBuff.ptr
         pTBBUTTON := RemoteBuff.Read(szTBBUTTON)
         pHWND := RemoteBuff.Read(szHWND, NumGet(pTBBUTTON + 8 + PtrSize) - RemoteBuff.ptr)
         hWnd := NumGet(pHWND + 0, PtrSize = 4 ? "UInt" : "UInt64")
         if (hWnd = A_ScriptHwnd)  {
            SendMessage, TB_GETITEMRECT, A_Index - 1, RemoteBuff.ptr
            pRECT := RemoteBuff.Read(16)
            x := NumGet(pRECT + 0, "Int") + xTB + 5, y := NumGet(pRECT + 4, "Int") + yTB + 5
            break
         }
      }
      RemoteBuff := "", ((x = "" || y = "") && x := xTB, y := yTB)
   }
   
   _Destroy()  {
      this.__Delete()
      this.SetCapacity(0)
      this.base := ""
   }
   
   __Delete()  {
      (this.hFont && DllCall("DeleteObject", Ptr, this.hFont))
      (this.Icon > 3 && DllCall("DestroyIcon", Ptr, this.Icon))
      DllCall("DestroyWindow", Ptr, this.hwnd)
   }
}

Class RemoteBuffer
{
   __New(PID, size)  {
      static PROCESS_VM_OPERATION := 0x8, PROCESS_VM_WRITE := 0x20, PROCESS_VM_READ := 0x10
         , MEM_COMMIT := 0x1000, PAGE_READWRITE := 0x4
         
      if !(this.hProc := DllCall("OpenProcess", UInt, PROCESS_VM_OPERATION|PROCESS_VM_READ|PROCESS_VM_WRITE, Int, 0, UInt, PID, Ptr))
         Return
      
      if !(this.ptr := DllCall("VirtualAllocEx", UInt, this.hProc, UInt, 0, UInt, size, UInt, MEM_COMMIT, UInt, PAGE_READWRITE, Ptr))
         Return, "", DllCall("CloseHandle", Ptr, this.hProc)
   }
   
   __Delete()  {
      DllCall("VirtualFreeEx", Ptr, this.hProc, Ptr, this.ptr, UInt, 0, UInt, MEM_RELEASE := 0x8000)
      DllCall("CloseHandle", Ptr, this.hProc)
   }
   
   Read(size, offset = 0)  {
      static LocalBuff
      VarSetCapacity(LocalBuff, size, 0)
      if !DllCall("ReadProcessMemory", Ptr, this.hProc, Ptr, this.ptr + offset, Ptr, &LocalBuff, UInt, size, UInt, 0)
         Return, 0, DllCall("MessageBox", Ptr, 0, Str, "Не удалось прочитать данные`nОшибка """ A_LastError """", Str, "", UInt, 0)
      
      VarSetCapacity(LocalBuff, -1)
      Return &LocalBuff
   }
}

Timer(oTip)  {
   static i := 0
   oTip.SetText("  Я исчезну через " (7 - ++i) " сек  ")
   if (i = 7)
      SetTimer,, Delete
}

CreateIconFromBase64(StringBASE64, Size)
{
   StringBase64ToData(StringBASE64, IconData)
   Return DllCall("CreateIconFromResourceEx", Ptr, &IconData + 4
      , UInt, NumGet(&IconData, "UInt"), UInt, true, UInt, 0x30000, Int, Size, Int, Size, UInt, 0)
}
   
StringBase64ToData(StringBase64, ByRef OutData)
{
   DllCall("Crypt32.dll\CryptStringToBinary", Ptr, &StringBase64 
      , UInt, StrLen(StringBase64), UInt, CRYPT_STRING_BASE64 := 1, UInt, 0, UIntP, Bytes, UIntP, 0, UIntP, 0)

   VarSetCapacity(OutData, Bytes) 
   DllCall("Crypt32.dll\CryptStringToBinary", Ptr, &StringBase64 
      , UInt, StrLen(StringBase64), UInt, CRYPT_STRING_BASE64, Str, OutData, UIntP, Bytes, UIntP, 0, UIntP, 0)
   Return Bytes
}

GetIcon()  {
   Icon32 = 
   (RTrim Join
      qBAAACgAAAAgAAAAQAAAAAEAIAAAAAAAgBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
      FRgjABMXIQATFyEAFBchABMXIQAVGCMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
      AAAAABUYIwAAAAAAAAAAAAAAAAIAAAAAAAAAABUYIwAVGCMAExchABMXIRQUFyETExchABUYIwAVGCMAAAAAAAAAAAAAAAACAAAAAAAAAAAVGCMAAAAAAAAAAAAAAAAA
      AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFRgjABQXIgAUFyIAFBciABMXIQATFyEAFRgjABUYIwIUFyIAFBciqxQXIqoUFyIAFRgjAhUYIwAUFyIA
      FBgiABQXIgATFyIAExciABUYIwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVGCMAFBciABQXIhAUFiFCExgiABMWIQAAAAAA
      FRgjAxUYIwAVFiO4ExghuBUYIwAVGCMDAAAAABQXIgATGiIAExchQhMYIhATGCIAFRgjAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
      AAAAABUYIwEUFyIAFBchMhQXIv8TFyFDFBciABUXIwIVGCMCFRgjABUXI7sUGCK7FRgjABUYIwIUFyMCFBciABQXIkMUFyL/FBchMhQXIgAVGCMBAAAAAAAAAAAAAAAA
      AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFRgjABUXIgEVFyIAFBciuRQXItoVGSICFRgiARUYIwMUFyIBFBcinRMXIp0UFyIBFRgjAxUYIgEVGCIC
      FBci2hQXIroVFyIAFRciARUYIwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFRgjAAAAAAAAAAAAAAAAAgAAAAEVGCMAFBgjARQXIgAUFyIkFBci/xQXImEUFyIC
      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
      FBci2xQXIrcUGCMAFBgjARUYIwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVGCMBFRciABUXIjIUFyL/FBciQxQXIgAUFyMC
      FRgjAxUYIwAVFyO7FBgiuxUYIwAVGCMDFRgiAhQXIgAUFiFFFBci/xQXIjEUFyIAFRgjAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
      AAAAABUYIwAUFyIAFBciEBQXIkITGCYAFRQiAAAAAAAVGCMDFRgjABUWI7gTGCG4FRgjABUYIwMAAAAAExYgABQVHgATFiFDFBYiEBQWIgAVGCMAAAAAAAAAAAAAAAAA
      AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFRgjABQXIgAUFyEAFBciABQXJAAVFSIAFRgjABUYIwIVFyIAFBciqxQXIqoVFyIAFRgjAhUYIwATFiEA
      FBYgABMXIgAUFyIAFBciABUYIwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVGCMAAAAAAAAAAAAAAAACAAAAAAAAAAAVGCMA
      FRgjABUWIQAUFyEVFRYiFBUWIQAVGCMAFRgjAAAAAAAAAAAAAAAAAgAAAAAAAAAAFRgjAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
      AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVGCMAFRciABQXIgAVFiIAFRYiABUYIwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
      AAAAAAAAAAAAAAAA/////////////n////5///++ff//nnn//8/z///f+//38A/v8eAHj/jAAx//gAH//wAB//8AAP//AAD/wwAAw8MAAMP/AAD//wAA//+AAf//gAH/
      +MADH/HgB4/38A/v///////P8///nnn//759///+f////n////////////8=
   )
   Return Icon32
}

Вот так на Win 10 корректно с TrayTip работает, как я понимаю?

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

27

Re: AHK: Изменить размер шрифта TOOLTIP

teadrinker, а нет желания поставить win10 параллельно?
Всё-равно рано или поздно придется переходить.

28

Re: AHK: Изменить размер шрифта TOOLTIP

Да теперь уже только платно можно, вроде. Когда новый девайс на Windows куплю, там уже будет скорее всего Windows 10.

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

29

Re: AHK: Изменить размер шрифта TOOLTIP

teadrinker
Да, так нормально.

30

Re: AHK: Изменить размер шрифта TOOLTIP

Ок, спасибо!

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

31

Re: AHK: Изменить размер шрифта TOOLTIP

Да теперь уже только платно можно, вроде

Вроде как нет, но не проверял.
https://www.microsoft.com/ru-ru/accessi … s10upgrade

32

Re: AHK: Изменить размер шрифта TOOLTIP

А, да, точно, слышал о такой возможности. Может, как руки дойдут, попробую обновить старую XP до 10.

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

33 (изменено: teadrinker, 2016-12-20 01:54:03)

Re: AHK: Изменить размер шрифта TOOLTIP

Это гениально - более того что я ожидал !!!
Добавьте в коллекцию , пригодится к подобному вопросу.
И всем спасибо за поддержку !

Win10 x64

34 (изменено: teadrinker, 2016-12-20 18:04:48)

Re: AHK: Изменить размер шрифта TOOLTIP

Спасибо, только не нужно цитировать пост целиком. Подправленный вариант:

myTrayTip := new ToolTip({ text: "Модифицированный TrayTip"
                         , title: "Стандартная иконка «Info»"
                         , CloseButton: true
                         , Icon: 1              ; 1 — Info, 2 — Warning, 3 — Error, n > 3 — предполагается hIcon
                         , TrayTip: true
                         , FontSize: 16
                         , FontName: "Verdana" })

myToolTip := new ToolTip({ text: "Это модифицированный ToolTip.`nОн прозрачен для кликов мыши."
                         , title: "Кастомная иконка"
                         , Icon: hIcon := CreateIconFromBase64(GetIcon(), 32)
                         , transparent: true    ; если true — окно прозрачно для мыши
                         , BalloonTip: true
                         , FontSize: 22
                         , FontName: "Times New Roman"
                         , FontStyle: "italic" })
                         
ColoredTip:= new ToolTip({ text: "Я цветной ToolTip!`nЯ исчезну через 7 сек"
                         , x: A_ScreenWidth
                         , y: 0
                         , BalloonTip: true
                         , TextColor: "Navy"
                         , BackColor: 0xFFA500
                         , FontName: "Comic Sans MS"
                         , FontSize: 20
                         , TimeOut: 7000 })  ; будет автоматически удалён через 7000 мс
                         
oTimer := Func("Timer").Bind(ColoredTip)
SetTimer, % oTimer, 1000  ; этот таймер только для изменения текста
Sleep, 2500
myToolTip.Hide()  ; скрываем
myToolTip.SetText("Можно менять`nтекст и расположение")  ; меняем текст
Sleep, 500

myToolTip.Show(50, 50)  ; показываем в координатах x = 50, y = 50
Sleep, 2000

myToolTip.Hide()
myToolTip.SetText("I'm near the mouse cursor!")
Sleep, 500

myToolTip.Show()  ; без координат — в районе курсора
Sleep, 2500

myToolTip := ""   ; уничтожаем ToolTip, это можно было сделать автоматически, указав TimeOut

myTrayTip.SetTItle(2, "Изменённый заголовок")  ; меняем иконку и заголовок
myTrayTip.SetText("Goodbye!")
Sleep, 1000
myTrayTip.Destroy()
Sleep, 1000
ExitApp

class ToolTip {
/*
Версия: 1.03 — добавлена возможность смены заголовка

При создании экземпляра объекта в конструктор передаётся ассоциативный массив с опциями.
Возможные ключи:

   title
   text
   icon (1: Info, 2: Warning; 3: Error; n > 3: предполагается hIcon)
   CloseButton (true или false)
   transparent (true или false)
   x, y — координаты, если не указаны, ToolTip появится вблизи курсора
   BalloonTip (BalloonTip — это ToolTip с хвостиком, true или false)
   TrayTip — будет показан BalloonTip у иконки скрипта в трее, параметры x, y, и BalloonTip игнорируются
   FontName
   FontSize
   FontStyle (bold, italic, underline, strikeout в любом сочетании через пробел)
   TimeOut — время, через которое ToolTip будет уничтожен
   BackColor — цвет фона
   TextColor — цвет текста
   
Для указания цвета можно использовать литеральные названия, перечисленные здесь:
https://autohotkey.com/docs/commands/Progress.htm#colors
В этом случае название должно быть в кавычках.

Ключи можно задавать в любом порядке и в любой комбинации, как показано в примерах использования.
Если указан ключ TrayTip, удалить окно можно только методом Destroy(),
если нет, тогда можно просто прировнять ссылку на объект пустому значению.

После создания экземпляра объекта можно менять:
расположение — метод Show(x, y), x и y — координаты, если пустые значения — ToolTip будет показан возле курсора
видимость — методы Show() и Hide()
текст — метод SetText(text)
иконку и заголовок — метод SetTitle(icon, title)
*/
   __New( options )  {
      for k, v in options
         this[k] := v
      this._CreateToolTip()
      this.Show()
   }
   
   _CreateToolTip()  {
      static WS_POPUP := 0x80000000, WS_EX_TOPMOST := 8, WS_EX_TRANSPARENT := 0x20
           , TTS_NOPREFIX := 2, TTS_ALWAYSTIP := 1, TTS_BALLOON := 0x40, TTS_CLOSE := 0x80
           , TTF_TRACK := 0x20, TTF_ABSOLUTE := 0x80, szTI := A_PtrSize = 4 ? 48 : 72
     
      VarSetCapacity(TOOLINFO, szTI, 0)
      this.pTI := &TOOLINFO
      NumPut(szTI, TOOLINFO)
      (this.TrayTip && this.BalloonTip := true)
      NumPut(TTF_TRACK|(this.BalloonTip ? 0 : TTF_ABSOLUTE), &TOOLINFO + 4)
      
      this.hwnd := DllCall("CreateWindowEx", UInt, WS_EX_TOPMOST|(this.transparent ? WS_EX_TRANSPARENT : 0)
        , Str, "tooltips_class32", Str, ""
        , UInt, WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP | (this.CloseButton ? TTS_CLOSE : 0) | (this.BalloonTip ? TTS_BALLOON : 0)
        , Int, 0, Int, 0, Int, 0, Int, 0, Ptr, 0, Ptr, 0, Ptr, 0, Ptr, 0)
        
      if (this.FontName || this.FontSize || this.FontStyle)
         this._SetFont()
      
      if (this.TextColor != "" || this.BackColor != "")
         this._SetColor()
      
      this._SetInfo()

      if this.TimeOut  {
         timer := ObjBindMethod(this, "Destroy")
         SetTimer % timer, % "-" . this.TimeOut
      }
   }
   
   _SetFont()  {
      static WM_GETFONT := 0x31, mult := A_IsUnicode ? 2 : 1, szLF := 28 + 32 * mult
           , LOGPIXELSY := 90, ANTIALIASED_QUALITY := 4
           , styles := { bold: {value: 700, offset: 16, size: "Int"}
                       , italic: {value: 1, offset: 20, size: "Char"}
                       , underline: {value: 1, offset: 21, size: "Char"}
                       , strikeout: {value: 1, offset: 22, size: "Char"} }
                       
      hPrevFont := this._SendMessage(WM_GETFONT)
      VarSetCapacity(LOGFONT, szLF, 0)
      DllCall("GetObject", Ptr, hPrevFont, Int, szLF, Ptr, &LOGFONT)
      DllCall("DeleteObject", Ptr, hPrevFont)
      
      if this.FontSize  {
         hDC := DllCall("GetDC", Ptr, this.hwnd, Ptr)
         height := -DllCall("MulDiv", Int, this.FontSize, Int, DllCall("GetDeviceCaps", Ptr, hDC, Int, LOGPIXELSY), Int, 72)
         DllCall("ReleaseDC", Ptr, this.hwnd, Ptr, hDC)
         NumPut(height, LOGFONT, "Int")
      }
      FontStyle := this.FontStyle
      Loop, parse, FontStyle, %A_Space%
         if obj := styles[A_LoopField]
            NumPut(obj.value, &LOGFONT + obj.offset, obj.size)

      (this.FontSize > 24 && NumPut(ANTIALIASED_QUALITY, &LOGFONT + 26, "Char"))
      this.FontName && StrPut(this.FontName, &LOGFONT + 28, StrLen(this.FontName) * mult, A_IsUnicode ? "UTF-16" : "CP0")
      this.hFont := DllCall("CreateFontIndirect", Ptr, &LOGFONT, Ptr)
   }
   
   _SetColor()  {
      static WM_USER := 0x400, TTM_SETTIPBKCOLOR := WM_USER + 19, TTM_SETTIPTEXTCOLOR := WM_USER + 20
      
      VarSetCapacity(empty, 2, 0)
      DllCall("UxTheme\SetWindowTheme", Ptr, this.hwnd, Ptr, 0, Ptr, &empty)   
      ( this.TextColor != "" && this._SendMessage(TTM_SETTIPTEXTCOLOR, this._GetColor(this.TextColor)) )
      ( this.BackColor != "" && this._SendMessage(TTM_SETTIPBKCOLOR, this._GetColor(this.BackColor)) )
   }
   
   _GetColor(color)  {
      static WS_CHILD := 0x40000000, WM_CTLCOLORSTATIC := 0x138
      
      Gui, New, +hwndhGui +%WS_CHILD%
      Gui, Color, % color + 0 = "" ? color : Format("{:x}", color)
      Gui, Add, Text, hwndhText
      hdc := DllCall("GetDC", Ptr, hText, Ptr)
      SendMessage, WM_CTLCOLORSTATIC, hdc, hText,, ahk_id %hGui%
      clr := DllCall("GetBkColor", Ptr, hdc)
      DllCall("ReleaseDC", Ptr, hText, Ptr, hdc)
      Gui, Destroy
      Return clr
   }
   
   _SetInfo()  {
      static WM_USER := 0x400, TTM_SETMAXTIPWIDTH := WM_USER + 24
           , TTM_ADDTOOL := WM_USER + (A_IsUnicode ? 50 : 4), WM_SETFONT := 0x30
      
      this._SendMessage(WM_SETFONT, this.hFont, 1)
      this._SendMessage(TTM_ADDTOOL, 0, this.pTI)
      this.SetTitle(this.icon, this.title)
      this._SendMessage(TTM_SETMAXTIPWIDTH, 0, A_ScreenWidth)
      this.SetText(this.text)
   }
   
   SetText(text)  {
      static WM_USER := 0x400, TTM_UPDATETIPTEXT := WM_USER + (A_IsUnicode ? 57 : 12)
      NumPut(&text, this.pTI + (A_PtrSize = 4 ? 36 : 48))
      this._SendMessage(TTM_UPDATETIPTEXT, 0, this.pTI)
   }
   
   SetTitle(icon := "", title := "")  {
      static WM_USER := 0x400, TTM_SETTITLE := WM_USER + (A_IsUnicode ? 33 : 32), TTM_UPDATE := WM_USER + 29
      
      ((icon || this.CloseButton) && title = "") && title := " "
      this._SendMessage(TTM_SETTITLE, icon, &title)
      (icon > 3 && DllCall("DestroyIcon", Ptr, icon))
      this._SendMessage(TTM_UPDATE)
   }
   
   Show(x := "", y := "")  {
      static WM_USER := 0x400, TTM_TRACKACTIVATE := WM_USER + 17, TTM_TRACKPOSITION := WM_USER + 18
      
      if this.TrayTip  {
         this._GetTrayIconCoords(xTT, yTT)
         if !this.TrayTimer  {
            timer := ObjBindMethod(this, "Show")
            SetTimer, % timer, 1000
            this.TrayTimer := timer
         }
         else  {
            this._CheckPosAboveTaskBar()
            if (this.xTT = xTT && this.yTT = yTT)
               Return
            else
               this.xTT := xTT, this.yTT := yTT
         }
      }
      else  {
         xTT := x, yTT := y
         (xTT = "" && xTT := this.x)
         (yTT = "" && yTT := this.y)
      
         if (xTT = "" || yTT = "") {
            CoordMode, Mouse
            MouseGetPos, xm, ym
            (xTT = "" && xTT := xm + 10)
            (yTT = "" && yTT := ym + 10)
         }
      }
      this._SendMessage(TTM_TRACKPOSITION, 0, xTT|(yTT<<16))
      this._SendMessage(TTM_TRACKACTIVATE, 1, this.pTI)
      
      if this.BalloonTip
         xMax := A_ScreenWidth, yMax := A_ScreenHeight
      else  {
         WinGetPos,,, W, H, % "ahk_id" this.hwnd
         xMax := A_ScreenWidth - W - 10
         yMax := A_ScreenHeight - H - 10
      }
      
      if (xTT > xMax || yTT > yMax)  {
         (xTT > xMax && xTT := xMax)
         (yTT > yMax && yTT := yMax)
         this._SendMessage(TTM_TRACKPOSITION, 0, xTT|(yTT<<16))
      }
   }
   
   Hide()  {
      static WM_USER := 0x400, TTM_TRACKACTIVATE := WM_USER + 17
      this._SendMessage(TTM_TRACKACTIVATE, 0, this.pTI)
      if timer := this.TrayTimer  {
         SetTimer, % timer, Off
         this.TrayTimer := timer := ""
      }
   }
   
   Destroy()  {
      if timer := this.TrayTimer  {
         SetTimer, % timer, Off
         this.TrayTimer := timer := ""
      }
      this.__Delete()
      this.SetCapacity(0)
      this.base := ""
   }
   
   _CheckPosAboveTaskBar()  {
      static GW_HWNDNEXT := 2, SWP_NOSIZE := 1, SWP_NOMOVE := 2
      
      hTaskBar := WinExist("ahk_class Shell_TrayWnd")
      Loop
         hWnd := A_Index = 1 ? DllCall("GetTopWindow", Ptr, 0, Ptr) : DllCall("GetWindow", Ptr, hWnd, UInt, GW_HWNDNEXT, Ptr)
      until (hWnd = hTaskBar && TaskBarAbove := true) || hWnd = this.hwnd
      
      if TaskBarAbove
         DllCall("SetWindowPos", Ptr, this.hwnd, Ptr, 0
                               , Int, 0, Int, 0, Int, 0, Int, 0
                               , UInt, SWP_NOSIZE | SWP_NOMOVE )
   }
   
   _SendMessage(msg, wp := 0, lp := 0)  {
      Return DllCall("SendMessage", Ptr, this.hwnd, UInt, msg, Ptr, wp, Ptr, lp, Ptr)
   }
   
   _GetTrayIconCoords(ByRef x, ByRef y)  {
      static WM_USER := 0x400, TB_BUTTONCOUNT := WM_USER + 24, TB_GETBUTTON := WM_USER + 23, TB_GETITEMRECT := WM_USER + 29
           , PtrSize := A_Is64bitOS ? 8 : 4, szTBBUTTON := 8 + PtrSize*3, szHWND := PtrSize
         
      for k, v in ["TrayNotifyWnd", "SysPager", "ToolbarWindow32"]
         hTray := DllCall("FindWindowEx", Ptr, k = 1 ? WinExist("ahk_class Shell_TrayWnd") : hTray, Ptr, 0, Str, v, UInt, 0, Ptr)
      WinWait, ahk_id %hTray%
      WinGet, PID, PID
      WinGetPos, xTB, yTB
      
      if !IsObject(RemoteBuff := new this.RemoteBuffer(PID, szTBBUTTON))  {
         x := xTB, y := yTB
         MsgBox, % "Не удалось создать удалённый буфер`nОшибка " A_LastError
         Return
      }
      SendMessage, TB_BUTTONCOUNT
      Loop % ErrorLevel  {
         SendMessage, TB_GETBUTTON, A_Index - 1, RemoteBuff.ptr
         pTBBUTTON := RemoteBuff.Read(szTBBUTTON)
         pHWND := RemoteBuff.Read(szHWND, NumGet(pTBBUTTON + 8 + PtrSize) - RemoteBuff.ptr)
         hWnd := NumGet(pHWND + 0, PtrSize = 4 ? "UInt" : "UInt64")
         if (hWnd = A_ScriptHwnd)  {
            SendMessage, TB_GETITEMRECT, A_Index - 1, RemoteBuff.ptr
            pRECT := RemoteBuff.Read(16)
            x := xTB + ( NumGet(pRECT + 0, "Int") + NumGet(pRECT + 8, "Int") )//2
            y := yTB + ( NumGet(pRECT + 4, "Int") + NumGet(pRECT + 12, "Int") )//2 - 5
            break
         }
      }
      RemoteBuff := "", ((x = "" || y = "") && (x := xTB, y := yTB))
   }
   
   __Delete()  {
      (this.hFont && DllCall("DeleteObject", Ptr, this.hFont))
      (this.Icon > 3 && DllCall("DestroyIcon", Ptr, this.Icon))
      DllCall("DestroyWindow", Ptr, this.hwnd)
   }

   class RemoteBuffer
   {
      __New(PID, size)  {
         static PROCESS_VM_OPERATION := 0x8, PROCESS_VM_WRITE := 0x20, PROCESS_VM_READ := 0x10
              , MEM_COMMIT := 0x1000, PAGE_READWRITE := 0x4
            
         if !(this.hProc := DllCall("OpenProcess", UInt, PROCESS_VM_OPERATION|PROCESS_VM_READ|PROCESS_VM_WRITE, Int, 0, UInt, PID, Ptr))
            Return
         
         if !(this.ptr := DllCall("VirtualAllocEx", UInt, this.hProc, UInt, 0, UInt, size, UInt, MEM_COMMIT, UInt, PAGE_READWRITE, Ptr))
            Return, "", DllCall("CloseHandle", Ptr, this.hProc)
      }
      
      __Delete()  {
         DllCall("VirtualFreeEx", Ptr, this.hProc, Ptr, this.ptr, UInt, 0, UInt, MEM_RELEASE := 0x8000)
         DllCall("CloseHandle", Ptr, this.hProc)
      }
      
      Read(size, offset = 0)  {
         static LocalBuff
         VarSetCapacity(LocalBuff, size, 0)
         if !DllCall("ReadProcessMemory", Ptr, this.hProc, Ptr, this.ptr + offset, Ptr, &LocalBuff, UInt, size, UInt, 0)
            Return, 0, DllCall("MessageBox", Ptr, 0, Str, "Не удалось прочитать данные`nОшибка """ A_LastError """", Str, "", UInt, 0)
         
         VarSetCapacity(LocalBuff, -1)
         Return &LocalBuff
      }
   }
}

Timer(oTip)  {
   static i := 0
   oTip.SetText("Я цветной ToolTip!`r`nЯ исчезну через " (7 - ++i) " сек")
   if (i = 7)
      SetTimer,, Delete
}

CreateIconFromBase64(StringBASE64, Size)
{
   StringBase64ToData(StringBASE64, IconData)
   Return DllCall("CreateIconFromResourceEx", Ptr, &IconData + 4
      , UInt, NumGet(&IconData, "UInt"), UInt, true, UInt, 0x30000, Int, Size, Int, Size, UInt, 0)
}
   
StringBase64ToData(StringBase64, ByRef OutData)
{
   DllCall("Crypt32.dll\CryptStringToBinary", Ptr, &StringBase64 
      , UInt, StrLen(StringBase64), UInt, CRYPT_STRING_BASE64 := 1, UInt, 0, UIntP, Bytes, UIntP, 0, UIntP, 0)

   VarSetCapacity(OutData, Bytes) 
   DllCall("Crypt32.dll\CryptStringToBinary", Ptr, &StringBase64 
      , UInt, StrLen(StringBase64), UInt, CRYPT_STRING_BASE64, Str, OutData, UIntP, Bytes, UIntP, 0, UIntP, 0)
   Return Bytes
}

GetIcon()  {
   Icon32 = 
   (RTrim Join
      qBAAACgAAAAgAAAAQAAAAAEAIAAAAAAAgBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
      FRgjABMXIQATFyEAFBchABMXIQAVGCMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
      AAAAABUYIwAAAAAAAAAAAAAAAAIAAAAAAAAAABUYIwAVGCMAExchABMXIRQUFyETExchABUYIwAVGCMAAAAAAAAAAAAAAAACAAAAAAAAAAAVGCMAAAAAAAAAAAAAAAAA
      AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFRgjABQXIgAUFyIAFBciABMXIQATFyEAFRgjABUYIwIUFyIAFBciqxQXIqoUFyIAFRgjAhUYIwAUFyIA
      FBgiABQXIgATFyIAExciABUYIwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVGCMAFBciABQXIhAUFiFCExgiABMWIQAAAAAA
      FRgjAxUYIwAVFiO4ExghuBUYIwAVGCMDAAAAABQXIgATGiIAExchQhMYIhATGCIAFRgjAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
      AAAAABUYIwEUFyIAFBchMhQXIv8TFyFDFBciABUXIwIVGCMCFRgjABUXI7sUGCK7FRgjABUYIwIUFyMCFBciABQXIkMUFyL/FBchMhQXIgAVGCMBAAAAAAAAAAAAAAAA
      AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFRgjABUXIgEVFyIAFBciuRQXItoVGSICFRgiARUYIwMUFyIBFBcinRMXIp0UFyIBFRgjAxUYIgEVGCIC
      FBci2hQXIroVFyIAFRciARUYIwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFRgjAAAAAAAAAAAAAAAAAgAAAAEVGCMAFBgjARQXIgAUFyIkFBci/xQXImEUFyIC
      FRgjAAwOHwD/AAAA/wAAAAoRHQAVGCMAFBciAhQXImAUFyL/FBYiJRQXIgAUGCMBFBgiAAAAAAEAAAACAAAAAAAAAAAVGCMAAAAAAAAAAAAVGCMAFBUiABMVIgAUFyIA
      ExciABQXIgIUFyMAFRciABQXIgAUFiFRFBciKRUYJAAVHSoAFR8sIxMSGj0TEhs+FRsoJxUcKQEUGCQAFBcjKBMWIlEUFyIAFBciABQYIgAUFyICFBYiABQXIgASFyAA
      EhggABUYIwAAAAAAAAAAABUYIwATFSIAFBUiBRQXIl0TFyEWFBciABUXIwAUFyIAFRgjAxQXIgAVGiYAExUfcBILEtETERr8FRsn/xUbJ/8TEhv/EgsS1hMVH3QWHCYA
      FRgiABUYIwIUFyIAFBgiABQXIgAUFiEVFBchXBMWIAUSGCAAFRgjAAAAAAAAAAAAFRgjABQXIgAUFyMRExci7xQXIvcUFyJkFBciAxQYIgEUFyEAFBolKBMOFcwUGSX/
      Hlh5/yWLvf8pntn9KZ/Z/SaMv/8eW33/FBsn/xMOFc0UGiYlFBchABQXIwEUFyICFBciYxQXIvYUFyLvFBkiEBQYIgAVGCMAAAAAAAAAAAAVGCMAFRgiABQYIgAUFyES
      FBcilRQXIv8UFyGKFBYgABQdKyQTDxflGTdO/ymh2fouxP/8LsD//i28//4tvP/+LsD//i7E//0potz6GThP/xMPGOIVHiwfFBYhABQXIosUFyL/FBcilhQXIhMVGCMA
      FRgjABUYIwAAAAAAAAAAABUYIwAVGCMAFRgiABUXIwAUFyIAFBciMxQZJDATGSQDExAZxRg0Sf8stvX6Lb3//yuy8/4stPX+LLX2/yy19v8stPb+LLLz/i29//8stvT5
      GDJG/xMRGr4UFyIBFBgjMhQXIjQUFyIAFRgjABUWIwAVGCMAFRgjAAAAAAAAAAAAAAAAABUYIwAVGCMAFRciABQXIgEVGCMAFBEaABQYJFMUFyL/KJvV+y6///4rsvT+
      Lbb4/yy19/8stff/LLX3/yy19/8ttvj/K7L0/i6///4ol8/7FBUf/xQaJkwUEhwAFRgjABQXIgEUGCMAFRgjABUYIwAAAAAAAAAAABUYIwAUGyMAAAAAAhUYIwMVGCMD
      FhgjAxQYIwQMAAAAEggOsxtIZP0uwv/7LLL0/yy2+P8stff/Lbb4/y22+P8ttvj/Lbb4/yy19/8stvj/LLP1/y7C//sbRF/9EggOrgwAAAAUFyIEFRgkAxUYIwMVGCMD
      AAAAAhYYJQAVGCMAFRgjABUcIwAVFyIAFRgjABUYIwAUFyIAFBciABMwQwsSCxLkI3ek/i7B/vwrs/T+Lbb4/y22+P8ttvj/Lbb4/y22+P8ttvj/Lbb4/y22+P8rs/T+
      LsH+/CN1ov4SCxLjDyk4ChMYIQAUFyIAFRgjABUYIwAUGCIAFxgmABUYIwAVGCMBFBoiABQXIoYUGCK/FBgiuxQXIrcTFyEYFyY3FRMRGvcmjcH/Lb7+/Sy09f8stff/
      Lbb4/y22+P8ttvj/Lbb4/y22+P8ttvj/LLX3/yy09f8tvv79Joq+/xMQGfkYKTkYFBchGBQXIrcUGCK7FBcivxQXIoUVFyQAFRgjAhUYIwEUGSMAFBYihxQXIr8VFyO8
      FBYitxQVIRgXKDkUExEa9yaNwf8tvv79LLT1/yy19/8ttvj/Lbb4/y22+P8ttvj/Lbb4/y22+P8stff/LLT1/y2+/v0lir3/ExAZ+RgpORgTFiIYFBYiuBUXI7wUFyPA
      FBcihhUXJAAVGCMCFRgjABUdIwAVFyIAFRgjABUYIwAUFyIAFBchAA8sPAkSCxLiI3ej/i7B/vwrs/T+Lbb4/y22+P8ttvj/Lbb4/y22+P8ttvj/Lbb4/y22+P8rs/T+
      LsH+/CN2ov4SCxLjDic1ChMWIgAUFyIAFRgjABUYIwAUGCIAFxgmABUYIwAVGCMAFRsjAAAAAAIVGCMDFRgjAxUYIwMVGCIEDAAAABEIDa8bR2P9LsP/+yyy9P8stvj/
      LLX3/y22+P8ttvj/Lbb4/y22+P8stff/LLb4/yyz9P8uwv/7G0Rf/RIIDq8LAAAAFBcjBBQZIwMVGCMDFRgjAwAAAAIWGCUAFRgjAAAAAAAAAAAAFRgjABUYIwAUGCIA
      FBciARUYIwAUEhsAFBgkTxQWIf8omtT7Lr///iuy9P4ttvj/LLX3/yy19/8stff/LLX3/y22+P8rsvT+LsD//iiWzvsUFR//FBomTRQTHAAVGCMAExgiARQXIgAVGCMA
      FRgjAAAAAAAAAAAAAAAAABUYIwAVGCMAERghABQYIgAUFyEAFBciMxQZIzATFyECExEZwxgzSP8stvX6Lb3//yuy8/4stPb+LLX2/yy19v8stPb+K7Lz/i29//8stPL5
      GDFE/xMRGr8TFyIBExgjMBQXIjITGCMAFRcjABUXIQAVGCMAFRgjAAAAAAAAAAAAFRgjABUYIwAVFyMAFBciExQXIpYUFyL/FBciihQWIAAVHSskEw8X5Rk3Tv8podr6
      LsT//C7A//4tu//+Lbv//i7A//4uxP/9KaDZ+hk1S/8TDxjiFR4rIBQWIQAUFyKLFBci/xQXIpQUFyISFRciABUZIwAVGCMAAAAAAAAAAAAVGCMAFBciABYXIxAUFyLv
      FBci9hQXImQUFyICFRgjARQXIgAUGSUpEw4VzxUaJv8eWXr/Jo2//ymg2/0podv9Jo3A/x5ae/8UGSb/Ew4WzBQaJiUUFyEAFBgiARQXIgMUFyJmFBci9xQXIu4UFyIQ
      FBgiABUYIwAAAAAAAAAAABUYIwAUFSAAExUgBRQXIl0TFyIVFBciABQYIgAUFyIAFRgjAxQYIwAVHCgAFBUfcxILEtMTEhv+FRwo/xUcKf8UEhv/EgsS1hQVH3QVGSgA
      FRciABUYIwIUFyMAFBcjABQXIgATFyEXFBciXhQVIwUUFSEAFRgjAAAAAAAAAAAAFRgjABQVIAAUFR8AFBciABQXIgAUFyICFBciABQYIgAUFyIAExchTxQXIScUGCQA
      FR0pABQcKCUTERo/FBAaQBQbJygVHCkBFRgjABQXISkTFyFPFRciABQXJAAUFyIAFBciAhMXIQAUFyIAFBYjABQVIQAVGCMAAAAAAAAAAAAVGCMAAAAAAAAAAAAAAAAC
      AAAAARUYIwAUFyIBFBciABQXISUUFyL/FBciXxQXIgIVGCMACw4VACEAAAAoAAAABwseABQYIwAUFyICFBciYhQXIv8UFyIjFBciABUXIgEUGCMAAAAAAQAAAAIAAAAA
      AAAAABUYIwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFRgjABUYIwEVGCMAFBciuhQXItkWGCICFRgiARUYIwMUFyIBFBcinBQXIpwUFyIBFRgjAxQXIwEVFyQC
      FBci2xQXIrcUGCMAFBgjARUYIwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVGCMBFRciABUXIjIUFyL/FBciQxQXIgAUFyMC
      FRgjAxUYIwAVFyO7FBgiuxUYIwAVGCMDFRgiAhQXIgAUFiFFFBci/xQXIjEUFyIAFRgjAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
      AAAAABUYIwAUFyIAFBciEBQXIkITGCYAFRQiAAAAAAAVGCMDFRgjABUWI7gTGCG4FRgjABUYIwMAAAAAExYgABQVHgATFiFDFBYiEBQWIgAVGCMAAAAAAAAAAAAAAAAA
      AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFRgjABQXIgAUFyEAFBciABQXJAAVFSIAFRgjABUYIwIVFyIAFBciqxQXIqoVFyIAFRgjAhUYIwATFiEA
      FBYgABMXIgAUFyIAFBciABUYIwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVGCMAAAAAAAAAAAAAAAACAAAAAAAAAAAVGCMA
      FRgjABUWIQAUFyEVFRYiFBUWIQAVGCMAFRgjAAAAAAAAAAAAAAAAAgAAAAAAAAAAFRgjAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
      AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVGCMAFRciABQXIgAVFiIAFRYiABUYIwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
      AAAAAAAAAAAAAAAA/////////////n////5///++ff//nnn//8/z///f+//38A/v8eAHj/jAAx//gAH//wAB//8AAP//AAD/wwAAw8MAAMP/AAD//wAA//+AAf//gAH/
      +MADH/HgB4/38A/v///////P8///nnn//759///+f////n////////////8=
   )
   Return Icon32
}

Добавлено отслеживание перемещения иконки скрипта в трее для TrayTip'а и нахождения его поверх панели задач.

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

35

Re: AHK: Изменить размер шрифта TOOLTIP

Добавлено в Коллекцию.

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

36

Re: AHK: Изменить размер шрифта TOOLTIP

teadrinker, как устранить ошибку?

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

http://puu.sh/sVJQd/c0906be561.png

37

Re: AHK: Изменить размер шрифта TOOLTIP

Обновить AHK до последней версии.

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

38

Re: AHK: Изменить размер шрифта TOOLTIP

Версия 1.03 — добавлена возможность смены заголовка.

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

39 (изменено: svoboden, 2017-03-11 22:02:19)

Re: AHK: Изменить размер шрифта TOOLTIP

Есть программа MacroCreator и у нее маленькая задержка ToolTip'a. Как ее увеличить? Спасибо!

40

Re: AHK: Изменить размер шрифта TOOLTIP

svoboden, что за MacroCreator, какое отношение он имеет к теме?

41

Re: AHK: Изменить размер шрифта TOOLTIP

MacroCreator - это макрорегистратор для AutoHotkey. Вопрос не по программе, а в том, как увеличить задержку ToolTip`a.

42

Re: AHK: Изменить размер шрифта TOOLTIP

Это тоже к теме не имеет отношения. У ToolTip'а нет задержки в принципе, он удаляется просто командой с пустыми параметрами.

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

43 (изменено: svoboden, 2017-03-18 23:19:34)

Re: AHK: Изменить размер шрифта TOOLTIP

По-моему, вопрос про ToolTip, вроде по теме все, не хочется создавать новую тему. Вопрос вроде бы простой для вас должен быть. ToolTip быстро исчезает, не удается прочитать даже, что написано.

44

Re: AHK: Изменить размер шрифта TOOLTIP

svoboden, спросите у автора программы.
Или так на 30 сек:

TTM_SETDELAYTIME := 0X403, TTDT_AUTOPOP := 2
loop
{
   WinWait ahk_class tooltips_class32
   SendMessage, TTM_SETDELAYTIME, TTDT_AUTOPOP, 30000
   WinWaitClose
}

45 (изменено: svoboden, 2017-04-20 20:49:14)

Re: AHK: Изменить размер шрифта TOOLTIP

Malcev, спасибо, но в Macro Creator не работает. Я в ресурсах нашел настройки ToolTip, гляну, может, получится поменять задержку. Программа вроде на ahk написана, может, сам разберусь.

46 (изменено: ypppu, 2017-01-17 19:14:39)

Re: AHK: Изменить размер шрифта TOOLTIP

Если он написан на AutoHotkey, значит нужно взять исходный код и увеличить задержку.

Добавлено:

Вот это наверное:

SetTimer, RemoveToolTip, -3000

47 (изменено: svoboden, 2017-03-18 23:17:09)

Re: AHK: Изменить размер шрифта TOOLTIP

ypppu, чтобы я без вашего совета делал.

48

Re: AHK: Изменить размер шрифта TOOLTIP

Только хотел спросить про метод

_Destroy()  {
   this.__Delete()
   this.SetCapacity(0)
   this.base := ""
}

, но загуглив __Delete сразу наткнулся на пост Lexikos'a:

You can clear all properties from the object from within the method.
this.Remove("", Chr(255)) would cover most property names (that is, keys; strings with which values are associated).
After removing all properties, this.SetCapacity(0) will ensure any memory associated with the object is freed (but not the allocation of the object itself).
Then you can this.base := "" to disconnect the object from its class (and therefore all user-defined methods).

Как я понял, извне экземпляра удалить экземпляр класса невозможно.

49

Re: AHK: Изменить размер шрифта TOOLTIP

stealzy, тут путаница. В скрипте я пытался запрограммировать удаление экземпляра объекта изнутри конструктора, с чем справился посредством некоторых танцев.

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

50

Re: AHK: Изменить размер шрифта TOOLTIP

teadrinker
Хорошая штука этот TrayTip из Коллекции, но возникла пара вопросов:
1. Подсказка возникает сразу после объявления new ToolTip. Логичнее было бы после .Show(). Хотя спорить не буду. Я её просто глушу .Hide() сразу же после объявления.
2. Если задан параметр TimeOut, то увидеть подсказку по .Show() получится только 1 раз. Вероятно потому что значение TimeOut загружается в таймер только при инициализации, а надо чтоб всякий раз когда вызывается метод .Show(). А пока приходится убирать этот параметр и гасить TrayTip вручную.

51

Re: AHK: Изменить размер шрифта TOOLTIP

1. Ещё логичнее было бы параметризировать поведение при создании объекта, может, и имеет смысл дополнить.
2. По истечении таймаута текущий экземпляр объекта удаляется, такова концепция. Теоретически, тоже можно было бы параметризировать.

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

52

Re: AHK: Изменить размер шрифта TOOLTIP

Класс изменён и дополнен, описание в комментарии.

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

53

Re: AHK: Изменить размер шрифта TOOLTIP

teadrinker
Спасибо за модификацию! На Win7 новые фичи работают как задумано. На Win10 почему то повторный вызов .Show(,, timeout) приводит к тому, что подсказка уже не гасится по истечении timeout-а.

myTrayTip := new ToolTip({ text: "Подсказка"
                        , TrayTip: true
                        , ShowNow: false})
myTrayTip.Show(,, 2000)
Sleep, 4000
myTrayTip.Show(,, 2000)

И, наверное, стоит обратить внимание что переход к выполнению следующей строки скрипта происходит не через указанное в .Show(,, timeout) время, а сразу же.

54

Re: AHK: Изменить размер шрифта TOOLTIP

mozers пишет:

На Win10 почему то повторный вызов .Show(,, timeout) приводит к тому, что подсказка уже не гасится по истечении timeout-а.

mozers, попробуйте в методе Hide() в строке

SetTimer, % timer, Off

заменить Off на Delete.

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

55

Re: AHK: Изменить размер шрифта TOOLTIP

teadrinker, увы, не помогло.

56

Re: AHK: Изменить размер шрифта TOOLTIP

Ещё можно попробовать в методе Show() стоку

this.timer := timer := ObjBindMethod(this, timeout > 0 ? "Hide" : "Destroy")

заменить на

this.timer := timer := this[timeout > 0 ? "Hide" : "Destroy"].Bind(this)
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

57

Re: AHK: Изменить размер шрифта TOOLTIP

teadrinker, увы, и это не помогло.
С моим примером, подсказка появляется, через 2 сек исчезает на долю секунды, опять появляется уже навсегда.
Если TrayTip: true убрать, то все работает как положено: 2сек-есть, 2сек-нет, 2сек-есть и исчезает навсегда.
Но проблема  в том, что мне нужен именно TrayTip: true.
Если исправление невозможно, то придется ограничить область применения Win7.

58

Re: AHK: Изменить размер шрифта TOOLTIP

mozers пишет:

С моим примером, подсказка появляется, через 2 сек исчезает на долю секунды, опять появляется

То есть, на десятке с таким примером

myTrayTip := new ToolTip({ text: "Подсказка"
                        , TrayTip: true
                        , ShowNow: false})
myTrayTip.Show(,, 2000)

тоже срабатывает неправильно?

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

59 (изменено: mozers, 2017-04-26 00:08:13)

Re: AHK: Изменить размер шрифта TOOLTIP

teadrinker, точно так. Мигнула после 2сек, но не исчезла насовсем.
Я даже не ожидал (думал сбоит только при втором вызове), а оказалось что сразу...
Кстати, такой код работает безошибочно (даже без всех предложенных исправлений):

myTrayTip := new ToolTip({ text: "Подсказка"
                        , TrayTip: true
                        , ShowNow: false})
myTrayTip.Show()
Sleep, 2000
myTrayTip.Hide()
Sleep, 2000
myTrayTip.Show()
Sleep, 2000
myTrayTip.Hide()

Так что можно вообще обойтись и без опции timeout.

60

Re: AHK: Изменить размер шрифта TOOLTIP

Ну, хотя бы понятно, куда копать.

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

61

Re: AHK: Изменить размер шрифта TOOLTIP

Попробуйте так:

myTrayTip := new ToolTip({ text: "Подсказка"
                         , TrayTip: true
                         , ShowNow: false })
myTrayTip.Show(,, 2000)
Sleep, 3000
myTrayTip.Show(,, 2000)

class ToolTip  {
/*
Версия: 1.04
Добавлено:
1. Псевдонимы ключей для краткости (можно, например, вместо CloseButton указать close).
   Возможные ключи и псевдонимы перечислены ниже.
2. Параметр ShowNow (или now) — показывать или нет ToolTip сразу после создания, 
   возможные значения — true или false, если не указан, тогда по умолчанию true,
   т. е. ToolTip будет показан сразу же.
3. Добавлен параметр "timeout" к методу Show(x, y, timeout).
   Если таймаут задан положительным числом, ToolTip будет скрыт через указанное время
   в милисекундах, если отрицательным, экземпляр объекта будет удалён без возможности
   дальнейшего использования.
   Если параметр не указан, ToolTip будет показываться до вызова Hide() или Destroy().

Изменено:
1. Опцию TimeOut при создании объекта можно указать в случае, если нужно показать
   ToolTip сразу после создания. Если TimeOut задан положительным числом, ToolTip будет
   скрыт через указанное время в милисекундах, если отрицательным, экземпляр объекта
   будет удалён без возможности дальнейшего использования.

При создании экземпляра объекта в конструктор передаётся ассоциативный массив с опциями.
Возможные ключи и их псевдонимы:

title
text
icon (1 — Info, 2 — Warning; 3 — Error; n > 3 — предполагается hIcon)
CloseButton (или close) — true или false
transparent (или trans) — true или false, указывает, будет ли ToolTip прозрачен для кликов мыши
ShowNow (или now) — true или false, показывать или не показывать ToolTip при создании экземпляра объекта
   Если параметр не указан, ToolTip будет показан сразу же.
x, y — координаты, если не указаны, ToolTip появится вблизи курсора
BalloonTip (или balloon, или ball) — true или false, BalloonTip — это ToolTip с хвостиком
TrayTip (или tray) — будет показан BalloonTip у иконки скрипта в трее, параметры x, y, и BalloonTip игнорируются
   Если указан ключ TrayTip, удалить экземпляр объекта можно либо методом Destroy(),
      либо указав TimeOut с отрицателным значением.
   Если нет, тогда можно просто прировнять ссылку на объект пустому значению.
FontName (или font)
FontSize (или size)
FontStyle (или style) — bold, italic, underline, strikeout в любом сочетании через пробел
TimeOut (или time) — время в милисекундах, через которое ToolTip будет скрыт, если число положительное,
   либо уничтожен, если отрицательное
BackColor (или back) — цвет фона
TextColor (или color) — цвет текста
   
Для указания цвета можно использовать литеральные названия, перечисленные здесь:
https://autohotkey.com/docs/commands/Progress.htm#colors
В этом случае название должно быть в кавычках.

Ключи можно задавать в любом порядке и в любой комбинации, как показано в примерах использования.
Если указан ключ TrayTip, удалить экземпляр объекта можно только методом Destroy(),
если нет, тогда можно просто прировнять ссылку на объект пустому значению.

После создания экземпляра объекта можно:

1. Изменить видимость, расположение и время показа — метод Show(x, y, timeout)
   x и y — координаты, если пустые значения — ToolTip будет показан возле курсора
   timeout — время в милисекундах, через которое ToolTip будет скрыт, если число положительное,
   либо уничтожен, если отрицательное
2. Скрыть ToolTip — метод Hide()
3. Изменить текст — метод SetText(text)
4. Изменить иконку и заголовок — метод SetTitle(icon, title)
5. Уничтожить экземпляр объекта — метод Destroy()
*/
   __New( options )  {
      this.ShowNow := true
      for k, v in options
         this[k] := v
      this._CreateToolTip()
      ( this.ShowNow && this.Show(this.x, this.y, this.TimeOut) )
   }
   
   __Set(key, value)  {
      static PsevdoKeys := { close: "CloseButton", trans: "transparent", size: "FontSize"
                           , balloon: "BalloonTip", ball: "BalloonTip", tray: "TrayTip"
                           , style: "FontStyle", time: "TimeOut", font: "FontName"
                           , back: "BackColor", color: "TextColor", now: "ShowNow" }
                           
      for k, v in PsevdoKeys
         if (key = k)
            this[v] := value
   }
   
   _CreateToolTip()  {
      static WS_POPUP := 0x80000000, WS_EX_TOPMOST := 8, WS_EX_TRANSPARENT := 0x20
           , TTS_NOPREFIX := 2, TTS_ALWAYSTIP := 1, TTS_BALLOON := 0x40, TTS_CLOSE := 0x80
           , TTF_TRACK := 0x20, TTF_ABSOLUTE := 0x80, szTI := A_PtrSize = 4 ? 48 : 72
     
      VarSetCapacity(TOOLINFO, szTI, 0)
      this.pTI := &TOOLINFO
      NumPut(szTI, TOOLINFO)
      (this.TrayTip && this.BalloonTip := true)
      NumPut(TTF_TRACK|(this.BalloonTip ? 0 : TTF_ABSOLUTE), &TOOLINFO + 4)
      
      this.hwnd := DllCall("CreateWindowEx", UInt, WS_EX_TOPMOST|(this.transparent ? WS_EX_TRANSPARENT : 0)
        , Str, "tooltips_class32", Str, ""
        , UInt, WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP | (this.CloseButton ? TTS_CLOSE : 0) | (this.BalloonTip ? TTS_BALLOON : 0)
        , Int, 0, Int, 0, Int, 0, Int, 0, Ptr, 0, Ptr, 0, Ptr, 0, Ptr, 0)
        
      if (this.FontName || this.FontSize || this.FontStyle)
         this._SetFont()
      
      if (this.TextColor != "" || this.BackColor != "")
         this._SetColor()
      
      this._SetInfo()
   }
   
   _SetFont()  {
      static WM_GETFONT := 0x31, mult := A_IsUnicode ? 2 : 1, szLF := 28 + 32 * mult
           , LOGPIXELSY := 90, ANTIALIASED_QUALITY := 4
           , styles := { bold: {value: 700, offset: 16, size: "Int"}
                       , italic: {value: 1, offset: 20, size: "Char"}
                       , underline: {value: 1, offset: 21, size: "Char"}
                       , strikeout: {value: 1, offset: 22, size: "Char"} }
                       
      hPrevFont := this._SendMessage(WM_GETFONT)
      VarSetCapacity(LOGFONT, szLF, 0)
      DllCall("GetObject", Ptr, hPrevFont, Int, szLF, Ptr, &LOGFONT)
      DllCall("DeleteObject", Ptr, hPrevFont)
      
      if this.FontSize  {
         hDC := DllCall("GetDC", Ptr, this.hwnd, Ptr)
         height := -DllCall("MulDiv", Int, this.FontSize, Int, DllCall("GetDeviceCaps", Ptr, hDC, Int, LOGPIXELSY), Int, 72)
         DllCall("ReleaseDC", Ptr, this.hwnd, Ptr, hDC)
         NumPut(height, LOGFONT, "Int")
      }
      FontStyle := this.FontStyle
      Loop, parse, FontStyle, %A_Space%
         if obj := styles[A_LoopField]
            NumPut(obj.value, &LOGFONT + obj.offset, obj.size)

      (this.FontSize > 24 && NumPut(ANTIALIASED_QUALITY, &LOGFONT + 26, "Char"))
      this.FontName && StrPut(this.FontName, &LOGFONT + 28, StrLen(this.FontName) * mult, A_IsUnicode ? "UTF-16" : "CP0")
      this.hFont := DllCall("CreateFontIndirect", Ptr, &LOGFONT, Ptr)
   }
   
   _SetColor()  {
      static WM_USER := 0x400, TTM_SETTIPBKCOLOR := WM_USER + 19, TTM_SETTIPTEXTCOLOR := WM_USER + 20
      
      VarSetCapacity(empty, 2, 0)
      DllCall("UxTheme\SetWindowTheme", Ptr, this.hwnd, Ptr, 0, Ptr, &empty)   
      ( this.TextColor != "" && this._SendMessage(TTM_SETTIPTEXTCOLOR, this._GetColor(this.TextColor)) )
      ( this.BackColor != "" && this._SendMessage(TTM_SETTIPBKCOLOR, this._GetColor(this.BackColor)) )
   }
   
   _GetColor(color)  {
      static WS_CHILD := 0x40000000, WM_CTLCOLORSTATIC := 0x138
      
      Gui, New, +hwndhGui +%WS_CHILD%
      Gui, Color, % color + 0 = "" ? color : Format("{:x}", color)
      Gui, Add, Text, hwndhText
      hdc := DllCall("GetDC", Ptr, hText, Ptr)
      SendMessage, WM_CTLCOLORSTATIC, hdc, hText,, ahk_id %hGui%
      clr := DllCall("GetBkColor", Ptr, hdc)
      DllCall("ReleaseDC", Ptr, hText, Ptr, hdc)
      Gui, Destroy
      Return clr
   }
   
   _SetInfo()  {
      static WM_USER := 0x400, TTM_SETMAXTIPWIDTH := WM_USER + 24
           , TTM_ADDTOOL := WM_USER + (A_IsUnicode ? 50 : 4), WM_SETFONT := 0x30
      
      this._SendMessage(WM_SETFONT, this.hFont, 1)
      this._SendMessage(TTM_ADDTOOL, 0, this.pTI)
      this.SetTitle(this.icon, this.title)
      this._SendMessage(TTM_SETMAXTIPWIDTH, 0, A_ScreenWidth)
      this.SetText(this.text)
   }
   
   SetText(text)  {
      static WM_USER := 0x400, TTM_UPDATETIPTEXT := WM_USER + (A_IsUnicode ? 57 : 12)
      NumPut(&text, this.pTI + (A_PtrSize = 4 ? 36 : 48))
      this._SendMessage(TTM_UPDATETIPTEXT, 0, this.pTI)
   }
   
   SetTitle(icon := "", title := "")  {
      static WM_USER := 0x400, TTM_SETTITLE := WM_USER + (A_IsUnicode ? 33 : 32), TTM_UPDATE := WM_USER + 29
      
      ((icon || this.CloseButton) && title = "") && title := " "
      this._SendMessage(TTM_SETTITLE, icon, &title)
      (icon > 3 && DllCall("DestroyIcon", Ptr, icon))
      this._SendMessage(TTM_UPDATE)
   }
   
   Show(x := "", y := "", timeout := "")  {
      static WM_USER := 0x400, TTM_TRACKACTIVATE := WM_USER + 17, TTM_TRACKPOSITION := WM_USER + 18
      if this.TrayTip  {
         this._GetTrayIconCoords(xTT, yTT)
         if !this.SetTrayTimer  {
            this.SetTrayTimer := true
            this.TrayTimer := timer := ObjBindMethod(this, "Show")
            SetTimer, % timer, 1000
         }
         else  {
            this._CheckPosAboveTaskBar()
            if (this.xTT = xTT && this.yTT = yTT)
               Return
            else
               this.xTT := xTT, this.yTT := yTT
         }
      }
      else  {
         xTT := x, yTT := y
      
         if (xTT = "" || yTT = "") {
            CoordMode, Mouse
            MouseGetPos, xm, ym
            (xTT = "" && xTT := xm + 10)
            (yTT = "" && yTT := ym + 10)
         }
      }
      this._SendMessage(TTM_TRACKPOSITION, 0, xTT|(yTT<<16))
      this._SendMessage(TTM_TRACKACTIVATE, 1, this.pTI)
      
      if this.BalloonTip
         xMax := A_ScreenWidth, yMax := A_ScreenHeight
      else  {
         WinGetPos,,, W, H, % "ahk_id" this.hwnd
         xMax := A_ScreenWidth - W - 10
         yMax := A_ScreenHeight - H - 10
      }
      
      if (xTT > xMax || yTT > yMax)  {
         (xTT > xMax && xTT := xMax)
         (yTT > yMax && yTT := yMax)
         this._SendMessage(TTM_TRACKPOSITION, 0, xTT|(yTT<<16))
      }

      if timeout  {
         timer := this.timer
         try SetTimer, % timer, Delete
         this.timer := timer := ObjBindMethod(this, timeout > 0 ? "Hide" : "Destroy")
         SetTimer % timer, % "-" . Abs(timeout)
      }
   }
   
   Hide()  {
      static WM_USER := 0x400, TTM_TRACKACTIVATE := WM_USER + 17
      this._SendMessage(TTM_TRACKACTIVATE, 0, this.pTI)
      if this.SetTrayTimer  {
         this.SetTrayTimer := false
         timer := this.TrayTimer
         SetTimer, % timer, Delete
      }
   }
   
   Destroy()  {
      this.__Delete()
      this.SetCapacity(0)
      this.base := ""
   }
   
   _CheckPosAboveTaskBar()  {
      static GW_HWNDNEXT := 2, SWP_NOSIZE := 1, SWP_NOMOVE := 2
      
      hTaskBar := WinExist("ahk_class Shell_TrayWnd")
      Loop
         hWnd := A_Index = 1 ? DllCall("GetTopWindow", Ptr, 0, Ptr) : DllCall("GetWindow", Ptr, hWnd, UInt, GW_HWNDNEXT, Ptr)
      until (hWnd = hTaskBar && TaskBarAbove := true) || hWnd = this.hwnd
      
      if TaskBarAbove
         DllCall("SetWindowPos", Ptr, this.hwnd, Ptr, 0
                               , Int, 0, Int, 0, Int, 0, Int, 0
                               , UInt, SWP_NOSIZE | SWP_NOMOVE )
   }
   
   _SendMessage(msg, wp := 0, lp := 0)  {
      Return DllCall("SendMessage", Ptr, this.hwnd, UInt, msg, Ptr, wp, Ptr, lp, Ptr)
   }
   
   _GetTrayIconCoords(ByRef x, ByRef y)  {
      static WM_USER := 0x400, TB_BUTTONCOUNT := WM_USER + 24, TB_GETBUTTON := WM_USER + 23, TB_GETITEMRECT := WM_USER + 29
           , PtrSize := A_Is64bitOS ? 8 : 4, szTBBUTTON := 8 + PtrSize*3, szHWND := PtrSize
         
      for k, v in ["TrayNotifyWnd", "SysPager", "ToolbarWindow32"]
         hTray := DllCall("FindWindowEx", Ptr, k = 1 ? WinExist("ahk_class Shell_TrayWnd") : hTray, Ptr, 0, Str, v, UInt, 0, Ptr)
      WinWait, ahk_id %hTray%
      WinGet, PID, PID
      WinGetPos, xTB, yTB
      
      if !IsObject(RemoteBuff := new this.RemoteBuffer(PID, szTBBUTTON))  {
         x := xTB, y := yTB
         MsgBox, % "Не удалось создать удалённый буфер`nОшибка " A_LastError
         Return
      }
      SendMessage, TB_BUTTONCOUNT
      Loop % ErrorLevel  {
         SendMessage, TB_GETBUTTON, A_Index - 1, RemoteBuff.ptr
         pTBBUTTON := RemoteBuff.Read(szTBBUTTON)
         pHWND := RemoteBuff.Read(szHWND, NumGet(pTBBUTTON + 8 + PtrSize) - RemoteBuff.ptr)
         hWnd := NumGet(pHWND + 0, PtrSize = 4 ? "UInt" : "UInt64")
         if (hWnd = A_ScriptHwnd)  {
            SendMessage, TB_GETITEMRECT, A_Index - 1, RemoteBuff.ptr
            pRECT := RemoteBuff.Read(16)
            x := xTB + ( NumGet(pRECT + 0, "Int") + NumGet(pRECT + 8, "Int") )//2
            y := yTB + ( NumGet(pRECT + 4, "Int") + NumGet(pRECT + 12, "Int") )//2 - 5
            break
         }
      }
      RemoteBuff := "", ((x = "" || y = "") && (x := xTB, y := yTB))
   }
   
   __Delete()  {
      (this.hFont && DllCall("DeleteObject", Ptr, this.hFont))
      (this.Icon > 3 && DllCall("DestroyIcon", Ptr, this.Icon))
      DllCall("DestroyWindow", Ptr, this.hwnd)
   }

   class RemoteBuffer
   {
      __New(PID, size)  {
         static PROCESS_VM_OPERATION := 0x8, PROCESS_VM_WRITE := 0x20
              , PROCESS_VM_READ := 0x10, MEM_COMMIT := 0x1000, PAGE_READWRITE := 0x4
            
         if !(this.hProc := DllCall("OpenProcess", UInt, PROCESS_VM_OPERATION|PROCESS_VM_READ|PROCESS_VM_WRITE, Int, 0, UInt, PID, Ptr))
            Return
         
         if !(this.ptr := DllCall("VirtualAllocEx", Ptr, this.hProc, Ptr, 0, Ptr, size, UInt, MEM_COMMIT, UInt, PAGE_READWRITE, Ptr))
            Return, "", DllCall("CloseHandle", Ptr, this.hProc)
         
         this.hHeap := DllCall("GetProcessHeap", Ptr)
      }
      
      __Delete()  {
         DllCall("VirtualFreeEx", Ptr, this.hProc, Ptr, this.ptr, UInt, 0, UInt, MEM_RELEASE := 0x8000)
         DllCall("CloseHandle", Ptr, this.hProc)
         DllCall("HeapFree", Ptr, this.hHeap, UInt, 0, Ptr, this.pHeap)
      }
      
      Read(size, offset = 0)  {
         (this.pHeap && DllCall("HeapFree", Ptr, this.hHeap, UInt, 0, Ptr, this.pHeap))
         this.pHeap := DllCall("HeapAlloc", Ptr, this.hHeap, UInt, HEAP_ZERO_MEMORY := 0x8, Ptr, size, Ptr)
         if !DllCall("ReadProcessMemory", Ptr, this.hProc, Ptr, this.ptr + offset, Ptr, this.pHeap, Ptr, size, Int, 0)
            Return, 0, DllCall("MessageBox", Ptr, 0, Str, "Не удалось прочитать данные`nОшибка " A_LastError, Str, "", UInt, 0)
         Return this.pHeap
      }
      
      Write(pLocalBuff, size, offset = 0)  {
         if !res := DllCall("WriteProcessMemory", Ptr, this.hProc, Ptr, this.ptr + offset, Ptr, pLocalBuff, Ptr, size, PtrP, writtenBytes)
            DllCall("MessageBox", Ptr, 0, Str, "Не удалось записать данные`nОшибка " A_LastError, Str, "", UInt, 0)
         Return writtenBytes
      }
   }
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

62

Re: AHK: Изменить размер шрифта TOOLTIP

teadrinker, на Win7 - все четко. На Win10 смогу проверить только вечером.

63

Re: AHK: Изменить размер шрифта TOOLTIP

teadrinker пишет:

Попробуйте так:

На моей 10 работает так же, как с классом из Коллекции — моргает и остаётся.

64

Re: AHK: Изменить размер шрифта TOOLTIP

Ничо не понимаю. Почему-то срабатывает уже удалённый таймер. На семёрке тоже удалось воспроизвести проблему, поиграв со значением таймаута.

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

65 (изменено: teadrinker, 2017-04-26 20:11:17)

Re: AHK: Изменить размер шрифта TOOLTIP

А так:

myTrayTip := new ToolTip({ text: "Подсказка"
                         , TrayTip: true
                         , ShowNow: false })
myTrayTip.Show(,, 3100)
Sleep, 4000
myTrayTip.Show(,, 2000)

class ToolTip  {
/*
Версия: 1.04
Добавлено:
1. Псевдонимы ключей для краткости (можно, например, вместо CloseButton указать close).
   Возможные ключи и псевдонимы перечислены ниже.
2. Параметр ShowNow (или now) — показывать или нет ToolTip сразу после создания, 
   возможные значения — true или false, если не указан, тогда по умолчанию true,
   т. е. ToolTip будет показан сразу же.
3. Добавлен параметр "timeout" к методу Show(x, y, timeout).
   Если таймаут задан положительным числом, ToolTip будет скрыт через указанное время
   в милисекундах, если отрицательным, экземпляр объекта будет удалён без возможности
   дальнейшего использования.
   Если параметр не указан, ToolTip будет показываться до вызова Hide() или Destroy().

Изменено:
1. Опцию TimeOut при создании объекта можно указать в случае, если нужно показать
   ToolTip сразу после создания. Если TimeOut задан положительным числом, ToolTip будет
   скрыт через указанное время в милисекундах, если отрицательным, экземпляр объекта
   будет удалён без возможности дальнейшего использования.

При создании экземпляра объекта в конструктор передаётся ассоциативный массив с опциями.
Возможные ключи и их псевдонимы:

title
text
icon (1 — Info, 2 — Warning; 3 — Error; n > 3 — предполагается hIcon)
CloseButton (или close) — true или false
transparent (или trans) — true или false, указывает, будет ли ToolTip прозрачен для кликов мыши
ShowNow (или now) — true или false, показывать или не показывать ToolTip при создании экземпляра объекта
   Если параметр не указан, ToolTip будет показан сразу же.
x, y — координаты, если не указаны, ToolTip появится вблизи курсора
BalloonTip (или balloon, или ball) — true или false, BalloonTip — это ToolTip с хвостиком
TrayTip (или tray) — будет показан BalloonTip у иконки скрипта в трее, параметры x, y, и BalloonTip игнорируются
   Если указан ключ TrayTip, удалить экземпляр объекта можно либо методом Destroy(),
      либо указав TimeOut с отрицателным значением.
   Если нет, тогда можно просто прировнять ссылку на объект пустому значению.
FontName (или font)
FontSize (или size)
FontStyle (или style) — bold, italic, underline, strikeout в любом сочетании через пробел
TimeOut (или time) — время в милисекундах, через которое ToolTip будет скрыт, если число положительное,
   либо уничтожен, если отрицательное
BackColor (или back) — цвет фона
TextColor (или color) — цвет текста
   
Для указания цвета можно использовать литеральные названия, перечисленные здесь:
https://autohotkey.com/docs/commands/Progress.htm#colors
В этом случае название должно быть в кавычках.

Ключи можно задавать в любом порядке и в любой комбинации, как показано в примерах использования.
Если указан ключ TrayTip, удалить экземпляр объекта можно только методом Destroy(),
если нет, тогда можно просто прировнять ссылку на объект пустому значению.

После создания экземпляра объекта можно:

1. Изменить видимость, расположение и время показа — метод Show(x, y, timeout)
   x и y — координаты, если пустые значения — ToolTip будет показан возле курсора
   timeout — время в милисекундах, через которое ToolTip будет скрыт, если число положительное,
   либо уничтожен, если отрицательное
2. Скрыть ToolTip — метод Hide()
3. Изменить текст — метод SetText(text)
4. Изменить иконку и заголовок — метод SetTitle(icon, title)
5. Уничтожить экземпляр объекта — метод Destroy()
*/
   __New( options )  {
      this.ShowNow := true
      for k, v in options
         this[k] := v
      this._CreateToolTip()
      ( this.ShowNow && this.Show(this.x, this.y, this.TimeOut) )
   }
   
   __Set(key, value)  {
      static PsevdoKeys := { close: "CloseButton", trans: "transparent", size: "FontSize"
                           , balloon: "BalloonTip", ball: "BalloonTip", tray: "TrayTip"
                           , style: "FontStyle", time: "TimeOut", font: "FontName"
                           , back: "BackColor", color: "TextColor", now: "ShowNow" }
                           
      for k, v in PsevdoKeys
         if (key = k)
            this[v] := value
   }
   
   _CreateToolTip()  {
      static WS_POPUP := 0x80000000, WS_EX_TOPMOST := 8, WS_EX_TRANSPARENT := 0x20
           , TTS_NOPREFIX := 2, TTS_ALWAYSTIP := 1, TTS_BALLOON := 0x40, TTS_CLOSE := 0x80
           , TTF_TRACK := 0x20, TTF_ABSOLUTE := 0x80, szTI := A_PtrSize = 4 ? 48 : 72
     
      VarSetCapacity(TOOLINFO, szTI, 0)
      this.pTI := &TOOLINFO
      NumPut(szTI, TOOLINFO)
      (this.TrayTip && this.BalloonTip := true)
      NumPut(TTF_TRACK|(this.BalloonTip ? 0 : TTF_ABSOLUTE), &TOOLINFO + 4)
      
      this.hwnd := DllCall("CreateWindowEx", UInt, WS_EX_TOPMOST|(this.transparent ? WS_EX_TRANSPARENT : 0)
        , Str, "tooltips_class32", Str, ""
        , UInt, WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP | (this.CloseButton ? TTS_CLOSE : 0) | (this.BalloonTip ? TTS_BALLOON : 0)
        , Int, 0, Int, 0, Int, 0, Int, 0, Ptr, 0, Ptr, 0, Ptr, 0, Ptr, 0)
        
      if (this.FontName || this.FontSize || this.FontStyle)
         this._SetFont()
      
      if (this.TextColor != "" || this.BackColor != "")
         this._SetColor()
      
      this._SetInfo()
   }
   
   _SetFont()  {
      static WM_GETFONT := 0x31, mult := A_IsUnicode ? 2 : 1, szLF := 28 + 32 * mult
           , LOGPIXELSY := 90, ANTIALIASED_QUALITY := 4
           , styles := { bold: {value: 700, offset: 16, size: "Int"}
                       , italic: {value: 1, offset: 20, size: "Char"}
                       , underline: {value: 1, offset: 21, size: "Char"}
                       , strikeout: {value: 1, offset: 22, size: "Char"} }
                       
      hPrevFont := this._SendMessage(WM_GETFONT)
      VarSetCapacity(LOGFONT, szLF, 0)
      DllCall("GetObject", Ptr, hPrevFont, Int, szLF, Ptr, &LOGFONT)
      DllCall("DeleteObject", Ptr, hPrevFont)
      
      if this.FontSize  {
         hDC := DllCall("GetDC", Ptr, this.hwnd, Ptr)
         height := -DllCall("MulDiv", Int, this.FontSize, Int, DllCall("GetDeviceCaps", Ptr, hDC, Int, LOGPIXELSY), Int, 72)
         DllCall("ReleaseDC", Ptr, this.hwnd, Ptr, hDC)
         NumPut(height, LOGFONT, "Int")
      }
      FontStyle := this.FontStyle
      Loop, parse, FontStyle, %A_Space%
         if obj := styles[A_LoopField]
            NumPut(obj.value, &LOGFONT + obj.offset, obj.size)

      (this.FontSize > 24 && NumPut(ANTIALIASED_QUALITY, &LOGFONT + 26, "Char"))
      this.FontName && StrPut(this.FontName, &LOGFONT + 28, StrLen(this.FontName) * mult, A_IsUnicode ? "UTF-16" : "CP0")
      this.hFont := DllCall("CreateFontIndirect", Ptr, &LOGFONT, Ptr)
   }
   
   _SetColor()  {
      static WM_USER := 0x400, TTM_SETTIPBKCOLOR := WM_USER + 19, TTM_SETTIPTEXTCOLOR := WM_USER + 20
      
      VarSetCapacity(empty, 2, 0)
      DllCall("UxTheme\SetWindowTheme", Ptr, this.hwnd, Ptr, 0, Ptr, &empty)   
      ( this.TextColor != "" && this._SendMessage(TTM_SETTIPTEXTCOLOR, this._GetColor(this.TextColor)) )
      ( this.BackColor != "" && this._SendMessage(TTM_SETTIPBKCOLOR, this._GetColor(this.BackColor)) )
   }
   
   _GetColor(color)  {
      static WS_CHILD := 0x40000000, WM_CTLCOLORSTATIC := 0x138
      
      Gui, New, +hwndhGui +%WS_CHILD%
      Gui, Color, % color + 0 = "" ? color : Format("{:x}", color)
      Gui, Add, Text, hwndhText
      hdc := DllCall("GetDC", Ptr, hText, Ptr)
      SendMessage, WM_CTLCOLORSTATIC, hdc, hText,, ahk_id %hGui%
      clr := DllCall("GetBkColor", Ptr, hdc)
      DllCall("ReleaseDC", Ptr, hText, Ptr, hdc)
      Gui, Destroy
      Return clr
   }
   
   _SetInfo()  {
      static WM_USER := 0x400, TTM_SETMAXTIPWIDTH := WM_USER + 24
           , TTM_ADDTOOL := WM_USER + (A_IsUnicode ? 50 : 4), WM_SETFONT := 0x30
      
      this._SendMessage(WM_SETFONT, this.hFont, 1)
      this._SendMessage(TTM_ADDTOOL, 0, this.pTI)
      this.SetTitle(this.icon, this.title)
      this._SendMessage(TTM_SETMAXTIPWIDTH, 0, A_ScreenWidth)
      this.SetText(this.text)
   }
   
   SetText(text)  {
      static WM_USER := 0x400, TTM_UPDATETIPTEXT := WM_USER + (A_IsUnicode ? 57 : 12)
      NumPut(&text, this.pTI + (A_PtrSize = 4 ? 36 : 48))
      this._SendMessage(TTM_UPDATETIPTEXT, 0, this.pTI)
   }
   
   SetTitle(icon := "", title := "")  {
      static WM_USER := 0x400, TTM_SETTITLE := WM_USER + (A_IsUnicode ? 33 : 32), TTM_UPDATE := WM_USER + 29
      
      ((icon || this.CloseButton) && title = "") && title := " "
      this._SendMessage(TTM_SETTITLE, icon, &title)
      (icon > 3 && DllCall("DestroyIcon", Ptr, icon))
      this._SendMessage(TTM_UPDATE)
   }
   
   Show(x := "", y := "", timeout := "")  {
      static WM_USER := 0x400, TTM_TRACKACTIVATE := WM_USER + 17, TTM_TRACKPOSITION := WM_USER + 18
      
      if (x = "TrayTimer")
         Critical
      
      if this.TrayTip  {
         this._GetTrayIconCoords(xTT, yTT)
         if !this.SetTrayTimer  {
            this.TrayTimer := timer := ObjBindMethod(this, "Show", "TrayTimer")
            SetTimer, % timer, 1000
            this.SetTrayTimer := true
         }
         else  {
            this._CheckPosAboveTaskBar()
            if (this.xTT = xTT && this.yTT = yTT)
               Return
            else
               this.xTT := xTT, this.yTT := yTT
         }
      }
      else  {
         xTT := x, yTT := y
      
         if (xTT = "" || yTT = "") {
            CoordMode, Mouse
            MouseGetPos, xm, ym
            (xTT = "" && xTT := xm + 10)
            (yTT = "" && yTT := ym + 10)
         }
      }
      this._SendMessage(TTM_TRACKPOSITION, 0, xTT|(yTT<<16))
      this._SendMessage(TTM_TRACKACTIVATE, 1, this.pTI)
      
      if this.BalloonTip
         xMax := A_ScreenWidth, yMax := A_ScreenHeight
      else  {
         WinGetPos,,, W, H, % "ahk_id" this.hwnd
         xMax := A_ScreenWidth - W - 10
         yMax := A_ScreenHeight - H - 10
      }
      
      if (xTT > xMax || yTT > yMax)  {
         (xTT > xMax && xTT := xMax)
         (yTT > yMax && yTT := yMax)
         this._SendMessage(TTM_TRACKPOSITION, 0, xTT|(yTT<<16))
      }

      if timeout  {
         timer := this.timer
         try SetTimer, % timer, Delete
         this.timer := timer := ObjBindMethod(this, timeout > 0 ? "Hide" : "Destroy")
         SetTimer % timer, % "-" . Abs(timeout)
      }
   }
   
   Hide()  {
      static WM_USER := 0x400, TTM_TRACKACTIVATE := WM_USER + 17
      this._SendMessage(TTM_TRACKACTIVATE, 0, this.pTI)
      if this.SetTrayTimer  {
         this.SetTrayTimer := false
         timer := this.TrayTimer
         SetTimer, % timer, Delete
      }
   }
   
   Destroy()  {
      this.__Delete()
      this.SetCapacity(0)
      this.base := ""
   }
   
   _CheckPosAboveTaskBar()  {
      static GW_HWNDNEXT := 2, SWP_NOSIZE := 1, SWP_NOMOVE := 2
      
      hTaskBar := WinExist("ahk_class Shell_TrayWnd")
      Loop
         hWnd := A_Index = 1 ? DllCall("GetTopWindow", Ptr, 0, Ptr) : DllCall("GetWindow", Ptr, hWnd, UInt, GW_HWNDNEXT, Ptr)
      until (hWnd = hTaskBar && TaskBarAbove := true) || hWnd = this.hwnd
      
      if TaskBarAbove
         DllCall("SetWindowPos", Ptr, this.hwnd, Ptr, 0
                               , Int, 0, Int, 0, Int, 0, Int, 0
                               , UInt, SWP_NOSIZE | SWP_NOMOVE )
   }
   
   _SendMessage(msg, wp := 0, lp := 0)  {
      Return DllCall("SendMessage", Ptr, this.hwnd, UInt, msg, Ptr, wp, Ptr, lp, Ptr)
   }
   
   _GetTrayIconCoords(ByRef x, ByRef y)  {
      static WM_USER := 0x400, TB_BUTTONCOUNT := WM_USER + 24, TB_GETBUTTON := WM_USER + 23, TB_GETITEMRECT := WM_USER + 29
           , PtrSize := A_Is64bitOS ? 8 : 4, szTBBUTTON := 8 + PtrSize*3, szHWND := PtrSize
         
      for k, v in ["TrayNotifyWnd", "SysPager", "ToolbarWindow32"]
         hTray := DllCall("FindWindowEx", Ptr, k = 1 ? WinExist("ahk_class Shell_TrayWnd") : hTray, Ptr, 0, Str, v, UInt, 0, Ptr)
      WinWait, ahk_id %hTray%
      WinGet, PID, PID
      WinGetPos, xTB, yTB
      
      if !IsObject(RemoteBuff := new this.RemoteBuffer(PID, szTBBUTTON))  {
         x := xTB, y := yTB
         MsgBox, % "Не удалось создать удалённый буфер`nОшибка " A_LastError
         Return
      }
      SendMessage, TB_BUTTONCOUNT
      Loop % ErrorLevel  {
         SendMessage, TB_GETBUTTON, A_Index - 1, RemoteBuff.ptr
         pTBBUTTON := RemoteBuff.Read(szTBBUTTON)
         pHWND := RemoteBuff.Read(szHWND, NumGet(pTBBUTTON + 8 + PtrSize) - RemoteBuff.ptr)
         hWnd := NumGet(pHWND + 0, PtrSize = 4 ? "UInt" : "UInt64")
         if (hWnd = A_ScriptHwnd)  {
            SendMessage, TB_GETITEMRECT, A_Index - 1, RemoteBuff.ptr
            pRECT := RemoteBuff.Read(16)
            x := xTB + ( NumGet(pRECT + 0, "Int") + NumGet(pRECT + 8, "Int") )//2
            y := yTB + ( NumGet(pRECT + 4, "Int") + NumGet(pRECT + 12, "Int") )//2 - 5
            break
         }
      }
      RemoteBuff := "", ((x = "" || y = "") && (x := xTB, y := yTB))
   }
   
   __Delete()  {
      (this.hFont && DllCall("DeleteObject", Ptr, this.hFont))
      (this.Icon > 3 && DllCall("DestroyIcon", Ptr, this.Icon))
      DllCall("DestroyWindow", Ptr, this.hwnd)
   }

   class RemoteBuffer
   {
      __New(PID, size)  {
         static PROCESS_VM_OPERATION := 0x8, PROCESS_VM_WRITE := 0x20
              , PROCESS_VM_READ := 0x10, MEM_COMMIT := 0x1000, PAGE_READWRITE := 0x4
            
         if !(this.hProc := DllCall("OpenProcess", UInt, PROCESS_VM_OPERATION|PROCESS_VM_READ|PROCESS_VM_WRITE, Int, 0, UInt, PID, Ptr))
            Return
         
         if !(this.ptr := DllCall("VirtualAllocEx", Ptr, this.hProc, Ptr, 0, Ptr, size, UInt, MEM_COMMIT, UInt, PAGE_READWRITE, Ptr))
            Return, "", DllCall("CloseHandle", Ptr, this.hProc)
         
         this.hHeap := DllCall("GetProcessHeap", Ptr)
      }
      
      __Delete()  {
         DllCall("VirtualFreeEx", Ptr, this.hProc, Ptr, this.ptr, UInt, 0, UInt, MEM_RELEASE := 0x8000)
         DllCall("CloseHandle", Ptr, this.hProc)
         DllCall("HeapFree", Ptr, this.hHeap, UInt, 0, Ptr, this.pHeap)
      }
      
      Read(size, offset = 0)  {
         (this.pHeap && DllCall("HeapFree", Ptr, this.hHeap, UInt, 0, Ptr, this.pHeap))
         this.pHeap := DllCall("HeapAlloc", Ptr, this.hHeap, UInt, HEAP_ZERO_MEMORY := 0x8, Ptr, size, Ptr)
         if !DllCall("ReadProcessMemory", Ptr, this.hProc, Ptr, this.ptr + offset, Ptr, this.pHeap, Ptr, size, Int, 0)
            Return, 0, DllCall("MessageBox", Ptr, 0, Str, "Не удалось прочитать данные`nОшибка " A_LastError, Str, "", UInt, 0)
         Return this.pHeap
      }
      
      Write(pLocalBuff, size, offset = 0)  {
         if !res := DllCall("WriteProcessMemory", Ptr, this.hProc, Ptr, this.ptr + offset, Ptr, pLocalBuff, Ptr, size, PtrP, writtenBytes)
            DllCall("MessageBox", Ptr, 0, Str, "Не удалось записать данные`nОшибка " A_LastError, Str, "", UInt, 0)
         Return writtenBytes
      }
   }
}

? Попробуйте разные значения таймаута.

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

66

Re: AHK: Изменить размер шрифта TOOLTIP

Так нормально. Пробовал также 1, 2, 4 секунды.

67

Re: AHK: Изменить размер шрифта TOOLTIP

Спасибо! Так понял, проблема была в прерывании одного незавершённого потока другим, Critical помогло.

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

68

Re: AHK: Изменить размер шрифта TOOLTIP

Подтверждаю. Все абсолютно так же. Предпоследний вариант - подсказка не пропадает. Последний - полет нормальный!
teadrinker, спасибо за доработку!
И так уж... Мысль вслух: Тот кто будет использовать TrayTip: true тому родной Tip будет только мешать. Лично я, твою функцию RemoveTip собираюсь засунуть внутрь класса.

69 (изменено: teadrinker, 2017-04-26 22:27:57)

Re: AHK: Изменить размер шрифта TOOLTIP

mozers, спасибо за тестирование!

mozers пишет:

Тот кто будет использовать TrayTip: true тому родной Tip будет только мешать.

Почему, не все же будут использовать TrayTip именно при наведении на иконку.
Исправлено в Коллекции.

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

70

Re: AHK: Изменить размер шрифта TOOLTIP

А можно как-то менять режим отображения как для простого ToolTip

CoordMode,ToolTip, Relative

А то у меня всё время только в экранных координатах выводит. Может я не нашёл чего-то?

71

Re: AHK: Изменить размер шрифта TOOLTIP

Не-а, не предусмотрено, только экранные.

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

72 (изменено: vlad1986, 2017-12-19 16:20:20)

Re: AHK: Изменить размер шрифта TOOLTIP

teadrinker

Помогите пожалуйста, советом.

Как использовать Ваш скрипт в таком Gui?

Gui, add, button, w100

Gui, add, button, w100

Gui, add, button, w100

gui, show,w200, Справочник

OnMessage(0x200, "Help")

return

Help(wParam, lParam, Msg) {

MouseGetPos,,,, OutputVarControl

IfEqual, OutputVarControl, Button1

	Help := "Кнопка №1"

else IfEqual, OutputVarControl, Button2

	Help := "Кнопка №2"

else IfEqual, OutputVarControl, Button3

	Help := "Кнопка №3"

ToolTip % Help

}

Тоесть чтобы все работало точно так же: Навел курсор на кнопку в Gui -- всплыла соответствующая этой кнопке подсказка, убрал -- подсказка исчезла. С той лишь разницей, чтобы  вместо стандартного ToolTip всплывал например тот, что из Вашего примера:

myToolTip := new ToolTip({ title: "Title"
                         , text: "I'm the colored TrayTip!"
                         , icon: 1  ; icon Info                        
                         , FontName: "Comic Sans MS"
                         , FontSize: 20
                         , TextColor: "Navy"
                         , BackColor: 0xFFA500 })
#Include %A_ScriptDir%\ToolTip.ahk

73

Re: AHK: Изменить размер шрифта TOOLTIP

Как-то так:

Gui, add, button, w100 vButton1
Gui, add, button, w100 vButton2
Gui, add, button, w100 vButton3
gui, show,w200, Справочник

options := { ShowNow: false
           , FontName: "Comic Sans MS"
           , FontSize: 20
           , TextColor: "Navy"
           , BackColor: 0xFFA500 }
           
options.text := "Кнопка 1", tooltip1 := new ToolTip(options)
options.text := "Кнопка 2", tooltip2 := new ToolTip(options)
options.text := "Кнопка 3", tooltip3 := new ToolTip(options)

ShowToolTip({controls: { Button1: tooltip1, Button2: tooltip2, Button3: tooltip3 }, delay: 500, duration: 2000})

ShowToolTip(wp, lp = "", msg = "")  {
   static WM_MOUSEMOVE := 0x200, SS_NOTIFY := 0x100, MyPID := DllCall("GetCurrentProcessId"), prev, opt
   
   fn := A_ThisFunc, GuiCtrl := A_GuiControl
   if (!opt && opt := wp)  {
      OnMessage(WM_MOUSEMOVE, fn)
   }
   else if msg  {
      for k, v in opt.controls  {
         if (GuiCtrl = k && (hover := true) && GuiCtrl != prev && prev := GuiCtrl)  {
            %fn%("hide")
            opt.timers.Push( timer := Func(fn).Bind("show", k) )
            SetTimer, % timer, % "-" . opt.delay
         }
      }
      (!hover && %fn%("hide", true))
   }
   else if (wp = "show")  {
      MouseGetPos,,, hwnd
      WinGet, PID, PID, ahk_id %hwnd%
      ( MyPID = PID && opt.controls[lp].Show() )
      opt.timers.Push( timer := Func(fn).Bind("TrackOut") )
      SetTimer, % timer, 100
      opt.timers.Push( timer := Func(fn).Bind("hide") )
      SetTimer, % timer, % "-" opt.duration
   }
   else if (wp = "hide")  {
      for k, v in opt.controls
         v.Hide()
      for key, timer in opt.timers
         SetTimer, % timer, Delete
      opt.timers := [], (lp && prev := "")
   }
   else if (wp = "TrackOut")  {
      MouseGetPos,,, hwnd
      WinGet, PID, PID, ahk_id %hwnd%
      (MyPID != PID && %fn%("hide", true))
   }
}

#Include %A_ScriptDir%\ToolTip.ahk
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

74

Re: AHK: Изменить размер шрифта TOOLTIP

teadrinker

Огромное спасибо, то что нужно!

75

Re: AHK: Изменить размер шрифта TOOLTIP

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


global kkk ; сюда копируется хендл тултипа из _CreateToolTip()
myTrayTip := new ToolTip({ title: " Look!"
	, text: " It's a blue TrayTip! "
	, FontSize: 18
	, icon: 2            ; icon Warning
	, TrayTip: true      ; будет отображаться возле иконки скрипта в трее
	, Timeout: -4000     ; TrayTip будет удалён через 4 секунды
	, BackColor: 0x0055aa
	, TextColor: "white" })
; ToolTip % kkk " " DllCall("IsWindowVisible", Ptr, kkk)
WinShow % "ahk_id" kkk
WinMove % "ahk_id" kkk,, 200, 100, 200, 100
WinGetPos, x, y, W, H, % "ahk_id" kkk
; ToolTip % x " | " y " | " W " " H

76 (изменено: teadrinker, 2018-01-24 19:10:52)

Re: AHK: Изменить размер шрифта TOOLTIP

stealzy пишет:

Win7x64, AutoHotkey 1.1.24.

Эта версия устарела слегка, может, в этом проблема.

stealzy пишет:
global kkk ; сюда копируется хендл тултипа из _CreateToolTip()

Вообще, хэндл можно так увидеть:

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

77

Re: AHK: Изменить размер шрифта TOOLTIP

У меня на Win7x64 работает с любой версией интерпретатора (64, 32, 32 ANSI), не представляю, в чём может быть проблема. Может, просто где-то опечатка в коде? Попробуйте выложить сюда полный код вместе с классом.
Каюсь, в классе не уделено достаточного внимания обработке ошибок.

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