Dibujar un circulo al pulsar una tecla

Esta sección es para preguntas sobre programación/scripting usando AutoHotkey.

Moderator: Flipeador

Nucleorion
Posts: 50
Joined: 11 Dec 2016, 11:33

Dibujar un circulo al pulsar una tecla

Post by Nucleorion » 13 Oct 2023, 03:08

Hola,

En un juego que para abrir el micro hay que tener la tecla pulsada, tengo un codigo que la mantiene al pulsar y la suelta al volver a pulsar. Para saber cuando la tengo pulsada y cuando no, me gustaria dibujar un circulo en la pantalla. he intentado esto pero ando muy perdido.

Code: Select all

<::
MicOn := !MicOn
if MicOn
{
  Send {< down}
	Gui, Color, 0x00FF00
	gui, +AlwaysOnTop +Owner
	;WinSet, TransColor, FFFFFF
	gui, -Caption
	WinGetPos, X, Y, W, H,
	;Gui, Add, R50, x300 y1000 w50 h50
	Gui, Show, x963 y565 w50 h50
}
else
{
  Send {< up}
	Gui, Destroy
}
Return

sofista
Posts: 650
Joined: 24 Feb 2020, 13:59
Location: Buenos Aires

Re: Dibujar un circulo al pulsar una tecla

Post by sofista » 13 Oct 2023, 08:19

Hola: Esto es lo básico, Gdip para muchas más opciones

Code: Select all

<::
MicOn := !MicOn
d := 50                                ; diámetro, ajustar según necesidad
if MicOn {
	Send {< down}
	Gui, +AlwaysOnTop -Caption +LastFound -SysMenu +ToolWindow -DPIScale
	WinSet, Transparent, 255           ; opaco, disminuir el valor para ver el fondo
	Gui, Color, 0x00FF00
	Gui, Show, w%d% h%d% x963 y565
	WinSet, Region, 0-0 w%d% h%d% E    ; la opción "E" convierte el cuadrado en un círculo
} else {
	Send {< up}
	Gui, Destroy
}
return
Saludos

Nucleorion
Posts: 50
Joined: 11 Dec 2016, 11:33

Re: Dibujar un circulo al pulsar una tecla

Post by Nucleorion » 17 Oct 2023, 03:59

Muchas gracias! y gracias por comentar las lineas de código :D

En modo ventana funciona, pero en pantalla completa pierdo el foco y hace un parpadeo, aunque le mandásemos de nuevo el foco al juego que se ejecuta en pantalla completa habría un parpadeo, y perdería el control sobre el juego por un momento. ¿Hay alguna forma de que lo dibuje sin que pierda el foco la pantalla completa?

sofista
Posts: 650
Joined: 24 Feb 2020, 13:59
Location: Buenos Aires

Re: Dibujar un circulo al pulsar una tecla

Post by sofista » 17 Oct 2023, 11:06

Hola: Tengo buenas y malas noticias. Las malas primero: no conozco modo de evitar la pérdida de foco, aunque, de todos modos, la pérdida dura un instante, al menos en mi portátil. Para mí está bien, y seguro que ha de ser así porque ya no juego a (casi) nada.

Hola: Releí la documentación y vi que se me había pasado lo siguiente: para evitar perder el foco, se agrega a la línea 9 la opción NA —ya que muestra la ventana sin activarla—:

Code: Select all

Gui, Show, w%d% h%d% x963 y565 NA
Las buenas noticias son que es posible eliminar el parpadeo. Con la opción que mencioné en el mensaje anterior: Gdip. Y siguiendo con las buenas noticias, el tutorial 1 de Gdip, Cómo dibujar figuras, te lo deja casi servido.

Para no copiar todo el script, sugiero que hagas estos cambios:

Línea 11: incluye o enlaza la Lib según tu equipo.
Línea 49: Reemplázala por esta:

Code: Select all

pBrush := Gdip_BrushCreateSolid(0xff00ff00)    ; color verde
Línea 53: Reemplázala por esta otra:

Code: Select all

Gdip_FillEllipse(G, pBrush, 963, 565, 50, 50)    ; posición y diámetro del círculo
Líneas 58-66: Borralas, ya que dibujan el rectángulo que ahora no se necesita.

Esto es todo.

Nucleorion
Posts: 50
Joined: 11 Dec 2016, 11:33

Re: Dibujar un circulo al pulsar una tecla

Post by Nucleorion » 18 Oct 2023, 02:42

Tengo que meter todo Gdip.Tutorial.1-Draw.Shapes.ahk dentro del condicionante if MicOn?

sofista
Posts: 650
Joined: 24 Feb 2020, 13:59
Location: Buenos Aires

Re: Dibujar un circulo al pulsar una tecla

Post by sofista » 18 Oct 2023, 19:36

