Dicas de Delphi - Teclado e Mouse


Programar teclas de atalho do Windows

Inclua na seção uses: Windows, Dialogs
Problema:

Gostaria de programar algumas teclas de atalho para chamar,
por exemplo, uma calculadora, quando meu aplicativo estiver
aberto. Como fazer?

Solução:

- No evento OnCreate do form coloque o código abaixo:

procedure TForm1.FormCreate(Sender: TObject);
begin
  if not RegisterHotkey(Handle, 1, MOD_CONTROL or MOD_ALT, VK_F11) then
    ShowMessage('Erro ao programar Ctrl+Alt+F11');

  if not RegisterHotkey(Handle, 2, MOD_CONTROL or MOD_ALT, VK_F12) then
    ShowMessage('Erro ao programar Ctrl+Alt+F12');
end;

- No evento OnDestroy do form coloque o código abaixo:

procedure TForm1.FormDestroy(Sender: TObject);
begin
  UnRegisterHotkey(Handle, 1);
  UnRegisterHotkey(Handle, 2);
end;

- Declere a procedure abaixo na seção private:

  private
    procedure WMHotkey(var Msg: TWMHotkey); message WM_HOTKEY;

- Abaixo da palavra implementation escreva a procedure:

procedure TForm1.WMHotkey(var Msg: TWMHotkey);
begin
  case Msg.HotKey of
    1: WinExec('calc.exe', SW_SHOW);
    2: ShowMessage('Ctrl+Alt+F12 foram pressionadas');
  end;
end;

- Execute este programa e experimente pressionar Ctrl+Alt+F11
  ou Ctrl+Alt+F12.

Observações

Se a combinação de teclas já estiver em uso (num atalho, por exemplo), não será possível usá-la em nossa aplicação. Existem outras formas de implementar teclas de atalho em programas escritos em Delphi, mas a forma apresentada é bastante funcional.

Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br

Início


Ocultar/exibir o cursor do mouse

Inclua na seção uses: Windows
- Escreva a função abaixo:

function MouseShowCursor(const Show: boolean): boolean;
var
  I: integer;
begin
  I := ShowCursor(LongBool(true));
  if Show then begin
    Result := I >= 0;
    while I < 0 do begin
      Result := ShowCursor(LongBool(true)) >= 0;
      Inc(I);
    end;
  end else begin
    Result := I < 0;
    while I >= 0 do begin
      Result := ShowCursor(LongBool(false)) < 0;
      Dec(I);
    end;
  end;
end;

- Exemplos de uso:

MouseShowCursor(false); { Oculta o cursor }

MouseShowCursor(true); { Exibe o cursor }

Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br

Início


Simular o pressionamento de uma combinação de teclas (ex: Ctrl+F2)

Inclua na seção uses: Windows
{ Mantém pressionada CTRL }
keybd_event(VK_CONTROL, 0, KEYEVENTF_EXTENDEDKEY or 0, 0);

{ Pressiona F2 }
keybd_event(VK_F2, 0, 0, 0);

{ Libera (solta) CTRL }
keybd_event(VK_CONTROL, $45, KEYEVENTF_EXTENDEDKEY or KEYEVENTF_KEYUP, 0);

Observações

Neste exemplo pressionamos Ctrl+F2. Não se esqueça das teclas que precisam manter pressionadas: Ctrl, Alt, Shift.

Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br

Início


Simular o pressionamento de uma tecla

Inclua na seção uses: Windows
A API keybd_event do Windows serve para fazer isto. No exemplo
abaixo estamos simulando o pressionamento da tecla F2:

keybd_event(VK_F2, 0, 0, 0);

Para testar faça o exemplo a seguir:

- Mude a propriedade KeyPreview do form para true.
- Escreva no evento OnKeyDown do form como abaixo:

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if Key = VK_F2 then
    ShowMessage('F2 pressionada');
end;

- Coloque um botão e escreva no OnClick (do botão) como abaixo:

procedure TForm1.Button1Click(Sender: TObject);
begin
  keybd_event(VK_F2, 0, 0, 0);
end;

Observações

Consulte as constantes para os códigos das teclas (ex: VK_RETURN, VK_DOWN, etc).

Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br

Início


Ligar/desligar a tecla Caps Lock

Inclua na seção uses: Windows
{ Esta função liga/desliga Caps Lock, conforme o parãmetro
  State }

procedure tbSetCapsLock(State: boolean);
begin
  if (State and ((GetKeyState(VK_CAPITAL) and 1) = 0)) or
     ((not State) and ((GetKeyState(VK_CAPITAL) and 1) = 1)) then
  begin
    keybd_event(VK_CAPITAL, $45, KEYEVENTF_EXTENDEDKEY or 0, 0);
    keybd_event(VK_CAPITAL, $45, KEYEVENTF_EXTENDEDKEY or KEYEVENTF_KEYUP, 0);
  end;
