Entwickler-Ecke

Windows API - Tastatureingaben an Handle senden


maxk - Sa 12.07.03 11:47
Titel: Tastatureingaben an Handle senden
Hi,

wie kann ich Tastatureingaben an ein Handle senden? Ich habe z.B. das Handle eines Notepad-Fensters und möchte an dieses nun VK_RETURN senden. Wie ist das realisierbar, wenn das Fenster NICHT im Vordergrund ist (sonst ist's ja einfach...)?

So geht es nicht:

Delphi-Quelltext
1:
SendMessage(Hnd,WM_KEYDOWN,VK_RETURN,0);                    


Danke schon mal,
maxk


schneegurke - Di 22.07.03 10:55

Hiermit sollte das gehen. Ist ein Stück Source aus der JEDI-VCL (http://www.delphi-jedi.org). Ist übrigens sehr zu empfehlen!


Delphi-Quelltext
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:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
procedure SendShift(H: HWND; Down: Boolean);
var
  vKey, ScanCode: Word;
  lParam: Longint;
begin
  vKey := VK_SHIFT;
  ScanCode := MapVirtualKey(vKey, 0);
  lParam := Longint(ScanCode) shl 16 or 1;
  if not Down then
    lParam := lParam or $C0000000;
  SendMessage(H, WM_KEYDOWN, vKey, lParam);
end;

procedure SendCtrl(H: HWND; Down: Boolean);
var
  vKey, ScanCode: Word;
  lParam: Longint;
begin
  vKey := VK_CONTROL;
  ScanCode := MapVirtualKey(vKey, 0);
  lParam := Longint(ScanCode) shl 16 or 1;
  if not Down then
    lParam := lParam or $C0000000;
  SendMessage(H, WM_KEYDOWN, vKey, lParam);
end;

function SendKey(AppName: string; Key: Char): Boolean;
var
  vKey, ScanCode: Word;
  lParam, ConvKey: longint;
  Shift, Ctrl: Boolean;
  H: HWND;
begin
  H := FindWindow(PChar(AppName), nil);
  if H <> 0 then
  begin
    ConvKey := OemKeyScan(Ord(Key));
    Shift := (ConvKey and $00020000) <> 0;
    Ctrl := (ConvKey and $00040000) <> 0;
    ScanCode := ConvKey and $000000FF or $FF00;
    vKey := Ord(Key);
    lParam := Longint(ScanCode) shl 16 or 1;
    if Shift then
      SendShift(H, True);
    if Ctrl then
      SendCtrl(H, True);
    SendMessage(H, WM_KEYDOWN, vKey, lParam);
    SendMessage(H, WM_CHAR, vKey, lParam);
    lParam := lParam or $C0000000;
    SendMessage(H, WM_KEYUP, vKey, lParam);
    if Shift then
      SendShift(H, False);
    if Ctrl then
      SendCtrl(H, False);
    Result := True;
  end
  else
    Result := False;
end;


maxk - Di 22.07.03 21:26

Danke, werd's gleich mal ausprobieren


maxk - Fr 26.09.03 21:13

Sorry, ich bin erst jetzt dazu gekommen auf diese Frage zu "antworten". Leider funktioniert es nicht. SendKey('Notepad','T') bringt nicht den gewünschten Effekt - Notepad ist natürlich offen!


Delete - Fr 26.09.03 22:47

da das "T" wohl im Edit von Notepad erscheinen sioll, solltest du mal das Handle von dem angeben und nicht vom Hauptfenster.


maxk - Sa 27.09.03 18:47

:oops:


Gerhard - So 28.09.03 19:01

Hi,

ich habe versucht die oben angeführten Delphi-Anweisung aufzunehmen, aber leider hat Delphi folgendes angezeigt:

HWND ist kein gültiger Typenbezeichner.

Frage: Ist eine spezielle Unit aufzunehmen oder ist das ein prinzipelles Problem mit Delphi3?

Danke Gerhard


maxk - So 28.09.03 19:06

Einfach mal mit Cardinal versuchen...


Delete - So 28.09.03 19:58

Windows.pas ist deklariert als THandle.


Gerhard - So 28.09.03 20:18

Danke für den Hinweis,

aber viel weiter komme ich nicht, denn in der Zeile

lParam := Longint(ScanCode) shl 16 or 1;

klempt es schon wieder mit der Meldung: '(' erwartet, aber ':=' gefunden.
Sowie mit der Meldeung: Anweisung erforderlich, aber Ausdruck vom Typ 'Integer' gefunden.


Danke Gerhard


maxk - Mo 29.09.03 18:11

D.h., dass dein Compiler nicht weiß, dass es sich bei Longint um einen Typen handelt. Versuche mal über den Code folgendes zu schreiben:

Delphi-Quelltext
1:
type LongInt=–2147483648..2147483647;                    

LongInt entspricht einer 32-bit Zahl mit Vorzeichen, daher diese Typendefinition. Wird warscheinlich nicht funktionieren...


Delete - Mo 29.09.03 20:28

Das halte ich aber für ein Gerücht.

Von was für einem Datentyp ist ScanCode? Wenn es sschon ein Integer ist, dann sollte es ohne Cast zuweisbar sein. Aber aknn es sein, dass die Klammern nicht richtig sitzen?


Gerhard - Mo 29.09.03 20:56

Hi,

leider klemmt es noch immer, der Compiler meldet sich noch immer ... es geht nicht

LongInt. .... geht leider nicht

Unter uses habe ich
die Unit Windows eingebunden, fehlt da vielleicht noch eine Unit?

Gruß Gerhard

Danke für Hiweise!