1

Тема: AHK: Бегущая строка

Написал что в голову пришло:


info := "Бегущая строка"    
str := "              " info "              "
Gui, Color, 696969
Gui, Font, s44 cffffff
Gui, Add, Text, vText +0x1000, 00000000000000
Gui, Show 
StrLen := StrLen(str) , I := 0 

    Loop 
    {
        If (I = 0) 
            GuiControl, +Right, Text 
        Else If (I = 13) 
            GuiControl, +Left, Text 
        GuiControl,, Text, % SubStr(str, ++I, 14) 
        If (I = StrLen)
            I := 0 
        Sleep 100
    }
    Return 
    
GuiClose:
    ExitApp

и более ничего не приходило
У кого какие идеи как это сделать "поровнее", и желательно с попиксельным смещением строки?

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

2

Re: AHK: Бегущая строка

Если на скорую руку, то так:

Gui, Color, Gray
Gui, Add, Text, hwndhText 0x1000 x20 y20 w350 h50
Gui, Show, w390 h90

Gui, 2:+Parent%hText% -Caption
Gui, 2:Color, 606060
Gui, 2:Font, s24 cFFAA00
Gui, 2:Add, Text, vInfo x350 y6, Следующая станция "Международная".
Gui, 2:Show, x0 y0

Loop
{
    Sleep, 20
    GuiControl, 2:MoveDraw, Info, % "x" 350 - mod(A_Index*2, 900)
    Sleep, 10   ; так вроде меньше мелькает
}
return

GuiClose:
    ExitApp

Но некоторого мелькания, скорее всего, избежать не удастся. По-хорошему, такие вещи через GDI нужно делать.

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

3

Re: AHK: Бегущая строка

teadrinker
Как всегда гениально! Вот крутилось оно на уме... со вторым гуи.
Не пойму почему тут

mod(A_Index*2, 900)

именно 900?
Ещё строка не заканчиваясь слева до конца пропадает, и начинается снова...

teadrinker пишет:

По-хорошему, такие вещи через GDI нужно делать.

И пока вроде ещё никто не делал.
Я знаю вы в GDI дока.
Хотелось бы увидеть ваше решение.

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

4

Re: AHK: Бегущая строка

serzh82saratov пишет:

Не пойму почему тут ... именно 900?
Ещё строка не заканчиваясь слева до конца пропадает, и начинается снова...

900 — это 350 + примерная длина строки. У меня как раз хватает, у тебя, видимо, из за другого разрешения экрана нужно поменять на большее. На форуме где-то был код, определяющий размер текста.
Через GDI:

SetBatchLines, -1

Text = Следующая станция "Международная".
SleepDuration = 8  ; при уменьшении скорость возрастёт
Font = Arial
Size := 24
Margin := 11   ; отступ от верхнего края строки

DllCall("Winmm\timeBeginPeriod", UInt, 3)
OnExit, Exit

Gui, Color, Gray
Gui, Add, Text, hwndhText x20 y20 w350 h50
Gui, Show, w390 h90

pToken := Startup()

hbm := CreateDIBSection(350, 50)
hdc := DllCall("CreateCompatibleDC", "ptr", 0, "ptr")
obm := DllCall("SelectObject", "ptr", hdc, "ptr", hbm, "ptr")
DllCall("gdiplus\GdipCreateFromHDC", "ptr", hdc, "ptr*", G)
DllCall("gdiplus\GdipSetSmoothingMode", "ptr", G, "int", 4)

pFillBrush := Gdip_BrushCreateSolid(0xff606060)
hTextDC := GetDC(hText)

Loop
{
   DllCall("gdiplus\GdipFillRectangle", "ptr", G, "ptr", pFillBrush
      , "float", 0, "float", 0, "float", 350, "float", 50)

   Options := "x" 350 - mod(A_Index, w) " y" Margin " cFFFFAA00 r4 s" Size
   w := RegExReplace(Gdip_TextToGraphics(G, Text, Options, Font, w, 50), "(.*?\|){2}(.*?)(\.\d+)?\|.*", "$2") + 350

   BitBlt(hTextDC, -1, -1, 350, 50, hdc, 0, 0)
   DllCall("Sleep", UInt, SleepDuration)
}
return

GuiClose:
   ExitApp

Exit:
   DllCall("Winmm\timeEndPeriod", UInt, 3)
   Gdip_DeleteBrush(pFillBrush)
   DllCall("SelectObject", "ptr", hdc, "ptr", obm, "ptr"), DllCall("DeleteObject", "ptr", hbm)
   DeleteDC(hdc), ReleaseDC(hTextDC)
   DllCall("gdiplus\GdipDeleteGraphics", "ptr", G), Gdip_Shutdown(pToken)
   ExitApp
   
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", "uptr*", pToken, "ptr", &si, "ptr", 0)
   return pToken
}

Gdip_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, "ptr*", ppvBits, "ptr" , 0, "uint" , 0, "ptr")

   if !hdc
      ReleaseDC(hdc2)
   return hbm
}

Gdip_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 !Gdip_DeleteBrush(Gdip_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 := Gdip_FontFamilyCreate(Font)
   hFont := Gdip_FontCreate(hFamily, Size, Style)
   FormatStyle := NoWrap ? 0x4000 | 0x1000 : 0x4000
   hFormat := Gdip_StringFormatCreate(FormatStyle)
   pBrush := PassBrush ? pBrush : Gdip_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)
   Gdip_SetStringFormatAlign(hFormat, Align)
   Gdip_SetTextRenderingHint(pGraphics, Rendering)
   ReturnRC := Gdip_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 := Gdip_MeasureString(pGraphics, Text, hFont, hFormat, RC)
   }

   if !Measure
      E := Gdip_DrawString(pGraphics, Text, hFont, hFormat, pBrush, RC)

   if !PassBrush
      Gdip_DeleteBrush(pBrush)
   Gdip_DeleteStringFormat(hFormat)   
   Gdip_DeleteFont(hFont)
   Gdip_DeleteFontFamily(hFamily)
   return E ? E : ReturnRC
}

Gdip_DeleteBrush(pBrush)
{
   return DllCall("gdiplus\GdipDeleteBrush", "ptr", pBrush)
}

Gdip_CloneBrush(pBrush)
{
   DllCall("gdiplus\GdipCloneBrush", "ptr", pBrush, "ptr*", pBrushClone)
   return pBrushClone
}

Gdip_FontFamilyCreate(Font)
{
   DllCall("gdiplus\GdipCreateFontFamilyFromName", "wstr", Font, "ptr", 0, "ptr*", hFamily)
   return hFamily
}

Gdip_FontCreate(hFamily, Size, Style=0)
{
   DllCall("gdiplus\GdipCreateFont", "ptr", hFamily, "float", Size, "int", Style, "int", 0, "ptr*", hFont)
   return hFont
}

Gdip_DeleteGraphics(pGraphics)
{
   return DllCall("gdiplus\GdipDeleteGraphics", "ptr", pGraphics)
}

Gdip_StringFormatCreate(Format=0, Lang=0)
{
   DllCall("gdiplus\GdipCreateStringFormat", "int", Format, "int", Lang, "ptr*", hFormat)
   return hFormat
}

Gdip_BrushCreateSolid(ARGB=0xff000000)
{
   DllCall("gdiplus\GdipCreateSolidFill", "uint", ARGB, "ptr*", 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")
}

Gdip_SetStringFormatAlign(hFormat, Align)
{
   return DllCall("gdiplus\GdipSetStringFormatAlign", "ptr", hFormat, "int", Align)
}

Gdip_SetTextRenderingHint(pGraphics, RenderingHint)
{
   return DllCall("gdiplus\GdipSetTextRenderingHint", "ptr", pGraphics, "int", RenderingHint)
}

Gdip_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, "uint*", Chars, "uint*", Lines)
   return &RC ? NumGet(RC, 0, "float") "|" NumGet(RC, 4, "float") "|" NumGet(RC, 8, "float") "|" NumGet(RC, 12, "float") "|" Chars "|" Lines : 0
}

Gdip_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)
}

Gdip_DeleteStringFormat(hFormat)
{
   return DllCall("gdiplus\GdipDeleteStringFormat", "ptr", hFormat)
}

Gdip_DeleteFont(hFont)
{
   return DllCall("gdiplus\GdipDeleteFont", "ptr", hFont)
}

Gdip_DeleteFontFamily(hFamily)
{
   return DllCall("gdiplus\GdipDeleteFontFamily", "ptr", hFamily)
}

