Schrift
[thread]8796[/thread]

Globales Tasten-Event abfangen (win)

Leser: 1


<< |< 1 2 3 >| >> 21 Einträge, 3 Seiten
GoodFella
 2007-02-28 12:24
#74653 #74653
User since
2007-01-09
192 Artikel
BenutzerIn
[default_avatar]
Ich möchte, wenn jemand die Alt-Taste drückt (und mein Script läuft), darauf reagieren können. Perl / Tk bindings schliesse ich aus, da das hierbei nur innerhalb des Widgets funktioniert. Wie mache ich daS?
vayu
 2007-02-28 13:11
#74654 #74654
User since
2005-01-13
782 Artikel
BenutzerIn
[default_avatar]
angeblich soll

CPAN:Term::InKey das ermöglichen. Habs grad mal ausprobiert und krieg ne Fehlermeldung:
Quote
Not implemented on MSWin32: Das Handle ist ungültig at C:/Perl/site/lib/Term/InKey.pm line 32.


bei folgendem code:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
#!/usr/bin/perl

use strict;
use warnings;
use Term::InKey;

while(my $key = ReadKey) {
Clear;
print "You typed: ".$key;
}


EDIT: ah ... moment funktioniert, allerdings nur in der DosBox und NUR für Buchstaben, bei ALT, SHIFT etc geht das wohl nicht\n\n

<!--EDIT|vayu|1172661263-->
GwenDragon
 2007-02-28 13:37
#74655 #74655
User since
2005-01-17
14806 Artikel
Admin1
[Homepage]
user image
GoodFella
 2007-02-28 13:51
#74656 #74656
User since
2007-01-09
192 Artikel
BenutzerIn
[default_avatar]
Soweit war ich auch schon, hatte diesen Code hier:

Code (perl): (dl )
1
2
3
4
5
6
7
8
use Term::ReadKey;
  if (defined ($char = ReadKey(-1)) ) 
   {
    if(ord($char) == 27)
     {
      ...
     }
   }


Das ganze Dann als Repeat alle 100ms per Tk aufgerufen.
Ich möchte aber auch die Events abfangen, die _ausserhalb_ der Konsole benutzt werden.

Im Prinzip wurde ich darum gebeten, ein Chef-Programm zu schreiben, soll heissen: Man drückt eine Taste und ein Tk-Window poppt auf, dass den ganzen Bildschirm verdeckt, worauf ein Screenshot des Desktops auf einer Canvas abgebildet ist, der nach viel Arbeit aussieht. Dieses wird alle 10ms wieder in der Focus gebracht. Man drückt die Taste wieder und dieser verschwindet.

Es gibt da halt ein Online-Poker, der ständig den Focus nimmt, da hilft Alt-Tab nicht mehr ^^
Nicht, dass ich das verwenden würde ... ;P
topeg
 2007-02-28 15:05
#74657 #74657
User since
2006-07-10
2611 Artikel
BenutzerIn

user image
Wenn es Global funktionieren soll, wirst du unter Linux/Unix nicht um "X11::Protocol" herum kommen (ich glaube "GrabKeyboard" ist das richtige Stichwort dazu).
Unter Windows dürfte dir etwas aus "Win32" helfen.
vayu
 2007-02-28 15:10
#74658 #74658
User since
2005-01-13
782 Artikel
BenutzerIn
[default_avatar]
Wenn es auch NumLock, CapsLock oder ScrollLock sein darf :)

Code: (dl )
1
2
3
4
5
6
7
8
9
#!/usr/bin/perl

use strict;
use warnings;
use Win32::KeyState qw(:get);

while(1) {
print 'CapsNum is ', GetNumLock() ? 'On' : 'Off', "\n";
}


wenn du den windows code für die ALT-Taste kennst, müsstest auch hiermit den Status abfragen können

Code: (dl )
1
2
3
4
5
if (GetKeyState(0x10) & 1) {
print "Shift key is depressed\n"
} else {
print "Shift key is pressed\n"
}
\n\n

<!--EDIT|vayu|1172668517-->
GoodFella
 2007-02-28 18:05
#74659 #74659
User since
2007-01-09
192 Artikel
BenutzerIn
[default_avatar]
Cool danke... Es funktioniert soweit, bis auf dass es nicht einen Key Event empfängt, sondern, drückt man die Taste einmal, immer zu true evaluiert, bis man die Taste nochmal drückt. Bei Numlock und Scrolllock ist das ja gewünscht, aber bei normalen Tasten wie Escape = 0x1b nicht, hier mal das Beispielscript:

Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#!/usr/local/bin/perl -w

use Tk;
use Win32::KeyState qw(:get);

my $main =  new Tk::MainWindow;
$main->geometry('1030x740');

my $vis = 1;

sub read_stuff
 {
  &switch_vis if ((GetKeyState(0x1b) & 1) == 1);
 }
$handler = $main->repeat(500, \&read_stuff);


sub switch_vis
 {
  if($vis == 0)
   {
    $vis = 1;
    $main->deiconify;
   }
  else
   {
    $vis = 0;
    $main->iconify;
   }
 }

MainLoop;


Drückt mal Enter und nach einiger Zeit nochmals, dann seht ihr was ich meine.
esskar
 2007-02-28 18:26
#74660 #74660
User since
2003-08-04
7321 Artikel
ModeratorIn

user image
mit Hilfe von CPAN:Win32::API ( oder noch besser CPAN:Win32::API::Interface ) könntest du dich in die Windows-Hooks einhängen.\n\n

<!--EDIT|esskar|1172680003-->
GoodFella
 2007-02-28 22:25
#74661 #74661
User since
2007-01-09
192 Artikel
BenutzerIn
[default_avatar]
[quote=esskar,28.02.2007, 17:26]mit Hilfe von CPAN:Win32::API ( oder noch besser CPAN:Win32::API::Interface ) könntest du dich in die Windows-Hooks einhängen.[/quote]
Also, mein erster Versuch scheitert mit der Fehlermeldung
Quote
Can't locate object method "SetWindowsHookEx" via package "MyModule" at test.pl line 11, <DATA> line 164.


Code:

Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#!/usr/bin/perl
use strict;

package MyModule;
use base qw/Win32::API::Interface/;

__PACKAGE__->generate( "kernel32", "SetWindowsHookEx", "WH_MOUSE", \&test, "NULL", 0 );

1;

my $obj = MyModule->new();
$obj->SetWindowsHookEx();


sub test
 {
  print "Mouse Event\n";
 }


Ich war mir noch nie so unsicher mit Perlcode, hab einfach alles gelesen, was da stand und irgendwie miteinander verbunden. Hab noch nie eine package geschrieben, vielleicht liegts daran ... an API-Calls hab ich mich auch noch nie rangetraut.
Vielleicht magst du mir ja etwas unter die Arme greifen hierbei, esskar :)
GoodFella
 2007-03-01 01:19
#74662 #74662
User since
2007-01-09
192 Artikel
BenutzerIn
[default_avatar]
Ok, hab jetzt durch Win32::KeyState und das Lesen von der GetKeyState-Doku auf msdn genau das gefunden was ich gesucht habe. Code:
Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#!/usr/local/bin/perl -w

use Tk;
use Win32::API;

Win32::API->Import('user32', 'GetAsyncKeyState', 'I', 'I');

my $main =  new Tk::MainWindow;
$main->geometry('1030x740');

my $vis = 1;

sub read_stuff
{
 &switch_vis if ((GetAsyncKeyState(0x04) & 1) == 1);
}
$handler = $main->repeat(50, \&read_stuff);


sub switch_vis
{
  if($vis == 0)
   {
    $vis = 1;
    $main->deiconify;
   }
  else
   {
    $vis = 0;
    $main->withdraw;
   }
}

MainLoop;


Hilfreich war auch http://msdn.microsoft.com/library....des.asp
<< |< 1 2 3 >| >> 21 Einträge, 3 Seiten



View all threads created 2007-02-28 12:24.