Avatar billede hlj Nybegynder
18. oktober 2000 - 15:04 Der er 10 kommentarer og
1 løsning

Hvorfor virker det ikke??

Jeg har følgende kode, som kan bruges til at annulere et tastetryk.

Men det virker ikke hvis jeg gerne vil forhindre f.eks shift, ctrl eller menu tasten.

Hvad går der galt ??

implementation

{$R *.DFM}

const id_Alt = 101;

procedure TForm1.WMHotKey (var Msg : TWMHotKey);
begin
  if Msg.HotKey = id_Alt then begin
    ShowMessage(\'- - Got It - -\' + IntToStr(Msg.HotKey));
    Msg.HotKey := 0;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  if RegisterHotKey(Form1.Handle, id_Alt, 0, VK_MENU) = false then begin
    ShowMessage(\'Can not assign hotkey\');
  end;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  UnRegisterHotKey (Form1.Handle, id_Alt);
end;
end.
Avatar billede borrisholt Novice
18. oktober 2000 - 15:14 #1
Jeg kan ikke helt forstå dit spørgsmål, men der er et eller andet helt basalt galt med dit eksempel : WMHotKey() bliver aldrig kaldt ...

At registere en hotkey i windows kan pakkes ind i et komponent således det er nemmere ar bruge. Det kan gøres sådan her:

{------------------------------------------------------------------------------
  Unit    : GlobalHotKey.pas
  Purpose  : System hot key handling
  Status  : Freeware
  Copyright: ©2000 Jens Borrisholt, http://Borrisholt.com
  contact  : Jens@Borrisholt.com
-------------------------------------------------------------------------------

  History:

  Date                By      Comments
  ----                ----    --------
  15 August 2000      JB      Created

}
unit GlobalHotKey;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, menus;

type
  TGlobalHotKey = class(TComponent)
  private
    FEnabled: Boolean;
    FRegistered: Boolean;
    prOldWndProc: TWndMethod;
    FHotkey: TSHortcut;
    FOnHotKeyPressed: TNotifyEvent;
    prWindow: TWinControl;
    procedure RegisterKey;
    procedure UnRegisterKey;
    { Private declarations }
  protected
    { Protected declarations }
    procedure SetEnabled(const Value: Boolean);
    procedure SetHotKey(const Value: TShortcut);
    procedure NewWindowProc(var Message: TMessage);
    procedure Loaded; override;
  public
    { Public declarations }
    constructor Create(aOwner: TComponent); override;
    destructor Destroy; override;
    property Registered: boolean read FRegistered;
  published
    { Published declarations }
    property Enabled: Boolean read FEnabled write SetEnabled default true;
    property Key: TShortcut read FHotkey write SetHotkey;
    property OnHotKey: TNotifyEvent read FOnHotKeyPressed write FOnHotKeyPressed;
  end;

procedure Register;

implementation


{ TGlobalHotKey }

constructor TGlobalHotKey.Create(aOwner: TComponent);
begin
  inherited;
  FEnabled := True;
  FHotKey := 0;
  FRegistered := false;
  if not (csDesigning in ComponentState) then
  begin
    prWindow := TWinControl.CreateParented(GetDesktopWindow);
    prOldWndProc := prWindow.WindowProc;
    prWindow.WindowProc := NewWindowProc;
  end;
end;

destructor TGlobalHotKey.Destroy;
begin
  if not (csDesigning in ComponentState) then
  begin
    UnRegisterKey;
    prWindow.WindowProc := prOldWndProc;
    prWindow.Free;
  end;
  inherited;
end;

procedure TGlobalHotKey.Loaded;
begin
  inherited;
  if (FEnabled) and (not (csDesigning in ComponentState)) then RegisterKey;
end;

procedure TGlobalHotKey.NewWindowProc(var Message: TMessage);
begin
  case Message.Msg of
    WM_HOTKEY:
    begin
      if assigned(FOnHotkeyPressed) then FOnHotKeyPressed(self);
    end;
  end;
  prOldWndProc(Message);
end;

procedure TGlobalHotKey.RegisterKey;
var
  lVKey: word;
  lvShift: TShiftstate;
  lModifier: UINT;
begin
  if not FRegistered then
  begin
    lModifier := 0;
    ShortcutToKey(FHotkey, lvKey, lvShift);
    if ssShift in lvShift  then lModifier := lModifier or MOD_SHIFT;
    if ssAlt in lvShift then lModifier := lModifier or MOD_ALT;
    if ssCtrl in lvShift then lModifier := lModifier or MOD_CONTROL;
    FRegistered := RegisterHotKey(prWindow.Handle, 0, lModifier, LOBYTE(lVKey));
  end;
end;

procedure TGlobalHotKey.SetEnabled(const Value: Boolean);
begin
  FEnabled := Value;
  if FEnabled then RegisterKey else UnregisterKey;
end;

procedure TGlobalHotKey.UnRegisterKey;
begin
  if FRegistered then
  begin
    UnregisterHotKey(prWindow.Handle, 0);
    FRegistered := False;
  end;
end;

procedure TGlobalHotKey.SetHotKey(const Value: TShortcut);
begin
  if Value <> FHotkey then
  begin
    FHotkey := Value;
    if not (csDesigning in ComponentState) then
    begin
        UnRegisterKey;
        if FEnabled then RegisterKey;
    end;
  end;
end;

procedure Register;
begin
  RegisterComponents(\'System\', [TGlobalHotKey]);
end;

end.

Hvis dit problem er at du gerne vil \"spise\" visse taste try i visse situationer skal du bruge et keyboardhook.

jens B
Avatar billede hlj Nybegynder
18. oktober 2000 - 15:20 #2
Her noget af starten af mit program:

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private declarations }
    procedure WMHotKey(var Msg : TWMHotKey); message WM_HOTKEY;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation


Hvor messagen briver \'registreret\'

Jeg kan sagtens fange escape, tab og andre \'normalle\' taster.
Avatar billede hlj Nybegynder
18. oktober 2000 - 15:21 #3
Jeg kigger lige på din komponent.
Avatar billede hlj Nybegynder
18. oktober 2000 - 15:44 #4
Jeg har lige afprøvet din komponent og den virker godt nok som HotKey, men ikke lige som jeg gerne vil have det.

Og ja, jeg er sulten og vil gerne \'spise\' nogle tegn, men har ikke nogen erfaring med keyboardhook.

Er det for normale menesker eller skal man være en supernørd??

Har du evt. et eksempel?
Avatar billede borrisholt Novice
18. oktober 2000 - 15:48 #5
keyboardhook eksemple ja og nej ....

Jeg kan lave et .. hvis du fortæller mig hvad der skal spises ...

Jens B
Avatar billede hlj Nybegynder
18. oktober 2000 - 15:59 #6
Jeg vil gerne have spist menutasten, den der simulerer højre musetast. (VK_MENU)

Det ville være meget lækkert hvis du gad lave sådan et program/eksempel.

Iøvrig en spændende hjemmeside du har, med mange interesante programstumper.
Avatar billede borrisholt Novice
18. oktober 2000 - 16:31 #7
Den tast hedde altsp VK_APPS, VK_MENu er alt tasten .. any way prøv det her :

var
  HookHandle: HHOOK;

function KeyboardHook(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
begin
  if integer(wParam) = VK_APPS then
  begin
    Form1.Caption := \'got you .. Fuck face !!!! (Pardon my frence)\';
    result := 0;
  end
  else
    Result := CallNextHookEx(HookHandle, nCode, wParam, lParam);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  HookHandle :=  SetWindowsHookEx(WH_KEYBOARD, @KeyboardHook, HInstance, 0);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  UnhookWindowsHookEx(HookHandle);
end;

Det er den mindst langhåret løsning jeg kan komme op med ...

Jeg har også laven en komponent suite som klarer ærterne ... Det er ikke ret let tigængelig kode men meget nemt at bruge når først det er instaleret ... Hvis du vil have det så send en mail til jens@borrisholt.com


Jens B
Avatar billede borrisholt Novice
18. oktober 2000 - 16:33 #8
Hvis du have brugt mine komponenter havde det her været nok:

procedure TForm1.KeyboardHook1PostExecute(Hook: THook; var Hookmsg: THookMsg);
begin
  if integer(Hookmsg.wParam) = VK_APPS then
    Caption := intToStr(integer(Hookmsg.wParam));
end;


Jens B
Avatar billede borrisholt Novice
18. oktober 2000 - 16:35 #9
hov for create skulle se sådan her ud :

procedure TForm1.FormCreate(Sender: TObject);
begin
  HookHandle :=  SetWindowsHookEx(WH_KEYBOARD, @KeyboardHook, HInstance, GetCurrentThreadID());
end;


Jens B
Avatar billede hlj Nybegynder
19. oktober 2000 - 09:28 #10
Det virker for så vidt godt nok, der er bare det problem at det kun er i den samme application som hooken er i, at det fungerer.

Jeg havde tænkt mig en slags global hook, dvs at det egentlig er beregnet til at køre i baggrunden og forhindre VK_APPS i at blive aktiveret i andre programmer.

Jeg prøvede at sætte GetCurrentThreadID() til 0, hvor man ifølge hjælpen skulle hægte sig på alle Threads. Men det fik Windows 2000 til at opføre sig mærkeligt.

Kunne man forestille sig at man bruger :
WH_CALLWNDPROC    Installs a hook procedure that monitors messages before the system sends them to the destination window procedure.
eller skal der noget helt andet til?
Avatar billede borrisholt Novice
19. oktober 2000 - 09:31 #11
Du skal stadig bruge dit keyboard hook .. men i stedet lave det i en DLL fil ...

Jammen er det ikke kun for folk der tænker binært ... Tjoe... Måske men skriv lige tli Jens@borrisholt.com så skal jeg sende dig et eksemple der indeholder både et globalt mouse hook og en globalt keyboard hook ...

Jens B
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester