Dicas de Delphi - Teclado e Mouse
Programar teclas de atalho do WindowsInclua 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 Ocultar/exibir o cursor do mouseInclua 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 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 Simular o pressionamento de uma teclaInclua 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 Ligar/desligar a tecla Caps LockInclua 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 Verificar se uma determinada tecla está pressionadaInclua 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 Verificar o estado de NumLock e CapsLockInclua 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 Simular um CharCase no DBGridPara 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 Determinar se o cursor do mouse está em determinado controleInclua 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 Inverter os botões do mouseInclua na seção uses: Windows
{ Para inverter: }
SwapMouseButton(true);
{ Para voltar ao normal: }
SwapMouseButton(false);Autor: Daniel P. Guimarães Obter/definir o tempo máximo do duplo-click do mouseInclua 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 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 Limitar a região de movimentação do mouseInclua 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 Posicionar o cursor do mouse em um controleInclua 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 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 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 Página atualizada em 23 de janeiro de 2012 |