System weiten Hotkey

Für Fragen von Einsteigern und Programmieranfängern...
felix96
Beiträge: 287
Registriert: So 29. Nov 2009, 17:44
CPU-Target: 32BitWin+64bitUbunt

System weiten Hotkey

Beitrag von felix96 »

Guten Morgen,
Ich wollte mal Fragen, wie ich in lazarus einen System weiten hotkey realisiere?
In Delphi sol´s so gehen:

Code: Alles auswählen

procedure WmHotkey(var Msg: TMessage); message WM_HOTKEY;
    { private declarations }
  public
    { public declarations }
  end; 
 
var
  Form1: TForm1; 
 
implementation
 
{ TForm1 }
 
procedure TForm1.FormCreate(Sender: TObject);
begin 
hide;
RegisterHotKey(Handle, 1, MOD_WIN, 32); //Zum Registrieren der Tastenkombination Windows-Taste + Leertaste
end;
procedure TForm1.WmHotkey(var Msg: TMessage);
begin
if (Msg.WParam = 1) then
begin
Application.Restore; // Zum Wiederherstellen des Programms
Show; // Um sicher zu gehen, dass es angezeigt wird
messagebeep(0);
end;
end;
 
procedure TForm1.FormDestroy(Sender: TObject);
begin
UnregisterHotKey(Handle, 1); //beim beenden den Hotkey wieder entfernen
end;
Da rührt sich bei mir aber nichts :cry:
Danke schonmal für eure Antworten
it´s not a bug, it´s a feature!

_X_
Beiträge: 250
Registriert: Di 16. Dez 2008, 20:13
OS, Lazarus, FPC: aptosid (aptosid.com); Lazarus SVN gtk2+qt4; FPC 2.4.0
CPU-Target: 32/64Bit

Re: System weiten Hotkey

Beitrag von _X_ »

linux, windows, mac?
linux -> http://www.lazarusforum.de/viewtopic.php?p=33264#p33264" onclick="window.open(this.href);return false;
Unter windows müsste deins gehen.

mfg _X_

felix96
Beiträge: 287
Registriert: So 29. Nov 2009, 17:44
CPU-Target: 32BitWin+64bitUbunt

Re: System weiten Hotkey

Beitrag von felix96 »

Windows, aber es passiert nichts
Danke schonmal für eure Antworten
it´s not a bug, it´s a feature!

edewolf78
Beiträge: 12
Registriert: Mo 23. Nov 2009, 18:42
OS, Lazarus, FPC: Win (L 0.9.29 FPC 2.4.0)
CPU-Target: x32/x64
Wohnort: Ludwigsburg

Re: System weiten Hotkey

Beitrag von edewolf78 »

Hallo,
mit Lazarus für WIN, funktioniert es so :

Code: Alles auswählen

..
type 
   TWndProc = Windows.WNDPROC;    
...
var
  PrevWndProc : Long_ptr;
...
 
function MsgProc(Handle: HWnd; Msg: UInt; WParam: Windows.WParam; LParam: Windows.LParam): LResult; stdcall;
begin
    if Msg = WM_HOTKEY then  Main.HotKeyPressed(Wparam);
    Result := Windows.CallWindowProc(WNDPROC(PrevWndProc), Handle, Msg, WParam, LParam);
end; 
...
procedure TMain.FormCreate(Sender: TObject);
begin
...
  PrevWndProc            := Windows.GetWindowLongPtr(Self.Handle, GWL_WNDPROC);
  SetWindowLongPtr(Self.Handle,Windows.GWL_WNDPROC,Long_ptr(@MsgProc)); 
...
  RegisterHotKey(Handle, 1, MOD_WIN, 32);
...
end;
 
procedure TMain.HotKeyPressed(Key :  Long_Ptr);
begin
  if ( int(Key) = 1 ) then begin
     // Deine Hotkeyverarbeitung ....
  end;
end; 
...
procedure TMain.FormClose(Sender: TObject; var CloseAction: TCloseAction);
begin   
  UnregisterHotKey(Handle, 1);
...
end;
...
Gruss Edwin

