fix(windows): Windows touch keyboard would cancel on each keystroke

Fixes #2450. When Keyman serialized input, it would cause the touch keyboard to cancel
because the touch keyboard thought the received event meant the user was touching the
physical keyboard. This resolves that problem, using a watch timer to check the visibility
of the touch input panel.
This commit is contained in:
Marc Durdin 2020-02-04 16:14:37 +11:00
parent 76891caaa8
commit 1ebe2f5fa1
9 changed files with 500 additions and 8 deletions

View file

@ -34,4 +34,10 @@ object frmKeyman7Main: TfrmKeyman7Main
Left = 280
Top = 104
end
object tmrCheckInputPane: TTimer
Interval = 500
OnTimer = tmrCheckInputPaneTimer
Left = 96
Top = 104
end
end

View file

@ -150,6 +150,7 @@ uses
Keyman.System.DebugLogClient,
Keyman.System.DebugLogManager,
Keyman.System.FrameworkInputPane,
keymanapi_TLB,
//TOUCH UfrmTouchKeyboard,
@ -198,10 +199,12 @@ type
mnu: TPopupMenu;
tmrTestKeymanFunctioning: TTimer;
tmrOnlineUpdateCheck: TTimer;
tmrCheckInputPane: TTimer;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure tmrTestKeymanFunctioningTimer(Sender: TObject);
procedure tmrOnlineUpdateCheckTimer(Sender: TObject);
procedure tmrCheckInputPaneTimer(Sender: TObject);
private
InMenuLoop: Integer; // I1082 - Avoid menu nasty flicker with rapid click
FClosingApp: Boolean;
@ -225,6 +228,9 @@ type
FHotkeyWindow: HWND;
FHotkeys: TIntegerList;
FInputPane: TFrameworkInputPane;
FIsInputPaneVisible: Boolean;
//TOUCH FCurrentContext: string;
function AddTaskbarIcon: Boolean;
@ -533,6 +539,8 @@ begin
ChangeWindowMessageFilter(sMsg_TaskbarRestart, MSGFLT_ADD);
ChangeWindowMessageFilter(WM_USER_PlatformComms, MSGFLT_ADD);
FInputPane := TFrameworkInputPane.Create;
PostMessage(Handle, WM_USER_Start, 0, 0);
end;
@ -543,6 +551,8 @@ end;}
procedure TfrmKeyman7Main.FormDestroy(Sender: TObject);
begin
FreeAndNil(FInputPane);
ClosePlatformComms64;
UnregisterHotkeys;
@ -1766,6 +1776,23 @@ end;
//TOUCH else Result := kmcom.Options['koUseTouchLayout'].Value;
//TOUCH end;
procedure TfrmKeyman7Main.tmrCheckInputPaneTimer(Sender: TObject);
var
r: TRect;
isVisible: Boolean;
begin
if Assigned(FInputPane) and FInputPane.GetLocation(r) then
begin
isVisible := not r.IsEmpty;
if FIsInputPaneVisible <> isVisible then
begin
FIsInputPaneVisible := isVisible;
kmint.KeymanEngineControl.UpdateTouchPanelVisibility(isVisible);
end;
//TDebugLogClient.Instance.WriteMessage('InputPane Location: %d, %d, %d, %d', [r.Left, r.Top, r.Right, r.Bottom]);
end;
end;
procedure TfrmKeyman7Main.tmrOnlineUpdateCheckTimer(Sender: TObject);
begin
with TRegistryErrorControlled.Create do // I2890

View file

@ -140,7 +140,8 @@ uses
Keyman.System.DebugLogCommon in '..\..\global\delphi\debug\Keyman.System.DebugLogCommon.pas',
Keyman.System.SharedBuffers in 'Keyman.System.SharedBuffers.pas',
Keyman.System.Security in '..\..\global\delphi\general\Keyman.System.Security.pas',
Keyman.Winapi.VersionHelpers in '..\..\global\delphi\winapi\Keyman.Winapi.VersionHelpers.pas';
Keyman.Winapi.VersionHelpers in '..\..\global\delphi\winapi\Keyman.Winapi.VersionHelpers.pas',
Keyman.System.FrameworkInputPane in 'touchkeyboard\Keyman.System.FrameworkInputPane.pas';
{$R ICONS.RES}
{$R VERSION.RES}

View file