BitBlt(ddc, dx, dy, dw, dh, sdc, sx, sy, Raster="")
{
   return DllCall("gdi32\BitBlt", "ptr", dDC, "int", dx, "int", dy, "int", dw, "int", dh
   , "ptr", sDC, "int", sx, "int", sy, "uint", Raster ? Raster : 0x00CC0020)
}

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)
}

Длина строки должна автоматически считаться.

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

5

Re: AHK: Бегущая строка

Большое спасибо!
Буду курить. Но немножко мелькает у меня, но конечно меньше

На форуме где-то был код, определяющий размер текста.

Что то про тултип кажется.

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

6

Re: AHK: Бегущая строка

Чтобы совсем было идеально, нужно делать в layered window, как в примерах к GDI+. Но в них нельзя стандартные контролы вставлять, и они не могут быть дочерними.

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

7

Re: AHK: Бегущая строка

А вот удалось слоёное в обычное вставить:

SetBatchLines, -1
global hGuiBack, hGuiString, hdc, XDiff, YDiff, XGuiString, YGuiString

Text = Следующая станция "Международная".
SleepDuration = 8  ; при уменьшении скорость возрастёт
Font = Arial
Size := 24
Margin := 11   ; отступ от верхнего края строки

DllCall("Winmm\timeBeginPeriod", UInt, 3)
OnExit, Exit

Gui, Back:+hwndhGuiBack
Gui, Back:Color, Gray
Gui, Back:Show, w390 h90

Gui, -Caption +E0x80020 +OwnerBack +ToolWindow +hwndhGuiString
Gui, Show, NA

OnMessage(0x46, "WM_WINDOWPOSCHANGING")

pToken := Startup()

hbm := CreateDIBSection(350, 50)
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 + 20
YGuiString := YClient + 20

Loop
{
   DllCall("gdiplus\GdipGraphicsClear", Ptr, G, UInt, 0xff606060)

   Options := "x" 350 - mod(A_Index, w ? w : 10000) " y" Margin " cFFFFAA00 r4 s" Size
   RC := TextToGraphics(G, Text, Options, Font, w ? w : 10000, 50)
   w := RegExReplace(RC, "(.*?\|){2}(.*?)(\.\d+)?\|.*", "$2") + 350

   UpdateLayeredWindow(hGuiString, hdc, XGuiString, YGuiString, 350, 50)
   
   DllCall("Sleep", UInt, SleepDuration)
}
return

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)
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

8 (изменено: serzh82saratov, 2013-08-12 13:12:44)

Re: AHK: Бегущая строка

Спасибо за пример, отлично работает!
Я так понял, что все функции взяты в оригинальном виде из GDI?

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

9 (изменено: serzh82saratov, 2013-08-12 13:46:59)

Re: AHK: Бегущая строка

Кстати если двигать не текст, а всё окно то не мелькает:


Gui, Color, Gray
Gui, Add, Progress, hwndhControl Border Background606060 x20 y20 w350 h50  
Gui, Show, w390 h90

Gui, 2:+Parent%hControl% -Caption +Lastfound
Gui, 2:Color, 606060
Gui, 2:Font, s24 cFFAA00
Gui, 2:Add, Text, x350 y6, Следующая станция "Международная".
Gui, 2:Show, x0 y0
WinGetPos, , , Width 

Loop
{ 
    Gui, 2:Show, % "Na y0 x" I := I < -Width ? 0 : I - 1 
    Sleep 1  
}
return

И тут тоже спасибо. Я узнал что можно родительским делать не только окно, а ещё и контролы.

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

10

Re: AHK: Бегущая строка

serzh82saratov пишет:

Я так понял, что все функции взяты в оригинальном виде из GDI?

Взяты оттуда, но изменены для поддержки 64-битного интерпретатора.

serzh82saratov пишет:

Кстати если двигать не текст, а всё окно то не мелькает

Да, хорошее решение, у меня тоже не мелькает. Чуть-чуть подёргивается

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

11 (изменено: serzh82saratov, 2013-09-29 18:52:53)

Re: AHK: Бегущая строка

Ещё один способ:


Gui, Color, Gray 
Gui -DPIScale +AlwaysOnTop +Disabled
Gui, margin, 20, 20 
Gui, Add, ActiveX, w590 h90 vIE, shell explorer
IE.Navigate("about:blank")

html =
(  
<html>   
<center>
<body bgcolor=#606060> 
<font size="12" color="FFAA00" face="Arial">
<marquee scrollamount="10" "> 
Следующая станция "Международная".
</marquee>
</font> 
</body>
</center>
</html> 
)
IE.Document.Write(html) 
Gui, show  
Return
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

12

Re: AHK: Бегущая строка

Так совсем глючно.

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

13 (изменено: serzh82saratov, 2013-10-02 21:54:08)

Re: AHK: Бегущая строка

Так немного получше


width= 350 
height= 60 
fontsize= 50
ChrColor=FFAA00
 
html =
(           
  <style>
   marquee {
    position: absolute; /* Абсолютное позиционирование */
    right: 0px; /* Положение элемента от правого края */
    left: 0px; /* Положение элемента от правого края */
    top: 0px; /* Положение от верхнего края */
    width: %width%px; /* Ширина блока */ 
    background: #606060; /* Цвет фона */  
    color: "%ChrColor%"`;
    font-size: "%fontsize%"`; 
   } 
  </style>
   
 <body scroll="no" topmargin="0" leftmargin="0" onselectstart="return false"  oncontextmenu="return false">  
  <marquee bgcolor="#606060" color="%ChrColor%" width="%width%" height="%height%" truespeed scrollamount="1" scrolldelay="7" >  
   Следующая станция "Международная".  
  </marquee> 
 </body>  
)
 
OnExit HTMLGuiClose
Gui, HTML: Color, Gray 
Gui HTML: -DPIScale +AlwaysOnTop 
Gui, HTML: margin, 20, 20 
Gui, HTML: Add, ActiveX, w%width% h%height% vIE, HTMLFile 
Gui, HTML: show   
IE.Write(html)  
return 
 
HTMLGuiClose:
    IE := "" 
    ExitApp 

Ну это я предложил как "короткий" вариант.

И как способ без цикла, который нельзя прерывать.

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

14

Re: AHK: Бегущая строка

teadrinker
В этом посте у тебя как то хитро задаётся фон для текста через GdipGraphicsClear. Но я никак не пойму как в твоём примере сделать фон текста прозрачным.
Сделал свой вариант со сдвигом Bitmap текста поверх другого Bitmap с фоном, но оказалось очень прожорливо для процессора.


Loop
{
	If (XPos < -WText)
		XPos := W + 1
	Else
		XPos -= 1
	Gdip_DrawImage(GDest, pBmpBckg, 0, 0, W, H, 0, 0, W, H)
	Gdip_DrawImage(GDest, pBmpText, XPos, Margin, WText, HText, 0, 0, WText, HText)
	hBmpDest := Gdip_CreateHBITMAPFromBitmap(pBmpDest, 0x00000000)
	SelectObject(hDCDest, hBmpDest)
	DeleteObject(hBmpDest)
	UpdateLayeredWindow(hGui, hDCDest, X, Y, W, H)
	DllCall("Sleep", UInt, 2)
}

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

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

15

Re: AHK: Бегущая строка

DllCall("gdiplus\GdipGraphicsClear", Ptr, G, UInt, 0x0)

Так?

16

Re: AHK: Бегущая строка

Так я пробовал. У вас качество шрифта не ухудшается?

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

17 (изменено: teadrinker, 2019-03-02 22:40:50)

Re: AHK: Бегущая строка

Правильно, а потом вырезать из основного окна фон через WinSet, Region. У меня не ухудшается вроде.

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

18

Re: AHK: Бегущая строка

https://i.imgur.com/T0JGh7e.png
https://i.imgur.com/0SjKGNI.png
Про WinSet, Region не понял.

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

19

Re: AHK: Бегущая строка

serzh82saratov, у меня - нет.
https://imgur.com/a/I6dRiUb
Попробуйте так:


Loop
{
   DllCall("gdiplus\GdipGraphicsClear", Ptr, G, UInt, 0x0)

   Options := "x" 350 - mod(A_Index, w ? w : 10000) " y" Margin " cFFFFAA00 r4 s" Size
   DllCall("gdiplus\GdipSetTextRenderingHint", "Ptr", G, "int", 4)
   RC := TextToGraphics(G, Text, Options, Font, w ? w : 10000, 50)
   w := RegExReplace(RC, "(.*?\|){2}(.*?)(\.\d+)?\|.*", "$2") + 350

   UpdateLayeredWindow(hGuiString, hdc, XGuiString, YGuiString, 350, 50)
   DllCall("Sleep", UInt, SleepDuration)
}