Nucleorion wrote:
18 Oct 2023, 02:42
Tengo que meter todo Gdip.Tutorial.1-Draw.Shapes.ahk dentro del condicionante if MicOn?
En principio no sería conveniente hacer eso, ya que por el toggle hay que usarlo dos veces. No obstante, lo mejor es convertir el tutorial en una función y llamarla cuando se necesita con los parámetros adecuados.

En el ejemplo que sigue eliminé todos los comentarios del tutorial, así la función se ve en su totalidad de un vistazo. Además, agregué un segundo hotkey para salir de GDIp y de la aplicación —cambialo por el que más te guste—:

Code: Select all

; Basado en Gdip Tutorial 1 - Draw.Shapes.ahk

#SingleInstance, Force
#NoEnv
SetBatchLines, -1

#Include <Gdip_all>                        ; actualizar según tu sistema

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

	MicOn := !MicOn
	d := 50                                ; diámetro, ajustar según necesidad
	c := 0xff00ff00                        ; color verde
	x := 963                               ; posición h
	y := 565                               ; posición v
	if MicOn {
		Send {< down}
		MostrarCirculoGDIp(c, x, y, d)
	} else {
		Send {< up}
		MostrarCirculoGDIp(0, 0, 0, 0)
	}
return

w::                                        ; hotkey para salir de GDIp y del script
	Gdip_Shutdown(pToken)
	ExitApp
return

MostrarCirculoGDIp(color, x, y, d) {
	Width := 1400, Height := 1050
	Gui, 1: -Caption +E0x80000 +LastFound +AlwaysOnTop +ToolWindow +OwnDialogs
	Gui, 1: Show, NA
	hwnd1 := WinExist()
	hbm := CreateDIBSection(Width, Height)
	hdc := CreateCompatibleDC()
	obm := SelectObject(hdc, hbm)
	G := Gdip_GraphicsFromHDC(hdc)
	Gdip_SetSmoothingMode(G, 4)
	pBrush := Gdip_BrushCreateSolid(color)                 ; aplica el primer parámetro
	Gdip_FillEllipse(G, pBrush, x, y, d, d)                ; aplica los otros tres parámetros
	Gdip_DeleteBrush(pBrush)
	UpdateLayeredWindow(hwnd1, hdc, 0, 0, Width, Height)
	SelectObject(hdc, obm)
	DeleteObject(hbm)
	DeleteDC(hdc)
	Gdip_DeleteGraphics(G)
	Return
}


Nucleorion
Posts: 50
Joined: 11 Dec 2016, 11:33

Re: Dibujar un circulo al pulsar una tecla

Post by Nucleorion » 19 Oct 2023, 02:29

Funciona, pero al igual que:

Code: Select all

<::
MicOn := !MicOn
d := 50                                ; diámetro, ajustar según necesidad
if MicOn {
	Send {< down}
	Gui, +AlwaysOnTop -Caption +LastFound -SysMenu +ToolWindow -DPIScale
	WinSet, Transparent, 255           ; opaco, disminuir el valor para ver el fondo
	Gui, Color, 0x00FF00
	Gui, Show, w%d% h%d% x963 y565 NA
	WinSet, Region, 0-0 w%d% h%d% E    ; la opción "E" convierte el cuadrado en un círculo
} else {
	Send {< up}
	Gui, Destroy
}
return
se dibuja por detrás de la ventana de juego, no se si abrá alguna manera de se dibuje sobre todas las ventanas como una capa, al igual que hace la interfaz de steam, nvidia, o xbox app.

Quiero agradecerte enormemente Sofista, el tiempo que me estás dedicando. Eres un crack de ahk!!! :D

sofista
Posts: 650
Joined: 24 Feb 2020, 13:59
Location: Buenos Aires

Re: Dibujar un circulo al pulsar una tecla

Post by sofista » 19 Oct 2023, 16:13

Te agradezco la gentileza, pero no es para tanto :)

Como yo no juego, entiendo poco y nada de esta clase de problemas. No obstante, estuve mirando el tema y la respuesta que encontré en el foro es que todavía no hay una solución general para colocar una capa o layer sobre los juegos en pantalla completa, basados en DirectX. Aparentemente, no es un problema de AutoHotkey, sino una limitación de Windows. Breve explicación y enlaces que pueden sugerirte alguna idea.

Otra página para considerar: Tips para compatibilizar AutoHotkey con juegos.

Por último: en el código del post anterior, en vez de destruir y crear la Gui una y otra vez, lo adecuado es ocultarla y mostrarla:

Code: Select all

Gui, Hide    ; en vez de Gui, Destroy
y se sale del script con otro hotkey, por ejemplo:

Code: Select all

Esc::ExitApp
Suerte!

Post Reply

Return to “Pedir Ayuda”