end;

{ Exemplos de uso: }

tbSetCapsLock(true); { Liga Caps Lock }

tbSetCapsLock(false); { Desliga Caps Lock }

Observações

Aparentemente, podemos usar esta mesma técnica para ligar/desligar Num Lock. Neste caso trocaríamos VK_CAPITAL por VK_NUMLOCK. Por incrível que pareça não funcionou (pelo menos no teste que fiz). E tem mais: isto está na documentação do (R)Windows.

Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br

Início


Verificar se uma determinada tecla está pressionada

Inclua na seção uses: Windows
{ Esta função retorna true se a tecla informada
  estiver pressionada. False em caso contrário. }

function tbKeyIsDown(const Key: integer): boolean;
begin
  Result := GetKeyState(Key) and 128 > 0;
end;

{ Exemplos de uso: }

if tbKeyIsDown(VK_CONTROL) then
  { Tecla Ctrl pressionada }

if tbKeyIsDown(VK_MENU) then
  { Tecla Alt pressionada }

if tbKeyIsDown(VK_SHIFT) then
  { Tecla Shift pressionada }

if tbKeyIsDown(VK_F2) then
  { Tecla F2 pressionada }

Observações

Qualquer tecla pode ser verificada. Para isto basta saber o código virtual (Virtual Key Code) da tecla.

Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br

Início


Verificar o estado de NumLock e CapsLock

Inclua na seção uses: Windows
{ Esta função retorna true se a tecla informada estiver
  ligada. False em caso contrário }

function tbKeyIsOn(const Key: integer): boolean;
begin
  Result := GetKeyState(Key) and 1 > 0;
end;

{ Exemplo de uso: }

if tbKeyIsOn(VK_NUMLOCK) then
  { ... NumLock está ligada }
else
  { ... NumLock está desligada }

Observações

Qualquer tecla que possua os estados On/Off pode ser verificada. Basta, para isto, saber seu código. O código de CapsLock é VK_CAPITAL.

Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br

Início


Simular um CharCase no DBGrid

Para converter a digitação para maiúsculo, coloque isto no
evento OnKeyPress do DBGrid:

Key := AnsiUpperCase(Key)[1];

Para converter para minúsculo, troque por:

Key := AnsiLowerCase(Key)[1];

Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br

Início


Determinar se o cursor do mouse está em determinado controle

Inclua na seção uses: Windows
{ Os exemplos abaixo verificam se o cursor do mouse está em
  Button1: }

{ Solução 1: }
var
  Pt: TPoint;
  Rct: TRect;
begin
  GetCursorPos(Pt);
  GetWindowRect(Button1.Handle, Rct);
  if PtInRect(Rct, Pt) then
    { Está no botão }
  else
    { NÃO está no botão }
end;

{ Solução 2: }
var
  Pt: TPoint;
begin
  GetCursorPos(Pt);
  if WindowFromPoint(Pt) = Button1.Handle then
    { Está no botão }
  else
    { Não está no botão }
end;

Observações

A API GetWindowRect obtém o retângulo (TRect) ocupado por uma janela. Podemos usar GetClientRect para obter o somente da parte cliente da janela. Podemos também usar a propriedade BoundsRect que existe na maioria dos componentes visuais, ou mesmo informar qualquer outro retângulo da tela. Se usarmos a propriedade BoundsRect, precisaremos converter as coordenadas clientes para coordenadas de tela (com a função ClientToScreen). Um lembrete: a solução 2 só poderá ser aplicada a controles ajanelados.

Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br

Início


Inverter os botões do mouse

Inclua na seção uses: Windows
{ Para inverter: }
SwapMouseButton(true);

{ Para voltar ao normal: }
SwapMouseButton(false);

Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br

Início


Obter/definir o tempo máximo do duplo-click do mouse

Inclua na seção uses: Windows
{ - Coloque um botão no form e escreva seu OnClick como
    abaixo: }

procedure TForm1.Button6Click(Sender: TObject);
var
  Tempo: Cardinal;
begin
  { Obtém }
  Tempo := GetDoubleClickTime;
  ShowMessage(IntToStr(Tempo) + ' milisegundos');

  { Define }
  SetDoubleClickTime(300);
end;

Observações

Um duplo-click nada mais é que dois cliques consecutivos (óbvio). Porém estes dois cliques podem ser interpretados de duas formas: dois cliques isolados ou um duplo-click. Para o Windows resolver esta situação, ele usa o que chamo de "tempo máximo do duplo-click". Se o intervalo entre o primeiro e o segundo click for menor ou igual a esse tempo, então houve duplo-click. E você pode alterar este tempo. O padrão do Windows é 500 milisegundos. Um tempo muito curto (ex: 100), faz com que o duplo-click tenha que ser muito rápido (quase impossível), enquanto muito longo (ex: 2000) faz com que o Windows interprete dois clicks isolados como duplo-click.

Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br

Início