@ -7,7 +7,7 @@
<TargetedPlatforms>1</TargetedPlatforms>
<AppType>Console</AppType>
<FrameworkType>VCL</FrameworkType>
<ProjectVersion>18.4</ProjectVersion>
<ProjectVersion>18.7</ProjectVersion>
<Platform Condition="'$(Platform)'==''">Win32</Platform>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
@ -265,6 +265,7 @@
<DCCReference Include="Keyman.System.SharedBuffers.pas"/>
<DCCReference Include="..\..\global\delphi\general\Keyman.System.Security.pas"/>
<DCCReference Include="..\..\global\delphi\winapi\Keyman.Winapi.VersionHelpers.pas"/>
<DCCReference Include="touchkeyboard\Keyman.System.FrameworkInputPane.pas"/>
<None Include="Profiling\AQtimeModule1.aqt"/>
<BuildConfiguration Include="Debug">
<Key>Cfg_2</Key>
@ -327,9 +328,9 @@
<Platform value="Win64">False</Platform>
</Platforms>
<Deployment Version="3">
<DeployFile LocalName="keyman.exe" Configuration="Debug" Class="ProjectOutput">
<DeployFile LocalName="Profiling\AQtimeModule1.aqt" Configuration="Debug" Class="ProjectFile">
<Platform Name="Win32">
<RemoteName>keyman.exe</RemoteName>
<RemoteDir>.\</RemoteDir>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
@ -339,9 +340,9 @@
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="Profiling\AQtimeModule1.aqt" Configuration="Debug" Class="ProjectFile">
<DeployFile LocalName="keyman.exe" Configuration="Debug" Class="ProjectOutput">
<Platform Name="Win32">
<RemoteDir>.\</RemoteDir>
<RemoteName>keyman.exe</RemoteName>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
@ -350,7 +351,6 @@
<Operation>1</Operation>
</Platform>
<Platform Name="Win32">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>0</Operation>
</Platform>
</DeployClass>
@ -360,6 +360,12 @@
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidFileProvider">
<Platform Name="Android">
<RemoteDir>res\xml</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidGDBServer">
<Platform Name="Android">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
@ -396,6 +402,18 @@
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidSplashStylesV21">
<Platform Name="Android">
<RemoteDir>res\values-v21</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_Colors">
<Platform Name="Android">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_DefaultAppIcon">
<Platform Name="Android">
<RemoteDir>res\drawable</RemoteDir>
@ -432,6 +450,36 @@
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_NotificationIcon24">
<Platform Name="Android">
<RemoteDir>res\drawable-mdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_NotificationIcon36">
<Platform Name="Android">
<RemoteDir>res\drawable-hdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_NotificationIcon48">
<Platform Name="Android">
<RemoteDir>res\drawable-xhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_NotificationIcon72">
<Platform Name="Android">
<RemoteDir>res\drawable-xxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_NotificationIcon96">
<Platform Name="Android">
<RemoteDir>res\drawable-xxxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage426">
<Platform Name="Android">
<RemoteDir>res\drawable-small</RemoteDir>
@ -456,6 +504,12 @@
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_Strings">
<Platform Name="Android">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="DebugSymbols">
<Platform Name="iOSSimulator">
<Operation>1</Operation>
@ -472,6 +526,10 @@
<Operation>1</Operation>
<Extensions>.framework</Extensions>
</Platform>
<Platform Name="OSX64">
<Operation>1</Operation>
<Extensions>.framework</Extensions>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
@ -481,6 +539,10 @@
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="OSX64">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
<Extensions>.dll;.bpl</Extensions>
@ -503,6 +565,10 @@
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="OSX64">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
<Extensions>.bpl</Extensions>
@ -524,6 +590,9 @@
<Platform Name="OSX32">
<Operation>0</Operation>
</Platform>
<Platform Name="OSX64">
<Operation>0</Operation>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
@ -539,6 +608,17 @@
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch1024x768">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch1536">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
@ -550,6 +630,39 @@
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch1536x2048">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch1668">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch1668x2388">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch2048">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
@ -561,6 +674,61 @@
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch2048x1536">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch2048x2732">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch2224">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch2388x1668">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch2732x2048">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch768">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
@ -572,6 +740,116 @@
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch768x1024">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch1125">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch1136x640">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch1242">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch1242x2688">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch1334">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch1792">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch2208">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch2436">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch2688x1242">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch320">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
@ -605,6 +883,28 @@
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch750">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch828">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectAndroidManifest">
<Platform Name="Android">
<Operation>1</Operation>
@ -634,6 +934,7 @@
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectOSXDebug"/>
<DeployClass Name="ProjectOSXEntitlements"/>
<DeployClass Name="ProjectOSXInfoPList"/>
<DeployClass Name="ProjectOSXResource">
@ -641,6 +942,10 @@
<RemoteDir>Contents\Resources</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="OSX64">
<RemoteDir>Contents\Resources</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Required="true" Name="ProjectOutput">
<Platform Name="Android">
@ -662,6 +967,9 @@
<Platform Name="OSX32">
<Operation>1</Operation>
</Platform>
<Platform Name="OSX64">
<Operation>1</Operation>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
@ -701,6 +1009,7 @@
<ProjectRoot Platform="Win32" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="OSX32" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="Android" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="OSX64" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="iOSSimulator" Name="$(PROJECTNAME).app"/>
</Deployment>
</BorlandProject>