20

Re: AHK: Бегущая строка

Прошу прощения, скопировал заново код, не портит.

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

21

Re: AHK: Бегущая строка

serzh82saratov пишет:

Про WinSet, Region не понял.

Я подумал, ты хочешь сделать насквозь прозрачный фон.

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

22

Re: AHK: Бегущая строка

Нет, хочу подложить свой Bitmap, но это ещё тоже надо подумать. Тут ведь hdc полностью обновляется, и самое простое Bitmap отображать в GuiBack?
И если бы надо было текст двигать вместе с фоном, например сделав текстуру фона из картинки, как это лучше провернуть?

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

23

Re: AHK: Бегущая строка

Если фон менять не нужно, подложить картинку в основное окно, если двигать с фоном, тогда наверно подрисовывать фон после GdipGraphicsClear с тем же сдвигом, что и текст.

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

24

Re: AHK: Бегущая строка

Размер шрифта сильно влияет на производительность.


#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)
}
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

25

Re: AHK: Бегущая строка


#SingleInstance Force
#Persistent  
#NoEnv
SetBatchLines -1
ListLines Off


global hGuiBack, hGuiString, hdc, XDiff, YDiff, XGuiString, YGuiString

Text = Следующая станция "Международная".
SleepDuration = 1  ; при уменьшении скорость возрастёт
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)*2 " 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)
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

26 (изменено: serzh82saratov, 2019-03-02 23:46:16)

Re: AHK: Бегущая строка

SleepDuration = 1?
Под производительностью я имею ввиду нагрузку на процессор.
Как то многовато 10%.

Вот мой вариант с битмапом, кроме цвета фона, в bFile можно указать картинку и её прозрачность.
За счёт чего по твоему большая разница в производительности (на одинаковых малых шрифтах)?


#SingleInstance Force
#Persistent  
#NoEnv
SetBatchLines -1
ListLines Off

If !pToken := Gdip_Startup()
{
	MsgBox, 48, gdiplus error!, Gdiplus failed to start. Please ensure you have gdiplus on your system
	ExitApp
}

String = Бегущая строка

fTrans := 100
fColor := 0xffffff
fTrans := fTrans / 100 * 255
fColor := fTrans << 24 | fColor

bTrans := 100
bTrans := bTrans / 100 * 255
bColor := 0xFBD986
bColor := bTrans << 24 | bColor  ;	ARGB

bFileTrans = 10
bFileTrans := bFileTrans
bFile = logo.png

Margin = 20
Font = Arial 
fColor := Format("{1:08X}", fColor)

X := 111 
Y := 111 
W := 800
H := 300

Gui, -Caption +E0x80000 +HWNDhGui +AlwaysOnTop +ToolWindow +OwnDialogs +E0x08000000
Gui, Show, % "Na x" X " y" Y " w" W " h" H

pBmpBckg := Gdip_CreateBitmap(W, H)
GBckg := Gdip_GraphicsFromImage(pBmpBckg) 
Gdip_SetSmoothingMode(GBckg, 4)

pBrush := Gdip_BrushCreateSolid(bColor)
Gdip_FillRectangle(GBckg, pBrush, 0, 0, W, H)
Gdip_DeleteBrush(pBrush)

pBmpPic := Gdip_CreateBitmapFromFile(bFile)
Gdip_GetImageDimensions(pBmpPic, wPic, hPic)
Matrix := bFileTrans / 100
Gdip_DrawImage(GBckg, pBmpPic, 0, 0, W, H, 0, 0, wPic, hPic, Matrix)
Gdip_DisposeImage(pBmpPic)
Gdip_DeleteGraphics(GBckg)

FontSize := FontAreaH := H - Margin * 2

Loop  ;	Определение размера шрифта исходя из высоты зоны. Надо бы это перепилить.
{
	Options = s%FontSize% Italic c%fColor% vCenter Center r4 Font
	pBmpBuf := Gdip_CreateBitmap(1, 1)
	GBuf := Gdip_GraphicsFromImage(pBmpBuf)
	Gdip_DisposeImage(pBmpBuf)
	Data := Gdip_TextToGraphics(GBuf, String, Options, Font)
	Gdip_DeleteGraphics(GBuf)
	Arr := StrSplit(Data, "|")
	WText := Arr[3], HText := Arr[4]
	If (HText > FontAreaH) && FontSize--
		Continue
	Break
}

pBmpText := Gdip_CreateBitmap(WText, HText)
GText := Gdip_GraphicsFromImage(pBmpText) 
Gdip_SetSmoothingMode(GText, 4)
Data := Gdip_TextToGraphics(GText, String, Options, Font, WText, HText)
Gdip_DeleteGraphics(GText)


pBmpDest := Gdip_CreateBitmap(W, H)
GDest := Gdip_GraphicsFromImage(pBmpDest) 
Gdip_SetSmoothingMode(GDest, 4)
hDCDest := CreateCompatibleDC()

XPos := W + 1

Loop
{
	If (XPos < -WText)
		XPos := W + 1
	Else
		XPos -= 1
	Gdip_DrawImage(GDest, pBmpBckg, 0, 0, W, H, 0, 0, W, H)
	Gdip_DrawImage(GDest, pBmpText, XPos, Margin, WText, HText, 0, 0, WText, HText)
	hBmpDest := Gdip_CreateHBITMAPFromBitmap(pBmpDest, 0x00000000)
	SelectObject(hDCDest, hBmpDest)
	DeleteObject(hBmpDest)
	UpdateLayeredWindow(hGui, hDCDest, X, Y, W, H)
	DllCall("Sleep", UInt, 2)
}

~Esc::
GuiEscape: 
	ExitApp 

Exit() { 
	Global
	Gdip_DisposeImage(pBmpBckg)
	Gdip_DisposeImage(pBmpBckg)
	Gdip_DisposeImage(pBmpDest) 
	Gdip_DeleteGraphics(GDest)
	DeleteDC(hdcDest)
	Gdip_Shutdown(pToken)
	ExitApp
}

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

27

Re: AHK: Бегущая строка

А, нет, не так.

Options := "x" W - mod(A_Index*2, wt ? wt : 100000) " y" Margin " cFFFFAA00 r4 s" Size
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

28

Re: AHK: Бегущая строка

serzh82saratov пишет:

За счёт чего по твоему большая разница в производительности (на одинаковых малых шрифтах)?

Спроси что-нибудь полегче.

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

29

Re: AHK: Бегущая строка

teadrinker пишет:

A_Index*2

Это понятно, можно увеличивать шаг для скорости и ухудшения плавности.

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

30

Re: AHK: Бегущая строка

Без timeBeginPeriod использовать DllCall("Sleep", UInt, 2) не имеет смысла, будет 10-15.

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

31

Re: AHK: Бегущая строка

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

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

32

Re: AHK: Бегущая строка

Перемещение окна не грузит проц не зависимо от размеров. Но встаёт вопрос ограничения показа строки по краям.


#SingleInstance Force
#Persistent  
#NoEnv
SetBatchLines -1
ListLines Off

If !pToken := Gdip_Startup()
{
	MsgBox, 48, gdiplus error!, Gdiplus failed to start. Please ensure you have gdiplus on your system
	ExitApp
}

String = Бегущая строка

FontSize := 1111

Sleep := 1
BeginPeriod := 7

fTrans := 50
fColor := 0xF3D284
fTrans := fTrans / 100 * 255
fColor := fTrans << 24 | fColor

Margin = 20
Font = Arial 
fColor := Format("{1:08X}", fColor)

W := A_ScreenWidth

Gui, -Caption +E0x80000 +HWNDhGui +AlwaysOnTop +ToolWindow +OwnDialogs +E0x08000020
Gui, Show, Na

Options = s%FontSize% Italic c%fColor% vCenter Center r4 Font
pBmpBuf := Gdip_CreateBitmap(1, 1)
GBuf := Gdip_GraphicsFromImage(pBmpBuf)
Gdip_DisposeImage(pBmpBuf)
Data := Gdip_TextToGraphics(GBuf, String, Options, Font)
Gdip_DeleteGraphics(GBuf)
Arr := StrSplit(Data, "|")
WText := Arr[3], HText := Arr[4]

pBmpText := Gdip_CreateBitmap(WText, HText)
GText := Gdip_GraphicsFromImage(pBmpText) 
Gdip_SetSmoothingMode(GText, 4)

Gdip_TextToGraphics(GText, String, Options, Font, WText, HText)
Gdip_DeleteGraphics(GText)

