Hallo,
im Moment verwende ich die Prozedur
FPostKey, um den Druck einer Taste des Keyboards in einem Konsolenfenster zu simulieren:
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: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105:
| procedure TDosThread.FPostKey(key: Word; const shift: TShiftState; specialkey: Boolean); type TBuffers = array [0..1] of TKeyboardState; var pKeyBuffers: ^TBuffers; lParam: LongInt; hWindow: HWND;
begin hWindow := TargetWindow; if IsWindow(hWindow) then begin
pKeyBuffers := nil; lParam := MakeLong(0, MapVirtualKey(key, 0));
if specialkey then lParam := lParam or $1000000;
New(pKeyBuffers); try GetKeyboardState(pKeyBuffers^[1]); FillChar(pKeyBuffers^[0], SizeOf(TKeyboardState), 0);
if ssShift in shift then pKeyBuffers^[0][VK_SHIFT] := $80; if ssAlt in shift then begin pKeyBuffers^[0][VK_MENU] := $80; lParam := lParam or $20000000; end; if ssCtrl in shift then pKeyBuffers^[0][VK_CONTROL] := $80; if ssLeft in shift then pKeyBuffers^[0][VK_LBUTTON] := $80; if ssRight in shift then pKeyBuffers^[0][VK_RBUTTON] := $80; if ssMiddle in shift then pKeyBuffers^[0][VK_MBUTTON] := $80;
SetKeyboardState(pKeyBuffers^[0]); if ssAlt in Shift then begin PostMessage(hWindow, WM_SYSKEYDOWN, key, lParam); PostMessage(hWindow, WM_SYSKEYUP, key, lParam or $C0000000); end else begin PostMessage(hWindow, WM_KEYDOWN, key, lParam); PostMessage(hWindow, WM_KEYUP, key, lParam or $C0000000); end; Application.ProcessMessages;
SetKeyboardState(pKeyBuffers^[1]); finally if pKeyBuffers <> nil then Dispose(pKeyBuffers); end; end else raise Exception.Create('Console Window could not be localized!'); end; |
Um alle Tasten simulieren zu können, werden der Thread des Fensters und der Programmthreads vorher mit
AttachThreadInput verbunden.
So kann man zum Beispiel die Eingabe eines '
A' mit
FPostKey(Ord('A'),[ssShift],False) oder die Eingabe eines '
a' mit
FPostKey(Ord('A'),[],False) simulieren. '
Enter' geht mit
FPostKey(VK_RETURN,[],False) . So weit - so gut.
Allerdings will ich jetzt eine Prozedur
FPostLine(ALine: String; Eol: Boolean) entwerfen, die automatisch das "schreiben" eines ganzen Strings simuliert (wenn Eol Wahr ist, wird am Ende das Drücken von Enter simuliert). Der String ALine sollte A-Z, a-z, 0-9 und zumindest die wichtigsten Sonderzeichen enthalten können. Für ein deutsches Tastaturlayout könnte man das ganze ja relativ einfach schreiben.
Für mich wäre allerdings wichtig, dass der String mit jeder (westlichen) Tastatur richtig simuliert wird:
So sollte der String 'LaLa$%(good=' korrekt an die Konsolenanwendung übergeben werden, als hätte man diesen Text auch wirklich so über die Tastatur getippt - egal ob das Windowstastaturlayout Deutsch, Englisch(US) oder z.B. Französisch ist!
Wie übergebe ich das jetzt an FPostKey? Oder gibt es eine andere Möglichkeit?
Wäre für jede Hilfe dankbar,
Frankie