View file

@ -0,0 +1,106 @@
unit Keyman.System.FrameworkInputPane;
interface
uses
Winapi.Windows;
// See https://stackoverflow.com/a/55513524/1836776
// https://gist.github.com/DelphiWorlds/2098ebafd20aa43f6c5a69503b06c4ca
// https://docs.microsoft.com/en-us/windows/win32/api/shobjidl_core/nn-shobjidl_core-iframeworkinputpane
const
CLSID_FrameworkInputPane: TGUID = '{D5120AA3-46BA-44C5-822D-CA8092C1FC72}';
type
IFrameworkInputPaneHandler = interface
['{226C537B-1E76-4D9E-A760-33DB29922F18}']
function Showing(
var rcInputPaneScreenLocation: TRect;
fEnsureFocusedElementInView: BOOL
): HResult; stdcall;
function Hiding(
fEnsureFocusedElementInView: BOOL
): HResult; stdcall;
end;
IFrameworkInputPane = interface
['{5752238B-24F0-495A-82F1-2FD593056796}']
function Advise(
pWindow: IUnknown;
pHandler: IFrameworkInputPaneHandler;
var pdwCookie: DWORD
): HRESULT; stdcall;
function AdviseWithHWND(
hwnd: HWND;
pHandler: IFrameworkInputPaneHandler;
var pdwCookie: DWORD
): HRESULT; stdcall;
function Unadvise(
dwCookie: DWORD
): HRESULT; stdcall;
function Location(
var prcInputPaneScreenLocation: TRect
): HRESULT; stdcall;
end;
TFrameworkInputPane = class
private
FInputPane: IFrameworkInputPane;
public
constructor Create;
destructor Destroy; override;
function GetLocation(var rt: TRECT): Boolean;
end;
implementation
uses
Winapi.ActiveX,
Keyman.System.DebugLogClient;
{ TFrameworkInputWrapper }
constructor TFrameworkInputPane.Create;
var
hr: HRESULT;
begin
inherited Create;
FInputPane := nil;
hr := CoCreateInstance(
CLSID_FrameworkInputPane, nil, CLSCTX_ALL {CLSCTX_INPROC_SERVER}, IFrameworkInputPane, FInputPane);
if not Succeeded(hr) then
begin
// We'll silently fail; this may be an older OS
FInputPane := nil;
TDebugLogClient.Instance.WriteMessage('Unable to instantiate IFrameworkInputPane: %x', [hr]);
end;
end;
destructor TFrameworkInputPane.Destroy;
begin
FInputPane := nil;
inherited Destroy;
end;
function TFrameworkInputPane.GetLocation(var rt: TRECT): Boolean;
begin
Result := False;
rt := rt.Empty;
if Assigned(FInputPane) then
begin
Result := not FAILED(FInputPane.Location(rt));
end;
end;
end.

View file

@ -34,3 +34,5 @@ EXPORTS
Keyman_ResetInitialisation
Keyman_WriteDebugEvent
Keyman_UpdateTouchPanelVisibility

View file