pBmpDest := Gdip_CreateBitmap(WText, HText)
GDest := Gdip_GraphicsFromImage(pBmpDest)
Gdip_SetSmoothingMode(GDest, 4)
hDCDest := CreateCompatibleDC()

Gdip_DrawImage(GDest, pBmpText, 0, 0, WText, HText, 0, 0, WText, HText)
hBmpDest := Gdip_CreateHBITMAPFromBitmap(pBmpDest, 0x00000000)
SelectObject(hDCDest, hBmpDest)
DeleteObject(hBmpDest)

DllCall("Winmm\timeBeginPeriod", UInt, BeginPeriod)

uFlags := 0x0001|0x0400|0x0008|0x0100|0x0010|0x2000
XPos := W + 1
YPos := (A_ScreenHeight - HText) / 2

UpdateLayeredWindow(hGui, hDCDest, XPos, YPos, WText, HText)

Loop
{
	If (XPos < -WText)
		XPos := W + 1
	Else
		XPos -= 1 
	; WinMove, % "ahk_id " hGui, , XPos 
	DllCall("SetWindowPos", "Ptr", hGui, "UInt", 0
	, "Int", XPos, "Int", YPos
	, "Int", 0, "Int", 0, "UInt", uFlags)
	DllCall("Sleep", UInt, Sleep)
}

~Esc::
GuiEscape: 
	ExitApp 

Exit() { 
	Global 
	DllCall("Winmm\timeEndPeriod", UInt, BeginPeriod)
	Gdip_DisposeImage(pBmpDest) 
	Gdip_DeleteGraphics(GDest)
	DeleteDC(hdcDest)
	Gdip_Shutdown(pToken)
	ExitApp
}

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

33

Re: AHK: Бегущая строка

serzh82saratov пишет:

Но встаёт вопрос ограничения показа строки по краям.

Можно перемещать дочернее окно внутри родительского.

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

34

Re: AHK: Бегущая строка

Как здесь? Тогда оно не будет прозрачным для фона, это только если текст с фоном двигать.

Это как бы тоже подходит под "перемещать дочернее", но качество перемещения тут не на отлично. И главное при больших шрифтах резко поднимается нагрузка.

#SingleInstance Force
#NoEnv 
ListLines Off
SetBatchLines -1
OnExit, Exit

WS_EX_COMPOSITED := 0x02000000, WS_EX_LAYERED := 0x00080000

Pic = Pic1.jpg
String = Бегущая строка
MinPeriod := 3
Sleep := 5
Step := 1
FontSize := 82

Width := 640
Height := 480
Gui, +AlwaysOnTop +HWNDHWND +E%WS_EX_COMPOSITED% +E%WS_EX_LAYERED%  
Gui, Font, s%FontSize% q4 Italic, Arial
Gui, Margin, 0, 0
Gui, Color, 0xFFFF80
Gui, Add, Text, cFFFF80 x0 y50 +0x201 +BackgroundTrans hwndhText, % String
Gui, Add, Pic, x0 y0 w%Width% h%Height%, % Pic

DllCall("Winmm\timeBeginPeriod", UInt, MinPeriod)

GuiControlGet, Pos, Pos, %hText%

XPos := PosX + PosW + Step
YPos := (Height - PosH) / 2
DllCall("MoveWindow", "Ptr", hText, UInt, XPos, UInt, YPos, UInt, PosW, UInt, PosH, Int, 1)
Gui, Show, w%Width% h%Height%

Loop
{
	If (XPos < -PosW)
		XPos := PosX + PosW + Step
	Else
		XPos -= Step
	DllCall("MoveWindow", "Ptr", hText, UInt, XPos, UInt, YPos, UInt, PosW, UInt, PosH, Int, 1)
	DllCall("Sleep", UInt, Sleep)
}

Escape:: 
Exit: 
	DllCall("Winmm\timeEndPeriod", UInt, MinPeriod)
	ExitApp
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

35

Re: AHK: Бегущая строка

Можешь поизучать:
https://www.codeproject.com/Articles/44 … g-with-GDI

36

Re: AHK: Бегущая строка

А ты пробовал? Как то сомнительно выглядит попадать в vsync по таймеру.

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

37

Re: AHK: Бегущая строка

У меня экзешник в архиве идет плавно и память не съедается.

38

Re: AHK: Бегущая строка

Можешь скинуть.

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

39

Re: AHK: Бегущая строка

https://ru.files.fm/u/mfsyzjmd

40 (изменено: serzh82saratov, 2019-03-03 18:32:05)

Re: AHK: Бегущая строка

У меня постоянные как бы дрожания на шрифте, в общем ужас.

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

41

Re: AHK: Бегущая строка

А галочки все включены в визуальных эффектах в Perfomance options?

42

Re: AHK: Бегущая строка

Это где?

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

43

Re: AHK: Бегущая строка

В винде?

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

44

Re: AHK: Бегущая строка

https://www.sevenforums.com/attachments/tutorials/118204d1290882436-visual-effects-settings-change-starter_basic.jpg

45

Re: AHK: Бегущая строка

Винду трогать не надо.

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

46 (изменено: Malcev, 2019-03-03 17:20:44)

Re: AHK: Бегущая строка

Тогда вряд ли что-то путное выйдет.
Классическая тема не для эффектов предназначена.

47

Re: AHK: Бегущая строка

Просьба не употреблять вобщем и вообщем.

48 (изменено: serzh82saratov, 2019-03-03 19:07:43)

Re: AHK: Бегущая строка

ypppu
Извиняюсь, поправил. Уже не первый раз, прилипло.

Так вроде ничего работает.
Костыль конечно, но надежд на то что можно быстро менять графику уже почти не осталось.
Ну и конечно это только с аеро.


#SingleInstance Force
#Persistent  
#NoEnv
SetBatchLines -1
ListLines Off
OnExit("Exit")
; Process, Priority, , High

If !pToken := Gdip_Startup()
{
	MsgBox, 48, gdiplus error!, Gdiplus failed to start. Please ensure you have gdiplus on your system
	ExitApp
}

String = Бегущая строка
FontSize := 244

Sleep := 2
BeginPeriod := 3
Step := 1

SleepNew := 200

fTrans := 40
fColor := 0x000000
fTrans := fTrans / 100 * 255
fColor := fTrans << 24 | fColor

Margin = 20
Font = Arial 
fColor := Format("{1:08X}", fColor)

Pic = Pic1.jpg

Width := A_ScreenWidth - 100
Height := 480

Options = s%FontSize% Italic c%fColor% vCenter Center r4 Font

Gui, +AlwaysOnTop +HWNDHWND -Caption +ToolWindow +E0x08000000
Gui, Margin, 0, 0
Gui, Color, 0xFFFF80
Gui, Add, Pic, x0 y0 w%Width% h%Height%, % Pic
Gui, Show, Na
WinGetPos, WinX, WinY, WinWidth, WinHeight, % "ahk_id" HWND
WinX2 := WinX + WinWidth

Gui, New
Gui, -Caption +E0x80000 +HWNDhGui +AlwaysOnTop +ToolWindow +OwnDialogs +E0x08000020
Gui, Show, Na

pBmpBuf := Gdip_CreateBitmap(1, 1)
GBuf := Gdip_GraphicsFromImage(pBmpBuf)
Gdip_DisposeImage(pBmpBuf)
Data := Gdip_TextToGraphics(GBuf, String, Options, Font)
Gdip_DeleteGraphics(GBuf)
Arr := StrSplit(Data, "|")
WText := Arr[3], HText := Arr[4]

pBmpText := Gdip_CreateBitmap(WText, HText)
GText := Gdip_GraphicsFromImage(pBmpText) 
Gdip_SetSmoothingMode(GText, 4)
Gdip_TextToGraphics(GText, String, Options, Font, WText, HText)
Gdip_DeleteGraphics(GText)
hDCDest := CreateCompatibleDC()
hBmpDest := Gdip_CreateHBITMAPFromBitmap(pBmpText, 0x00000000)
Gdip_DisposeImage(pBmpText)
SelectObject(hDCDest, hBmpDest)
DeleteObject(hBmpDest)
UpdateLayeredWindow(hGui, hDCDest, 0, 0, WText, HText)
DeleteDC(hdcDest)

DllCall("Winmm\timeBeginPeriod", UInt, BeginPeriod) 

uFlags := 0x0001|0x0400|0x0008|0x0100|0x0010|0x2000

XPos := WinX2 + Step
YPos := WinY + (WinHeight - HText) / 2
XEnd := -(WText - WinX)

