diff --git a/Source/colormath/simba.colormath.pas b/Source/colormath/simba.colormath.pas index 6cc3f8bcf..36662610a 100644 --- a/Source/colormath/simba.colormath.pas +++ b/Source/colormath/simba.colormath.pas @@ -38,6 +38,9 @@ interface function AsString: String; end; + TColor = Graphics.TColor; + PColor = ^TColor; + TColorHelper = type helper for TColor function ToBGRA: TColorBGRA; function ToRGB: TColorRGB; diff --git a/Source/components/simba.component_menubar.pas b/Source/components/simba.component_menubar.pas index 86a9738e9..27f308707 100644 --- a/Source/components/simba.component_menubar.pas +++ b/Source/components/simba.component_menubar.pas @@ -51,6 +51,7 @@ TSimbaMainMenuBar = class(TCustomControl) function GetMenus: TPopupMenuArray; public constructor Create(AOwner: TComponent); override; + destructor Destroy; override; property Menus: TPopupMenuArray read GetMenus; procedure AddMenu(Title: String; APopupMenu: TPopupMenu); @@ -235,6 +236,8 @@ procedure TSimbaMainMenuBar.MouseLeave; procedure TSimbaMainMenuBar.DoMenuClose(Sender: TObject); begin + if (FTrackTimer = nil) then + Exit; FTrackTimer.Enabled := False; Application.QueueAsyncCall(@ClearPopupIndex, 0); @@ -286,6 +289,14 @@ constructor TSimbaMainMenuBar.Create(AOwner: TComponent); CalculateSizes(); end; +destructor TSimbaMainMenuBar.Destroy; +begin + Application.RemoveAsyncCalls(Self); + FTrackTimer := nil; + + inherited Destroy(); +end; + procedure TSimbaMainMenuBar.AddMenu(Title: String; APopupMenu: TPopupMenu); var I: Integer; diff --git a/Source/components/simba.component_statusbar.pas b/Source/components/simba.component_statusbar.pas index a96730bc3..35762b564 100644 --- a/Source/components/simba.component_statusbar.pas +++ b/Source/components/simba.component_statusbar.pas @@ -32,7 +32,7 @@ TSimbaStatusBar = class(TCustomControl) procedure Paint; override; procedure PaintPanel(Index: Integer); - procedure InvalidatePanel(Index: Integer); + procedure InvalidatePanelASync(Data: PtrInt); function PanelRect(Index: Integer): TRect; procedure CheckIndex(Index: Integer); @@ -78,10 +78,9 @@ procedure TSimbaStatusBar.SetPanelText(Index: Integer; Value: String); begin if (FPanelText[Index] = Value) then Exit; - FPanelText[Index] := Value; - InvalidatePanel(Index); + Application.QueueAsyncCall(@InvalidatePanelASync, Index); end; procedure TSimbaStatusBar.SetPanelTextMeasure(Index: Integer; Value: String); @@ -194,11 +193,11 @@ procedure TSimbaStatusBar.PaintPanel(Index: Integer); Canvas.TextRect(R, R.Left + 5, R.Top, FPanelText[Index], Style); end; -procedure TSimbaStatusBar.InvalidatePanel(Index: Integer); +procedure TSimbaStatusBar.InvalidatePanelASync(Data: PtrInt); var R: TRect; begin - R := PanelRect(Index); + R := PanelRect(Data); InvalidateRect(Handle, @R, False); end; @@ -226,4 +225,3 @@ function TSimbaStatusBar.PanelRect(Index: Integer): TRect; end; end. - diff --git a/Source/imagebox/simba.imagebox.pas b/Source/imagebox/simba.imagebox.pas index 7e9117807..731235651 100644 --- a/Source/imagebox/simba.imagebox.pas +++ b/Source/imagebox/simba.imagebox.pas @@ -10,7 +10,7 @@ interface uses - Classes, SysUtils, Forms, Controls, Graphics, ComCtrls, LCLType, + Classes, SysUtils, Forms, Controls, Graphics, GraphType, ComCtrls, LCLType, simba.mufasatypes, simba.image, simba.dtm, simba.imagebox_image, simba.colormath; @@ -112,7 +112,7 @@ TSimbaImageBox = class(TWinControl) implementation uses - Math, GraphType, LCLIntf, + Math, LCLIntf, simba.finder, simba.image_lazbridge, simba.windowhandle; procedure TSimbaImageBox_ScrollBox.GetPreferredSize(var PreferredWidth, PreferredHeight: integer; Raw: boolean; WithThemeSpace: boolean); diff --git a/Source/simba.ide_events.pas b/Source/simba.ide_events.pas index dbe79617f..8d24330d0 100644 --- a/Source/simba.ide_events.pas +++ b/Source/simba.ide_events.pas @@ -44,6 +44,7 @@ SimbaIDEEvents = class // Called every 500ms from a script instance while a script is running. + // Called on a seperate thread - synchronize if doing GUI stuff! // Sender = TSimbaScriptInstance class procedure CallOnScriptRunning(Sender: TObject); class procedure RegisterMethodOnScriptRunning(Proc: TNotifyEvent); diff --git a/Source/simba.input.pas b/Source/simba.input.pas index 92d538c61..88cf177fd 100644 --- a/Source/simba.input.pas +++ b/Source/simba.input.pas @@ -24,8 +24,8 @@ interface EMouseEventType = (TELEPORT, MOVING, CLICK, DOWN, UP); {$SCOPEDENUMS OFF} const - DEFAULT_KEY_PRESS_MIN = 30; - DEFAULT_KEY_PRESS_MAX = 140; + DEFAULT_KEY_PRESS_MIN = 20; + DEFAULT_KEY_PRESS_MAX = 125; DEFAULT_CLICK_MIN = 40; DEFAULT_CLICK_MAX = 220; @@ -389,9 +389,16 @@ procedure TSimbaInput.MouseScroll(Scrolls: Integer); procedure TSimbaInput.KeySend(Text: String); var I: Integer; + SleepTimes: TIntegerArray; begin - for I := 1 to Length(Text) do - Target.KeySend(Text[I], GetRandomKeyPressTime() div 2, GetRandomKeyPressTime() div 2, GetRandomKeyPressTime() div 2, GetRandomKeyPressTime() div 2); + if (Length(Text) = 0) then + Exit; + + SetLength(SleepTimes, Length(Text) * 5); + for I := 0 to High(SleepTimes) do + SleepTimes[I] := GetRandomKeyPressTime(); + + Target.KeySend(PChar(Text), @SleepTimes[0]); end; procedure TSimbaInput.KeyPress(Key: EKeyCode); diff --git a/Source/simba.nativeinterface.pas b/Source/simba.nativeinterface.pas index 0dc10d8a5..e9028233a 100644 --- a/Source/simba.nativeinterface.pas +++ b/Source/simba.nativeinterface.pas @@ -16,11 +16,6 @@ interface type TSimbaNativeInterface = class public - procedure KeyDownNativeKeyCode(EKeyCode: Integer); virtual; abstract; - procedure KeyUpNativeKeyCode(EKeyCode: Integer); virtual; abstract; - - function GetNativeKeyCodeAndModifiers(Character: Char; out Code: Integer; out Modifiers: TShiftState): Boolean; virtual; abstract; - function GetWindowImage(Window: TWindowHandle; X, Y, Width, Height: Integer; var ImageData: PColorBGRA): Boolean; virtual; abstract; function GetWindowBounds(Window: TWindowHandle; out Bounds: TBox): Boolean; virtual; abstract; function GetWindowBounds(Window: TWindowHandle): TBox; virtual; abstract; @@ -34,6 +29,7 @@ TSimbaNativeInterface = class function GetMousePosition: TPoint; virtual; abstract; function GetMousePosition(Window: TWindowHandle): TPoint; virtual; abstract; + procedure KeySend(Text: PChar; TextLen: Integer; SleepTimes: PInt32); virtual; abstract; function KeyPressed(Key: EKeyCode): Boolean; virtual; abstract; procedure KeyDown(Key: EKeyCode); virtual; abstract; procedure KeyUp(Key: EKeyCode); virtual; abstract; @@ -84,8 +80,6 @@ TSimbaNativeInterface = class procedure OpenURL(URL: String); virtual; function GetVirtualKeyCode(Character: Char): Integer; virtual; - - procedure KeySend(Key: Char; KeyDownTime, KeyUpTime, ModifierDownTime, ModifierUpTime: Integer); virtual; end; var @@ -109,36 +103,6 @@ implementation simba.nativeinterface_darwin; {$ENDIF} -procedure TSimbaNativeInterface.KeySend(Key: Char; KeyDownTime, KeyUpTime, ModifierDownTime, ModifierUpTime: Integer); -var - NativeKeyCode: Integer; - KeyModifiers: TShiftState; -begin - if not GetNativeKeyCodeAndModifiers(Key, NativeKeyCode, KeyModifiers) then - raise Exception.CreateFmt('TSimbaNativeInterface.SendChar: Unknown key code for "%s"', [Key]); - - if (KeyModifiers <> []) then - begin - if (ssShift in KeyModifiers) then KeyDown(EKeyCode.SHIFT); - if (ssCtrl in KeyModifiers) then KeyDown(EKeyCode.CONTROL); - if (ssAlt in KeyModifiers) then KeyDown(EKeyCode.MENU); - - PreciseSleep(ModifierDownTime); - end; - - KeyDownNativeKeyCode(NativeKeyCode); PreciseSleep(KeyDownTime); - KeyUpNativeKeyCode(NativeKeyCode); PreciseSleep(KeyUpTime); - - if (KeyModifiers <> []) then - begin - if (ssShift in KeyModifiers) then KeyUp(EKeyCode.SHIFT); - if (ssCtrl in KeyModifiers) then KeyUp(EKeyCode.CONTROL); - if (ssAlt in KeyModifiers) then KeyUp(EKeyCode.MENU); - - PreciseSleep(ModifierUpTime); - end; -end; - function TSimbaNativeInterface.WindowHandleToStr(WindowHandle: TWindowHandle): String; begin Result := IntToStr(WindowHandle); diff --git a/Source/simba.nativeinterface_linux.pas b/Source/simba.nativeinterface_linux.pas index 969a06df0..97ee70dd6 100644 --- a/Source/simba.nativeinterface_linux.pas +++ b/Source/simba.nativeinterface_linux.pas @@ -10,17 +10,12 @@ interface uses - classes, sysutils, - simba.mufasatypes, simba.nativeinterface, simba.colormath; + Classes, SysUtils, + simba.mufasatypes, simba.nativeinterface; type TSimbaNativeInterface_Linux = class(TSimbaNativeInterface) public - procedure KeyDownNativeKeyCode(EKeyCode: Integer); override; - procedure KeyUpNativeKeyCode(EKeyCode: Integer); override; - - function GetNativeKeyCodeAndModifiers(Character: Char; out Code: Integer; out Modifiers: TShiftState): Boolean; override; - function GetWindowBounds(Window: TWindowHandle; out Bounds: TBox): Boolean; override; function GetWindowBounds(Window: TWindowHandle): TBox; override; overload; procedure SetWindowBounds(Window: TWindowHandle; Bounds: TBox); override; @@ -36,6 +31,7 @@ TSimbaNativeInterface_Linux = class(TSimbaNativeInterface) procedure MouseTeleport(RelativeWindow: TWindowHandle; P: TPoint); override; function MousePressed(Button: EMouseButton): Boolean; override; + procedure KeySend(Text: PChar; TextLen: Integer; SleepTimes: PInt32); override; function KeyPressed(Key: EKeyCode): Boolean; override; procedure KeyDown(Key: EKeyCode); override; procedure KeyUp(Key: EKeyCode); override; @@ -201,6 +197,76 @@ function VirtualKeyToNativeKeyCode(VirtualKey: EKeyCode): Integer; Result := SimbaXLib.XKeySymToKeyCode(Symbol); end; +function CharToKeySym(Key: Char): TKeySym; +begin + case Key of + #9 : Result := XK_TAB; + #10: Result := XK_RETURN; + #32: Result := XK_SPACE; + #34: Result := XK_QUOTEDBL; + #39: Result := XK_APOSTROPHE; + '!': Result := XK_EXCLAM; + '#': Result := XK_NUMBERSIGN; + '%': Result := XK_PERCENT; + '$': Result := XK_DOLLAR; + '&': Result := XK_AMPERSAND; + '(': Result := XK_PARENLEFT; + ')': Result := XK_PARENRIGHT; + '=': Result := XK_EQUAL; + ',': Result := XK_COMMA; + '.': Result := XK_PERIOD; + ':': Result := XK_COLON; + ';': Result := XK_SEMICOLON; + '<': Result := XK_LESS; + '>': Result := XK_GREATER; + '?': Result := XK_QUESTION; + '@': Result := XK_AT; + '[': Result := XK_BRACKETLEFT; + ']': Result := XK_BRACKETRIGHT; + '\': Result := XK_BACKSLASH; + '^': Result := XK_ASCIICIRCUM; + '_': Result := XK_UNDERSCORE; + '`': Result := XK_GRAVE; + '{': Result := XK_BRACELEFT; + '|': Result := XK_BAR; + '}': Result := XK_BRACERIGHT; + '~': Result := XK_ASCIITILDE; + '+': Result := XK_PLUS; + '-': Result := XK_MINUS; + '*': Result := XK_ASTERISK; + '/': Result := XK_SLASH; + else + Result := SimbaXLib.XStringToKeysym(PChar(String(Key))); + end; +end; + +procedure GetKeyModifiers(KeySym: TKeySym; KeyCode: TKeyCode; out Shift, Ctrl, Alt: Boolean); +var + Index: Integer; +begin + Shift := False; + Ctrl := False; + Alt := False; + + if (KeyCode > 0) then + begin + Index := 0; + while (Index < 8) and (SimbaXLib.XKeyCodeToKeySym(KeyCode, Index) <> KeySym) do + Inc(Index); + + if (Index > 0) then + begin + Dec(Index); + + case Index of + ControlMapIndex: Ctrl := True; + ShiftMapIndex: Shift := True; + Mod1MapIndex..Mod5MapIndex: Alt := True; + end; + end; + end; +end; + function GetWindowProperty(Window: TWindow; Prop: TAtom): Int64; var Atom: TAtom; @@ -226,97 +292,6 @@ function HasWindowProperty(Window: TWindow; Name: String): Boolean; Result := GetWindowProperty(Window, SimbaXLib.XInternAtom(PChar(Name), False)) > 0; end; -procedure TSimbaNativeInterface_Linux.KeyDownNativeKeyCode(EKeyCode: Integer); -begin - SimbaXLib.XTestFakeKeyEvent(EKeyCode, True, 0); - SimbaXLib.XSync(False); -end; - -procedure TSimbaNativeInterface_Linux.KeyUpNativeKeyCode(EKeyCode: Integer); -begin - SimbaXLib.XTestFakeKeyEvent(EKeyCode, False, 0); - SimbaXLib.XSync(False); -end; - -function TSimbaNativeInterface_Linux.GetNativeKeyCodeAndModifiers(Character: Char; out Code: Integer; out Modifiers: TShiftState): Boolean; - - function GetSpecialKeySym(Key: Char): TKeySym; - begin - case Key of - #9 : Result := XK_TAB; - #10: Result := XK_RETURN; - #32: Result := XK_SPACE; - #34: Result := XK_QUOTEDBL; - #39: Result := XK_APOSTROPHE; - '!': Result := XK_EXCLAM; - '#': Result := XK_NUMBERSIGN; - '%': Result := XK_PERCENT; - '$': Result := XK_DOLLAR; - '&': Result := XK_AMPERSAND; - '(': Result := XK_PARENLEFT; - ')': Result := XK_PARENRIGHT; - '=': Result := XK_EQUAL; - ',': Result := XK_COMMA; - '.': Result := XK_PERIOD; - ':': Result := XK_COLON; - ';': Result := XK_SEMICOLON; - '<': Result := XK_LESS; - '>': Result := XK_GREATER; - '?': Result := XK_QUESTION; - '@': Result := XK_AT; - '[': Result := XK_BRACKETLEFT; - ']': Result := XK_BRACKETRIGHT; - '\': Result := XK_BACKSLASH; - '^': Result := XK_ASCIICIRCUM; - '_': Result := XK_UNDERSCORE; - '`': Result := XK_GRAVE; - '{': Result := XK_BRACELEFT; - '|': Result := XK_BAR; - '}': Result := XK_BRACERIGHT; - '~': Result := XK_ASCIITILDE; - '+': Result := XK_PLUS; - '-': Result := XK_MINUS; - '*': Result := XK_ASTERISK; - '/': Result := XK_SLASH; - else - Result := 0; - end; - end; - -var - Symbol: TKeySym; - Index: Integer; -begin - Symbol := GetSpecialKeySym(Character); - if (Symbol = NoSymbol) then - Symbol := SimbaXLib.XStringToKeysym(PChar(String(Character))); - - Code := SimbaXLib.XKeySymToKeycode(Symbol); - Modifiers := []; - - Result := (Code > 0); - if Result then - begin - Index := 0; - while (Index < 8) and (SimbaXLib.XKeyCodeToKeySym(Code, Index) <> Symbol) do - Inc(Index); - - if (Index > 0) then - begin - Dec(Index); - - case Index of - ControlMapIndex: - Modifiers := [ssCtrl]; - ShiftMapIndex: - Modifiers := [ssShift]; - Mod1MapIndex..Mod5MapIndex: - Modifiers := [ssAlt]; - end; - end; - end; -end; - function TSimbaNativeInterface_Linux.GetWindowBounds(Window: TWindowHandle; out Bounds: TBox): Boolean; var Child: TWindow; @@ -467,6 +442,70 @@ function TSimbaNativeInterface_Linux.MousePressed(Button: EMouseButton): Boolean Result := ((Event.State and Mask) > 0); end; +procedure TSimbaNativeInterface_Linux.KeySend(Text: PChar; TextLen: Integer; SleepTimes: PInt32); +var + ShiftDown, CtrlDown, AltDown: Boolean; + + procedure DoSleep; + begin + PreciseSleep(SleepTimes^); + Inc(SleepTimes); + end; + + procedure EnsureModifier(const Needed: Boolean; var isDown: Boolean; const KeyCode: EKeyCode); + begin + if (Needed = isDown) then + Exit; + isDown := Needed; + + if Needed then + KeyDown(KeyCode) + else + KeyUp(KeyCode); + + DoSleep(); + end; + + procedure KeyEvent(KeyCode: TKeyCode; Down: Boolean); + begin + SimbaXLib.XTestFakeKeyEvent(KeyCode, Down, 0); + SimbaXLib.XSync(False); + + DoSleep(); + end; + +var + I: Integer; + KeySym: TKeySym; + KeyCode: TKeyCode; + Shift, Ctrl, Alt: Boolean; +begin + ShiftDown := False; + CtrlDown := False; + AltDown := False; + + try + for I := 0 to TextLen - 1 do + begin + KeySym := CharToKeySym(Text[I]); + KeyCode := SimbaXLib.XKeySymToKeycode(KeySym); + + GetKeyModifiers(KeySym, KeyCode, Shift, Ctrl, Alt); + + EnsureModifier(Shift, ShiftDown, EKeyCode.SHIFT); + EnsureModifier(Ctrl, CtrlDown, EKeyCode.CONTROL); + EnsureModifier(Alt, AltDown, EKeyCode.MENU); + + KeyEvent(KeyCode, True); + KeyEvent(KeyCode, False); + end; + finally + EnsureModifier(False, ShiftDown, EKeyCode.SHIFT); + EnsureModifier(False, CtrlDown, EKeyCode.CONTROL); + EnsureModifier(False, AltDown, EKeyCode.MENU); + end; +end; + function TSimbaNativeInterface_Linux.KeyPressed(Key: EKeyCode): Boolean; var Code: TKeySym; diff --git a/Source/simba.nativeinterface_windows.pas b/Source/simba.nativeinterface_windows.pas index 4022fd812..4a6af7e3c 100644 --- a/Source/simba.nativeinterface_windows.pas +++ b/Source/simba.nativeinterface_windows.pas @@ -27,11 +27,6 @@ TSimbaNativeInterface_Windows = class(TSimbaNativeInterface) constructor Create; destructor Destroy; override; - procedure KeyDownNativeKeyCode(EKeyCode: Integer); override; - procedure KeyUpNativeKeyCode(EKeyCode: Integer); override; - - function GetNativeKeyCodeAndModifiers(Character: Char; out Code: Integer; out Modifiers: TShiftState): Boolean; override; - function GetWindowBounds(Window: TWindowHandle; out Bounds: TBox): Boolean; override; function GetWindowBounds(Window: TWindowHandle): TBox; override; overload; procedure SetWindowBounds(Window: TWindowHandle; Bounds: TBox); override; @@ -47,6 +42,7 @@ TSimbaNativeInterface_Windows = class(TSimbaNativeInterface) function GetMousePosition: TPoint; override; function GetMousePosition(Window: TWindowHandle): TPoint; override; + procedure KeySend(Text: PChar; TextLen: Integer; SleepTimes: PInt32); override; function KeyPressed(Key: EKeyCode): Boolean; override; procedure KeyDown(Key: EKeyCode); override; procedure KeyUp(Key: EKeyCode); override; @@ -438,6 +434,74 @@ function TSimbaNativeInterface_Windows.GetMousePosition(Window: TWindowHandle): Result.Y := Result.Y - Bounds.Y1; end; +procedure TSimbaNativeInterface_Windows.KeySend(Text: PChar; TextLen: Integer; SleepTimes: PInt32); +var + ShiftDown, CtrlDown, AltDown: Boolean; + + procedure DoSleep; + begin + PreciseSleep(SleepTimes^); + Inc(SleepTimes); + end; + + procedure EnsureModifier(const Needed: Boolean; var isDown: Boolean; const KeyCode: EKeyCode); + begin + if (Needed = isDown) then + Exit; + isDown := Needed; + + if Needed then + KeyDown(KeyCode) + else + KeyUp(KeyCode); + + DoSleep(); + end; + + procedure KeyEvent(VirtualKey: Integer; Down: Boolean); + var + Input: TInput; + begin + Input := Default(TInput); + Input._Type := INPUT_KEYBOARD; + if Down then + Input.ki.dwFlags := KEYEVENTF_SCANCODE + else + Input.ki.dwFlags := KEYEVENTF_KEYUP or KEYEVENTF_SCANCODE; + Input.ki.wScan := MapVirtualKey(VirtualKey, 0); + + SendInput(1, @Input, SizeOf(Input)); + + DoSleep(); + end; + +var + I: Integer; + ScanCode: SHORT; +begin + ShiftDown := False; + CtrlDown := False; + AltDown := False; + + try + for I := 0 to TextLen - 1 do + begin + ScanCode := VKKeyScan(Text[I]); + + EnsureModifier((ScanCode and $100) > 0, ShiftDown, EKeyCode.SHIFT); + EnsureModifier((ScanCode and $200) > 0, CtrlDown, EKeyCode.CONTROL); + EnsureModifier((ScanCode and $400) > 0, AltDown, EKeyCode.MENU); + + KeyEvent(ScanCode and $FF, True); + KeyEvent(ScanCode and $FF, False); + end; + finally + EnsureModifier(False, ShiftDown, EKeyCode.SHIFT); + EnsureModifier(False, CtrlDown, EKeyCode.CONTROL); + EnsureModifier(False, AltDown, EKeyCode.MENU); + end; +end; + function TSimbaNativeInterface_Windows.MousePressed(Button: EMouseButton): Boolean; begin Result := False; @@ -456,38 +520,6 @@ function TSimbaNativeInterface_Windows.KeyPressed(Key: EKeyCode): Boolean; Result := (GetAsyncKeyState(Ord(Key)) and $8000 <> 0); //only check if high-order bit is set end; -procedure TSimbaNativeInterface_Windows.KeyDownNativeKeyCode(EKeyCode: Integer); -var - Input: TInput; -begin - Input := Default(TInput); - Input._Type := INPUT_KEYBOARD; - Input.ki.dwFlags := KEYEVENTF_SCANCODE; - Input.ki.wScan := MapVirtualKey(EKeyCode, 0); - - SendInput(1, @Input, SizeOf(Input)); -end; - -procedure TSimbaNativeInterface_Windows.KeyUpNativeKeyCode(EKeyCode: Integer); -var - Input: TInput; -begin - Input := Default(TInput); - Input._Type := INPUT_KEYBOARD; - Input.ki.dwFlags := KEYEVENTF_KEYUP or KEYEVENTF_SCANCODE; - Input.ki.wScan := MapVirtualKey(EKeyCode, 0); - - SendInput(1, @Input, SizeOf(Input)); -end; - -function TSimbaNativeInterface_Windows.GetNativeKeyCodeAndModifiers(Character: Char; out Code: Integer; out Modifiers: TShiftState): Boolean; -begin - Result := True; - - Code := VKKeyScan(Character) and $FF; - Modifiers := TShiftState(VKKeyScan(Character) shr 8 and $FF); -end; - procedure TSimbaNativeInterface_Windows.KeyDown(Key: EKeyCode); var Input: TInput; diff --git a/Source/simba.target.pas b/Source/simba.target.pas index 378dd51a3..735b6800a 100644 --- a/Source/simba.target.pas +++ b/Source/simba.target.pas @@ -31,7 +31,7 @@ TTargetMethods = record KeyDown: procedure(Target: Pointer; Key: EKeyCode); KeyUp: procedure(Target: Pointer; Key: EKeyCode); - KeySend: procedure(Target: Pointer; Key: Char; KeyDownTime, KeyUpTime, ModifierDownTime, ModifierUpTime: Integer); + KeySend: procedure(Target: Pointer; Text: PChar; TextLen: Int32; SleepTimes: PInt32); KeyPressed: function(Target: Pointer; Key: EKeyCode): Boolean; MouseTeleport: procedure(Target: Pointer; P: TPoint); @@ -111,7 +111,7 @@ TTargetMethods = record procedure KeyDown(Key: EKeyCode); procedure KeyUp(Key: EKeyCode); - procedure KeySend(Key: Char; KeyDownTime, KeyUpTime, ModifierDownTime, ModifierUpTime: Integer); + procedure KeySend(Text: String; SleepTimes: PInt32); function KeyPressed(Key: EKeyCode): Boolean; function ValidateBounds(var ABounds: TBox): Boolean; @@ -495,12 +495,14 @@ procedure TSimbaTarget.KeyUp(Key: EKeyCode); FMethods.KeyUp(FTarget, Key); end; -procedure TSimbaTarget.KeySend(Key: Char; KeyDownTime, KeyUpTime, ModifierDownTime, ModifierUpTime: Integer); +procedure TSimbaTarget.KeySend(Text: String; SleepTimes: PInt32); begin + if (Length(Text) = 0) then + Exit; CheckAutoFocus(); if HasMethod(FMethods.KeySend, 'KeySend') then - FMethods.KeySend(FTarget, Key, KeyDownTime, KeyUpTime, ModifierDownTime, ModifierUpTime); + FMethods.KeySend(FTarget, PChar(Text), Length(Text), SleepTimes); end; function TSimbaTarget.KeyPressed(Key: EKeyCode): Boolean; diff --git a/Source/targets/simba.target_eios.pas b/Source/targets/simba.target_eios.pas index c1570bb9b..2371bf17d 100644 --- a/Source/targets/simba.target_eios.pas +++ b/Source/targets/simba.target_eios.pas @@ -85,7 +85,7 @@ procedure EIOSTarget_GetDimensions(Target: Pointer; out Width, Height: Integer); procedure EIOSTarget_KeyDown(Target: Pointer; Key: EKeyCode); procedure EIOSTarget_KeyUp(Target: Pointer; Key: EKeyCode); -procedure EIOSTarget_KeySend(Target: Pointer; Key: Char; KeyDownTime, KeyUpTime, ModifierDownTime, ModifierUpTime: Integer); +procedure EIOSTarget_KeySend(Target: Pointer; Text: PChar; TextLen: Int32; SleepTimes: PInt32); function EIOSTarget_KeyPressed(Target: Pointer; Key: EKeyCode): Boolean; function EIOSTarget_MousePressed(Target: Pointer; Button: EMouseButton): Boolean; @@ -278,12 +278,12 @@ procedure EIOSTarget_KeyUp(Target: Pointer; Key: EKeyCode); end; end; -procedure EIOSTarget_KeySend(Target: Pointer; Key: Char; KeyDownTime, KeyUpTime, ModifierDownTime, ModifierUpTime: Integer); +procedure EIOSTarget_KeySend(Target: Pointer; Text: PChar; TextLen: Int32; SleepTimes: PInt32); begin with PEIOSTarget(Target)^ do begin if Assigned(SendString) then - SendString(Target, PChar(String(Key)), KeyDownTime, ModifierDownTime); + SendString(Target, Text, SleepTimes[0], SleepTimes[1]); end; end; diff --git a/Source/targets/simba.target_plugin.pas b/Source/targets/simba.target_plugin.pas index b978fe181..87cfa402a 100644 --- a/Source/targets/simba.target_plugin.pas +++ b/Source/targets/simba.target_plugin.pas @@ -38,7 +38,7 @@ TSimbaPluginTarget = record KeyDown: procedure(Target: Pointer; Key: Int32); cdecl; KeyUp: procedure(Target: Pointer; Key: Int32); cdecl; - KeySend: procedure(Target: Pointer; Key: Char; KeyDownTime, KeyUpTime, ModifierDownTime, ModifierUpTime: Int32); cdecl; + KeySend: procedure(Target: Pointer; Text: PChar; TextLen: Int32; SleepTimes: PInt32); cdecl; KeyPressed: function(Target: Pointer; Key: Int32): Boolean; cdecl; end; @@ -57,7 +57,7 @@ procedure PluginTarget_MouseScroll(Target: Pointer; Scrolls: Integer); procedure PluginTarget_KeyDown(Target: Pointer; Key: EKeyCode); procedure PluginTarget_KeyUp(Target: Pointer; Key: EKeyCode); -procedure PluginTarget_KeySend(Target: Pointer; Key: Char; KeyDownTime, KeyUpTime, ModifierDownTime, ModifierUpTime: Integer); +procedure PluginTarget_KeySend(Target: Pointer; Text: PChar; TextLen: Int32; SleepTimes: PInt32); function PluginTarget_KeyPressed(Target: Pointer; Key: EKeyCode): Boolean; function PluginTarget_IsValid(Target: Pointer): Boolean; @@ -231,13 +231,13 @@ procedure PluginTarget_KeyUp(Target: Pointer; Key: EKeyCode); end; end; -procedure PluginTarget_KeySend(Target: Pointer; Key: Char; KeyDownTime, KeyUpTime, ModifierDownTime, ModifierUpTime: Integer); +procedure PluginTarget_KeySend(Target: Pointer; Text: PChar; TextLen: Int32; SleepTimes: PInt32); begin with PSimbaPluginTarget(Target)^ do begin CheckExported('SimbaPluginTarget_KeySend', KeySend); - KeySend(Target, Key, KeyDownTime, KeyUpTime, ModifierDownTime, ModifierUpTime); + KeySend(Target, Text, TextLen, SleepTimes); end; end; diff --git a/Source/targets/simba.target_window.pas b/Source/targets/simba.target_window.pas index 162d5710f..b2742f184 100644 --- a/Source/targets/simba.target_window.pas +++ b/Source/targets/simba.target_window.pas @@ -17,7 +17,7 @@ function WindowTarget_IsValid(Target: Pointer): Boolean; procedure WindowTarget_KeyDown(Target: Pointer; Key: EKeyCode); procedure WindowTarget_KeyUp(Target: Pointer; Key: EKeyCode); -procedure WindowTarget_KeySend(Target: Pointer; Key: Char; KeyDownTime, KeyUpTime, ModifierDownTime, ModifierUpTime: Integer); +procedure WindowTarget_KeySend(Target: Pointer; Text: PChar; TextLen: Integer; SleepTimes: PInt32); function WindowTarget_KeyPressed(Target: Pointer; Key: EKeyCode): Boolean; procedure WindowTarget_MouseTeleport(Target: Pointer; P: TPoint); @@ -79,9 +79,9 @@ procedure WindowTarget_KeyUp(Target: Pointer; Key: EKeyCode); SimbaNativeInterface.KeyUp(Key); end; -procedure WindowTarget_KeySend(Target: Pointer; Key: Char; KeyDownTime, KeyUpTime, ModifierDownTime, ModifierUpTime: Integer); +procedure WindowTarget_KeySend(Target: Pointer; Text: PChar; TextLen: Integer; SleepTimes: PInt32); begin - SimbaNativeInterface.KeySend(Key, KeyDownTime, KeyUpTime, ModifierDownTime, ModifierUpTime); + SimbaNativeInterface.KeySend(Text, TextLen, SleepTimes); end; function WindowTarget_KeyPressed(Target: Pointer; Key: EKeyCode): Boolean;