Tornar o cursor invisível/visível Topic is solved

Tire suas dúvidas sobre programação em AutoHotkey

Moderator: Gio

LuanMts
Posts: 18
Joined: 24 May 2020, 00:36

Tornar o cursor invisível/visível

05 Jun 2020, 15:12

Boa tarde,

Gostaria que quando eu apertar "a" o cursor fique invisível e clique no centro da tela, e quando "a" for clicado novamente o cursor aparece solto no centro da tela.

Fico no aguardo e agradeço a ajuda do fórum!
Last edited by BoBo on 05 Jun 2020, 16:04, edited 1 time in total.
Reason: Moved to Português forum section.
User avatar
Gio
Posts: 1058
Joined: 30 Sep 2013, 10:54
Location: Brazil

Re: Tornar o cursor invisível/visível  Topic is solved

08 Jun 2020, 10:49

Bom dia LuanMts.

O assunto dos cursores é mais complexo do que se imaginaria olhando pelo lado do usuário.

1. Introdução aos cursores, e explicação de como esconder o cursor

O cursor (mouse) é uma funcionalidade do Windows e seu uso (e acessos pelos programas) são gerenciados pelo Sistema Operacional. Essa gerência funciona basicamente através de duas "instâncias de acesso": A primeira é um acesso especial que os programas têm e que se limita às janelas que eles criarem. Com esse acesso, é extremamente simples esconder o mouse, porém, esse efeito será limitado às janelas do seu programa (ou seja, não será possível usar esse acesso para interferir em janelas de outros programas).

Exemplo:

No código abaiaxo, ao apertar F2, você esconde o mouse na janela do seu programa. Ao apertar F3, ele volta a ficar visível na janela do seu programa (aperte F2, mova o mouse em cima da janela, depois apertar F3 e mova em cima da janela também. Você logo vai perceber o efeito).

Code: Select all

Gui, show, w400 h300

F2::
DllCall("ShowCursor", "Uint", 0)
return

F3::
DllCall("ShowCursor", "Uint", 1)
Return

:arrow: A segunda instância de acesso é a instância do sistema (cursor do sistema). Esta instância de acesso também pode ser acessada pelos programas, mas não funciona da mesma forma que o outro acesso: Aqui não existe uma função "esconder cursor". Vou te explicar o porquê:

Pense o seguinte: O windows foi construído em cima do princípio TTP (trust the programmer, ou "confie no programador"). Isso é ótimo para nós programadores, porque significa que o sistema operacional tenta sempre maximizar as nossas possibilidades de programar do jeito que quisermos.

No entanto, esse princípio precisa ser implementado com sabedoria, pois se você simplesmente tornar os programas "onipotentes", um programa poderá implementar algo que destrua a previsibilidade de outro programa literalmente "sem querer". Então a forma como o Windows encontrou de deixar os programas controlarem os cursores do jeito que quisessem sem que nenhum programador perdesse facilmente a previsibilidade dos efeitos do seu código sobre outros programas foi a seguinte: todos os programas podem desenhar seus próprios cursores e também podem trocar os cursores do sistema por esses que desenharam.

Então se um programa usa o cursor padrão do sistema, você pode trocar esse cursor padrão por um desenho 100% transparente, escondendo totalmente o cursor sem sequer conhecer o programa alvo. Mas se o programa escolher desenhar o próprio cursor, a coisa muda de figura: seu programa vai precisar saber qual o "código" do novo cursor criado para então substituir o desenho dele por um desenho transparente, forçando você a programar com os alvos sempre em mente. É assim que o Windows garante que você não faça algo destrutivo para outros programas "sem querer".

Exemplo:
No código abaixo, de autoria do usuário Empardopo (publicado aqui), implementa-se a ideia de esconder os principais cursores do sistema trocando-os por imagens transparentes. Veja que isso não vai apagar todos os cursores em todos os programas: alguns programas ainda exibirão cursores em alguns casos.

Rode o código abaixo e aperte F2 para esconder os cursores padrões do sistema e depois F3 para reexibilos. OBS: neste código exemplo você só pode reexibir os cursores na mesma instância que escondeu eles (então não finalize a aplicação com F2 apertado !!). Isso ocorre porque os cursores anteriores são salvos em variáveis (portanto, se você quiser, reescreva o código implementando uma rotina de salvamento dos cursores em arquivos para fazer com que o código rode entre duas instâncias):

Code: Select all

F2::
SystemCursor(0)
return

F3::
SystemCursor(1)
Return