Loop
{
	If (XPos < XEnd)
	{ 
		XPos := WinX2 + Step
		If SleepNew
			DllCall("Sleep", UInt, SleepNew)  
	}
	Else
		XPos -= Step
	
	DllCall("SetWindowPos", "Ptr", hGui, "UInt", 0
		, "Int", XPos, "Int", YPos
		, "Int", 0, "Int", 0, "UInt", uFlags)
		
	WStr := XPos > WinX2 ? 0 : XPos < WinX ? WinWidth : WinX2 - XPos
	XStr := XPos > WinX ? 0 : WinX - XPos
	
	WinSet, Region, % XStr + Step "-" 0 " W" WStr - Step " H" HText, ahk_id %hGui%
	
	DllCall("Sleep", UInt, Sleep) 
}

~Esc::
GuiEscape: 
	ExitApp  

Exit() { 
	Global 
	DllCall("Winmm\timeEndPeriod", UInt, BeginPeriod) 
	Gdip_Shutdown(pToken)
	ExitApp
}
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

49

Re: AHK: Бегущая строка

serzh82saratov пишет:

Костыль конечно, но надежд на то что можно быстро менять графику уже почти не осталось.

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

50

Re: AHK: Бегущая строка

Не, не пробовал. А ты?

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

51

Re: AHK: Бегущая строка

Попробуй.
У меня не стоит студия.

52

Re: AHK: Бегущая строка

Да я с ней не дружу, при компиляции стороннего кода всегда какие то ошибки, сейчас точно не осилю.

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

53

Re: AHK: Бегущая строка

Ну вот и будет практика.
Ставишь виртуалку, устанавливаешь нужную версию студии и компилишь код.
https://rutracker.org/forum/viewtopic.php?t=2566619

54

Re: AHK: Бегущая строка

Там ещё и версию надо подобрать, я со своими способностями ещё полгода буду разбираться.

Код из 48 начинает заметно тормозить, если начать делать снимки экрана. Например в AhkSpy запустить лупу. Интересно, это влияет именно на перемещение окон.

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

55 (изменено: Malcev, 2019-03-04 14:45:14)

Re: AHK: Бегущая строка

serzh82saratov пишет:

Там ещё и версию надо подобрать, я со своими способностями ещё полгода буду разбираться.

Преувеличиваешь.
Смотришь в OSD.vcproj в какой версии он был сохранен, получаешь Version="7.10".
Смотришь памятку:

VS 6.0 -> 6.0
VS 2002 -> 7.0
VS 2003 -> 8.0
VS 2005 -> 9.0
VS 2008 -> 10.0
VS 2010 -> 11.0
VS 2012 -> 12.0
VS 2013 -> 10.0 to 12.0
VS 2015 -> 10.0 to 14.0
VS 2017 -> 10.0 to 15.0

Ну и можно, как автор, через BitBlt и SetLayeredWindowAttributes с анимацией работать.
Возможно дергаться не будет, да и процессор меньше потреблять.
Если не секрет, зачем тебе бегущая огромная надпись на экране?

56

Re: AHK: Бегущая строка

В магазине в окне наружу экраном стоит телевизор, внимание привлекать.
А BitBlt прозрачность поддерживает?

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

57

Re: AHK: Бегущая строка

serzh82saratov пишет:

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

А зачем вообще здесь автохотки?

serzh82saratov пишет:

А BitBlt прозрачность поддерживает?

BitBlt - да.
SetLayeredWindowAttributes, через цвет вытесняет.

58

Re: AHK: Бегущая строка

Malcev пишет:

А зачем вообще здесь автохотки?

В смысле, а что тут надо?

Malcev пишет:

SetLayeredWindowAttributes, через цвет вытесняет.

А полупрозрачность?

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

59

Re: AHK: Бегущая строка

serzh82saratov пишет:

В смысле, а что тут надо?

Смотря какая задача.
Допустим тебе надо подправить контрастность на фотографии, ты ее тоже через автохотки вкупе с GDI+ будешь решать?

serzh82saratov пишет:

А полупрозрачность?

Не совсем понимаю вопроса.
Альфа канал он не поддерживает, степень прозрачности идет 3 параметром.

60

Re: AHK: Бегущая строка

Malcev пишет:

надо подправить контрастность на фотографии, ты ее тоже через автохотки вкупе с GDI+ будешь решать?

Да, а как ещё я это решу исходя из незнания других языков и технологий работы с изображениями.

Malcev пишет:

Не совсем понимаю вопроса.

Фон текста полностью прозрачен, сам текст прозрачен на половину, под двигающимся текстом две неподвижных полупрозрачных картинки на фоне заданного цвета.

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

61 (изменено: Malcev, 2019-03-04 18:17:28)

Re: AHK: Бегущая строка

serzh82saratov пишет:

Да, а как ещё я это решу исходя из незнания других языков и технологий работы с изображениями.

Есть же фотошоп и прочие программы для работы с изображениями.
Для создания анимации есть афтер эффектс или другие композеры.
Если требуется текст читать с файла, то есть adobe animate.

serzh82saratov пишет:

Фон текста полностью прозрачен, сам текст прозрачен на половину

Я не пробовал, но судя по документации можно:
https://docs.microsoft.com/en-us/window … attributes
Ну а если подходить серьезно, то есть готовые решения для видеостен или их аналогов.

62 (изменено: serzh82saratov, 2019-03-04 18:32:00)

Re: AHK: Бегущая строка

Malcev пишет:

Есть же фотошоп и прочие программы для работы с изображениями.

Так разговор про собственную программную обработку.

Malcev пишет:

Я не пробовал, но судя по документации можно:

Я сделал выводы, в том числе отсюда, что это просто задаёт один полностью прозрачный цвет, и не более.

Malcev пишет:

Для создания анимации есть афтер эффектс или другие композеры.

Конские ценники и время на обучение.

Malcev пишет:

Ну а если подходить серьезно, то есть готовые решения для видеостен или их аналогов.

Не понял.

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

63

Re: AHK: Бегущая строка

Ты имеешь ввиду оборудование?

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

64 (изменено: Malcev, 2019-03-04 18:49:58)

Re: AHK: Бегущая строка

serzh82saratov пишет:

Я сделал выводы, в том числе отсюда, что это просто задаёт один полностью прозрачный цвет, и не более.

https://docs.microsoft.com/en-us/window … attributes

An action to be taken. This parameter can be one or more of the following values.
Value Meaning

LWA_ALPHA
0x00000002

Use bAlpha to determine the opacity of the layered window.

LWA_COLORKEY
0x00000001

Use crKey as the transparency color.

serzh82saratov пишет:

Конские ценники и время на обучение.

Если ценники не устраивают, а там сейчас действует подписка 20 долларов в месяц, то можно использовать народные версии.
Купить готовый шаблон еще 10-20 долларов, хотя можно скачать в интернете бесплатно.
https://videohive.net/category/after-ef … ject-files
Для учебы - на ютубе полно уроков.
Работы для новичка на пару часов.

serzh82saratov пишет:

Ты имеешь ввиду оборудование?

Готовые хардверные/софтверные комплексы.

65

Re: AHK: Бегущая строка

SetLayeredWindowAttributes

Я читал, но из чего там можно сделать вывод - "как текст сделать с определённой степенью прозрачности"?
Да и WinSet, Transparent (как пишет Lexikos - аналог SetLayeredWindowAttributes) при удалении фона из текста создаёт артефакты.

Malcev пишет:

Работы для новичка на пару часов.

Ну это ты уже со своей колокольни, я ещё новее.

Сторонний варезный софт, или тем более хардвер, это слишком серьёзно.

Интересно всё таки пока, как есть недавняя тема - "Что может GDI".

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

66

Re: AHK: Бегущая строка

serzh82saratov пишет:

как текст сделать с определённой степенью прозрачности

Если на Win-7, то создаешь 2 окна - окно с фоном и окно с текстом, вытесняешь текст, накладываешь прозрачность на окно.
На Win-8+ достаточно одного окна, так как можно вытеснять дочерние окна.

serzh82saratov пишет:

при удалении фона из текста создаёт артефакты

Ну это можно проверить, подобрать фон у шрифта близкий к подложке, вытеснить и решить устраивает качество или нет.

serzh82saratov пишет:

Ну это ты уже со своей колокольни, я ещё новее.

Для того и существуют шаблоны, в которых достаточно просто вбить новый текст и сделать экспорт.
Во всяком случае это привлечет больше внимания, чем топорно движущаяся надпись.

serzh82saratov пишет:

Сторонний варезный софт, или тем более хардвер, это слишком серьёзно.

