Page 1 of 1

Dibujar un circulo al pulsar una tecla

Posted: 13 Oct 2023, 03:08
by Nucleorion
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

Re: Dibujar un circulo al pulsar una tecla

Posted: 13 Oct 2023, 08:19
by sofista
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

Re: Dibujar un circulo al pulsar una tecla

Posted: 17 Oct 2023, 03:59
by Nucleorion
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?

Re: Dibujar un circulo al pulsar una tecla

Posted: 17 Oct 2023, 11:06
by sofista
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.

Re: Dibujar un circulo al pulsar una tecla

Posted: 18 Oct 2023, 02:42
by Nucleorion
Tengo que meter todo Gdip.Tutorial.1-Draw.Shapes.ahk dentro del condicionante if MicOn?

Re: Dibujar un circulo al pulsar una tecla

Posted: 18 Oct 2023, 19:36
by sofista
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
}


Re: Dibujar un circulo al pulsar una tecla

Posted: 19 Oct 2023, 02:29
by Nucleorion
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

Re: Dibujar un circulo al pulsar una tecla

Posted: 19 Oct 2023, 16:13
by sofista
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!