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
Skype dmitry_fiveg

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
Skype dmitry_fiveg

6

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

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

По вопросам возмездной помощи пишите в личку
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.25.01 (Unicode 32-bit).

7

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

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

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

8

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

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

По вопросам возмездной помощи пишите в личку
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.25.01 (Unicode 32-bit).

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
Skype dmitry_fiveg

10

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

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

11

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

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

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

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
Skype dmitry_fiveg

13 (изменено: stealzy, 2016-12-06 23:39:57)

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

Можно самим нарисовать ToolTip. Даже библиотеки для этого делали:
https://autohotkey.com/board/topic/4487 … ns-v04991/

Win7x64, AutoHotkey_L v1.1.24

14

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

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

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

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

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

teadrinker пишет:

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

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

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

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

Post's attachments

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

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

16

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

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

17

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

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

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

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

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

18

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

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

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

19

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
Skype dmitry_fiveg

20

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

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

21

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

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

22

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

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

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

23

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

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

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

24

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

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

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

25

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
Skype dmitry_fiveg