Хардвер - согласен, варезный софт тоже не есть хорошо, но для каждой задачи есть свои инструменты.
Есть ли смысл делать анимационное видео в программе для этого непредназначенной?
ИМХО только ради спортивного интереса.

67

Re: AHK: Бегущая строка

Malcev пишет:

вытесняешь текст, накладываешь прозрачность на окно.

Ок, а двигать как?

Malcev пишет:

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

Согласен, намного круче. А эти программы в результате создают простой видео файл, или у них свои плееры?

Malcev пишет:

ИМХО только ради спортивного интереса.

Это даже интереснее, чем просто решить вопрос.

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

68

Re: AHK: Бегущая строка

Кстати ради интереса, на ахк можно сделать видео из GdiPlus.

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

69

Re: AHK: Бегущая строка

Даже, если и написать кодек, который будет обрабатывать, к примеру, .mp4, то имхо GDI на пару с кодеком замучают процессор. (Вспомним, никакого аппаратного ускорения у GDI нет. Соответственно производительность будет меньше.)

70 (изменено: serzh82saratov, 2019-03-05 11:48:22)

Re: AHK: Бегущая строка

Ну по идее надо же просто сделать много картинок из каждого сдвига текста, и из этого создать видео, разве это будет невероятно затратно?
В реальном времени даже UpdateLayeredWindow у меня кушает не более 10%.
То есть надо один раз "прогнать" строку, а потом уже "гонять" видео на повторе в плеере.

АП:
Я имею ввиду что видео надо сделать заранее, а не в реальном времени создавать его, и показывать.

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

71

Re: AHK: Бегущая строка

serzh82saratov пишет:

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

В таком случае, выгоднее будет написать что-то вроде класса, который будет работать с анимацией. На вход даем ему текст, шрифт, цвет, начальные координаты+конечные, свойства какие-нибудь для анимации(затухание и пр.) и он рисует.
Это если в идеале, а можно и иначе, одним скриптом делаем много PNG-картинок(кадры), другим считываем. Будет что-то вроде слайд-шоу.
FPS*секунды=кол-во картинок
P.S. где-то была тема по этому поводу на форуме автохотки. Они там пытались сначала просто менять путь к картинке у элемента Picture. По итогу перешли на GDI из-за мельканий.

72

Re: AHK: Бегущая строка

Так тут и встаёт вопрос производительности, сколько FPS выдаст AutoHotkey, и при какой нагрузке на проц. И конечно пропуск кадров для синхрона времени, правда в презентациях это не особо важно. Готовое решение ввиде WMP для вопроизведения выглядит как то по проще и надежнее.

скриптом делаем много PNG-картинок(кадры)

Если говорить про самодельный плеер, то сохранять кучу картинок можно и в один файл, и не PNG, а сами Bitmap, по сути это и будет видео файл без кодеков для сжатия.

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

73 (изменено: Malcev, 2019-03-05 16:15:43)

Re: AHK: Бегущая строка

serzh82saratov пишет:

Ок, а двигать как?

Через BitBlt.

///////////////////////////////////////////////////////////////////
// Force draw a new frame
///////////////////////////////////////////////////////////////////
public:
void ForceFrame()
{    
    PaintWithMemDC(m_hWnd);
}

////////////////////////////////////////////////////////////////////
// Paint with MemDC
////////////////////////////////////////////////////////////////////
public:
inline
void PaintWithMemDC( HWND hWnd )
{
    if (m_MemDC == NULL) return;

    HDC    hDC = GetDC(hWnd);

    if (! BitBlt(
        hDC,         // handle to destination DC
        0,           // x-coord of destination upper-left corner
        0,           // y-coord of destination upper-left corner
        WIN_WIDTH,   // width of destination rectangle
        WIN_HEIGHT,  // height of destination rectangle
        m_MemDC,     // handle to source DC
        m_ScrollCnt, // x-coordinate of source upper-left corner
        0,           // y-coordinate of source upper-left corner
        SRCCOPY      // raster operation code
    ))
    {
        PostMessage(m_hWnd, WM_CLOSE, 0, 0);
    }

    m_ScrollCnt += m_ScrollSpeed;

    if (m_ScrollCnt > m_StrLen + WIN_WIDTH)
    {
        m_ScrollCnt = 0;
        
        StopTimer();        
        
        CreateMemDC(hWnd); // re create the new memDC
        
        SafeStartTimer();
    }

    ReleaseDC(hWnd, hDC);
}

//////////////////////////////////////////////////////////////////////
// On Left Button Up , at the same time when windows position moved.
//////////////////////////////////////////////////////////////////////
private:
void OnLBtnUp( WINDOWPOS* lpwp)
{
    int cy = GetSystemMetrics(SM_CYSCREEN);

    m_ScreenHalfHeight = cy/2;

    if ( (UINT)(lpwp->y + WIN_HEIGHT) < (m_ScreenHalfHeight) )
    {
        m_bOnScreenUp = TRUE;
        gbUsed        = FALSE;
    }
    else
    {
        m_bOnScreenUp = FALSE;
    }
}

Кстати есть еще вариант через SetDIBitsToDevice:
https://habr.com/ru/post/164705/

serzh82saratov пишет:

А эти программы в результате создают простой видео файл, или у них свои плееры?

Простой видеофайл, но adobe animate она же бывший макромедиа флеш может создавать swf, которая может на ходу подхватывать файлы, текст извне.

serzh82saratov пишет:

Кстати ради интереса, на ахк можно сделать видео из GdiPlus.

Из картинок видео сделать можно, но не так просто, как кажется.
https://www.autoitscript.com/forum/topi … ent-927370
https://docs.microsoft.com/en-us/window … p/api/vfw/

74

Re: AHK: Бегущая строка

Malcev пишет:

Кстати есть еще вариант через SetDIBitsToDevice:

15000 фпс, такое надо попробовать!

Malcev пишет:

Через BitBlt.

А ты пример кода привёл, он отличается как то от "распространённых"?

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

75

Re: AHK: Бегущая строка

https://www.opennet.ru/docs/RUS/qt3_prog/x2947.html

76

Re: AHK: Бегущая строка

Я за тобой не успеваю. Это относится к чему то выше, или ещё один метод.

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

77

Re: AHK: Бегущая строка

Там просто объясняется принцип работы BitBlt.

78

Re: AHK: Бегущая строка

Кстати есть еще вариант через SetDIBitsToDevice:
https://habr.com/ru/post/164705/

А с WriteableBitmap не сталкивался, автор его в пример приводит.

Вот что то есть, у меня не открывает.

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

79

Re: AHK: Бегущая строка

Нет, по-моему это для NET.

80

Re: AHK: Бегущая строка

А там разве просто длл нельзя использовать, или что то надо устанавливать.
https://www.nuget.org/packages/WriteableBitmapEx/1.6.2

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

81

Re: AHK: Бегущая строка

Без понятия.
Про работу с NET можешь почитать тут:
https://www.autohotkey.com/boards/viewtopic.php?t=4633

82 (изменено: serzh82saratov, 2019-03-06 23:19:21)

Re: AHK: Бегущая строка

А, да, как то использовал готовый пример с ней.
Как по твоему, почему теоретически SetDIBits может быть шустрее чем UpdateLayeredWindow, и в чём преимущества перед BitBllt?

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

83

Re: AHK: Бегущая строка

Не совсем понял почему ты сравниваешь SetDIBits с UpdateLayeredWindow и BitBlt?

84

Re: AHK: Бегущая строка

UpdateLayeredWindow на GDI+, но она тормозит. BitBlt и SetDIBits на GDI, ты предлагал их в качестве менее прожорливой альтернативы если я правильно понял.

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

85

Re: AHK: Бегущая строка

Не SetDIBits, а SetDIBitsToDevice.
Это совсем разные функции.
Теоретически сказать не могу, я бы исходил из практики - попробовать все варианты и выбрать наиболее подходящий.
МСДН пишет, что BitBlt быстрее:
https://docs.microsoft.com/en-us/window … nt-bitmaps
Хотя возможно тебя  ни один из вариантов не устроит и тогда придется садиться за изучение Direct2D:
https://autohotkey.com/board/topic/9464 … animation/
https://github.com/neptercn/Direct2D

86

Re: AHK: Бегущая строка

Тогда не понятно почему автор предпочёл SetDIBitsToDevice вместо BitBlt для большего кол-ва fps. Судя по опыту создания экранной лупы, BitBlt при перерисовке больших площадей периодически мелькает, и не даёт существенный прирост производительности в сравнении с UpdateLayeredWindow.

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

