Entwickler-Ecke

Windows API - Tastatendruck auf fremdes Fenster mit "ohne" shift


huhn - Fr 14.01.11 01:24
Titel: Tastatendruck auf fremdes Fenster mit "ohne" shift
Hi Forum,

ist es möglich mit einem Programm einem anderen Programm einen Tastenbefehl mit shift zu schicken ohne global die shift taste zu "drücken"?
Hab schon eine Weile gesucht jedoch nicht das gefunden was ich wollte.
http://www.swissdelphicenter.ch/de/showcode.php?id=220
Ich hab es mit

Delphi-Quelltext
1:
    PostMessage( h, WM_KEYDOWN, key, lparam);                    

probiert jedoch mit weniger erfolg.

mfg huhn


Moderiert von user profile iconNarses: Topic aus Delphi Language (Object-Pascal) / CLX verschoben am Fr 14.01.2011 um 11:03


bummi - Fr 14.01.11 01:31

Ich habe hier zuhause nur einen uralt Fetzen Code liegen, vielleicht hilft er Dir trotzdem

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:
procedure SendKeys(sText: String);

var
 i             : Integer;
 shift         : Boolean;
 vk, scancode   : Word;
 ch            : Char;
 c, s          : Byte;
const
 vk_keys       : Array[0..9of Byte=(VK_HOME, VK_END, VK_UP, VK_DOWN, VK_LEFT, VK_RIGHT, VK_PRIOR, VK_NEXT, VK_INSERT, VK_DELETE);
 vk_shft       : Array[0..2of Byte=(VK_SHIFT, VK_CONTROL, VK_MENU);
 flags         : Array[FALSE..TRUE] of Integer = (KEYEVENTF_KEYUP, 0);
 C_ALTGRS = ['\','@','~','²','³','€','{','}','[',']'];

begin
 shift:=FALSE;
 for i:=1 to Length(sText) do begin
   ch:=sText[i];
     if (ch>=#250then begin
     s:=Ord(ch)-250;
     shift:=NOT Odd(s);
     c:=vk_shft[s shr 1];
     scancode:=MapVirtualKey(c, 0);
     Keybd_Event(c, scancode, flags[shift], 0);
   end else begin
     vk:=0;
     if (ch>=#240then
       c:=vk_keys[Ord(ch)-240]
     else if (ch>=#228then
       c:=Ord(ch)-116
     else if (ch<#32then
       c:=Ord(ch)
     else begin
       vk:=VkKeyScan(ch);
       c:=LoByte(vk);
     end;

     scancode:=MapVirtualKey(c, 0);

     if (sText[i] in C_AltGRS) then Keybd_Event(VK_RMENU, MapVirtualKey(VK_RMENU,0), 00)
     else if (NOT shift AND (Hi(vk)>0)) then Keybd_Event(VK_SHIFT, $2A00 );
     Keybd_Event( c, scancode, 00 );
     Keybd_Event( c, scancode, KEYEVENTF_KEYUP, 0 );
     if (sText[i] in C_AltGRS) then Keybd_Event(VK_RMENU,MapVirtualKey(VK_RMENU,0), KEYEVENTF_KEYUP, 0)
     else if (NOT shift AND (Hi(vk)>0)) then Keybd_Event(VK_SHIFT, $2A, KEYEVENTF_KEYUP, 0);

   end;
   Application.ProcessMessages;
 end;
end;


huhn - Fr 14.01.11 01:35

nicht viel aber danke, bei deinem code oder methode kann ich nicht an ein fremdes program schicken


Logikmensch - Fr 14.01.11 07:40

Das Problem bei der Geschichte "Anderes Programm über Tastenanschläge fernsteuern" ist vor allem die Tatsache, dass man meist nicht genau weiß, wie die Tastenanschläge des Zielprogramms ausgewertet werden. Die meisten Formulare/Programme werten die Tastenanschläge nur aus, wenn sie den Eingabefokus haben (d.h. wenn sie gerade aktiviert sind).


huhn - Fr 14.01.11 19:21

kann ich das nicht mit den lparam wie bei alt ctrl machen?


Logikmensch - Fr 14.01.11 19:41

Wie gesagt: Du kannst mit PostMessage natürlich was aussenden. Aber nicht jedes Programm wertet die Informationen aus. Gut klappt eine Fernsteuerung über die hier im Forum zu findenden Methoden (PostMessage, SendKeys etc.) z.B. mit Notepad, aber das ist eine relativ primitive Anwendung.
Ich habe lange und breit versucht, mehrere verschiedene Anwendungen mit Hilfe eines standardisierten Verfahrens (Senden von Tastenanschlägen, Aktivieren der Zielanwendung, PostMessage usw.) zu steuern, aber es hat entweder gar nicht oder nur teilweise funktioniert (d.h. es wurde z.B. nur auf jeden 3. Tastenanschlag reagiert).

Aber probieren geht über studieren. Vielleicht kriegst Du es ja mit Deiner Zielanwendung hin...


huhn - Fr 14.01.11 21:00

kannst du mir mal ein beispiel schnipsel schicken, zb shift+1 also !?
möcht nur ma guckn ob ich das richtig gemacht habe

mfg huhn


Gerd Kayser - Sa 15.01.11 15:45

user profile iconLogikmensch hat folgendes geschrieben Zum zitierten Posting springen:
(d.h. es wurde z.B. nur auf jeden 3. Tastenanschlag reagiert).
Dann liegt die Vermutung nahe, dass Du die Zielanwendung förmlich mit "Tastaturanschlägen" bombardiert hast. Gib der Zielanwendung die benötigte Zeit, um reagieren zu können, in dem Du ein kleines Delay zwischen den einzelnen "Tastenanschlägen" einbaust.


Logikmensch - Sa 15.01.11 18:39

Suche einfach nach Postkey oder PostkexEx32 bzw. Sendkeys. Ich habe meine Testfälle auch hier aus dem Forum.. Ein fertiges Stück Testcode habe ich im Moment nicht parat, aber Gerd Kayser hat natürlich recht mit den Delays. Ich habe versucht, mit verschiedenen Delays versucht, aber es ist mir nicht gelungen, eine zuverlässige und universelle Send/Postkey-Methode zu entwickeln, die auch auf verschiedenen Computern funktioniert.