Tornar o cursor invisível/visível

Post a reply


In an effort to prevent automatic submissions, we require that you complete the following challenge.
Smilies
:D :) ;) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :!: :?: :idea: :| :mrgreen: :geek: :ugeek: :arrow: :angel: :clap: :crazy: :eh: :lolno: :problem: :shh: :shifty: :sick: :silent: :think: :thumbup: :thumbdown: :salute: :wave: :wtf: :yawn: :facepalm: :bravo: :dance: :beard: :morebeard: :xmas: :HeHe: :trollface: :cookie: :rainbow: :monkeysee: :monkeysay: :happybday: :headwall: :offtopic: :superhappy: :terms: :beer:
View more smilies

BBCode is ON
[img] is OFF
[flash] is OFF
[url] is ON
Smilies are ON

Topic review
   

Expand view Topic review: Tornar o cursor invisível/visível

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

Post by Gio » 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).

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

Post by LuanMts » 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! :)

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

Post by LuanMts » 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! :)

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

Post by Gio » 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.

Tornar o cursor invisível/visível

Post by LuanMts » 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!

Top