87

Re: AHK: Бегущая строка

Кто ж его знает.
Рассуждать можно до бесконечности.
Реальные результаты можно получить только с помощью бенчмарков.

88

Re: AHK: Бегущая строка

Direct2D выглядит хорошо, но судя по тому что на AutoHotkey это чуть ли не единственный пример, путь одолеет не каждый идущий.

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

89

Re: AHK: Бегущая строка

Самое главное то, что написан враппер.
Берешь какую-нибудь книжку по Direct2D, читаешь, изучаешь уроки.
Потом с помощью враппера выполняешь их на ахк.
Если какие-то функции переведены на ахк не будут, ищешь их на мсдн, считаешь сдвиги и добавляешь.

90

Re: AHK: Бегущая строка

Тут его более полные библиотеки:
https://github.com/neptercn/Component_AHK
Пример от которого можно отталкиваться:

#SingleInstance force
#NoTrayIcon
SetBatchLines,-1

;dll structure
;Result := DllCall("DllFile\Function", "Type1", Arg1, "Type2", Arg2,.....,"TypeX",ArgX) ;pretty straight forward

DllCall("LoadLibrary","str","d2d1.dll") ;default path C:\Windows\SysWOW64\d2d1.dll on 64bit
global 	sizeX = 300,sizeY = 300, hGui ; hwnd
		,pFactory ; the Direct2d Factory
		,pWDFactory ;the DWrite Factory
DllCall("d2d1\D2D1CreateFactory","uint",0,"ptr",guid(CLSID,"{06152247-6f50-465a-9245-118bfd3b6007}"),"uint*",0,"ptr*",pFactory) ;Create D2D1 Factory

DllCall("LoadLibrary","str","dwrite.dll")
DllCall("dwrite\DWriteCreateFactory","uint",0,"ptr",GUID(CLSID,"{b859ee5a-d838-4b5b-a2e8-1adc7d93db48}"),"ptr*",pWDFactory) ;Create DWriteFactory


Gui,new,hwndhGui
;CustomColor = EEAA99  ; Can be any RGB color (it will be made transparent below).
Gui +AlwaysOnTop -Caption ;+ToolWindow  ; +ToolWindow avoids a taskbar button and an alt-tab menu item.
;Gui, Color, %CustomColor%
;WinSet, TransColor, %CustomColor% 0

;gui,new,hwndhGui
gui,show,w%sizeX% h%sizeY%

_rectangle()
return
GuiClose:
ExitApp


_rectangle()
{

	static pRenderTarget,pBrush3,pBackgroundBrush,pTxtBrush,textFormat
	
	if A_PtrSize=8
		_struct(tD2D1_HWND_RENDER_TARGET_PROPERTIES,"uint;uint;uint;uint",hGui,hGui>>32,sizeX,sizeY)
	else
		_struct(tD2D1_HWND_RENDER_TARGET_PROPERTIES,"uint;uint;uint",hGui,sizeX,sizeY)
	
	;PixelFormat:
		_struct(tD2D1_PIXEL_FORMAT,"uint;uint",28,0)
	;	Tooltip % &tD2D1_PIXEL_FORMAT
		
		;_struct(tD2D1_RENDER_TARGET_PROPERTIES,"uint;uint;uint;float;float;uint;uint")
		_struct(tD2D1_RENDER_TARGET_PROPERTIES,"uint;uint;uint;float;float;uint;uint",0,0,1,0,0,0,0)
		;Colors
		_struct(tD2D1_COLOR_F4,"float;float;float;float",0,0,0,0) ;BackGround
		_struct(tD2D1_COLOR_F3,"float;float;float;float",1,0,0,1) ;Square
		_struct(tD2D1_COLOR_F5,"float;float;float;float",1,1,0,1) ;Text
		
		_struct(HBITMAP,"uint;uint;uint;uint;uint",500,500,1,32,0)
		

	;ID2D1Factory
	DllCall(vt(pFactory,14),"ptr",pFactory
			,"ptr",&tD2D1_RENDER_TARGET_PROPERTIES
			,"ptr",&tD2D1_HWND_RENDER_TARGET_PROPERTIES
			,"ptr*",pRenderTarget)  ;CreateHwndRenderTarget

	;CreateBitmap
;	DllCall(vt(pRenderTarget,4),"ptr",pRenderTarget,"uint",500,"uint",500,"uint",1,"ptr",32,"float",0,"ptr*",bitmap)
	;im lost here

/*
	DllCall(vt(pFactory,13),"ptr",pFactory
			,"ptr",&HBITMAP ; not sure how or what.
			,"ptr"&tD2D1_RENDER_TARGET_PROPERTIES
			,"ptr*",pRenderTarget) ;CreateWicBitmapRenderTarget
			
	;DllCall(vt(pFactory,16),"ptr",&tD2D1_RENDER_TARGET_PROPERTIES,"ptr*",pRenderTarget)
			
		Tooltip % 	DllCall(vt(pRenderTarget,56),pRenderTarget,tD2D1_RENDER_TARGET_PROPERTIES)
		*/


	;ID2D1RenderTarget
	DllCall(vt(pRenderTarget,8),"ptr",pRenderTarget
			,"ptr",&tD2D1_COLOR_F4
			,"ptr",0,"ptr*",pBackgroundBrush) ;CreateSolidColorBrush
			
	;ID2D1RenderTarget
	DllCall(vt(pRenderTarget,8),"ptr",pRenderTarget
			,"ptr",&tD2D1_COLOR_F3			
			,"ptr",0,"ptr*",pBrush3) ;CreateSolidColorBrush					
			
	;ID2D1RenderTarget
	DllCall(vt(pRenderTarget,8),"ptr",pRenderTarget
			,"ptr",&tD2D1_COLOR_F5
			,"ptr",0,"ptr*",pTxtBrush) ;CreateSolidColorBrush
			
	_struct(tD2D1_RECT_F,"float;float;float;float",0,0,sizeX,sizeY)
	_struct(tD2D1_ROUNDED_RECT,"float;float;float;float;float;float",0.12*sizeX,0.12*sizeY,0.88*sizeX,0.88*sizeY)	
	_struct(tD2D1_TEXT,"float;float;float;float",5,5,sizeX,sizeY)

	
	
	;DllCall(vt(pWDFactory,15),"str",fontFamilyName,"ptr",fontCollection,"int",fontWeight,"int",fontStyle,"int",fontStretch,"float",fontSize,"str",localeName,"ptr*",textFormat)	
	
	;ID2D1RenderTarget
	DllCall(vt(pRenderTarget,48),"ptr",pRenderTarget) ;start draw
	DllCall(vt(pRenderTarget,17),"ptr",pRenderTarget,"ptr",&tD2D1_RECT_F,"ptr",pBackgroundBrush) ;background
	DllCall(vt(pRenderTarget,18),"ptr",pRenderTarget,"ptr",&tD2D1_ROUNDED_RECT,"ptr",pBrush3,"float",2,"ptr",pStrokeStyle) ;rectangle
	DllCall(vt(pWDFactory,15),"str","Arial","ptr",0,"int",700,"int",1,"int",0,"float",13.0,"str","en-us","ptr*",textFormat)	
	DllCall(vt(pRenderTarget,27),"ptr",pRenderTarget,"str","Michael","uint",7,"ptr",textFormat,"ptr",&tD2D1_TEXT,"ptr",pTxtBrush,"uint",0,"unit",0) ;drawtext
	DllCall(vt(pRenderTarget,47),"ptr",pRenderTarget,"ptr",&tD2D1_RECT_F)
	DllCall(vt(pRenderTarget,49),"ptr",pRenderTarget,"uint64*",0,"uint64*",0) ;end draw
	

}

GUID(ByRef GUID, sGUID){ 
    VarSetCapacity(GUID,16,0)
    return DllCall("ole32\CLSIDFromString","wstr",sGUID,"ptr",&GUID)>= 0?&GUID:""
}