@ -94,6 +94,25 @@ BOOL IsConsoleWindow(HWND hwnd) {
return last_isConsoleWindow;
}
/*
Test for touch panel visibility (#2450). UpdateTouchPanelVisibility is called periodically by
keyman.exe to refresh the visibility flag.
*/
static BOOL touchPanelVisible;
void WINAPI Keyman_UpdateTouchPanelVisibility(BOOL isVisible) {
touchPanelVisible = isVisible;
SendDebugMessageFormat(0, sdmAIDefault, 0, "Keyman_UpdateTouchPanelVisibility: isVisible=%d", touchPanelVisible);
}
BOOL IsTouchPanelVisible() {
// Note: GetCurrentInputMessageSource does not work in this context
// Using IFrameworkInputPaneHandler events only works for a specific window, so not helpful for us.
return touchPanelVisible;
}
/*
Cache UseRegisterHotkey debug flag for this session
*/
@ -132,6 +151,13 @@ LRESULT _kmnLowLevelKeyboardProc(
return CallNextHookEx(Globals::get_hhookLowLevelKeyboardProc(), nCode, wParam, lParam);
}
if (IsTouchPanelVisible()) {
// See #2450. The touch panel will close automatically if we reprocess key events
// So we don't want to reprocess events when it is visible.
//SendDebugMessageFormat(0, sdmAIDefault, 0, "kmnLowLevelKeyboardProc: touch panel is visible. Not reprocessing keystrokes");
return CallNextHookEx(Globals::get_hhookLowLevelKeyboardProc(), nCode, wParam, lParam);
}
DWORD Flag = 0;
if (UseRegisterHotkey()) {
switch (hs->vkCode) {

View file

@ -73,6 +73,7 @@ type
TKeyman32GetInitialisedFunction = function(var FSingleApp: BOOL): BOOL; stdcall;
TKeyman32ControllerSendMessageFunction = function(msg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
TKeyman32ControllerPostMessageFunction = procedure(msg: UINT; wParam: WPARAM; lParam: LPARAM); stdcall;
TKeyman32UpdateTouchPanelVisibilityFunction = procedure(Value: BOOL); stdcall;
TKeymanControl = class(TKeymanAutoObject, IKeymanCustomisationAccess, IIntKeymanControl, IKeymanControl, IKeymanEngineControl)
private
@ -92,6 +93,7 @@ type
FKeyman_PostMasterController: TKeyman32ControllerPostMessageFunction;
FKeyman_PostControllers: TKeyman32ControllerPostMessageFunction;
FKeyman_StartExit: TKeyman32ExitFunction; // I3092
FKeyman_UpdateTouchPanelVisibility: TKeyman32UpdateTouchPanelVisibilityFunction;
procedure LoadKeyman32;
procedure StartKeyman32;
procedure Do_Keyman_Exit;
@ -133,7 +135,7 @@ type
procedure StopKeyman; safecall;
procedure StopVisualKeyboard; safecall;
{ IKeymanControlRestart }
{ IKeymanEngineControl }
procedure RestartEngine; safecall; // 32 bit only
procedure ShutdownKeyman32Engine; safecall; // 32 bit only
procedure StartKeyman32Engine; safecall; // 32 bit only
@ -143,6 +145,7 @@ type
procedure UnregisterControllerWindow(Value: LongWord); safecall; // 32 bit only
procedure DisableUserInterface; safecall;
procedure EnableUserInterface; safecall;
procedure UpdateTouchPanelVisibility(Value: Boolean); safecall;
{ IIntKeymanControl }
procedure AutoApplyKeyman;
@ -570,6 +573,16 @@ begin
{$ENDIF}
end;
procedure TKeymanControl.UpdateTouchPanelVisibility(Value: Boolean);
begin
{$IFDEF WIN64}
Error(Cardinal(E_NOTIMPL));
{$ELSE}
LoadKeyman32;
FKeyman_UpdateTouchPanelVisibility(Value);
{$ENDIF}
end;
procedure TKeymanControl.ShutdownKeyman32Engine;
begin
{$IFDEF WIN64}
@ -707,6 +720,7 @@ begin
@FKeyman_SendMasterController := ProcAddr('Keyman_SendMasterController');
@FKeyman_PostMasterController := ProcAddr('Keyman_PostMasterController');
@FKeyman_PostControllers := ProcAddr('Keyman_PostControllers');
@FKeyman_UpdateTouchPanelVisibility := ProcAddr('Keyman_UpdateTouchPanelVisibility');
end;
end;

View file

@ -31,6 +31,7 @@ type
procedure UnregisterControllerWindow(Value: LongWord); safecall;
procedure DisableUserInterface; safecall;
procedure EnableUserInterface; safecall;
procedure UpdateTouchPanelVisibility(Value: Boolean); safecall;
end;
implementation