mirror of
https://github.com/keymanapp/keyman.git
synced 2026-09-24 08:37:42 +00:00
Merge pull request #16162 from keymanapp/fix/windows/15152/basekeyboard-user-not-admin
fix(windows): set basekeyboard as current user not the admin user on an elevated process
This commit is contained in:
commit
f8ee1b7c8a
16 changed files with 329 additions and 105 deletions
|
|
@ -91,6 +91,27 @@ function IsProjectFile(const FileName: string): Boolean;
|
|||
function IsKeyboardFile(const FileName: string): Boolean;
|
||||
function RemoveFileExtension(Filename, Extension: string): string;
|
||||
|
||||
(**
|
||||
* Builds the compiled keyboard filename by inserting the base keyboard ID
|
||||
* before the .kmx extension.
|
||||
*
|
||||
* @param KeyboardFileName Keyboard filename, in the form '[path\]keyboardid[.kmx]'
|
||||
* @param BaseKeyboardIDHex Base keyboard KLID in eight digit hexadecimal form
|
||||
* @return Compiled keyboard filename, in the form '[path\]keyboardid-<KLID>.kmx'
|
||||
*)
|
||||
function BuildKeyboardFilenameWithBaseKeyboardID(const KeyboardFileName: string; BaseKeyboardIDHex: string): string;
|
||||
|
||||
(**
|
||||
* Builds the dead-key compiled keyboard filename by inserting the base
|
||||
* keyboard ID and -d suffix before the .kmx extension.
|
||||
*
|
||||
* @param KeyboardFileName Keyboard filename, in the form '[path]\keyboardid[.kmx]'
|
||||
* @param BaseKeyboardIDHex Base keyboard KLID in eight digit hexadecimal form
|
||||
* @return Dead-key compiled keyboard filename, in the form '[path\]keyboardid-<KLID>-d.kmx'
|
||||
*)
|
||||
function BuildKeyboardFilenameWithBaseKeyboardIDAndDeadkey(const KeyboardFileName: string; BaseKeyboardIDHex: string): string;
|
||||
|
||||
|
||||
type
|
||||
TKeymanFileTypeInfo = class
|
||||
public
|
||||
|
|
@ -208,4 +229,14 @@ begin
|
|||
SameText(ExtractFileExt(Filename), ExtractFileExt(PackageFile_Welcome)));
|
||||
end;
|
||||
|
||||
function BuildKeyboardFilenameWithBaseKeyboardID(const KeyboardFileName: string; BaseKeyboardIDHex: string): string;
|
||||
begin
|
||||
Result := ChangeFileExt(KeyboardFileName, '') + '-' + BaseKeyboardIDHex + '.kmx';
|
||||
end;
|
||||
|
||||
function BuildKeyboardFilenameWithBaseKeyboardIDAndDeadkey(const KeyboardFileName: string; BaseKeyboardIDHex: string): string;
|
||||
begin
|
||||
Result := ChangeFileExt(KeyboardFileName, '') + '-' + BaseKeyboardIDHex + '-d.kmx';
|
||||
end;
|
||||
|
||||
end.
|
||||
|
|
|
|||
|
|
@ -1,18 +1,18 @@
|
|||
(*
|
||||
Name: utilstr
|
||||
Copyright: Copyright (C) SIL International.
|
||||
Documentation:
|
||||
Description:
|
||||
Documentation:
|
||||
Description:
|
||||
Create Date: 1 Aug 2006
|
||||
|
||||
Modified Date: 8 Jun 2012
|
||||
Authors: mcdurdin
|
||||
Related Files:
|
||||
Dependencies:
|
||||
Related Files:
|
||||
Dependencies:
|
||||
|
||||
Bugs:
|
||||
Todo:
|
||||
Notes:
|
||||
Bugs:
|
||||
Todo:
|
||||
Notes:
|
||||
History: 01 Aug 2006 - mcdurdin - Refactor util functions into multiple units
|
||||
23 Aug 2006 - mcdurdin - Add StringToExtString and WideQuotedStr functions
|
||||
14 Sep 2006 - mcdurdin - Add RectToString, StringToRect, use widestrings for some functions
|
||||
|
|
@ -58,8 +58,6 @@ function GetTokenFromCaret(line: string; var selx, sellen: Integer): string;
|
|||
|
||||
function WideQuotedStr(const str: WideString): WideString; deprecated; // I3310
|
||||
|
||||
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
|
|
@ -78,7 +76,7 @@ begin
|
|||
Result := '';
|
||||
Exit;
|
||||
end;
|
||||
|
||||
|
||||
if s[1] = '"' then
|
||||
begin
|
||||
Delete(s,1,1);
|
||||
|
|
|
|||
|
|
@ -46,7 +46,8 @@ uses
|
|||
kmint,
|
||||
RegistryKeys,
|
||||
utilexecute,
|
||||
utilkmshell;
|
||||
utilkmshell,
|
||||
utilfiletypes;
|
||||
|
||||
const
|
||||
{ CurrentMnemonicLayoutVersion = 476; // First 9.0 build with fixes for mnemonic layouts }
|
||||
|
|
@ -170,7 +171,7 @@ begin
|
|||
FBaseKeyboardIDHex := IntToHex(BaseKeyboardID, 8);
|
||||
FBaseFileName := Keyboard.Filename;
|
||||
FDestFileName := OutputFileName;
|
||||
FDestDeadkeyFileName := ChangeFileExt(FDestFileName, '') + '-d.kmx'; // I4552
|
||||
FDestDeadkeyFileName := BuildKeyboardFilenameWithBaseKeyboardIDAndDeadkey(FBaseFileName, FBaseKeyboardIDHex); // I4552
|
||||
FMCompilePath := TKeymanPaths.KeymanEngineInstallPath(TKeymanPaths.S_MCompileExe);
|
||||
FDestPath := ExtractFileDir(Keyboard.Filename);
|
||||
|
||||
|
|
|
|||
|
|
@ -183,7 +183,8 @@ uses
|
|||
Keyman.System.DownloadUpdate in 'main\Keyman.System.DownloadUpdate.pas',
|
||||
Keyman.System.ExecutionHistory in '..\..\..\..\common\windows\delphi\general\Keyman.System.ExecutionHistory.pas',
|
||||
Keyman.Configuration.UI.UfrmStartInstall in 'main\Keyman.Configuration.UI.UfrmStartInstall.pas' {frmStartInstall},
|
||||
Keyman.Configuration.Util.NetworkConnection in 'util\Keyman.Configuration.Util.NetworkConnection.pas';
|
||||
Keyman.Configuration.Util.NetworkConnection in 'util\Keyman.Configuration.Util.NetworkConnection.pas',
|
||||
Keyman.Configuration.System.BaseKeyboard in 'main\Keyman.Configuration.System.BaseKeyboard.pas';
|
||||
|
||||
{$R VERSION.RES}
|
||||
{$R manifest.res}
|
||||
|
|
|
|||
|
|
@ -358,6 +358,7 @@
|
|||
<Form>frmStartInstall</Form>
|
||||
</DCCReference>
|
||||
<DCCReference Include="util\Keyman.Configuration.Util.NetworkConnection.pas"/>
|
||||
<DCCReference Include="main\Keyman.Configuration.System.BaseKeyboard.pas"/>
|
||||
<None Include="Profiling\AQtimeModule1.aqt"/>
|
||||
<BuildConfiguration Include="Debug">
|
||||
<Key>Cfg_2</Key>
|
||||
|
|
@ -419,6 +420,12 @@
|
|||
<Platform value="Win64">False</Platform>
|
||||
</Platforms>
|
||||
<Deployment Version="3">
|
||||
<DeployFile LocalName="bin\Win32\Debug\kmshell.exe" Configuration="Debug" Class="ProjectOutput">
|
||||
<Platform Name="Win32">
|
||||
<RemoteName>kmshell.exe</RemoteName>
|
||||
<Overwrite>true</Overwrite>
|
||||
</Platform>
|
||||
</DeployFile>
|
||||
<DeployFile LocalName="Profiling\AQtimeModule1.aqt" Configuration="Debug" Class="ProjectFile">
|
||||
<Platform Name="Win32">
|
||||
<RemoteDir>.\</RemoteDir>
|
||||
|
|
@ -431,12 +438,6 @@
|
|||
<Overwrite>true</Overwrite>
|
||||
</Platform>
|
||||
</DeployFile>
|
||||
<DeployFile LocalName="bin\Win32\Debug\kmshell.exe" Configuration="Debug" Class="ProjectOutput">
|
||||
<Platform Name="Win32">
|
||||
<RemoteName>kmshell.exe</RemoteName>
|
||||
<Overwrite>true</Overwrite>
|
||||
</Platform>
|
||||
</DeployFile>
|
||||
<DeployClass Name="AdditionalDebugSymbols">
|
||||
<Platform Name="OSX32">
|
||||
<Operation>1</Operation>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,108 @@
|
|||
(*
|
||||
* Keyman is copyright (C) SIL Global. MIT License.
|
||||
*
|
||||
* Created by Ross Cruickshank on 2026-09-12
|
||||
*
|
||||
*
|
||||
* This unit assists in setting the base keyboard configuration,
|
||||
* including compiling the installed keyboard layouts against
|
||||
* the selected base keyboard.
|
||||
*)
|
||||
unit Keyman.Configuration.System.BaseKeyboard;
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Winapi.Windows,
|
||||
System.SysUtils,
|
||||
keymanapi_TLB;
|
||||
|
||||
(**
|
||||
* Returns true if the keyboard files need to be compiled for the specified KLID.
|
||||
* @param BaseKeyboardID KLID of the base keyboard to compile.
|
||||
* @returns True If the keyboard files need to be compiled.
|
||||
*)
|
||||
function BaseKeyboardNeedsMCompile(BaseKeyboardID: Integer): Boolean;
|
||||
|
||||
(**
|
||||
* Sets the base keyboard KLID for the current user and compiles the keyboard
|
||||
* layout files if necessary. In the case the compiled keyboard files are
|
||||
*not present, it will require elevation.
|
||||
* @param WindowHandle Window handle to own the elevation prompt.
|
||||
* @param BaseKeyboardID KLID of the base keyboard KLID to set.
|
||||
* @returns True when the base keyboard setting has been applied.
|
||||
*)
|
||||
function SetBaseKeyboard(WindowHandle: THandle; BaseKeyboardID: Integer): Boolean;
|
||||
|
||||
(**
|
||||
* Compiles the installed keyboard layouts for the specified KLID.
|
||||
* Must run elevated.
|
||||
*
|
||||
* @param BaseKeyboardID KLID of the base keyboard to compile.
|
||||
* @returns True when the compilation is successful.
|
||||
*)
|
||||
function MCompileBaseKeyboard(BaseKeyboardID: Integer): Boolean;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
kmint,
|
||||
utilkmshell,
|
||||
utilfiletypes;
|
||||
|
||||
function BaseKeyboardNeedsMCompile(BaseKeyboardID: Integer): Boolean;
|
||||
var
|
||||
I: Integer;
|
||||
Keyboard: IKeymanKeyboardInstalled;
|
||||
KeyboardFileName: string;
|
||||
BaseKeyboardIDHex: string;
|
||||
begin
|
||||
BaseKeyboardIDHex := IntToHex(BaseKeyboardID, 8);
|
||||
for I := 0 to kmcom.Keyboards.Count - 1 do
|
||||
begin
|
||||
Keyboard := kmcom.Keyboards.Items[I];
|
||||
KeyboardFileName := Keyboard.Filename;
|
||||
if FileExists(KeyboardFileName) and
|
||||
(not FileExists(BuildKeyboardFilenameWithBaseKeyboardID(KeyboardFileName, BaseKeyboardIDHex)) or
|
||||
not FileExists(BuildKeyboardFilenameWithBaseKeyboardIDAndDeadkey(KeyboardFileName, BaseKeyboardIDHex))) then
|
||||
Exit(True);
|
||||
end;
|
||||
Result := False;
|
||||
end;
|
||||
|
||||
function SetBaseKeyboard(WindowHandle: THandle; BaseKeyboardID: Integer): Boolean;
|
||||
begin
|
||||
Result := True;
|
||||
if BaseKeyboardNeedsMCompile(BaseKeyboardID) then
|
||||
begin
|
||||
if not kmcom.SystemInfo.IsAdministrator then
|
||||
begin
|
||||
Result := WaitForElevatedConfiguration(WindowHandle, '-mcompilekbds ' + IntToHex(BaseKeyboardID, 8)) = 0;
|
||||
end
|
||||
else
|
||||
Result := MCompileBaseKeyboard(BaseKeyboardID);
|
||||
end;
|
||||
if not Result then
|
||||
Exit;
|
||||
kmcom.Options['koBaseLayout'].Value := BaseKeyboardID;
|
||||
kmcom.Options.Apply;
|
||||
end;
|
||||
|
||||
function MCompileBaseKeyboard(BaseKeyboardID: Integer): Boolean;
|
||||
var
|
||||
i: Integer;
|
||||
kbd: IKeymanKeyboardInstalled;
|
||||
begin
|
||||
Result := False;
|
||||
// can be called from command line so test for admin
|
||||
if not kmcom.SystemInfo.IsAdministrator then
|
||||
Exit;
|
||||
for i := 0 to kmcom.Keyboards.Count - 1 do
|
||||
begin
|
||||
kbd := kmcom.Keyboards[i];
|
||||
(kbd as IKeymanKeyboardInstalled2).MCompileForBaseKeyboard(BaseKeyboardID);
|
||||
end;
|
||||
Result := True;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
|
@ -11,13 +11,21 @@ type
|
|||
TfrmBaseKeyboard = class(TfrmWebContainer)
|
||||
procedure TntFormCreate(Sender: TObject);
|
||||
private
|
||||
FBaseKeyboardID: Integer;
|
||||
procedure Footer_Cancel;
|
||||
procedure Footer_OK(params: TStringList);
|
||||
protected
|
||||
procedure FireCommand(const command: WideString; params: TStringList); override;
|
||||
end;
|
||||
|
||||
function ConfigureBaseKeyboard: Boolean;
|
||||
(**
|
||||
* Displays a form for the user to select a base keyboard. If the user selects a base
|
||||
* keyboard, the KLID is used to Set the Base Keyboard.
|
||||
*
|
||||
* @returns True if the user selected base keyboard has been set.
|
||||
*)
|
||||
function ConfigureAndSetBaseKeyboard(WindowHandle: THandle): Boolean;
|
||||
|
||||
|
||||
implementation
|
||||
|
||||
|
|
@ -25,15 +33,22 @@ implementation
|
|||
|
||||
uses
|
||||
BaseKeyboards,
|
||||
kmint;
|
||||
ErrorControlledRegistry,
|
||||
RegistryKeys,
|
||||
keymanapi_TLB,
|
||||
Keyman.Configuration.System.BaseKeyboard,
|
||||
kmint,
|
||||
utilkmshell;
|
||||
|
||||
function ConfigureBaseKeyboard: Boolean;
|
||||
|
||||
function ConfigureAndSetBaseKeyboard(WindowHandle: THandle): Boolean;
|
||||
var BaseKeyboardID: Integer;
|
||||
begin
|
||||
with TfrmBaseKeyboard.Create(nil) do
|
||||
try
|
||||
Result := ShowModal = mrOk;
|
||||
if Result then
|
||||
kmcom.Apply;
|
||||
SetBaseKeyboard(WindowHandle, FBaseKeyboardID)
|
||||
finally
|
||||
Free;
|
||||
end;
|
||||
|
|
@ -65,9 +80,9 @@ var
|
|||
v: Integer;
|
||||
begin
|
||||
if not TryStrToInt('$'+params.Values['id'], v) then Exit;
|
||||
kmcom.Options['koBaseLayout'].Value := v;
|
||||
kmcom.Options.Apply;
|
||||
FBaseKeyboardID := v;
|
||||
ModalResult := mrOk;
|
||||
end;
|
||||
|
||||
|
||||
end.
|
||||
|
|
|
|||
|
|
@ -174,6 +174,7 @@ uses
|
|||
Hints,
|
||||
HotkeyUtils,
|
||||
initprog,
|
||||
Keyman.Configuration.System.BaseKeyboard,
|
||||
Keyman.Configuration.System.TIPMaintenance,
|
||||
Keyman.Configuration.UI.UfrmDiagnosticTests,
|
||||
KeymanOptionNames,
|
||||
|
|
@ -198,6 +199,7 @@ uses
|
|||
Keyman.Configuration.UI.UfrmStartInstall,
|
||||
RegistryKeys,
|
||||
SupportXMLRenderer,
|
||||
UfrmBaseKeyboard,
|
||||
UfrmChangeHotkey,
|
||||
UfrmHTML,
|
||||
UfrmInstallKeyboardFromWeb,
|
||||
|
|
@ -664,9 +666,14 @@ end;
|
|||
------------------------------------------------------------------------------}
|
||||
|
||||
procedure TfrmMain.Options_BaseKeyboard; // I4169
|
||||
var
|
||||
BaseKeyboardID: Integer;
|
||||
begin
|
||||
WaitForElevatedConfiguration(Handle, '-basekeyboard');
|
||||
// Refresh will be triggered by elevated process
|
||||
if ConfigureAndSetBaseKeyboard(Handle) then
|
||||
begin
|
||||
DoRefresh;
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
procedure TfrmMain.Options_SettingsManager;
|
||||
|
|
|
|||
|
|
@ -90,6 +90,7 @@ type
|
|||
fmKeyboardWelcome, // I2569
|
||||
fmKeyboardPrint, // I2329
|
||||
fmBaseKeyboard, // I4169
|
||||
fmMCompileKbds,
|
||||
fmUpgradeMnemonicLayout, // I4553
|
||||
fmRepair,
|
||||
fmKeepInTouch,
|
||||
|
|
@ -114,6 +115,7 @@ uses
|
|||
GetOsVersion,
|
||||
help,
|
||||
HTMLHelpViewer,
|
||||
Keyman.Configuration.System.BaseKeyboard,
|
||||
Keyman.Configuration.UI.InstallFile,
|
||||
Keyman.Configuration.System.TIPMaintenance,
|
||||
Keyman.Configuration.System.UImportOlderVersionKeyboards11To13,
|
||||
|
|
@ -205,7 +207,7 @@ end;
|
|||
|
||||
function Init(var FMode: TKMShellMode; KeyboardFileNames: TStrings; var FSilent, FForce, FNoWelcome: Boolean;
|
||||
var FLogFile, FQuery: string; var FDisablePackages, FDefaultUILanguage: string; var FStartWithConfiguration: Boolean;
|
||||
var FParentWindow: THandle; var FDefaultBCP47: string; var FDefaultLangID: Integer): Boolean;
|
||||
var FParentWindow: THandle; var FDefaultBCP47: string; var FDefaultLangID, FBaseKeyboard: Integer): Boolean;
|
||||
var
|
||||
s: string;
|
||||
i: Integer;
|
||||
|
|
@ -262,6 +264,14 @@ begin
|
|||
else if s = '-bd' then FMode := fmBackgroundDownload
|
||||
else if s = '-an' then FMode := fmApplyInstallNow
|
||||
else if s = '-basekeyboard' then FMode := fmBaseKeyboard // I4169
|
||||
else if s = '-mcompilekbds' then
|
||||
begin
|
||||
// Requires elevated context
|
||||
FMode := fmMCompileKbds;
|
||||
Inc(i);
|
||||
if i > ParamCount then Exit;
|
||||
FBaseKeyboard := StrToInt('$' + ParamStr(i));
|
||||
end
|
||||
else if s = '-nowelcome' then FNoWelcome := True
|
||||
else if s = '-kw' then FMode := fmKeyboardWelcome // I2569
|
||||
else if s = '-kp' then FMode := fmKeyboardPrint // I2329
|
||||
|
|
@ -321,7 +331,7 @@ end;
|
|||
|
||||
procedure RunKMCOM(FMode: TKMShellMode; KeyboardFileNames: TStrings; FSilent, FForce, FNoWelcome: Boolean;
|
||||
FLogFile, FQuery: string; FDisablePackages, FDefaultUILanguage: string; FStartWithConfiguration: Boolean; FParentWindow: THandle;
|
||||
const FDefaultBCP47: string; FDefaultLangID: Integer); forward;
|
||||
const FDefaultBCP47: string; FDefaultLangID, FBaseKeyboard: Integer); forward;
|
||||
|
||||
procedure Run;
|
||||
var
|
||||
|
|
@ -332,7 +342,7 @@ var
|
|||
FForce: Boolean;
|
||||
FParentWindow: THandle;
|
||||
FLogFile: string;
|
||||
FDefaultLangID: Integer;
|
||||
FDefaultLangID, FBaseKeyboard: Integer;
|
||||
FDefaultBCP47, FDisablePackages, FDefaultUILanguage: string;
|
||||
FStartWithConfiguration: Boolean;
|
||||
begin
|
||||
|
|
@ -341,7 +351,7 @@ begin
|
|||
KeyboardFileNames := TStringList.Create;
|
||||
try
|
||||
FParentWindow := 0;
|
||||
if not Init(FMode, KeyboardFileNames, FSilent, FForce, FNoWelcome, FLogFile, FQuery, FDisablePackages, FDefaultUILanguage, FStartWithConfiguration, FParentWindow, FDefaultBCP47, FDefaultLangID) then
|
||||
if not Init(FMode, KeyboardFileNames, FSilent, FForce, FNoWelcome, FLogFile, FQuery, FDisablePackages, FDefaultUILanguage, FStartWithConfiguration, FParentWindow, FDefaultBCP47, FDefaultLangID, FBaseKeyboard) then
|
||||
begin
|
||||
//TODO: TUtilExecute.Shell(PChar('hh.exe mk:@MSITStore:'+ExtractFilePath(KMShellExe)+'keyman.chm::/context/keyman_usage.html'), SW_SHOWNORMAL);
|
||||
Exit;
|
||||
|
|
@ -349,7 +359,7 @@ begin
|
|||
|
||||
if not LoadKMCOM then Exit;
|
||||
try
|
||||
RunKMCOM(FMode, KeyboardFileNames, FSilent, FForce, FNoWelcome, FLogFile, FQuery, FDisablePackages, FDefaultUILanguage, FStartWithConfiguration, FParentWindow, FDefaultBCP47, FDefaultLangID);
|
||||
RunKMCOM(FMode, KeyboardFileNames, FSilent, FForce, FNoWelcome, FLogFile, FQuery, FDisablePackages, FDefaultUILanguage, FStartWithConfiguration, FParentWindow, FDefaultBCP47, FDefaultLangID, FBaseKeyboard);
|
||||
finally
|
||||
kmcom := nil;
|
||||
end;
|
||||
|
|
@ -388,7 +398,7 @@ end;
|
|||
|
||||
procedure RunKMCOM(FMode: TKMShellMode; KeyboardFileNames: TStrings; FSilent, FForce, FNoWelcome: Boolean;
|
||||
FLogFile, FQuery: string; FDisablePackages, FDefaultUILanguage: string; FStartWithConfiguration: Boolean;
|
||||
FParentWindow: THandle; const FDefaultBCP47: string; FDefaultLangID: Integer);
|
||||
FParentWindow: THandle; const FDefaultBCP47: string; FDefaultLangID, FBaseKeyboard: Integer);
|
||||
var
|
||||
kdl: IKeymanDefaultLanguage;
|
||||
FIcon: string;
|
||||
|
|
@ -540,7 +550,12 @@ begin
|
|||
end;
|
||||
|
||||
fmBaseKeyboard: // I4169
|
||||
if ConfigureBaseKeyboard
|
||||
if ConfigureAndSetBaseKeyboard(0)
|
||||
then ExitCode := 0
|
||||
else ExitCode := 1;
|
||||
|
||||
fmMCompileKbds:
|
||||
if MCompileBaseKeyboard(FBaseKeyboard)
|
||||
then ExitCode := 0
|
||||
else ExitCode := 1;
|
||||
|
||||
|
|
|
|||
|
|
@ -63,7 +63,8 @@ type
|
|||
TKeymanKeyboardInstalled = class( // I3581
|
||||
TKeymanKeyboard,
|
||||
IIntKeymanKeyboardInstalled,
|
||||
IKeymanKeyboardInstalled)
|
||||
IKeymanKeyboardInstalled,
|
||||
IKeymanKeyboardInstalled2)
|
||||
private
|
||||
FRegKeyboard: TRegKeyboard;
|
||||
FVisualKeyboard: IKeymanVisualKeyboard;
|
||||
|
|
@ -109,9 +110,11 @@ type
|
|||
{ IIntKeymanKeyboardInstalled }
|
||||
function RegKeyboard: TRegKeyboard;
|
||||
procedure ClearVisualKeyboard;
|
||||
procedure UpdateBaseLayout; // I4169
|
||||
procedure RefreshInstallation;
|
||||
|
||||
{ IKeymanKeyboardInstalled2 }
|
||||
procedure MCompileForBaseKeyboard(KLID: Integer); safecall;
|
||||
|
||||
public
|
||||
constructor Create(AContext: TKeymanContext; const Name: string);
|
||||
destructor Destroy; override;
|
||||
|
|
@ -151,17 +154,6 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
procedure TKeymanKeyboardInstalled.UpdateBaseLayout; // I4169
|
||||
begin
|
||||
if FRegKeyboard.MnemonicLayout and FileExists(FRegKeyboard.KeymanFile) then // I4615
|
||||
with TKPRecompileMnemonicKeyboard.Create(Context) do
|
||||
try
|
||||
Execute(FRegKeyboard.KeymanFile, FRegKeyboard.PackageName);
|
||||
finally
|
||||
Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TKeymanKeyboardInstalled.Get_Copyright: WideString;
|
||||
begin
|
||||
Result := FRegKeyboard.Copyright;
|
||||
|
|
@ -475,5 +467,21 @@ begin
|
|||
Result := FRegKeyboard;
|
||||
end;
|
||||
|
||||
{ IKeymanKeyboardInstalled2 }
|
||||
procedure TKeymanKeyboardInstalled.MCompileForBaseKeyboard(KLID: Integer); safecall;
|
||||
var
|
||||
RecompileMnemonicKeyboard: TKPRecompileMnemonicKeyboard;
|
||||
begin
|
||||
if FRegKeyboard.MnemonicLayout and FileExists(FRegKeyboard.KeymanFile) then
|
||||
begin
|
||||
RecompileMnemonicKeyboard := TKPRecompileMnemonicKeyboard.Create(Context);
|
||||
try
|
||||
RecompileMnemonicKeyboard.Execute(FRegKeyboard.KeymanFile, FRegKeyboard.PackageName, KLID);
|
||||
finally
|
||||
RecompileMnemonicKeyboard.Free;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
|
|
|
|||
|
|
@ -1,18 +1,18 @@
|
|||
(*
|
||||
Name: keymanoptions
|
||||
Copyright: Copyright (C) SIL International.
|
||||
Documentation:
|
||||
Description:
|
||||
Documentation:
|
||||
Description:
|
||||
Create Date: 20 Jun 2006
|
||||
|
||||
Modified Date: 6 Feb 2015
|
||||
Authors: mcdurdin
|
||||
Related Files:
|
||||
Dependencies:
|
||||
Related Files:
|
||||
Dependencies:
|
||||
|
||||
Bugs:
|
||||
Todo:
|
||||
Notes:
|
||||
Bugs:
|
||||
Todo:
|
||||
Notes:
|
||||
History: 20 Jun 2006 - mcdurdin - Initial version
|
||||
01 Aug 2006 - mcdurdin - Add AutoRefershKeyman call
|
||||
12 Aug 2008 - mcdurdin - Avoid crash with missing options
|
||||
|
|
@ -67,6 +67,7 @@ uses
|
|||
ErrorControlledRegistry,
|
||||
RegistryKeys,
|
||||
Glossary,
|
||||
isadmin,
|
||||
Keyman.System.BaseKeyboard,
|
||||
KeymanOptionNames,
|
||||
keymanerrorcodes;
|
||||
|
|
@ -111,29 +112,8 @@ begin
|
|||
end;
|
||||
|
||||
procedure TKeymanOptions.Apply;
|
||||
var
|
||||
I, FOldBaseLayout: Integer;
|
||||
begin
|
||||
with TRegistryErrorControlled.Create do // I3717
|
||||
try
|
||||
if OpenKey(SRegKey_KeymanEngine_CU, True) then
|
||||
begin
|
||||
if ValueExists(SRegValue_UnderlyingLayout)
|
||||
then FOldBaseLayout := StrToIntDef('$'+ReadString(SRegValue_UnderlyingLayout),0) // I3759
|
||||
else FOldBaseLayout := TBaseKeyboard.GetDefaultBaseLayoutID;
|
||||
end
|
||||
else
|
||||
FOldBaseLayout := TBaseKeyboard.GetDefaultBaseLayoutID;
|
||||
finally
|
||||
Free;
|
||||
end;
|
||||
|
||||
FInternalOptions.Save(Context);
|
||||
|
||||
if FOldBaseLayout <> Get_Items('koBaseLayout').Value then
|
||||
for I := 0 to Context.Keyboards.Count - 1 do // I4169
|
||||
(Context.Keyboards.Items[I] as IIntKeymanKeyboardInstalled).UpdateBaseLayout;
|
||||
|
||||
Context.Control.AutoApplyKeyman;
|
||||
end;
|
||||
|
||||
|
|
|
|||
50
windows/src/engine/kmcomapi/keymanapi_TLB.pas
generated
50
windows/src/engine/kmcomapi/keymanapi_TLB.pas
generated
|
|
@ -12,7 +12,7 @@ unit keymanapi_TLB;
|
|||
// ************************************************************************ //
|
||||
|
||||
// $Rev: 52393 $
|
||||
// File generated on 16/09/2021 6:54:44 PM from Type Library described below.
|
||||
// File generated on 7/09/2026 3:54:23 PM from Type Library described below.
|
||||
|
||||
// ************************************************************************ //
|
||||
// Type Lib: C:\Projects\keyman\app\windows\src\engine\kmcomapi\kmcomapi (1)
|
||||
|
|
@ -87,6 +87,7 @@ const
|
|||
IID_IKeymanKeyboardLanguagesInstalled: TGUID = '{7DC22BC0-85BB-45C0-8EDB-A2F4BD1D500B}';
|
||||
IID_IKeymanKeyboardLanguagesFile: TGUID = '{5F90BCDA-F1C1-433A-8FD0-B498299D3C30}';
|
||||
IID_IKeymanKeyboardsInstalled2: TGUID = '{EA57C94F-C140-485E-941A-3F1D5A229024}';
|
||||
IID_IKeymanKeyboardInstalled2: TGUID = '{3086C85C-932A-4726-BF76-2D74DD133AC9}';
|
||||
IID_IKeymanPackagesInstalled2: TGUID = '{F23B9848-2AEF-4A2B-BC3A-292E3A00D691}';
|
||||
IID_IKeymanKeyboardFile2: TGUID = '{EDE4326B-51F4-42D5-8251-B20B71993EC8}';
|
||||
IID_IKeymanPackageFile2: TGUID = '{9B43B6BC-C622-47EF-915E-6780CF53BAAA}';
|
||||
|
|
@ -248,6 +249,8 @@ type
|
|||
IKeymanKeyboardLanguagesFileDisp = dispinterface;
|
||||
IKeymanKeyboardsInstalled2 = interface;
|
||||
IKeymanKeyboardsInstalled2Disp = dispinterface;
|
||||
IKeymanKeyboardInstalled2 = interface;
|
||||
IKeymanKeyboardInstalled2Disp = dispinterface;
|
||||
IKeymanPackagesInstalled2 = interface;
|
||||
IKeymanPackagesInstalled2Disp = dispinterface;
|
||||
IKeymanKeyboardFile2 = interface;
|
||||
|
|
@ -1590,6 +1593,51 @@ type
|
|||
out References: OleVariant): WideString; dispid 401;
|
||||
end;
|
||||
|
||||
// *********************************************************************//
|
||||
// Interface: IKeymanKeyboardInstalled2
|
||||
// Flags: (4416) Dual OleAutomation Dispatchable
|
||||
// GUID: {3086C85C-932A-4726-BF76-2D74DD133AC9}
|
||||
// *********************************************************************//
|
||||
IKeymanKeyboardInstalled2 = interface(IKeymanKeyboardInstalled)
|
||||
['{3086C85C-932A-4726-BF76-2D74DD133AC9}']
|
||||
procedure MCompileForBaseKeyboard(KLID: Integer); safecall;
|
||||
end;
|
||||
|
||||
// *********************************************************************//
|
||||
// DispIntf: IKeymanKeyboardInstalled2Disp
|
||||
// Flags: (4416) Dual OleAutomation Dispatchable
|
||||
// GUID: {3086C85C-932A-4726-BF76-2D74DD133AC9}
|
||||
// *********************************************************************//
|
||||
IKeymanKeyboardInstalled2Disp = dispinterface
|
||||
['{3086C85C-932A-4726-BF76-2D74DD133AC9}']
|
||||
procedure MCompileForBaseKeyboard(KLID: Integer); dispid 288;
|
||||
property IconFilename: WideString readonly dispid 257;
|
||||
procedure InstallVisualKeyboard(const Filename: WideString); dispid 258;
|
||||
property KeymanID: Integer readonly dispid 259;
|
||||
property Languages: IKeymanKeyboardLanguagesInstalled readonly dispid 260;
|
||||
property Loaded: WordBool dispid 261;
|
||||
property Options: IKeymanKeyboardOptions readonly dispid 262;
|
||||
property OwnerPackage: IKeymanPackageInstalled readonly dispid 263;
|
||||
property VisualKeyboard: IKeymanVisualKeyboard readonly dispid 264;
|
||||
procedure Uninstall; dispid 265;
|
||||
property Bitmap: IPicture readonly dispid 1;
|
||||
property Copyright: WideString readonly dispid 2;
|
||||
property DefaultBCP47Languages: WideString readonly dispid 3;
|
||||
property DefaultPrimaryLanguage: Integer readonly dispid 4;
|
||||
property DefaultWindowsLanguages: WideString readonly dispid 5;
|
||||
property DefaultHotkey: IKeymanHotkey readonly dispid 6;
|
||||
property Encodings: KeymanKeyboardEncodings readonly dispid 7;
|
||||
property Filename: WideString readonly dispid 8;
|
||||
function GetCharsUsed: WideString; dispid 9;
|
||||
property ID: WideString readonly dispid 10;
|
||||
property LayoutType: KeymanKeyboardLayoutType readonly dispid 11;
|
||||
property Message: WideString readonly dispid 12;
|
||||
property Name: WideString readonly dispid 13;
|
||||
property Version: WideString readonly dispid 14;
|
||||
function SerializeXML(Flags: tagKeymanSerializeFlags; const ImagePath: WideString;
|
||||
out References: OleVariant): WideString; dispid 401;
|
||||
end;
|
||||
|
||||
// *********************************************************************//
|
||||
// Interface: IKeymanPackagesInstalled2
|
||||
// Flags: (4416) Dual OleAutomation Dispatchable
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
// However, when applying changes via the Editor this file will be regenerated
|
||||
// and comments or formatting changes will be lost.
|
||||
// ************************************************************************ //
|
||||
// File generated on 16/09/2021 6:54:45 PM (- $Rev: 12980 $, 32940875).
|
||||
// File generated on 7/09/2026 4:05:40 PM (- $Rev: 12980 $, 1707828).
|
||||
|
||||
[
|
||||
uuid(F16E2A9A-DA46-4EA3-BFF3-BA46B480C961),
|
||||
|
|
@ -60,6 +60,7 @@ library keymanapi
|
|||
interface IKeymanKeyboardLanguagesInstalled;
|
||||
interface IKeymanKeyboardLanguagesFile;
|
||||
interface IKeymanKeyboardsInstalled2;
|
||||
interface IKeymanKeyboardInstalled2;
|
||||
interface IKeymanPackagesInstalled2;
|
||||
interface IKeymanKeyboardFile2;
|
||||
interface IKeymanPackageFile2;
|
||||
|
|
@ -936,6 +937,19 @@ library keymanapi
|
|||
HRESULT _stdcall RefreshInstalledKeyboards(void);
|
||||
};
|
||||
|
||||
[
|
||||
uuid(3086C85C-932A-4726-BF76-2D74DD133AC9),
|
||||
version(19.0),
|
||||
helpstring("https://help.keyman.com/developer/engine/windows/19.0/api/IKeymanKeyboardInstalled2"),
|
||||
dual,
|
||||
oleautomation
|
||||
]
|
||||
interface IKeymanKeyboardInstalled2: IKeymanKeyboardInstalled
|
||||
{
|
||||
[id(0x00000120)]
|
||||
HRESULT _stdcall MCompileForBaseKeyboard(long KLID);
|
||||
};
|
||||
|
||||
[
|
||||
uuid(F23B9848-2AEF-4A2B-BC3A-292E3A00D691),
|
||||
version(14.0),
|
||||
|
|
|
|||
|
|
@ -125,6 +125,7 @@ var
|
|||
FExitCode: Integer;
|
||||
FKVKName: WideString;
|
||||
FCreatedIcon: Boolean;
|
||||
BaseKeyboardID: Integer;
|
||||
begin
|
||||
KL.MethodEnter(Self, 'Execute', [FileName,PackageID,ikPartOfPackage in FInstallOptions ,Force]);
|
||||
try
|
||||
|
|
@ -248,9 +249,11 @@ begin
|
|||
// Recompile a mnemonic layout to the user's selected base layout
|
||||
if ki.MnemonicLayout then // I4169
|
||||
begin
|
||||
with Context as TKeymanContext do
|
||||
BaseKeyboardID := (Options as IKeymanOptions).Items['koBaseLayout'].Value;
|
||||
with TKPRecompileMnemonicKeyboard.Create(Context) do
|
||||
try
|
||||
Execute(FDestFileName, PackageID);
|
||||
Execute(FDestFileName, PackageID, BaseKeyboardID);
|
||||
finally
|
||||
Free;
|
||||
end;
|
||||
|
|
|
|||
|
|
@ -1,18 +1,18 @@
|
|||
(*
|
||||
Name: kprecompilemnemonickeyboard
|
||||
Copyright: Copyright (C) SIL International.
|
||||
Documentation:
|
||||
Description:
|
||||
Documentation:
|
||||
Description:
|
||||
Create Date: 24 Apr 2014
|
||||
|
||||
Modified Date: 13 Mar 2015
|
||||
Authors: mcdurdin
|
||||
Related Files:
|
||||
Dependencies:
|
||||
Related Files:
|
||||
Dependencies:
|
||||
|
||||
Bugs:
|
||||
Todo:
|
||||
Notes:
|
||||
Bugs:
|
||||
Todo:
|
||||
Notes:
|
||||
History: 24 Apr 2014 - mcdurdin - I4174 - V9 - mcompile logs should be stored in diag folder
|
||||
06 Feb 2015 - mcdurdin - I4552 - V9.0 - Add mnemonic recompile option to ignore deadkeys
|
||||
13 Mar 2015 - mcdurdin - I4615 - CrashID:kmshell.exe_9.0.481.0_2C6795CE_EOleException
|
||||
|
|
@ -27,7 +27,7 @@ uses
|
|||
|
||||
type
|
||||
TKPRecompileMnemonicKeyboard = class(TKPBase)
|
||||
procedure Execute(const FileName: string; const PackageName: string);
|
||||
procedure Execute(const FileName: string; const PackageName: string; BaseKeyboardID: Cardinal);
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
|
@ -42,13 +42,12 @@ uses
|
|||
Winapi.Windows,
|
||||
|
||||
errorcontrolledregistry,
|
||||
keymancontext,
|
||||
keymanerrorcodes,
|
||||
KeymanPaths,
|
||||
keymanapi_TLB,
|
||||
RegistryKeys,
|
||||
utilexecute,
|
||||
utilkeyman,
|
||||
utilfiletypes,
|
||||
utilsystem;
|
||||
|
||||
function GetKeyboardLayoutFileName(id: Integer): string;
|
||||
|
|
@ -67,7 +66,7 @@ begin
|
|||
Result := '';
|
||||
end;
|
||||
|
||||
procedure TKPRecompileMnemonicKeyboard.Execute(const FileName,PackageName: string);
|
||||
procedure TKPRecompileMnemonicKeyboard.Execute(const FileName,PackageName: string; BaseKeyboardID: Cardinal);
|
||||
var
|
||||
FDestPath, FDestFileName: string;
|
||||
FBaseKeyboardIDHex: string;
|
||||
|
|
@ -76,7 +75,6 @@ var
|
|||
FExitCode: Integer;
|
||||
FMCompilePath: string;
|
||||
FBaseKeyboardFileName: string;
|
||||
BaseKeyboardID: Cardinal;
|
||||
FDestDeadkeyFileName: string;
|
||||
FCommand: string;
|
||||
begin
|
||||
|
|
@ -84,13 +82,10 @@ begin
|
|||
then FDestPath := GetPackageInstallPath(PackageName) // I3581
|
||||
else FDestPath := GetKeyboardInstallPath(FileName); // I3581
|
||||
|
||||
with Context as TKeymanContext do
|
||||
BaseKeyboardID := (Options as IKeymanOptions).Items['koBaseLayout'].Value;
|
||||
|
||||
FBaseKeyboardIDHex := IntToHex(BaseKeyboardID, 8);
|
||||
FBaseFileName := FDestPath + '\' + ExtractFileName(FileName); // I3581
|
||||
FDestFileName := ChangeFileExt(FBaseFileName, '') + '-'+FBaseKeyboardIDHex + '.kmx';
|
||||
FDestDeadkeyFileName := ChangeFileExt(FBaseFileName, '') + '-'+FBaseKeyboardIDHex + '-d.kmx'; // I4552
|
||||
FDestFileName := BuildKeyboardFilenameWithBaseKeyboardID(FBaseFileName, FBaseKeyboardIDHex);
|
||||
FDestDeadkeyFileName := BuildKeyboardFilenameWithBaseKeyboardIDAndDeadkey(FBaseFileName, FBaseKeyboardIDHex); // I4552
|
||||
FMCompilePath := TKeymanPaths.KeymanEngineInstallPath(TKeymanPaths.S_MCompileExe);
|
||||
|
||||
{ Recompile with the traditional deadkey behaviour }
|
||||
|
|
|
|||
|
|
@ -1,24 +1,24 @@
|
|||
(*
|
||||
Name: internalinterfaces
|
||||
Copyright: Copyright (C) 2003-2017 SIL International.
|
||||
Documentation:
|
||||
Description:
|
||||
Documentation:
|
||||
Description:
|
||||
Create Date: 25 Jan 2011
|
||||
|
||||
Modified Date: 17 Aug 2014
|
||||
Authors: mcdurdin
|
||||
Related Files:
|
||||
Dependencies:
|
||||
Related Files:
|
||||
Dependencies:
|
||||
|
||||
Bugs:
|
||||
Todo:
|
||||
Notes:
|
||||
Bugs:
|
||||
Todo:
|
||||
Notes:
|
||||
History: 25 Jan 2011 - mcdurdin - I2569 - Keyboard welcome should always shown from kmshell
|
||||
01 Jan 2013 - mcdurdin - I3717 - V9.0 - Need ability to select base keyboard in Keyman Configuration
|
||||
16 Apr 2014 - mcdurdin - I4169 - V9.0 - Mnemonic layouts should be recompiled to positional based on user-selected base keyboard
|
||||
17 Aug 2014 - mcdurdin - I4376 - V9.0 - Unticked keyboards in configuration should be removed from language profile
|
||||
17 Aug 2014 - mcdurdin - I4381 - V9.0 - Keyman keyboards should be removed from language bar when Keyman exits
|
||||
|
||||
|
||||
*)
|
||||
unit internalinterfaces;
|
||||
|
||||
|
|
@ -41,7 +41,7 @@ type
|
|||
IIntKeymanInterface = interface
|
||||
['{D1EBBED5-B9E3-4807-969D-DCF9E1FFB287}']
|
||||
function XMLClassName: WideString;
|
||||
function Serialize(Flags: TOleEnum; const ImagePath: WideString; References: TStrings): WideString;
|
||||
function Serialize(Flags: TOleEnum; const ImagePath: WideString; References: TStrings): WideString;
|
||||
function DoSerialize(Flags: TOleEnum; const ImagePath: WideString; References: TStrings): WideString; // Wraps serialize with tag
|
||||
end;
|
||||
|
||||
|
|
@ -67,7 +67,6 @@ type
|
|||
['{4876E6DF-C557-46E2-84F4-787BE5F55DDA}']
|
||||
function RegKeyboard: TRegKeyboard;
|
||||
procedure ClearVisualKeyboard;
|
||||
procedure UpdateBaseLayout; // I4169
|
||||
procedure RefreshInstallation;
|
||||
end;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue