Тема: AHK V2: GUI окно мерцает (GDIP)
Всех приветствую!
Мой скрипт - это, по сути, Radial Menu, и он практически доделан. Но у меня возникала проблема, которую я не могу решить, а именно мерцание GUI окна. Как я понимаю, это происходит из-за WinSetTransColor, так как если закомментировать эту строку кода, то все будет работать нормально. Почему так работает, я не особо понимаю.
GUI мерцает не особо часто, но всё же это хорошо заметно. У кого-нибудь есть идеи, как это исправить?
Буду признателен за любую помощь.
И да, для запуска скрипта нужна библиотека
GDIP: https://raw.githubusercontent.com/bulia … ip_All.ahk
А также класс Vector: https://www.autohotkey.com/boards/viewt … 13#p583213
#Requires AutoHotkey v2.0
#SingleInstance Force
#Include Gdip_All.ahk ; https://raw.githubusercontent.com/buliasz/AHKv2-Gdip/master/Gdip_All.ahk
#Include Vectors.ahk ; https://www.autohotkey.com/boards/viewtopic.php?f=83&t=132770&p=583213#p583213
CoordMode "Mouse", "Screen"
pToken := Gdip_Startup()
Gui1 := Gui("+ToolWindow -Caption +E0x02000000 +E0x00080000 +E0x80000")
Gui1.BackColor := "0x010101"
Gui1.Elements2 := CursorElements()
Gui1.Elements := OwerlayElements()
;Cursorpic := Gui1.Add("Picture", "x190 y190 w20 h20 +BackgroundTrans", ".\Pic\cor.png")
Gui1.Pic1 := Gui1.Add( "Picture" , "x185 y185 +BackgroundTrans" , "hBitmap: " CursorFunction( Gui1.Elements2 ,, "hBitmap" ) ) ; custom cursor
Gui1.Pic2 := Gui1.Add( "Picture" , "x-0 y-0" , "hBitmap: " OwerlayFunction( Gui1.Elements ,, "hBitmap" ) ) ; circle
WinSetTransColor(Gui1.BackColor " 255", Gui1)
;WinSetTransColor "010101 250", Gui1
OwerlayElements(){
local Elements := []
Elements.Push( { Index: 1 , Layer: 1 , ElementType: "DrawArc" , Rect: { X: 115 + 0 , Y: 115 + 0 , W: 170 , H: 170 } , StartAngle: "0" , SweepAngle: "360" , Thickness: "3" , Note: "" , BrushObject: { BrushType: "SolidBrush" , Color1: "0xFFFF0000" } } )
Elements.Push( { Index: 2 , Layer: 1 , ElementType: "DrawArc" , Rect: { X: 118 + 0 , Y: 118 + 0 , W: 164 , H: 164 } , StartAngle: "0" , SweepAngle: "360" , Thickness: "3" , Note: "" , BrushObject: { BrushType: "SolidBrush" , Color1: "0xFF000000" } } )
Elements.Push( { Index: 3 , Layer: 1 , ElementType: "DrawArc" , Rect: { X: 121 + 0 , Y: 121 + 0 , W: 158 , H: 158 } , StartAngle: "0" , SweepAngle: "360" , Thickness: "3" , Note: "" , BrushObject: { BrushType: "SolidBrush" , Color1: "0xFFFF0000" } } )
Elements.Push( { Index: 4 , Layer: 1 , ElementType: "DrawArc" , Rect: { X: 124 + 0 , Y: 124 + 0 , W: 152 , H: 152 } , StartAngle: "0" , SweepAngle: "360" , Thickness: "3" , Note: "" , BrushObject: { BrushType: "SolidBrush" , Color1: "0xFF000000" } } )
Elements.Push( { Index: 5 , Layer: 1 , ElementType: "BorderedSimplePolygon" , StartVector: { X: 300 + 0 , Y: 200 + 0 } , Radius: 12 , Sides: 3 , StartAngle: 120 , Thickness: 6 , Color1: 0xFFFA7878 , Color2: 0xFF373737 , Note: "" } )
Elements.Push( { Index: 6 , Layer: 1 , ElementType: "BorderedSimplePolygon" , StartVector: { X: 270 + 0 , Y: 270 + 0 } , Radius: 12 , Sides: 3 , StartAngle: 165 , Thickness: 6 , Color1: 0xFFFA7878 , Color2: 0xFF373737 , Note: "" } )
Elements.Push( { Index: 7 , Layer: 1 , ElementType: "BorderedSimplePolygon" , StartVector: { X: 200 + 0 , Y: 300 + 0 } , Radius: 12 , Sides: 3 , StartAngle: 210 , Thickness: 6 , Color1: 0xFFFA7878 , Color2: 0xFF373737 , Note: "" } )
Elements.Push( { Index: 8 , Layer: 1 , ElementType: "BorderedSimplePolygon" , StartVector: { X: 130 + 0 , Y: 270 + 0 } , Radius: 12 , Sides: 3 , StartAngle: 255 , Thickness: 6 , Color1: 0xFFFA7878 , Color2: 0xFF373737 , Note: "" } )
Elements.Push( { Index: 9 , Layer: 1 , ElementType: "BorderedSimplePolygon" , StartVector: { X: 100 + 0 , Y: 200 + 0 } , Radius: 12 , Sides: 3 , StartAngle: 300 , Thickness: 6 , Color1: 0xFFFA7878 , Color2: 0xFF373737 , Note: "" } )
Elements.Push( { Index: 10 , Layer: 1 , ElementType: "BorderedSimplePolygon" , StartVector: { X: 130 + 0 , Y: 130 + 0 } , Radius: 12 , Sides: 3 , StartAngle: 345 , Thickness: 6 , Color1: 0xFFFA7878 , Color2: 0xFF373737 , Note: "" } )
Elements.Push( { Index: 11 , Layer: 1 , ElementType: "BorderedSimplePolygon" , StartVector: { X: 200 + 0 , Y: 100 + 0 } , Radius: 12 , Sides: 3 , StartAngle: 390 , Thickness: 6 , Color1: 0xFFFA7878 , Color2: 0xFF373737 , Note: "" } )
Elements.Push( { Index: 12 , Layer: 1 , ElementType: "BorderedSimplePolygon" , StartVector: { X: 270 + 0 , Y: 130 + 0 } , Radius: 12 , Sides: 3 , StartAngle: 437 , Thickness: 6 , Color1: 0xFFFA7878 , Color2: 0xFF373737 , Note: "" } )
return Elements
}
;******************************************************************************************************
OwerlayFunction( Elements , Scale := 1 , returnType := "pBitmap" ){
local pBitmap := Gdip_CreateBitmap( 400 * Scale , 400 * Scale )
local pGraphics := Gdip_GraphicsFromImage( pBitmap )
;Layer: 1
Gdip_SetSmoothingMode( pGraphics , 2 ) , Gdip_SetInterpolationMode( pGraphics , 7 )
element := Elements[ 1 ] , Brush := element.BrushObject
pPen := Gdip_CreatePen( Brush.Color1 , element.Thickness * scale )
Gdip_DrawArc( pGraphics , pPen , ( element.Rect.X ) * scale , ( element.Rect.Y ) * scale , ( element.Rect.W ) * scale , ( element.Rect.H ) * scale , element.StartAngle , element.SweepAngle )
Gdip_DeletePen( pPen )
element := Elements[ 2 ] , Brush := element.BrushObject
pPen := Gdip_CreatePen( Brush.Color1 , element.Thickness * scale )
Gdip_DrawArc( pGraphics , pPen , ( element.Rect.X ) * scale , ( element.Rect.Y ) * scale , ( element.Rect.W ) * scale , ( element.Rect.H ) * scale , element.StartAngle , element.SweepAngle )
Gdip_DeletePen( pPen )
element := Elements[ 3 ] , Brush := element.BrushObject
pPen := Gdip_CreatePen( Brush.Color1 , element.Thickness * scale )
Gdip_DrawArc( pGraphics , pPen , ( element.Rect.X ) * scale , ( element.Rect.Y ) * scale , ( element.Rect.W ) * scale , ( element.Rect.H ) * scale , element.StartAngle , element.SweepAngle )
Gdip_DeletePen( pPen )
element := Elements[ 4 ] , Brush := element.BrushObject
pPen := Gdip_CreatePen( Brush.Color1 , element.Thickness * scale )
Gdip_DrawArc( pGraphics , pPen , ( element.Rect.X ) * scale , ( element.Rect.Y ) * scale , ( element.Rect.W ) * scale , ( element.Rect.H ) * scale , element.StartAngle , element.SweepAngle )
Gdip_DeletePen( pPen )
element := Elements[ 5 ]
pBrush := Gdip_BrushCreateSolid( element.Color1 )
pPen := Gdip_CreatePen( element.Color2 , element.Thickness * scale )
sv := Vector( element.StartVector )
sv.Mult( scale )
shape := Vector.PolygonShape( sv , element.Radius * scale , element.Sides , element.StartAngle )
shape .= "|" StrSplit( shape , "|" )[2]
Gdip_DrawLines( pGraphics , pPen , shape )
Gdip_FillPolygon( pGraphics , pBrush , shape )
Gdip_DeletePen( pPen )
Gdip_DeleteBrush( pBrush )
element := Elements[ 6 ]
pBrush := Gdip_BrushCreateSolid( element.Color1 )
pPen := Gdip_CreatePen( element.Color2 , element.Thickness * scale )
sv := Vector( element.StartVector )
sv.Mult( scale )
shape := Vector.PolygonShape( sv , element.Radius * scale , element.Sides , element.StartAngle )
shape .= "|" StrSplit( shape , "|" )[2]
Gdip_DrawLines( pGraphics , pPen , shape )
Gdip_FillPolygon( pGraphics , pBrush , shape )
Gdip_DeletePen( pPen )
Gdip_DeleteBrush( pBrush )
element := Elements[ 7 ]
pBrush := Gdip_BrushCreateSolid( element.Color1 )
pPen := Gdip_CreatePen( element.Color2 , element.Thickness * scale )
sv := Vector( element.StartVector )
sv.Mult( scale )
shape := Vector.PolygonShape( sv , element.Radius * scale , element.Sides , element.StartAngle )
shape .= "|" StrSplit( shape , "|" )[2]
Gdip_DrawLines( pGraphics , pPen , shape )
Gdip_FillPolygon( pGraphics , pBrush , shape )
Gdip_DeletePen( pPen )
Gdip_DeleteBrush( pBrush )
element := Elements[ 8 ]
pBrush := Gdip_BrushCreateSolid( element.Color1 )
pPen := Gdip_CreatePen( element.Color2 , element.Thickness * scale )
sv := Vector( element.StartVector )
sv.Mult( scale )
shape := Vector.PolygonShape( sv , element.Radius * scale , element.Sides , element.StartAngle )
shape .= "|" StrSplit( shape , "|" )[2]
Gdip_DrawLines( pGraphics , pPen , shape )
Gdip_FillPolygon( pGraphics , pBrush , shape )
Gdip_DeletePen( pPen )
Gdip_DeleteBrush( pBrush )
element := Elements[ 9 ]
pBrush := Gdip_BrushCreateSolid( element.Color1 )
pPen := Gdip_CreatePen( element.Color2 , element.Thickness * scale )
sv := Vector( element.StartVector )
sv.Mult( scale )
shape := Vector.PolygonShape( sv , element.Radius * scale , element.Sides , element.StartAngle )
shape .= "|" StrSplit( shape , "|" )[2]
Gdip_DrawLines( pGraphics , pPen , shape )
Gdip_FillPolygon( pGraphics , pBrush , shape )
Gdip_DeletePen( pPen )
Gdip_DeleteBrush( pBrush )
element := Elements[ 10 ]
pBrush := Gdip_BrushCreateSolid( element.Color1 )
pPen := Gdip_CreatePen( element.Color2 , element.Thickness * scale )
sv := Vector( element.StartVector )
sv.Mult( scale )
shape := Vector.PolygonShape( sv , element.Radius * scale , element.Sides , element.StartAngle )
shape .= "|" StrSplit( shape , "|" )[2]
Gdip_DrawLines( pGraphics , pPen , shape )
Gdip_FillPolygon( pGraphics , pBrush , shape )
Gdip_DeletePen( pPen )
Gdip_DeleteBrush( pBrush )
element := Elements[ 11 ]
pBrush := Gdip_BrushCreateSolid( element.Color1 )
pPen := Gdip_CreatePen( element.Color2 , element.Thickness * scale )
sv := Vector( element.StartVector )
sv.Mult( scale )
shape := Vector.PolygonShape( sv , element.Radius * scale , element.Sides , element.StartAngle )
shape .= "|" StrSplit( shape , "|" )[2]
Gdip_DrawLines( pGraphics , pPen , shape )
Gdip_FillPolygon( pGraphics , pBrush , shape )
Gdip_DeletePen( pPen )
Gdip_DeleteBrush( pBrush )
element := Elements[ 12 ]
pBrush := Gdip_BrushCreateSolid( element.Color1 )
pPen := Gdip_CreatePen( element.Color2 , element.Thickness * scale )
sv := Vector( element.StartVector )
sv.Mult( scale )
shape := Vector.PolygonShape( sv , element.Radius * scale , element.Sides , element.StartAngle )
shape .= "|" StrSplit( shape , "|" )[2]
Gdip_DrawLines( pGraphics , pPen , shape )
Gdip_FillPolygon( pGraphics , pBrush , shape )
Gdip_DeletePen( pPen )
Gdip_DeleteBrush( pBrush )
Gdip_DeleteGraphics( pGraphics )
if( returnType = "hBitmap" ){
hBitmap := Gdip_CreateHBITMAPFromBitmap( pBitmap )
Gdip_DisposeImage( pBitmap )
return hBitmap
}
return pBitmap
}
;******************************************************************************************************
;******************************************************************************************************
;******************************************************************************************************
CursorElements(){
local Elements2 := []
Elements2.Push( { Index: 1 , Layer: 1 , ElementType: "DrawArc" , Rect: { X: 2 + 0 , Y: 2 + 0 , W: 26 , H: 26 } , StartAngle: "0" , SweepAngle: "360" , Thickness: "2" , Note: "" , BrushObject: { BrushType: "SolidBrush" , Color1: "0xFFFF0000" } } )
Elements2.Push( { Index: 2 , Layer: 1 , ElementType: "DrawArc" , Rect: { X: 4 + 0 , Y: 4 + 0 , W: 22 , H: 22 } , StartAngle: "0" , SweepAngle: "360" , Thickness: "2.5" , Note: "" , BrushObject: { BrushType: "SolidBrush" , Color1: "0xFF000000" } } )
Elements2.Push( { Index: 3 , Layer: 1 , ElementType: "DrawArc" , Rect: { X: 6 + 0 , Y: 6 + 0 , W: 18 , H: 18 } , StartAngle: "0" , SweepAngle: "360" , Thickness: "2" , Note: "" , BrushObject: { BrushType: "SolidBrush" , Color1: "0xFFFF0000" } } )
return Elements2
}
;******************************************************************************************************
CursorFunction( Elements2 , Scale := 1 , returnType := "pBitmap" ){
local pBitmap := Gdip_CreateBitmap( 30 * Scale , 30 * Scale )
local pGraphics := Gdip_GraphicsFromImage( pBitmap )
;Layer: 1
Gdip_SetSmoothingMode( pGraphics , 2 ) , Gdip_SetInterpolationMode( pGraphics , 7 )
element := Elements2[ 1 ] , Brush := element.BrushObject
pPen := Gdip_CreatePen( Brush.Color1 , element.Thickness * scale )
Gdip_DrawArc( pGraphics , pPen , ( element.Rect.X ) * scale , ( element.Rect.Y ) * scale , ( element.Rect.W ) * scale , ( element.Rect.H ) * scale , element.StartAngle , element.SweepAngle )
Gdip_DeletePen( pPen )
element := Elements2[ 2 ] , Brush := element.BrushObject
pPen := Gdip_CreatePen( Brush.Color1 , element.Thickness * scale )
Gdip_DrawArc( pGraphics , pPen , ( element.Rect.X ) * scale , ( element.Rect.Y ) * scale , ( element.Rect.W ) * scale , ( element.Rect.H ) * scale , element.StartAngle , element.SweepAngle )
Gdip_DeletePen( pPen )
element := Elements2[ 3 ] , Brush := element.BrushObject
pPen := Gdip_CreatePen( Brush.Color1 , element.Thickness * scale )
Gdip_DrawArc( pGraphics , pPen , ( element.Rect.X ) * scale , ( element.Rect.Y ) * scale , ( element.Rect.W ) * scale , ( element.Rect.H ) * scale , element.StartAngle , element.SweepAngle )
Gdip_DeletePen( pPen )
Gdip_DeleteGraphics( pGraphics )
if( returnType = "hBitmap" ){
hBitmap := Gdip_CreateHBITMAPFromBitmap( pBitmap )
Gdip_DisposeImage( pBitmap )
return hBitmap
}
return pBitmap
}
;******************************************************************************************************
global lastSection := 0 ; Не нужно это трогать
global snapEnabled := false ; Флаг для включения / выключения примагничивания
global snapStrength := 0.05 ; Сила притяжения (0.0 - нет, 1.0 - моментальное прилипание)
global cursorPositionEnabled := false ; Флаг для появления GUI относительно курсора
F1::
{
SystemCursor("Hide")
MouseGetPos(&startX, &startY)
if (cursorPositionEnabled) {
; Позиция GUI относительно курсора
guiX := startX - 200
guiY := startY - 200
Gui1.Show("x" guiX " y" guiY " w400 h400")
} else {
Gui1.Show("w400 h400")
}
;DllCall("ShowCursor", "int", 0)
Gui1.Show("w400 h400")
WinGetPos(&guiX, &guiY, , , Gui1)
MouseMove(guiX + 199, guiY + 199, 0)
SetTimer(RestrictCursor, 1)
KeyWait("F1")
SetTimer(RestrictCursor, 0)
Gui1.Hide()
SystemCursor("Show")
;DllCall("ShowCursor", "int", 1)
SystemCursor(cmd) {
static visible := true, c := Map()
static sys_cursors := [32512, 32513, 32514, 32515, 32516, 32642
, 32643, 32644, 32645, 32646, 32648, 32649, 32650]
if (cmd = "Reload" or !c.Count) {
for i, id in sys_cursors {
h_cursor := DllCall("LoadCursor", "Ptr", 0, "Ptr", id)
h_default := DllCall("CopyImage", "Ptr", h_cursor, "UInt", 2
, "Int", 0, "Int", 0, "UInt", 0)
h_blank := DllCall("CreateCursor", "Ptr", 0, "Int", 0, "Int", 0
, "Int", 32, "Int", 32
, "Ptr", Buffer(32*4, 0xFF)
, "Ptr", Buffer(32*4, 0))
c[id] := {default: h_default, blank: h_blank}
}
}
switch cmd {
case "Show": visible := true
case "Hide": visible := false
case "Toggle": visible := !visible
default: return
}
for id, handles in c {
h_cursor := DllCall("CopyImage"
, "Ptr", visible ? handles.default : handles.blank
, "UInt", 2, "Int", 0, "Int", 0, "UInt", 0)
DllCall("SetSystemCursor", "Ptr", h_cursor, "UInt", id)
}
}
MouseGetPos(&x, &y)
x -= guiX
y -= guiY
centerX := 200
centerY := 200
radius := 76
edgeThreshold := 60
dist := Sqrt((x - centerX)**2 + (y - centerY)**2)
if (dist >= edgeThreshold) {
angle := ATan2(x - centerX, y - centerY)
section := Floor(angle / 45) + 1
switch section {
Case 1: Run "calc.exe" ; Sector 1 (0° - 45°) + 22.5
Case 2: MsgBox "Sector 2 (45°-90°)" "`nDist: " dist "`nAngle: " angle ; Sector 2 (45° - 90°) + 22.5
Case 3: MsgBox "Sector 3 (90°-135°)" "`nDist: " dist "`nAngle: " angle ; Sector 3 (90° - 135°) + 22.5
Case 4: MsgBox "Sector 4 (135°-180°)" "`nDist: " dist "`nAngle: " angle ; Sector 4 (135° - 180°) + 22.5
Case 5: MsgBox "Sector 5 (180°-225°)" "`nDist: " dist "`nAngle: " angle ; Sector 5 (180° - 225°) + 22.5
Case 6: MsgBox "Sector 6 (225°-270°)" "`nDist: " dist "`nAngle: " angle ; Sector 6 (225° - 270°) + 22.5
Case 7: MsgBox "Sector 7 (270°-315°)" "`nDist: " dist "`nAngle: " angle ; Sector 7 (270° - 315°) + 22.5
Case 8: MsgBox "Sector 8 (315°-360°)" "`nDist: " dist "`nAngle: " angle ; Sector 8 (315° - 360°) + 22.5
}
}
MouseMove(startX, startY, 0)
}
RestrictCursor() {
MouseGetPos(&x, &y)
WinGetPos(&guiX, &guiY, , , Gui1)
relX := x - guiX
relY := y - guiY
centerX := 200
centerY := 200
radius := 76
if ((relX - centerX)**2 + (relY - centerY)**2 > radius**2) {
dx := relX - centerX
dy := relY - centerY
dist := Sqrt(dx**2 + dy**2)
if (dist > radius) {
relX := centerX + dx * radius / dist
relY := centerY + dy * radius / dist
MouseMove(relX + guiX, relY + guiY, 0)
}
}
; Логика примагничивания
edgeThreshold := 64
dist := Sqrt((relX - centerX)**2 + (relY - centerY)**2)
if (snapEnabled && dist >= edgeThreshold) {
angle := ATan2(relX - centerX, relY - centerY)
section := Floor(angle / 45) + 1
if (section >= 1 && section <= 8) {
targetAngle := (section - 1) * 45
targetRad := targetAngle * 0.0174532925 ; Градусы в радианы (π/180)
targetX := centerX + Cos(targetRad) * radius
targetY := centerY + Sin(targetRad) * radius
; Интерполяция текущей позиции к целевой
relX := relX + (targetX - relX) * snapStrength
relY := relY + (targetY - relY) * snapStrength
MouseMove(relX + guiX, relY + guiY, 0)
}
}
Gui1.Pic1.Move(relX - 14, relY - 14)
;Cursorpic.Move(relX - 10, relY - 10)
edgeThreshold := 60
dist := Sqrt((relX - centerX)**2 + (relY - centerY)**2)
Loop 8 {
Gui1.Elements[A_Index + 4].Color1 := "0xFFFA7878"
Gui1.Elements[A_Index + 4].Color2 := "0xFF373737"
Gui1.Elements[A_Index + 4].Radius := 12
}
global currentSection := 0
if (dist >= edgeThreshold) {
angle := ATan2(relX - centerX, relY - centerY)
currentSection := Floor(angle / 45) + 1
if (currentSection >= 1 && currentSection <= 8) {
switch currentSection {
Case 1: Gui1.Elements[5].Color1 := "0xffff0000"
Gui1.Elements[5].Color2 := "0xff000000"
Gui1.Elements[5].Radius := 16
Case 2: Gui1.Elements[6].Color1 := "0xffff0000"
Gui1.Elements[6].Color2 := "0xff000000"
Gui1.Elements[6].Radius := 16
Case 3: Gui1.Elements[7].Color1 := "0xffff0000"
Gui1.Elements[7].Color2 := "0xff000000"
Gui1.Elements[7].Radius := 16
Case 4: Gui1.Elements[8].Color1 := "0xffff0000"
Gui1.Elements[8].Color2 := "0xff000000"
Gui1.Elements[8].Radius := 16
Case 5: Gui1.Elements[9].Color1 := "0xffff0000"
Gui1.Elements[9].Color2 := "0xff000000"
Gui1.Elements[9].Radius := 16
Case 6: Gui1.Elements[10].Color1 := "0xffff0000"
Gui1.Elements[10].Color2 := "0xff000000"
Gui1.Elements[10].Radius := 16
Case 7: Gui1.Elements[11].Color1 := "0xffff0000"
Gui1.Elements[11].Color2 := "0xff000000"
Gui1.Elements[11].Radius := 16
Case 8: Gui1.Elements[12].Color1 := "0xffff0000"
Gui1.Elements[12].Color2 := "0xff000000"
Gui1.Elements[12].Radius := 16
}
}
}
global lastSection
if (currentSection != lastSection) {
Sleep 1
Gui1.Pic2.Value := "hBitmap: " OwerlayFunction(Gui1.Elements ,, "hBitmap")
lastSection := currentSection
}
}
ATan2(x, y) {
Static Rad2Deg := 45/ATan(1)
A := DllCall("msvcrt\atan2", "Double", y, "Double", x, "CDECL Double") * Rad2Deg
A := A + 22.5
return A < 0 ? A + 360 : A
}