Hallo!
Es gab ja nun schon viele Fragen zu dem Thema, ich hab aber ein etwas anderes Problem. Ich kann zwar senden, und es scheint auch korrekt anzukommen, nur wird nach der Tastenkombination ein WM_CHAR ausgelöst. Das wird meines Wissens durch TranslateMessage ausgelöst.
Nur funktioniert halt dann die Tastenkombination (in diesem Fall Strg+R) nicht.
Problem: Ich möchte PostMessage benutzen, damit das Fenster auch minimiert oder hinter einem anderen sein kann, das geht mit SendInput oder keybd_event nicht...
Hier der Message-Log für das bestreffende Fenster:
1: so sollte es sein (Tastatureingabe)
2: So funktioniert es (aber das Fenster braucht den Fokus dafür, da ich SendInput benutze)
3: Das passiert bei PostMessage...
4: Das ist wohl das Problem!
Hier das Log:
Und hier der Source:
www.buchmanager-berl...eyboardInterface.pas
bzw.
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: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140:
| uses Windows, Messages, SysUtils, JwaWinAble;
type TKeyboardInterface = class private function GetKeyCode(uKeyDesc: String): Integer; public procedure DoSendKeyStrokes(uWindowCaption: String; uKeyStrokes: array of Integer); overload; procedure DoPostKeyStrokes(uWindowCaption: String; uKeyStrokes: array of Integer); overload; procedure SendKeyStrokes(uWindowCaption, uKeyStrokes: String; uPost: Boolean); overload; end;
implementation
function TKeyboardInterface.GetKeyCode(uKeyDesc: String): Integer; begin uKeyDesc := UpperCase(uKeyDesc); if uKeyDesc[1] = '<' then begin if uKeyDesc[2] = 'f' then begin Delete(uKeyDesc, 1, 2); if Length(uKeyDesc) = 2 then Delete(uKeyDesc, 2, 1) else Delete(uKeyDesc, 3, 1); Result := VK_F1 + StrToInt(uKeyDesc) - 1; end else if uKeyDesc = '<RETURN>' then Result := VK_RETURN else if uKeyDesc = '<ESCAPE>' then Result := VK_ESCAPE else if uKeyDesc = '<ESC>' then Result := VK_ESCAPE else if uKeyDesc = '<SHIFT>' then Result := VK_SHIFT else if uKeyDesc = '<STRG>' then Result := VK_CONTROL else if uKeyDesc = '<CONTROL>' then Result := VK_CONTROL else if uKeyDesc = '<STEUERUNG>' then Result := VK_CONTROL else if uKeyDesc = '<INS>' then Result := VK_INSERT else if uKeyDesc = '<INSERT>' then Result := VK_INSERT else if uKeyDesc = '<DEL>' then Result := VK_DELETE else if uKeyDesc = '<DELETE>' then Result := VK_DELETE else Result := -1; end else Result := Ord(uKeyDesc[1]); end;
procedure TKeyboardInterface.DoSendKeyStrokes(uWindowCaption: String; uKeyStrokes: array of Integer);
procedure SendKey(uVirtKey: Word; uFlags: Cardinal); var tmp: Windows.tagINPUT; begin tmp.Itype := INPUT_KEYBOARD; tmp.ki.wVk := uVirtKey; tmp.ki.wScan := 0; tmp.ki.dwFlags := uFlags; tmp.ki.time := 0; tmp.ki.dwExtraInfo := 0; SendInput(1, @tmp, SizeOf(tmp)); end;
var i: Integer; tmpHandle: Cardinal; begin tmpHandle := FindWindow(nil, PChar(uWindowCaption)); if tmpHandle = 0 then Exit;
BlockInput(True); SetForegroundWindow(tmpHandle); Sleep(100); for i := 0 to High(uKeyStrokes) do SendKey(uKeyStrokes[i], 0); for i := High(uKeyStrokes) downto 0 do SendKey(uKeyStrokes[i], KEYEVENTF_KEYUP); BlockInput(False); end;
procedure TKeyboardInterface.DoPostKeyStrokes(uWindowCaption: String; uKeyStrokes: array of Integer); var i: Integer; tmpHandle: Cardinal; begin tmpHandle := FindWindow(nil, PChar(uWindowCaption)); for i := 0 to High(uKeyStrokes) do PostMessage(tmpHandle, WM_KEYDOWN, uKeyStrokes[i], 0); for i := High(uKeyStrokes) downto 0 do PostMessage(tmpHandle, WM_KEYUP, uKeyStrokes[i], 0); end;
procedure TKeyboardInterface.SendKeyStrokes(uWindowCaption: String; uKeyStrokes: String; uPost: Boolean); var tmp: array of Integer; begin SetLength(tmp, 0); while uKeyStrokes <> '' do begin if uKeyStrokes[1] <> '<' then begin SetLength(tmp, Length(tmp) + 1); tmp[High(tmp)] := GetKeyCode(uKeyStrokes[1]); Delete(uKeyStrokes, 1, 1); end else begin SetLength(tmp, Length(tmp) + 1); tmp[High(tmp)] := GetKeyCode(Copy(uKeyStrokes, 1, Pos('>', uKeyStrokes))); Delete(uKeyStrokes, 1, Pos('>', uKeyStrokes)); end; end; if uPost then Self.DoPostKeyStrokes(uWindowCaption, tmp) else Self.DoSendKeyStrokes(uWindowCaption, tmp); end; |
Für das Beispiel habe ich SendKeyStrokes('Testfenster', '<Strg>R', True) bzw. dasselbe mit False benutzt. Mit False (Bringt das Fenster in den Vordergrund und setzt die Zeichen in den aktuellen Eingabestream) geht es, mit True (benutzt PostMessage, damit das Fenster auch minimiert sein kann) geht es nicht.
Danke schonmal...