SystemCursor(OnOff=1)   ; INIT = "I","Init"; OFF = 0,"Off"; TOGGLE = -1,"T","Toggle"; ON = others
{
    static AndMask, XorMask, $, h_cursor
        ,c0,c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13 ; system cursors
        , b1,b2,b3,b4,b5,b6,b7,b8,b9,b10,b11,b12,b13   ; blank cursors
        , h1,h2,h3,h4,h5,h6,h7,h8,h9,h10,h11,h12,h13   ; handles of default cursors
    if (OnOff = "Init" or OnOff = "I" or $ = "")       ; init when requested or at first call
    {
        $ = h                                          ; active default cursors
        VarSetCapacity( h_cursor,4444, 1 )
        VarSetCapacity( AndMask, 32*4, 0xFF )
        VarSetCapacity( XorMask, 32*4, 0 )
        system_cursors = 32512,32513,32514,32515,32516,32642,32643,32644,32645,32646,32648,32649,32650
        StringSplit c, system_cursors, `,
        Loop %c0%
        {
            h_cursor   := DllCall( "LoadCursor", "Ptr",0, "Ptr",c%A_Index% )
            h%A_Index% := DllCall( "CopyImage", "Ptr",h_cursor, "UInt",2, "Int",0, "Int",0, "UInt",0 )
            b%A_Index% := DllCall( "CreateCursor", "Ptr",0, "Int",0, "Int",0
                , "Int",32, "Int",32, "Ptr",&AndMask, "Ptr",&XorMask )
        }
    }
    if (OnOff = 0 or OnOff = "Off" or $ = "h" and (OnOff < 0 or OnOff = "Toggle" or OnOff = "T"))
        $ = b  ; use blank cursors
    else
        $ = h  ; use the saved cursors

    Loop %c0%
    {
        h_cursor := DllCall( "CopyImage", "Ptr",%$%%A_Index%, "UInt",2, "Int",0, "Int",0, "UInt",0 )
        DllCall( "SetSystemCursor", "Ptr",h_cursor, "UInt",c%A_Index% )
    }
}


:arrow: OBS: É claro que isso que eu disse sobre as instâncias dos cursores é um pouco relativo também. Em último caso essas regras não limitam nada totalmente, pois em última instância as possibilidades do programador no Windows são tantas que você poderia até hacker o sistema operacional para destruir por completo o cursor. Mas eu acho que essas duas instâncias têm a sua razão de ser e não recomendo a você seguir essa via.


2. Outras ações com o cursor

Agora que já explicamos como funciona o cursor, vamos às outras possibilidades que você perguntou:

2.1 Para bloquear o movimento do mouse use o comando BlockInput (BlockInput, MouseMove para bloquear e depois BlockInput, MouseMoveOff para desbloquear).

2.2 Para mover o mouse, usa o comando MouseMove.

2.3 Para clicar em algum lugar, use o comando Click.

2.4 Para restringir o mouse a uma área da tela, use a função nativa do windows ClipCursor.
Exemplo:

Code: Select all

F2::
RectangleStructure := ""
VarSetCapacity(RectangleStructure, 16, 0)  ; PRIMEIRO, NÓS CRIAMOS UMA ARRAY DE 4 INTEGERS.

; Depois, colocamos os valores.
NumPut(200, RectangleStructure, 0) ; Coordenada X do ponto superior-esquerdo da área de contenção do mouse.
NumPut(200, RectangleStructure, 4) ;Coordenada Y do ponto superior-esquerdo da área de contenção do mouse.
Numput(300, RectangleStructure, 8) ; Coordenada X do ponto inferior-direito da área de contenção do mouse.
NumPut(300, RectangleStructure, 12) ; Coordenada Y do ponto inferior-direito da área de contenção do mouse.
DllCall("ClipCursor", "Uint", &RectangleStructure)
return


F3::
DllCall("ClipCursor", "Uint", "NULL") ; By the press of F3, we call the ClipCursor function while passing a null pointer. This will "free" our mouse.
Return
Com esses outros comandos explicados você deve conseguir fazer o que descreveu.

Mais informações sobre cursores do windows e funções disponíveis: https://docs.microsoft.com/en-us/windows/win32/menurc/cursors

Se ainda tiver alguma dúvida sobre algum desses códigos ou sobre o assunto, basta postar abaixo.
LuanMts
Posts: 18
Joined: 24 May 2020, 00:36

Re: Tornar o cursor invisível/visível

28 Jun 2020, 11:54

Muito obrigado, Gio! Ótima explicação sobre essas ferramentas. Fiquei realmente surpreso quando soube que realmente tem como restringir a área do cursor. Esse tópico me ajudou e vai continuar me ajudando. Muito grato! :)
LuanMts
Posts: 18
Joined: 24 May 2020, 00:36

Re: Tornar o cursor invisível/visível

18 Sep 2020, 23:33

Gio, só mais uma coisa... tem alguma forma de restringir o mouse a toda a tela exceto a um retângulo nela?
Agradeço muito a sua atenção! :)
User avatar
Gio
Posts: 1058
Joined: 30 Sep 2013, 10:54
Location: Brazil

Re: Tornar o cursor invisível/visível

23 Sep 2020, 17:21

Boa tarde LuanMTS.

Esta pergunta é praticamente a mesma deste tópico (A primeira solução proposta será a mesma também).

Return to “Ajuda e Suporte Geral”

Who is online

Users browsing this forum: No registered users and 5 guests