felix96
Beiträge: 287
Registriert: So 29. Nov 2009, 17:44
CPU-Target: 32BitWin+64bitUbunt

Re: System weiten Hotkey

Beitrag von felix96 »

Hier mal mein Quelltext:

Code: Alles auswählen

unit Unit1; 
 
{$mode objfpc}{$H+}
 
interface
 
uses
  Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs, windows
  , messages;
 
type
  TWndProc = Windows.WNDPROC;
 
  { TForm1 }
 
  TForm1 = class(TForm)
    procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
    procedure FormCreate(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end; 
 
var
  Form1: TForm1;
PrevWndProc : Long_ptr; 
 
implementation
 
 
procedure TMain.HotKeyPressed(Key :  Long_Ptr);
begin
  if ( int(Key) = 1 ) then begin
     // Deine Hotkeyverarbeitung ....
     showmessage('Hotkey');
  end;
end;
 
function MsgProc(Handle: HWnd; Msg: UInt; WParam: Windows.WParam; LParam: Windows.LParam): LResult; stdcall;
begin
    if Msg = WM_HOTKEY then  Main.HotKeyPressed(Wparam);
    Result := Windows.CallWindowProc(WNDPROC(PrevWndProc), Handle, Msg, WParam, LParam);
end;
 
{ TForm1 }
 
procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
begin
   UnregisterHotKey(Handle, 1);
end;
 
procedure TForm1.FormCreate(Sender: TObject);
begin
   PrevWndProc            := Windows.GetWindowLongPtr(Self.Handle, GWL_WNDPROC);
  SetWindowLongPtr(Self.Handle,Windows.GWL_WNDPROC,Long_ptr(@MsgProc));
  RegisterHotKey(Handle, 1, MOD_WIN, 32);
end;
 
initialization
  {$I unit1.lrs}
 
end.
und hier mal die Fehlermeldungen:

unit1.pas(32,30) Error: method identifier expected
unit1.pas(42,34) Error: Identifier not found "Main"
unit1.pas(43,38) Hint: Conversion between ordinals and pointers is not portable
unit1.pas(56,52) Hint: Conversion between ordinals and pointers is not portable
unit1.pas(65) Fatal: There were 2 errors compiling module, stopping

:cry:
Danke schonmal für eure Antworten
it´s not a bug, it´s a feature!

edewolf78
Beiträge: 12
Registriert: Mo 23. Nov 2009, 18:42
OS, Lazarus, FPC: Win (L 0.9.29 FPC 2.4.0)
CPU-Target: x32/x64
Wohnort: Ludwigsburg

Re: System weiten Hotkey

Beitrag von edewolf78 »

Hallo,

bei mir ist der Name der Form 1 "Main", bei Dir muss es dem entsprechend "Form1" bzw "TForm1" heissen.


Gruss Edwin

felix96
Beiträge: 287
Registriert: So 29. Nov 2009, 17:44
CPU-Target: 32BitWin+64bitUbunt

Re: System weiten Hotkey

Beitrag von felix96 »

DANKE :wink: :wink: :wink: :wink:
Danke schonmal für eure Antworten
it´s not a bug, it´s a feature!

Delphi-Laie
Beiträge: 26
Registriert: So 24. Jan 2010, 21:56

Re: System weiten Hotkey

Beitrag von Delphi-Laie »

Hallo, ich kämpfe mich gerade durch diese Thematik. Bei mir funktioniert es nicht mit o.g. Code, weil die Prozedur:

Code: Alles auswählen

procedure TForm1.HotKeyPressed(Key :  Long_Ptr);
begin
  if ( int(Key) = 1 ) then begin
     // Deine Hotkeyverarbeitung ....
     showmessage('Hotkey');
  end;
end;
gar nicht deklariert ist. Wo muß die deklariert werden? Vermutlich in der TForm1-Deklaration, aber wo konkret? Public? Private? Oder schon davor? Im o.a. Quelltext fehlt die Deklaration, insofern wundert mich, daß das funktionieren soll.

Danke für Eure Aufmerksamkeit!

Edit: So, Fehler gefunden, die Deklaration fehlte tatsächlich. Es muß

Code: Alles auswählen

unit Unit1; 
 
{$mode objfpc}{$H+}
 
interface
 
uses
  Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs, Windows, Messages;
 
type
  TWndProc = Windows.WNDPROC;
 
  { TForm1 }
 
  TForm1 = class(TForm)
    procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
    procedure FormCreate(Sender: TObject);
    procedure HotKeyPressed(Key :  Long_Ptr); // auf DIESE Deklaration kam es an
  private
    { private declarations }
  public
    { public declarations }
  end; 
 
var
  Form1: TForm1;
  PrevWndProc : Long_ptr;
 
implementation
 
 
procedure TForm1.HotKeyPressed(Key :  Long_Ptr);
begin
  if ( int(Key) = 1 ) then begin
     // Deine Hotkeyverarbeitung ....
     showmessage('Hotkey');
  end;
end;
 
 
function MsgProc(Handle: HWnd; Msg: UInt; WParam: Windows.WParam; LParam: Windows.LParam): LResult; stdcall;
begin
if Msg = WM_HOTKEY then Form1.HotKeyPressed(Wparam);
Result := Windows.CallWindowProc(WNDPROC(PrevWndProc), Handle, Msg, WParam, LParam);
end;
 
{ TForm1 }
 
procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
begin
UnregisterHotKey(Handle, 1);
end;
 
procedure TForm1.FormCreate(Sender: TObject);
begin
PrevWndProc:= Windows.GetWindowLongPtr(Self.Handle, GWL_WNDPROC);
SetWindowLongPtr(Self.Handle,Windows.GWL_WNDPROC,Long_ptr(@MsgProc));
RegisterHotKey(Handle, 1, MOD_WIN, 32);
end;
 
initialization
  {$I unit1.lrs}
 
end.

Delphi-Laie
Beiträge: 26
Registriert: So 24. Jan 2010, 21:56

Re: System weiten Hotkey

Beitrag von Delphi-Laie »

Funktionieren tat eigentlich nur der Compiler, der es nach meiner o.a. Anpassung akzeptierte.

Jedoch gelang es mir nicht, einen Hotkey dem Programm zu entlocken. Es tut sich rein gar nichts.

felix96, konnten Sie einen funktionierenden Hotkey installieren?

Oder weiß sonst jemand Rat? Am besten wäre ein Beispielprogramm. Falls jemand eines hier bieten kann oder für sonstige Antworten danke ich schon mal im voraus!

Gruß

Delphi-Laie

felix96
Beiträge: 287
Registriert: So 29. Nov 2009, 17:44
CPU-Target: 32BitWin+64bitUbunt

Re: System weiten Hotkey

Beitrag von felix96 »

Was für einr Version von Lazarus haben Sie?
Beim Mir funktionirrt es ohne Probleme, wenn ich die Windows-Taste und die Space-Taste(Leer-Taste) drücke.
Kurtz: Win+Space
Danke schonmal für eure Antworten
it´s not a bug, it´s a feature!

Delphi-Laie
Beiträge: 26
Registriert: So 24. Jan 2010, 21:56

Re: System weiten Hotkey

Beitrag von Delphi-Laie »

Meine Version lautet 0.9.28.2.

War denn meine Ergänzung richtig, daß die Prozedur TForm1.HotKeyPressed deklariert und in das Formular eingebunden werden muß? Oder wie bekamen Sie das hin?

Gruß Delphi-Laie

Edit: So, ich bekam es jetzt immerhin soweit hin, daß Win+Leertaste (in dieser Reihenfolge!) erkannt und darauf reagiert wird.

Doch ich möchte die F-Tasten als Hotkey installieren. Mit

Code: Alles auswählen

RegisterHotKey(Handle,1,VK_F1,32)
tut sich jedenfalls leider - wie bekannt - nicht.
Zuletzt geändert von Delphi-Laie am Mo 19. Apr 2010, 19:59, insgesamt 2-mal geändert.

felix96
Beiträge: 287
Registriert: So 29. Nov 2009, 17:44
CPU-Target: 32BitWin+64bitUbunt

Re: System weiten Hotkey

Beitrag von felix96 »

Vielleicht muss man F+Leertaste drücken, 32=Leertaste :?:
http://www.torsten-horn.de/techdocs/ascii.htm
Oder die F-Tasten können nicht reserviert werden? Alles nur Vermutungen :P
Danke schonmal für eure Antworten
it´s not a bug, it´s a feature!

Delphi-Laie
Beiträge: 26
Registriert: So 24. Jan 2010, 21:56

Re: System weiten Hotkey

Beitrag von Delphi-Laie »

Tausend Dank!

Ihr Spürsinn brachte mich auf die richtige Fährte. Mit

Code: Alles auswählen

RegisterHotKey(Handle,1,0,VK_F1)
scheint die entscheidende Hürde überwunden zu sein (das ist anscheinend wie bei Delphi). Hoffentlich finde ich nicht noch etwas, was mich hier nach Hilfe schreien läßt.

Edit: Was mir noch nicht klar ist: Wo fügt man die Prozedur HotKeyPressed am besten ein: Direkt bei TForm noch vor private, als (nach) private oder als (nach) public? Es scheint überall zu funktionieren, doch wo ist es korrekt?

Edit 2: Noch als kleines Dankeschön hier, wie man mehr als eine Taste mit (jeweils) einem Hotkey belegt, also gleichzeitig mehr als ein Hotkey aktiv ist:

Code: Alles auswählen

unit Unit1; 
 
{$mode objfpc}{$H+}
//{$mode Delphi}{$H+}
 
interface
 
uses   Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
  ExtCtrls, StdCtrls, ComCtrls, Menus, Windows;
 
type
 
  { TForm1 }
 
  TForm1 = class(TForm)
    Edit1: TEdit;
    procedure FormCreate(Sender: TObject);
    procedure HotKeyPressed(Key:Long_Ptr);//auf DIESE Deklaration kam es an
  private
    { private declarations }
  public
    { public declarations }
  end; 
 
var
  Form1:TForm1;
  PrevWndProc:Long_ptr;
 
 
implementation
 
 
procedure TForm1.HotKeyPressed(Key:Long_Ptr);
begin
if int(Key)=1 then showmessage('F1');
if int(Key)=2 then showmessage('F2');
end;
 
function MsgProc(Handle:HWnd;Msg:UInt;WParam:Windows.WParam;LParam:Windows.LParam):LResult;stdcall;
begin
if Msg=WM_HOTKEY then Form1.HotKeyPressed(Wparam);
Result:=Windows.CallWindowProc(WNDPROC(PrevWndProc),Handle,Msg,WParam,LParam)
end;
 
{ TForm1 }
 
procedure TForm1.FormCreate(Sender: TObject);
begin
PrevWndProc:=Windows.GetWindowLongPtr(Self.Handle,GWL_WNDPROC);
SetWindowLongPtr(Self.Handle,Windows.GWL_WNDPROC,Long_ptr(@MsgProc));
RegisterHotKey(Handle,1,0,VK_F1);
RegisterHotKey(Handle,2,0,VK_F2);
end;
 
initialization
  {$I unit1.lrs}
 
end.
Zuletzt geändert von Delphi-Laie am Di 20. Apr 2010, 15:40, insgesamt 3-mal geändert.

felix96
Beiträge: 287
Registriert: So 29. Nov 2009, 17:44
CPU-Target: 32BitWin+64bitUbunt

Re: System weiten Hotkey

Beitrag von felix96 »

0 Ahnung, wüsste ich auch gerne :P
Danke schonmal für eure Antworten
it´s not a bug, it´s a feature!

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6768
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: System weiten Hotkey

Beitrag von af0815 »

Delphi-Laie hat geschrieben: Was mir noch nicht klar ist: Wo fügt man die Prozedur HotKeyPressed am besten ein: Direkt bei TForm noch vor private, als (nach) private oder als (nach) public? Es scheint überall zu funktionieren, doch wo ist es korrekt?
Faustregel: Wenn es kein abgeleitet Objekt (Kindobjekt) den Zugriff benötigt in private.

So wie du es verwendest ist es komplett egal, ausser man ist ein übergenauer Mensch.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Antworten