Descobrir o código ASCII de uma tecla

{ - Coloque um Label no form (Label1);
  - Mude a propriedade KeyPreview do form para true;
  - Altere o evento OnKeyDown do form como abaixo: }

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  Label1.Caption :=
    Format('O código da tecla pressionada é: %d', [Key]);
end;

Observações

Para testar execute e observe o Label enquanto pressiona as teclas desejadas.

Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br

Início


Limitar a região de movimentação do mouse

Inclua na seção uses: Windows
{ Coloque um botão no form e altera o evento OnClick dele
  conforme abaixo: }

procedure TForm1.Button1Click(Sender: TObject);
var
  R: TRect;
begin
  { Pega o retângulo da área cliente do form }
  R := GetClientRect;
  { Converte as coordenadas do form em coordenadas da tela }
  R.TopLeft := ClientToScreen(R.TopLeft);
  R.BottomRight := ClientToScreen(R.BottomRight);
  { Limita a região de movimentação do mouse }
  ClipCursor(@R);
  ShowMessage('Tente mover o mouse para fora da área cliente do Form');
  { Libera a movimentação }
  ClipCursor(nil);
end;

Observações

Cuidado! Isto pode irritar o usuário do seu programa.

Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br

Início


Posicionar o cursor do mouse em um controle

Inclua na seção uses: Windows
{ Digite a procedure abaixo imediatamente após a palavra
  implementation no código do seu formulário. }

procedure MouseParaControle(Controle: TControl);
var
  IrPara: TPoint;
begin
  IrPara.X := Controle.Left + (Controle.Width div 2);
  IrPara.Y := Controle.Top + (Controle.Height div 2);
  if Controle.Parent <> nil then
    IrPara := Controle.Parent.ClientToScreen(IrPara);
  SetCursorPos(IrPara.X, IrPara.Y);
end;

{ Para testar, coloque no Form um botão e troque o name dele
  para btnOK e modifique o evento OnShow do Form 
  conforme abaixo: }

procedure TForm1.FormShow(Sender: TObject);
begin
  MouseParaControle(btnOk);
end;

Observações

A função "MouseParaControle" recebe um parâmetro do tipo TControl. Isto significa que você poderá passar para ela qualquer controle do Delphi, tais como: TEdit, TButton, TSpeedButton, TPanel, etc. Pode ser até mesmo o próprio Form.

Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br

Início


ENTER em vez de TAB no formulário, no DBGrid e no StringGrid

{ Mude a propriedade "KeyPreview" do Form para true. }

{ No evento "OnKeyPress" do Form acrescente o código abaixo: }

procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);
begin
  if Key = #13 then begin
    Key := #0;
    Perform(WM_NEXTDLGCTL, 1, 0);
  end;
end;

{ Em StringGrid, escreva o evento OnKeyPress como abaixo: }

procedure TForm1.StringGrid1KeyPress(Sender: TObject; var Key: Char);
begin
  if Key = #13 then
    StringGrid1.Perform(WM_KEYDOWN, VK_TAB, 0);
end;

{ Em DBGrid, escreva o evento OnKeyPress como abaixo: }

procedure TForm1.DBGrid1KeyPress(Sender: TObject; var Key: Char);
begin
  if Key = #13 then
    DBGrid1.Perform(WM_KEYDOWN, VK_TAB, 0);
end;

Observações

É bom lembrar que a tecla ENTER no Windows tem seu papel já bem definido quando se trata de caixa de diálogo: executar a ação padrão, normalmente o botão OK. Se não tomar cuidado poderá confundir o usuário, em vez de ajudá-lo.

Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br

Início


Simular a vírgula através do ponto do teclado numérico

{ Na seção "private" do Form principal acrescente: }
procedure AppMsg(var Msg: TMsg; var Handled: Boolean);

{ Na seção "implementation" acrescente (troque TForm1 para
  o nome do seu form principal): }
procedure TForm1.AppMsg(var Msg: TMsg; var Handled: Boolean);
begin
  if Msg.Message = WM_KEYDOWN then
    if Msg.wParam = 110 then
      Msg.wParam := 188;
end;

{ No evento "OnCreate" do form principal, coloque: }
Application.OnMessage := AppMsg;

{ Uma segunda alternativa (José Geraldo - ES):
  Coloque o código abaixo no evento OnKeyPress do componente 
  onde se quer a conversão (Edit, DBEdit, etc). Neste caso
  a conversão funcionará apenas neste componente (óbvio). }

  if Key = '.' then Key = DecimalSeparator;

Observações

Na primeira alternativa, sempre que for pressionado o ponto do teclado numérico (da direita do teclado), este será convertido para vírgula, independentemente do controle que estiver em foco. Já na segunda, o ponto pode ser de qualquer lugar do teclado.

Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br

Início


Página atualizada em 23 de julho de 2014
Todos os direitos reservados
www.tecnobyte.com.br