_struct(ByRef var,type="",param*){
	if type is Integer
    {
		Loop % VarSetCapacity(var,type,0)//4
			if param[A_Index]
				NumPut(param[A_Index],var,(A_Index-1)*4,"uint")
	}else{
		StringSplit,key,type,`;,%A_Space%
		VarSetCapacity(var,key0*4,0)
		loop %key0%
			if param[A_Index]
				NumPut(param[A_Index],var,(A_Index-1)*4,key%A_Index%)
	}	
	return &var
}

vt(p,n){
	return NumGet(NumGet(p+0,"ptr")+n*A_PtrSize,"ptr")
}

91

Re: AHK: Бегущая строка

Хм, это окно у меня после сворачивания/разворачивания стало серым.

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

92

Re: AHK: Бегущая строка

#SingleInstance force
#NoTrayIcon
SetBatchLines,-1

;dll structure
;Result := DllCall("DllFile\Function", "Type1", Arg1, "Type2", Arg2,.....,"TypeX",ArgX) ;pretty straight forward

DllCall("LoadLibrary","str","d2d1.dll") ;default path C:\Windows\SysWOW64\d2d1.dll on 64bit
global 	sizeX = 300,sizeY = 300, hGui ; hwnd
		,pFactory ; the Direct2d Factory
		,pWDFactory ;the DWrite Factory
DllCall("d2d1\D2D1CreateFactory","uint",0,"ptr",guid(CLSID,"{06152247-6f50-465a-9245-118bfd3b6007}"),"uint*",0,"ptr*",pFactory) ;Create D2D1 Factory

DllCall("LoadLibrary","str","dwrite.dll")
DllCall("dwrite\DWriteCreateFactory","uint",0,"ptr",GUID(CLSID,"{b859ee5a-d838-4b5b-a2e8-1adc7d93db48}"),"ptr*",pWDFactory) ;Create DWriteFactory


Gui,new,hwndhGui
;CustomColor = EEAA99  ; Can be any RGB color (it will be made transparent below).
Gui +AlwaysOnTop -Caption ;+ToolWindow  ; +ToolWindow avoids a taskbar button and an alt-tab menu item.
;Gui, Color, %CustomColor%
;WinSet, TransColor, %CustomColor% 0

;gui,new,hwndhGui
gui,show,w%sizeX% h%sizeY%

OnMessage(0xF,"_rectangle")
OnMessage(0x14,"_WM_ERASEBKGND")
_rectangle()
return
GuiClose:
ExitApp


_WM_ERASEBKGND(){
	return 0
}

_rectangle()
{
	static pRenderTarget,pBrush3,pBackgroundBrush,pTxtBrush,textFormat
	
	if A_PtrSize=8
		_struct(tD2D1_HWND_RENDER_TARGET_PROPERTIES,"uint;uint;uint;uint",hGui,hGui>>32,sizeX,sizeY)
	else
		_struct(tD2D1_HWND_RENDER_TARGET_PROPERTIES,"uint;uint;uint",hGui,sizeX,sizeY)
	
	;PixelFormat:
		_struct(tD2D1_PIXEL_FORMAT,"uint;uint",28,0)
	;	Tooltip % &tD2D1_PIXEL_FORMAT
		
		;_struct(tD2D1_RENDER_TARGET_PROPERTIES,"uint;uint;uint;float;float;uint;uint")
		_struct(tD2D1_RENDER_TARGET_PROPERTIES,"uint;uint;uint;float;float;uint;uint",0,0,1,0,0,0,0)
		;Colors
		_struct(tD2D1_COLOR_F4,"float;float;float;float",0,0,0,0) ;BackGround
		_struct(tD2D1_COLOR_F3,"float;float;float;float",1,0,0,1) ;Square
		_struct(tD2D1_COLOR_F5,"float;float;float;float",1,1,0,1) ;Text
		
		_struct(HBITMAP,"uint;uint;uint;uint;uint",500,500,1,32,0)
		

	;ID2D1Factory
	DllCall(vt(pFactory,14),"ptr",pFactory
			,"ptr",&tD2D1_RENDER_TARGET_PROPERTIES
			,"ptr",&tD2D1_HWND_RENDER_TARGET_PROPERTIES
			,"ptr*",pRenderTarget)  ;CreateHwndRenderTarget

	;CreateBitmap
;	DllCall(vt(pRenderTarget,4),"ptr",pRenderTarget,"uint",500,"uint",500,"uint",1,"ptr",32,"float",0,"ptr*",bitmap)
	;im lost here

/*
	DllCall(vt(pFactory,13),"ptr",pFactory
			,"ptr",&HBITMAP ; not sure how or what.
			,"ptr"&tD2D1_RENDER_TARGET_PROPERTIES
			,"ptr*",pRenderTarget) ;CreateWicBitmapRenderTarget
			
	;DllCall(vt(pFactory,16),"ptr",&tD2D1_RENDER_TARGET_PROPERTIES,"ptr*",pRenderTarget)
			
		Tooltip % 	DllCall(vt(pRenderTarget,56),pRenderTarget,tD2D1_RENDER_TARGET_PROPERTIES)
		*/


	;ID2D1RenderTarget
	DllCall(vt(pRenderTarget,8),"ptr",pRenderTarget
			,"ptr",&tD2D1_COLOR_F4
			,"ptr",0,"ptr*",pBackgroundBrush) ;CreateSolidColorBrush
			
	;ID2D1RenderTarget
	DllCall(vt(pRenderTarget,8),"ptr",pRenderTarget
			,"ptr",&tD2D1_COLOR_F3			
			,"ptr",0,"ptr*",pBrush3) ;CreateSolidColorBrush					
			
	;ID2D1RenderTarget
	DllCall(vt(pRenderTarget,8),"ptr",pRenderTarget
			,"ptr",&tD2D1_COLOR_F5
			,"ptr",0,"ptr*",pTxtBrush) ;CreateSolidColorBrush
			
	_struct(tD2D1_RECT_F,"float;float;float;float",0,0,sizeX,sizeY)
	_struct(tD2D1_ROUNDED_RECT,"float;float;float;float;float;float",0.12*sizeX,0.12*sizeY,0.88*sizeX,0.88*sizeY)	
	_struct(tD2D1_TEXT,"float;float;float;float",5,5,sizeX,sizeY)

	
	
	;DllCall(vt(pWDFactory,15),"str",fontFamilyName,"ptr",fontCollection,"int",fontWeight,"int",fontStyle,"int",fontStretch,"float",fontSize,"str",localeName,"ptr*",textFormat)	
	
	;ID2D1RenderTarget
	DllCall(vt(pRenderTarget,48),"ptr",pRenderTarget) ;start draw
	DllCall(vt(pRenderTarget,17),"ptr",pRenderTarget,"ptr",&tD2D1_RECT_F,"ptr",pBackgroundBrush) ;background
	DllCall(vt(pRenderTarget,18),"ptr",pRenderTarget,"ptr",&tD2D1_ROUNDED_RECT,"ptr",pBrush3,"float",2,"ptr",pStrokeStyle) ;rectangle
	DllCall(vt(pWDFactory,15),"str","Arial","ptr",0,"int",700,"int",1,"int",0,"float",13.0,"str","en-us","ptr*",textFormat)	
	DllCall(vt(pRenderTarget,27),"ptr",pRenderTarget,"str","Michael","uint",7,"ptr",textFormat,"ptr",&tD2D1_TEXT,"ptr",pTxtBrush,"uint",0,"unit",0) ;drawtext
	DllCall(vt(pRenderTarget,47),"ptr",pRenderTarget,"ptr",&tD2D1_RECT_F)
	DllCall(vt(pRenderTarget,49),"ptr",pRenderTarget,"uint64*",0,"uint64*",0) ;end draw
	

}

GUID(ByRef GUID, sGUID){ 
    VarSetCapacity(GUID,16,0)
    return DllCall("ole32\CLSIDFromString","wstr",sGUID,"ptr",&GUID)>= 0?&GUID:""
}


_struct(ByRef var,type="",param*){
	if type is Integer
    {
		Loop % VarSetCapacity(var,type,0)//4
			if param[A_Index]
				NumPut(param[A_Index],var,(A_Index-1)*4,"uint")
	}else{
		StringSplit,key,type,`;,%A_Space%
		VarSetCapacity(var,key0*4,0)
		loop %key0%
			if param[A_Index]
				NumPut(param[A_Index],var,(A_Index-1)*4,key%A_Index%)
	}	
	return &var
}

vt(p,n){
	return NumGet(NumGet(p+0,"ptr")+n*A_PtrSize,"ptr")
}
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

93 (изменено: serzh82saratov, 2019-03-07 16:12:31)

Re: AHK: Бегущая строка

В _rectangle повторно надо наверное не всё выполнять, это есть в примере nepter.

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

94

Re: AHK: Бегущая строка

Если знаешь autoit, то тогда проще будет:
https://autoit.de/index.php?thread/45155-direct2d-udf/

95

Re: AHK: Бегущая строка

Спасибо, примеры интересные.

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

96

Re: AHK: Бегущая строка

_D2D_RenderTarget_DrawGlyphRun.au3 красиво смотрится. Даже не верится что это в реальном времени, при 2% процессора.

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