spiegel-keyman/windows/src/engine/kmcomapi/util/utilkeymancontrol.pas

124 lines
3.8 KiB
ObjectPascal

(*
Name: utilkeymancontrol
Copyright: Copyright (C) SIL International.
Documentation:
Description:
Create Date: 20 Jun 2006
Modified Date: 25 Oct 2016
Authors: mcdurdin
Related Files:
Dependencies:
Bugs:
Todo:
Notes:
History: 20 Jun 2006 - mcdurdin - Initial version
01 Aug 2006 - mcdurdin - Add HideVisualKeyboard and ShowVisualKeyboard
14 Sep 2006 - mcdurdin - Get path of kmcomapi.dll, not calling application
04 Dec 2006 - mcdurdin - Support running as elevated in Vista
16 May 2007 - mcdurdin - Return extra information if Keyman unable to start
30 May 2007 - mcdurdin - Refactor OS checks for newer OS versions
27 Mar 2008 - mcdurdin - Use the first active product for control when no product passed
12 Mar 2010 - mcdurdin - I2230 - Resolve crashes due to incorrect reference counting
03 May 2011 - mcdurdin - I2890 - Record diagnostic data when encountering registry errors
18 May 2012 - mcdurdin - I3331 - V9.0 - Remove koRunElevatedInVista option
08 Jun 2012 - mcdurdin - I3349 - V9.0 - Consolidate all process creation into TUtilExecute
25 Oct 2016 - mcdurdin - I5125 - Failure to start Keyman due to path errors
*)
unit utilkeymancontrol;
interface
uses Windows, custinterfaces, keymanapi_TLB;
type
TKeymanController = class
private
FKeyman: TObject;
procedure ControlKeyman(const code: string);
public
constructor Create(AKeyman: TObject);
procedure StartKeyman;
procedure StopKeyman;
procedure ShowVisualKeyboard;
procedure HideVisualKeyboard;
end;
implementation
uses
System.SysUtils,
System.Variants,
ErrorControlledRegistry,
RegistryKeys,
keymanerrorcodes,
GetOsVersion,
KeymanOptionNames,
keymanpaths,
utilexecute,
keyman_implementation;
{ TKeymanController }
constructor TKeymanController.Create(AKeyman: TObject);
begin
inherited Create;
FKeyman := AKeyman;
end;
procedure TKeymanController.StartKeyman;
begin
ControlKeyman('start');
end;
procedure TKeymanController.StopKeyman;
begin
ControlKeyman('stop');
end;
procedure TKeymanController.ControlKeyman(const code: string);
var
verb, path: string;
hwnd: THandle;
begin
path := TKeymanPaths.KeymanEngineInstallPath(TKeymanPaths.S_KeymanExe);
if not FileExists(path) then
begin
(FKeyman as TKeyman).Errors.AddFmt(KMN_E_KeymanControl_CannotStartProduct, VarArrayOf([path, 'Keyman']), kesFatal);
Exit;
end;
hwnd := GetActiveWindow;
if hwnd = 0 then
hwnd := GetDesktopWindow;
if ((FKeyman as TKeyman).Options as IKeymanOptions).Items[koDebugging].Value = True then
begin
// We run Keyman elevated when Debugging mode is switched on. This is because starting a
// trace requires certain permissions which a normal user doesn't have (refer StartTrace
// documentation). This is also a good visual reminder to the user that Debugging is
// active and as it is slightly annoying to be prompted to elevate, will over time encourage
// them to switch it off again, which is good ;-)
verb := 'runas';
end
else
verb := 'open';
if not TUtilExecute.Shell(hwnd, path, ExtractFileDir(path), '-kmc '+code, SW_SHOWNORMAL, verb) then // I3349
(FKeyman as TKeyman).Errors.AddFmt(KMN_E_KeymanControl_CannotStartProduct, VarArrayOf([path + ' (error='+IntToStr(GetLastError)+','+SysErrorMessage(GetLastError)+')', 'Keyman']), kesFatal);
end;
procedure TKeymanController.HideVisualKeyboard;
begin
ControlKeyman('hidevisualkeyboard');
end;
procedure TKeymanController.ShowVisualKeyboard;
begin
ControlKeyman('showvisualkeyboard');
end;
end.