Размер шрифта сильно влияет на производительность.
#SingleInstance Force
#Persistent
#NoEnv
SetBatchLines -1
ListLines Off
global hGuiBack, hGuiString, hdc, XDiff, YDiff, XGuiString, YGuiString
Text = Следующая станция "Международная".
SleepDuration = 4 ; при уменьшении скорость возрастёт
Font = Arial
Size := 700
Margin := 0 ; отступ от верхнего края строки
W := 1600
H := 900
DllCall("Winmm\timeBeginPeriod", UInt, 3)
OnExit, Exit
Gui, Back:+hwndhGuiBack
Gui, Back:Color, Gray
Gui, Back:Margin, 0, 0
Gui, Back:Add, Pic, w%W% h%H%, Pic1.jpg
Gui, Back:Show, w%W% h%H%
Gui, -Caption +E0x80020 +OwnerBack +ToolWindow +hwndhGuiString
Gui, Show, NA
OnMessage(0x46, "WM_WINDOWPOSCHANGING")
pToken := Startup()
hbm := CreateDIBSection(W, H)
hdc := DllCall("CreateCompatibleDC", Ptr, 0, Ptr)
obm := DllCall("SelectObject", Ptr, hdc, Ptr, hbm, Ptr)
DllCall("gdiplus\GdipCreateFromHDC", Ptr, hdc, PtrP, G)
DllCall("gdiplus\GdipSetSmoothingMode", Ptr, G, Int, 4)
VarSetCapacity(WI, 60), NumPut(60, WI, "UInt")
DllCall("GetWindowInfo", Ptr, hGuiBack, Ptr, &WI)
XGui := NumGet(WI, 4, "UInt"), YGui := NumGet(WI, 8, "UInt")
XClient := NumGet(WI, 20, "UInt"), YClient := NumGet(WI, 24, "UInt")
XDiff := XClient - XGui, YDiff := YClient - YGui
XGuiString := XClient
YGuiString := YClient
Loop
{
DllCall("gdiplus\GdipGraphicsClear", Ptr, G, UInt, 0)
Options := "x" W - mod(A_Index, wt ? wt : 100000) " y" Margin " cFFFFAA00 r4 s" Size
RC := TextToGraphics(G, Text, Options, Font, wt ? wt : 100000, H)
wt := RegExReplace(RC, "(.*?\|){2}(.*?)(\.\d+)?\|.*", "$2") + W
UpdateLayeredWindow(hGuiString, hdc, XGuiString, YGuiString, W, H)
DllCall("Sleep", UInt, SleepDuration)
}
return
~Esc::
GuiEscape:
ExitApp
BackGuiClose:
ExitApp
Exit:
DllCall("Winmm\timeEndPeriod", UInt, 3)
DllCall("SelectObject", Ptr, hdc, Ptr, obm, Ptr), DllCall("DeleteObject", Ptr, hbm)
DeleteDC(hdc), DllCall("gdiplus\GdipDeleteGraphics", Ptr, G), Shutdown(pToken)
ExitApp
WM_WINDOWPOSCHANGING(wp, lp, msg, hwnd)
{
x := NumGet(lp+0, A_PtrSize*2, "UInt"), y := NumGet(lp+0, A_PtrSize*2+4, "UInt")
if (x = 0 && y = 0)
return
UpdateLayeredWindow(hGuiString, hdc, XGuiString := x + XDiff + 20, YGuiString := y + YDiff + 20, 350, 50)
}
Startup()
{
if !DllCall("GetModuleHandle", Str, "gdiplus", Ptr)
DllCall("LoadLibrary", Str, "gdiplus")
VarSetCapacity(si, A_PtrSize = 8 ? 24 : 16, 0), si := Chr(1)
DllCall("gdiplus\GdiplusStartup", UPtrP, pToken, Ptr, &si, Ptr, 0)
return pToken
}
Shutdown(pToken)
{
DllCall("gdiplus\GdiplusShutdown", UPtr, pToken)
if hModule := DllCall("GetModuleHandle", Str, "gdiplus", Ptr)
DllCall("FreeLibrary", Ptr, hModule)
return 0
}
CreateDIBSection(w, h, hdc="", bpp=32, ByRef ppvBits=0)
{
hdc2 := hdc ? hdc : GetDC()
VarSetCapacity(bi, 40, 0)
NumPut(w, bi, 4, "UInt"), NumPut(h, bi, 8, "UInt"), NumPut(40, bi, 0, "UInt"), NumPut(1, bi, 12, "ushort"), NumPut(0, bi, 16), NumPut(bpp, bi, 14, "ushort")
hbm := DllCall("CreateDIBSection", Ptr , hdc2, Ptr , &bi, UInt , 0, PtrP, ppvBits, Ptr , 0, UInt , 0, Ptr)
if !hdc
ReleaseDC(hdc2)
return hbm
}
TextToGraphics(pGraphics, Text, Options, Font="Arial", Width="", Height="", Measure=0)
{
IWidth := Width, IHeight:= Height
RegExMatch(Options, "i)X([\-\d\.]+)(p*)", xpos)
RegExMatch(Options, "i)Y([\-\d\.]+)(p*)", ypos)
RegExMatch(Options, "i)W([\-\d\.]+)(p*)", Width)
RegExMatch(Options, "i)H([\-\d\.]+)(p*)", Height)
RegExMatch(Options, "i)C(?!(entre|enter))([a-f\d]+)", Colour)
RegExMatch(Options, "i)Top|Up|Bottom|Down|vCentre|vCenter", vPos)
RegExMatch(Options, "i)NoWrap", NoWrap)
RegExMatch(Options, "i)R(\d)", Rendering)
RegExMatch(Options, "i)S(\d+)(p*)", Size)
if !DeleteBrush(CloneBrush(Colour2))
PassBrush := 1, pBrush := Colour2
if !(IWidth && IHeight) && (xpos2 || ypos2 || Width2 || Height2 || Size2)
return -1
Style := 0, Styles := "Regular|Bold|Italic|BoldItalic|Underline|Strikeout"
Loop, Parse, Styles, |
{
if RegExMatch(Options, "\b" A_loopField)
Style |= (A_LoopField != "StrikeOut") ? (A_Index-1) : 8
}
Align := 0, Alignments := "Near|Left|Centre|Center|Far|Right"
Loop, Parse, Alignments, |
{
if RegExMatch(Options, "\b" A_loopField)
Align |= A_Index//2.1 ; 0|0|1|1|2|2
}
xpos := (xpos1 != "") ? xpos2 ? IWidth*(xpos1/100) : xpos1 : 0
ypos := (ypos1 != "") ? ypos2 ? IHeight*(ypos1/100) : ypos1 : 0
Width := Width1 ? Width2 ? IWidth*(Width1/100) : Width1 : IWidth
Height := Height1 ? Height2 ? IHeight*(Height1/100) : Height1 : IHeight
if !PassBrush
Colour := "0x" (Colour2 ? Colour2 : "ff000000")
Rendering := ((Rendering1 >= 0) && (Rendering1 <= 5)) ? Rendering1 : 4
Size := (Size1 > 0) ? Size2 ? IHeight*(Size1/100) : Size1 : 12
hFamily := FontFamilyCreate(Font)
hFont := FontCreate(hFamily, Size, Style)
FormatStyle := NoWrap ? 0x4000 | 0x1000 : 0x4000
hFormat := StringFormatCreate(FormatStyle)
pBrush := PassBrush ? pBrush : BrushCreateSolid(Colour)
if !(hFamily && hFont && hFormat && pBrush && pGraphics)
return !pGraphics ? -2 : !hFamily ? -3 : !hFont ? -4 : !hFormat ? -5 : !pBrush ? -6 : 0
CreateRectF(RC, xpos, ypos, Width, Height)
SetStringFormatAlign(hFormat, Align)
SetTextRenderingHint(pGraphics, Rendering)
ReturnRC := MeasureString(pGraphics, Text, hFont, hFormat, RC)
if vPos
{
StringSplit, ReturnRC, ReturnRC, |
if (vPos = "vCentre") || (vPos = "vCenter")
ypos += (Height-ReturnRC4)//2
else if (vPos = "Top") || (vPos = "Up")
ypos := 0
else if (vPos = "Bottom") || (vPos = "Down")
ypos := Height-ReturnRC4
CreateRectF(RC, xpos, ypos, Width, ReturnRC4)
ReturnRC := MeasureString(pGraphics, Text, hFont, hFormat, RC)
}
if !Measure
E := DrawString(pGraphics, Text, hFont, hFormat, pBrush, RC)
if !PassBrush
DeleteBrush(pBrush)
DeleteStringFormat(hFormat)
DeleteFont(hFont)
DeleteFontFamily(hFamily)
return E ? E : ReturnRC
}
DeleteBrush(pBrush)
{
return DllCall("gdiplus\GdipDeleteBrush", Ptr, pBrush)
}
CloneBrush(pBrush)
{
DllCall("gdiplus\GdipCloneBrush", Ptr, pBrush, PtrP, pBrushClone)
return pBrushClone
}
FontFamilyCreate(Font)
{
DllCall("gdiplus\GdipCreateFontFamilyFromName", WStr, Font, Ptr, 0, PtrP, hFamily)
return hFamily
}
FontCreate(hFamily, Size, Style=0)
{
DllCall("gdiplus\GdipCreateFont", Ptr, hFamily, Float, Size, Int, Style, Int, 0, PtrP, hFont)
return hFont
}
DeleteGraphics(pGraphics)
{
return DllCall("gdiplus\GdipDeleteGraphics", Ptr, pGraphics)
}
StringFormatCreate(Format=0, Lang=0)
{
DllCall("gdiplus\GdipCreateStringFormat", Int, Format, Int, Lang, PtrP, hFormat)
return hFormat
}
BrushCreateSolid(ARGB=0xff000000)
{
DllCall("gdiplus\GdipCreateSolidFill", UInt, ARGB, PtrP, pBrush)
return pBrush
}
CreateRectF(ByRef RectF, x, y, w, h)
{
VarSetCapacity(RectF, 16)
NumPut(x, RectF, 0, "float"), NumPut(y, RectF, 4, "float"), NumPut(w, RectF, 8, "float"), NumPut(h, RectF, 12, "float")
}
SetStringFormatAlign(hFormat, Align)
{
return DllCall("gdiplus\GdipSetStringFormatAlign", Ptr, hFormat, Int, Align)
}
SetTextRenderingHint(pGraphics, RenderingHint)
{
return DllCall("gdiplus\GdipSetTextRenderingHint", Ptr, pGraphics, Int, RenderingHint)
}
MeasureString(pGraphics, sString, hFont, hFormat, ByRef RectF)
{
VarSetCapacity(RC, 16)
DllCall("gdiplus\GdipMeasureString", Ptr, pGraphics
, WStr, sString, Int, -1, Ptr, hFont, Ptr, &RectF, Ptr, hFormat, Ptr, &RC, UIntP, Chars, UIntP, Lines)
return &RC ? NumGet(RC, 0, "float") "|" NumGet(RC, 4, "float") "|" NumGet(RC, 8, "float") "|" NumGet(RC, 12, "float") "|" Chars "|" Lines : 0
}
DrawString(pGraphics, sString, hFont, hFormat, pBrush, ByRef RectF)
{
return DllCall("gdiplus\GdipDrawString", Ptr, pGraphics
, WStr, sString, Int, -1, Ptr, hFont, Ptr, &RectF, Ptr, hFormat, Ptr, pBrush)
}
DeleteStringFormat(hFormat)
{
return DllCall("gdiplus\GdipDeleteStringFormat", Ptr, hFormat)
}
DeleteFont(hFont)
{
return DllCall("gdiplus\GdipDeleteFont", Ptr, hFont)
}
DeleteFontFamily(hFamily)
{
return DllCall("gdiplus\GdipDeleteFontFamily", Ptr, hFamily)
}
DeleteDC(hdc)
{
return DllCall("DeleteDC", Ptr, hdc)
}
GetDC(hwnd=0)
{
return DllCall("GetDC", Ptr, hwnd, Ptr)
}
ReleaseDC(hdc, hwnd=0)
{
return DllCall("ReleaseDC", Ptr, hwnd, Ptr, hdc)
}
UpdateLayeredWindow(hwnd, hdc, x="", y="", w="", h="", Alpha=255)
{
if ((x != "") && (y != ""))
VarSetCapacity(pt, 8), NumPut(x, pt, 0, "UInt"), NumPut(y, pt, 4, "UInt")
if (w = "") ||(h = "")
WinGetPos,,, w, h, ahk_id %hwnd%
return DllCall("UpdateLayeredWindow", Ptr, hwnd, Ptr, 0, Ptr, ((x = "") && (y = "")) ? 0 : &pt
, Int64P, w|h<<32, Ptr, hdc, Int64P, 0, UInt, 0, UIntP, Alpha<<16|1<<24, UInt, 2)
}