[Developer] Refactor importkeyboard_pas into kmconvert

This commit is contained in:
Marc Durdin 2018-09-21 13:26:43 +10:00
parent 625ae120dc
commit 02a53fa796
9 changed files with 214 additions and 773 deletions

View file

@ -17,7 +17,7 @@ type
FKMN: string;
FKVKS: string;
public
constructor Create(const inputHKL: string);
constructor Create(const inputHKL, nameFormatString: string);
procedure Execute;
property InputHKL: string read FInputHKL;
property KMN: string read FKMN;
@ -37,8 +37,11 @@ uses
System.Win.Registry,
ScanCodeMap,
Unicode,
VisualKeyboard,
VKeys;
type
TKBDShiftState = (
Base = 0, // 0
@ -53,6 +56,20 @@ type
ShftXxxx = 9 //Shft or Xxxx // 9
);
const
KBDShiftStateToVisualKeyboardShiftState: array[TKBDShiftState] of WORD = (
KVKS_NORMAL, //Base = 0,
KVKS_SHIFT, //Shft = 1,
KVKS_CTRL, //Ctrl = 2,
KVKS_SHIFT or KVKS_CTRL, //ShftCtrl = 3,
KVKS_ALT, //Menu = 4,
KVKS_SHIFT or KVKS_ALT, //ShftMenu = 5,
KVKS_RALT, //MenuCtrl = 6,
KVKS_SHIFT or KVKS_RALT, //ShftMenuCtrl = 7,
$FFFF, //Xxxx = 8,
$FFFF //ShftXxxx = 9
);
{ TDeadKey }
type
@ -97,6 +114,7 @@ type
procedure SetShiftState(shiftState: TKBDShiftState; value: string; isDeadKey, capsLock: Boolean);
function GetShiftStateName(capsLock: UINT; caps: Boolean; ss: TKBDShiftState): string;
function LayoutRow: string;
procedure AddKeysToVisualKeyboard(vk: TVisualKeyboard);
property VK: UINT read FVK;
property SC: UINT read FSC;
@ -131,6 +149,7 @@ type
procedure ClearKeyboardBuffer(vk: UINT; sc: UINT; hkl: HKL);
procedure ScanKeyboard(hkl: HKL);
function WriteOutputKMNFile: string;
function WriteOutputKVKSFile: string;
public
constructor Create(inputHKL, layoutFile, layoutText: string);
destructor Destroy; override;
@ -390,20 +409,29 @@ begin
end;
end;
// We don't add Shift+Space, Ctrl+Space as they are not
// useful
if (st = #$20) and (FVK = VK_SPACE) and (ss <> Base) then
isvalid := False;
if isvalid then
begin
// It's some characters; put 'em in there.
Result := Result + Format('+ [%s%s] > ', [
GetShiftStateName(capslock, caps, ss),
GetVKeyName
]);
Result := Result + Format('+ [%s%s] >', [GetShiftStateName(capslock, caps, ss), GetVKeyName]);
for ich := 1 to st.Length do
ich := 1;
while ich <= st.Length do
begin
//TODO: Support surrogate pairs
Result := Result + 'U+' + IntToHexLC(Ord(st[ich]), 4);
if ich < st.Length then
Result := Result + ' ';
if (ich < st.Length) and Uni_IsSurrogate1(st[ich]) and Uni_IsSurrogate2(st[ich+1]) then
begin
Result := Result + ' U+' + IntToHexLC(Uni_SurrogateToUTF32(st[ich], st[ich+1]), 6);
Inc(ich, 2);
end
else
begin
Result := Result + ' U+' + IntToHexLC(Ord(st[ich]), 4);
Inc(ich);
end;
end;
Result := Result + #13#10;
@ -413,6 +441,64 @@ begin
end;
end;
procedure TVirtualKey.AddKeysToVisualKeyboard(vk: TVisualKeyboard);
var
ss: TKBDShiftState;
st: string;
ich: Integer;
isvalid: Boolean;
vkk: TVisualKeyboardKey;
begin
for ss := Low(TKBDShiftState) to Loader.MaxShiftState do
begin
if (ss = Menu) or (ss = ShftMenu) then
begin
// Alt and Shift+Alt don't work, so skip them
Continue;
end;
st := GetShiftState(ss, False);
if st.Length = 0 then
begin
// No character assigned here
end
else if FRGFDeadKey[ss, False] then
begin
// It's a dead key
vkk := TVisualKeyboardKey.Create;
vkk.VKey := FVK;
vkk.Text := st[1];
vkk.Flags := [kvkkUnicode];
vkk.Shift := KBDShiftStateToVisualKeyboardShiftState[ss];
vk.Keys.Add(vkk);
end
else
begin
isvalid := True;
for ich := 1 to st.Length do
begin
if (st[ich] < #$20) or (st[ich] = #$7F) then
begin
isvalid := False;
Break;
end;
end;
if isvalid then
begin
// It's some characters; put 'em in there.
vkk := TVisualKeyboardKey.Create;
vkk.VKey := FVK;
vkk.Text := st;
vkk.Flags := [kvkkUnicode];
vkk.Shift := KBDShiftStateToVisualKeyboardShiftState[ss];
vk.Keys.Add(vkk);
end;
end;
end;
end;
(* public class Loader
{
@ -741,6 +827,8 @@ begin
end;
procedure TLoader.Main(var KMN, KVKS: string);
type
PHKL = ^HKL;
var
cKeyboards: Cardinal;
rghkl: array of HKL;
@ -751,6 +839,8 @@ begin
cKeyboards := GetKeyboardLayoutList(0, rghkl);
SetLength(rghkl, cKeyboards);
GetKeyboardLayoutList(cKeyboards, rghkl);
hkl := LoadKeyboardLayout(inputHKL, KLF_NOTELLSHELL);
if hkl = 0 then
raise EImportKeyboardDLL.CreateFmt('The keyboard %s could not be loaded (error %d, %s)',
@ -768,7 +858,7 @@ begin
end;
KMN := WriteOutputKMNFile;
//WriteOutputKVKSFile(KVKS);
KVKS := WriteOutputKVKSFile;
end;
function TLoader.WriteOutputKMNFile: string;
@ -793,7 +883,6 @@ begin
outFile.Add('c '#13#10);
outFile.Add('store(&Version) "10.0"');
outFile.Add(Format('store(&Name) "%s"', [layoutText]));
outFile.Add('store(&Copyright) "(C) 2018 SIL International"');
outFile.Add('store(&Targets) "windows macosx linux web"');
outFile.Add('');
outFile.Add('begin Unicode > use(main)'#13#10);
@ -819,6 +908,7 @@ begin
sbDKTo := Format('store(dkt%s)', [IntToHexLC(Ord(dk.DeadCharacter), 4)]);
for id := 0 to dk.Count - 1 do
begin
// Surrogate pairs not supported in kbd.dll
sbDKFrom := sbDKFrom + ' U+'+IntToHexLC(Ord(dk.GetBaseCharacter(id)), 4);
sbDKTo := sbDKTo + ' U+'+IntToHexLC(Ord(dk.GetCombinedCharacter(id)), 4);
end;
@ -837,12 +927,38 @@ begin
end;
end;
function TLoader.WriteOutputKVKSFile: string;
var
iKey: UINT;
vk: TVisualKeyboard;
ss: TStringStream;
begin
vk := TVisualKeyboard.Create;
ss := TStringStream.Create('', TEncoding.UTF8);
try
for iKey := 0 to Length(rgKey) - 1 do
begin
if (rgKey[iKey] <> nil) and rgKey[iKey].IsKeymanUsedKey and not rgKey[iKey].IsEmpty then
begin
rgKey[iKey].AddKeysToVisualKeyboard(vk);
end;
end;
vk.SaveToStream(ss, kvksfXML);
Result := ss.DataString;
finally
vk.Free;
ss.Free;
end;
end;
{ TImportKeyboardDLL }
const
CRootKey = 'System\CurrentControlSet\Control\Keyboard Layouts';
constructor TImportKeyboardDLL.Create(const inputHKL: string);
constructor TImportKeyboardDLL.Create(const inputHKL, nameFormatString: string);
var
r: TRegistry;
begin
@ -861,6 +977,8 @@ begin
FLayoutFile := r.ReadString('Layout File');
FLayoutText := r.ReadString('Layout Text');
if nameFormatString <> ''
then FLayoutText := Format(nameFormatString, [FLayoutText]);
finally
r.Free;
end;

View file

@ -21,7 +21,7 @@ type
FBCP47Tags: string;
FCopyright: string;
function LoadKLIDDetails: Boolean;
function ImportKeyboard(const DestinationFilename, Name: string): Boolean;
function ImportKeyboard(const DestinationFilename, DestinationKVKSFilename, Name: string): Boolean;
function GenerateIcon(const IconFilename: string): Boolean;
procedure SetAuthor(const Value: string);
procedure SetCopyright(const Value: string);
@ -31,6 +31,8 @@ type
procedure SetNameTemplate(const Value: string);
procedure SetSourceKLID(const Value: string);
procedure SetVersion(const Value: string);
procedure InjectSystemStores(const KeyboardFilename, OSKFilename,
IconFilename: string);
public
function Execute: Boolean; overload;
@ -47,13 +49,16 @@ type
implementation
uses
System.Win.Registry,
System.Classes,
System.SysUtils,
System.Win.Registry,
Winapi.Windows,
Keyman.Developer.System.ImportKeyboardDLL,
KeyboardParser,
kmxfileconsts,
RegistryKeys,
UKeymanTargets,
utilexecute;
UKeymanTargets;
{ TImportWindowsKeyboard }
@ -162,7 +167,7 @@ begin
// Run importkeyboard into destination file; this replaces the keyboard template
// file that has been generated
if not ImportKeyboard(FTemplate.KeyboardFilename, FTemplate.Name) then
if not ImportKeyboard(FTemplate.KeyboardFilename, FTemplate.OSKFilename, FTemplate.Name) then
Exit(Fail('Unable to run importkeyboard on '+FSourceKLID));
// Replace .ico with a new one based on the language id
@ -170,12 +175,8 @@ begin
if not GenerateIcon(FTemplate.IconFilename) then
Exit(Fail('Unable to generate an icon for '+FTemplate.KeyboardFilename));
// Load the source .kmn and add bitmap field
// importkeyboard interop assumption, adding at line 12 is okay (technically, by .kmn format
// we can add at any line, but line 12 is nice because it is in the middle of the system
// stores generated by importkeyboard.
// Save final kmn file
// Load the source .kmn and add bitmap, copyright, visualkeyboard fields
InjectSystemStores(FTemplate.KeyboardFilename, FTemplate.OSKFilename, FTemplate.IconFilename);
// Create .kpj
//FTemplate.SaveProjectFile; <-- already done
@ -186,25 +187,75 @@ begin
Result := True;
end;
function TImportWindowsKeyboard.ImportKeyboard(const DestinationFilename, Name: string): Boolean;
procedure TImportWindowsKeyboard.InjectSystemStores(const KeyboardFilename, OSKFilename, IconFilename: string);
var
AppLogText: string;
AppExitCode: Integer;
kp: TKeyboardParser;
sl: TStringList;
begin
if not TUtilExecute.Console(
Format('"%s\importkeyboard.exe" "%s" "%s" "%s"',
[ExtractFileDir(ParamStr(0)),
FSourceKLID,
DestinationFilename,
Name]),
GetCurrentDir,
AppLogText,
AppExitCode) then
Exit(False);
kp := TKeyboardParser.Create;
try
kp.FileName := KeyboardFilename;
kp.LoadFromFile(KeyboardFilename);
kp.Features.Add(kfIcon);
kp.Features.Add(kfOSK);
kp.SetSystemStoreValue(ssVisualKeyboard, ExtractFileName(OSKFilename));
kp.SetSystemStoreValue(ssBitmap, ExtractFilename(IconFilename));
kp.SetSystemStoreValue(ssCopyright, FCopyright);
if FAuthor <> '' then
kp.InitialComment := kp.InitialComment + 'Run by: ' + FAuthor + #13#10;
writeln(AppLogText);
sl := TStringList.Create;
try
sl.Text := kp.KeyboardText;
sl.SaveToFile(KeyboardFilename, TEncoding.UTF8);
finally
sl.Free;
end;
finally
kp.Free;
end;
end;
Exit(AppExitCode = 0);
function TImportWindowsKeyboard.ImportKeyboard(const DestinationFilename, DestinationKVKSFilename, Name: string): Boolean;
var
ik: TImportKeyboardDLL;
sl: TStringList;
ss: TStringStream;
begin
ik := TImportKeyboardDLL.Create(FSourceKLID, Name);
try
try
ik.Execute;
except
on E:EImportKeyboardDLL do
begin
writeln(E.Message);
Exit(False);
end;
end;
// Still need a BOM for .kmn ... for now
sl := TStringList.Create;
try
sl.Text := ik.KMN;
sl.SaveToFile(DestinationFilename, TEncoding.UTF8);
finally
sl.Free;
end;
// No BOM for .kvks
ss := TStringStream.Create(ik.KVKS, TEncoding.UTF8);
try
ss.SaveToFile(DestinationKVKSFilename);
finally
ss.Free;
end;
finally
ik.Free;
end;
Result := True;
end;
function TImportWindowsKeyboard.GenerateIcon(

View file

@ -1,115 +0,0 @@
unit Keyman.Developer.System.ImportKeyboardMain;
interface
procedure Run;
implementation
uses
System.Classes,
System.SysUtils,
System.Win.Registry,
Winapi.Windows,
Keyman.Developer.System.ImportKeyboardDLL;
procedure ShowKeyboardList; forward;
const
CRootKey = 'System\CurrentControlSet\Control\Keyboard Layouts';
procedure Run;
var
inputHKL, outputFileName: string;
ikd: TImportKeyboardDLL;
sl: TStringList;
ss: TStringStream;
begin
if ParamCount = 0 then
begin
writeln('Usage: importkeyboard /list | hkl [output.kmn] ');
writeln(' /list shows a list of keyboards available on your system.');
writeln(' hkl should be an 8 hex digit Keyboard ID. See /list to enumerate these.');
writeln(' If output.kmn is not specified, the filename of the source keyboard will be used; e.g. 00000409 will produce kbdus.kmn');
Exit;
end;
if SameText(ParamStr(1), '/list') then
begin
ShowKeyboardList;
Exit;
end;
inputHKL := ParamStr(1);
if ParamCount > 1 then
outputFileName := ParamStr(2);
ikd := TImportKeyboardDLL.Create(inputHKL); //, outputFileName, '');
try
if outputFileName = '' then
outputFileName := ikd.RecommendedOutputKMNFileName;
writeln('Importing Windows system keyboard '+ikd.InputHKL+' to Keyman keyboard '+outputFileName);
ikd.Execute;
// Still need a BOM for .kmn ... for now
sl := TStringList.Create;
try
sl.Text := ikd.KMN;
sl.SaveToFile(outputFileName, TEncoding.UTF8);
finally
sl.Free;
end;
// No BOM for .kvks
// ss := TStringStream.Create(ikd.KVKS, TEncoding.UTF8);
// try
// ss.SaveToFile(ChangeFileExt(outputFileName, '.kvks'));
// finally
// ss.Free;
// end;
finally
ikd.Free;
end;
end;
procedure ShowKeyboardList;
var
r: TRegistry;
keyboardIds: TStringList;
keyboardId: string;
layoutFile: string;
layoutText: string;
begin
r := TRegistry.Create;
keyboardIds := TStringList.Create;
try
r.RootKey := HKEY_LOCAL_MACHINE;
if r.OpenKeyReadOnly(CRootKey) then //TODO Use RegistryKeys
begin
r.GetKeyNames(keyboardIds);
for keyboardId in keyboardIds do
begin
if r.OpenKeyReadOnly('\' + CRootKey + '\' + keyboardId) then
begin
if not r.ValueExists('keyman install') then
begin
layoutFile := r.ReadString('layout file');
layoutText := r.ReadString('layout text');
if (layoutFile <> '') and (layoutText <> '') then
begin
writeln(' ' + keyboardId + #9 + layoutFile + #9 + layoutText);
end;
end;
end;
end;
end;
finally
r.Free;
keyboardIds.Free;
end;
end;
end.

View file

@ -1,21 +0,0 @@
program importkeyboard;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils,
Keyman.Developer.System.ImportKeyboardDLL in 'Keyman.Developer.System.ImportKeyboardDLL.pas',
VKeys in '..\..\..\global\delphi\general\VKeys.pas',
ScanCodeMap in '..\..\..\global\delphi\general\ScanCodeMap.pas',
Keyman.Developer.System.ImportKeyboardMain in 'Keyman.Developer.System.ImportKeyboardMain.pas';
begin
try
Run;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.

View file

@ -1,596 +0,0 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{6AED868A-E3B2-4A0E-9A3F-94F76052C85E}</ProjectGuid>
<ProjectVersion>18.4</ProjectVersion>
<FrameworkType>None</FrameworkType>
<MainSource>importkeyboard.dpr</MainSource>
<Base>True</Base>
<Config Condition="'$(Config)'==''">Debug</Config>
<Platform Condition="'$(Platform)'==''">Win32</Platform>
<TargetedPlatforms>1</TargetedPlatforms>
<AppType>Console</AppType>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Android' and '$(Base)'=='true') or '$(Base_Android)'!=''">
<Base_Android>true</Base_Android>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='OSX32' and '$(Base)'=='true') or '$(Base_OSX32)'!=''">
<Base_OSX32>true</Base_OSX32>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''">
<Base_Win32>true</Base_Win32>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win64' and '$(Base)'=='true') or '$(Base_Win64)'!=''">
<Base_Win64>true</Base_Win64>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_1)'!=''">
<Cfg_1>true</Cfg_1>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_1)'=='true') or '$(Cfg_1_Win32)'!=''">
<Cfg_1_Win32>true</Cfg_1_Win32>
<CfgParent>Cfg_1</CfgParent>
<Cfg_1>true</Cfg_1>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_2)'!=''">
<Cfg_2>true</Cfg_2>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Base)'!=''">
<DCC_DcuOutput>.\$(Platform)\$(Config)</DCC_DcuOutput>
<DCC_ExeOutput>.\$(Platform)\$(Config)</DCC_ExeOutput>
<DCC_E>false</DCC_E>
<DCC_N>false</DCC_N>
<DCC_S>false</DCC_S>
<DCC_F>false</DCC_F>
<DCC_K>false</DCC_K>
<DCC_UsePackage>RESTComponents;FireDAC;FireDACSqliteDriver;soaprtl;FireDACIBDriver;soapmidas;FireDACCommon;RESTBackendComponents;soapserver;CloudService;FireDACCommonDriver;inet;$(DCC_UsePackage)</DCC_UsePackage>
<DCC_Namespace>System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace)</DCC_Namespace>
<SanitizedProjectName>importkeyboard</SanitizedProjectName>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Android)'!=''">
<Android_LauncherIcon36>$(BDS)\bin\Artwork\Android\FM_LauncherIcon_36x36.png</Android_LauncherIcon36>
<Android_LauncherIcon48>$(BDS)\bin\Artwork\Android\FM_LauncherIcon_48x48.png</Android_LauncherIcon48>
<Android_LauncherIcon72>$(BDS)\bin\Artwork\Android\FM_LauncherIcon_72x72.png</Android_LauncherIcon72>
<Android_LauncherIcon96>$(BDS)\bin\Artwork\Android\FM_LauncherIcon_96x96.png</Android_LauncherIcon96>
<Android_LauncherIcon144>$(BDS)\bin\Artwork\Android\FM_LauncherIcon_144x144.png</Android_LauncherIcon144>
<Android_SplashImage426>$(BDS)\bin\Artwork\Android\FM_SplashImage_426x320.png</Android_SplashImage426>
<Android_SplashImage470>$(BDS)\bin\Artwork\Android\FM_SplashImage_470x320.png</Android_SplashImage470>
<Android_SplashImage640>$(BDS)\bin\Artwork\Android\FM_SplashImage_640x480.png</Android_SplashImage640>
<Android_SplashImage960>$(BDS)\bin\Artwork\Android\FM_SplashImage_960x720.png</Android_SplashImage960>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_OSX32)'!=''">
<DCC_UsePackage>DBXSqliteDriver;bindcompdbx;IndyIPCommon;DBXInterBaseDriver;IndyIPServer;IndySystem;tethering;fmxFireDAC;bindcompfmx;FireDACPgDriver;inetdb;DbxCommonDriver;fmx;fmxdae;xmlrtl;fmxobj;rtl;DbxClientDriver;CustomIPTransport;dbexpress;IndyCore;bindcomp;dsnap;IndyIPClient;dbxcds;bindengine;DBXMySQLDriver;dsnapxml;FireDACMySQLDriver;dbrtl;inetdbxpress;IndyProtocols;FireDACCommonODBC;fmxase;$(DCC_UsePackage)</DCC_UsePackage>
<DCC_ConsoleTarget>true</DCC_ConsoleTarget>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win32)'!=''">
<DCC_UsePackage>DBXSqliteDriver;bindcompdbx;IndyIPCommon;DBXInterBaseDriver;vcl;IndyIPServer;vclactnband;vclFireDAC;IndySystem;tethering;svnui;mbColorLibD10;dsnapcon;FireDACADSDriver;scFontCombo;DCPdelphi2009;FireDACMSAccDriver;fmxFireDAC;vclimg;Jcl;vcltouch;JvCore;vcldb;bindcompfmx;svn;FireDACPgDriver;inetdb;CEF4Delphi;DbxCommonDriver;fmx;fmxdae;xmlrtl;fmxobj;vclwinx;rtl;DbxClientDriver;CustomIPTransport;vcldsnap;dbexpress;IndyCore;vclx;bindcomp;appanalytics;dsnap;IndyIPClient;bindcompvcl;EmbeddedWebBrowser_XE;VCLRESTComponents;dbxcds;VclSmp;JvDocking;adortl;JclVcl;vclie;bindengine;DBXMySQLDriver;dsnapxml;FireDACMySQLDriver;dbrtl;inetdbxpress;IndyProtocols;keyman_components;FireDACCommonODBC;fmxase;$(DCC_UsePackage)</DCC_UsePackage>
<DCC_Namespace>Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace>
<BT_BuildType>Debug</BT_BuildType>
<VerInfo_Keys>CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
<VerInfo_Locale>1033</VerInfo_Locale>
<DCC_ConsoleTarget>true</DCC_ConsoleTarget>
<UWP_DelphiLogo44>$(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png</UWP_DelphiLogo44>
<UWP_DelphiLogo150>$(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png</UWP_DelphiLogo150>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win64)'!=''">
<DCC_UsePackage>DBXSqliteDriver;bindcompdbx;IndyIPCommon;DBXInterBaseDriver;vcl;IndyIPServer;vclactnband;vclFireDAC;IndySystem;tethering;dsnapcon;FireDACADSDriver;FireDACMSAccDriver;fmxFireDAC;vclimg;Jcl;vcltouch;vcldb;bindcompfmx;FireDACPgDriver;inetdb;DbxCommonDriver;fmx;fmxdae;xmlrtl;fmxobj;vclwinx;rtl;DbxClientDriver;CustomIPTransport;vcldsnap;dbexpress;IndyCore;vclx;bindcomp;appanalytics;dsnap;IndyIPClient;bindcompvcl;VCLRESTComponents;dbxcds;VclSmp;adortl;JclVcl;vclie;bindengine;DBXMySQLDriver;dsnapxml;FireDACMySQLDriver;dbrtl;inetdbxpress;IndyProtocols;FireDACCommonODBC;fmxase;$(DCC_UsePackage)</DCC_UsePackage>
<DCC_ConsoleTarget>true</DCC_ConsoleTarget>
<UWP_DelphiLogo44>$(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png</UWP_DelphiLogo44>
<UWP_DelphiLogo150>$(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png</UWP_DelphiLogo150>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1)'!=''">
<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
<DCC_DebugDCUs>true</DCC_DebugDCUs>
<DCC_Optimize>false</DCC_Optimize>
<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>
<DCC_DebugInfoInExe>true</DCC_DebugInfoInExe>
<DCC_RemoteDebug>true</DCC_RemoteDebug>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1_Win32)'!=''">
<DCC_RemoteDebug>false</DCC_RemoteDebug>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2)'!=''">
<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
<DCC_DebugInformation>0</DCC_DebugInformation>
</PropertyGroup>
<ItemGroup>
<DelphiCompile Include="$(MainSource)">
<MainSource>MainSource</MainSource>
</DelphiCompile>
<DCCReference Include="Keyman.Developer.System.ImportKeyboardDLL.pas"/>
<DCCReference Include="..\..\..\global\delphi\general\VKeys.pas"/>
<DCCReference Include="..\..\..\global\delphi\general\ScanCodeMap.pas"/>
<DCCReference Include="Keyman.Developer.System.ImportKeyboardMain.pas"/>
<BuildConfiguration Include="Release">
<Key>Cfg_2</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
<BuildConfiguration Include="Base">
<Key>Base</Key>
</BuildConfiguration>
<BuildConfiguration Include="Debug">
<Key>Cfg_1</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
</ItemGroup>
<ProjectExtensions>
<Borland.Personality>Delphi.Personality.12</Borland.Personality>
<Borland.ProjectType>Application</Borland.ProjectType>
<BorlandProject>
<Delphi.Personality>
<Source>
<Source Name="MainSource">importkeyboard.dpr</Source>
</Source>
</Delphi.Personality>
<Deployment Version="3">
<DeployFile LocalName="$(BDS)\Redist\osx32\libcgunwind.1.0.dylib" Class="DependencyModule">
<Platform Name="OSX32">
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="$(BDS)\Redist\iossimulator\libcgunwind.1.0.dylib" Class="DependencyModule">
<Platform Name="iOSSimulator">
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="$(BDS)\Redist\iossimulator\libPCRE.dylib" Class="DependencyModule">
<Platform Name="iOSSimulator">
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="$(BDS)\Redist\osx32\libcgsqlite3.dylib" Class="DependencyModule">
<Platform Name="OSX32">
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="Win32\Debug\importkeyboard.exe" Configuration="Debug" Class="ProjectOutput">
<Platform Name="Win32">
<RemoteName>importkeyboard.exe</RemoteName>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployClass Name="AdditionalDebugSymbols">
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
<Platform Name="OSX32">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Win32">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidClassesDexFile">
<Platform Name="Android">
<RemoteDir>classes</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidGDBServer">
<Platform Name="Android">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidLibnativeArmeabiFile">
<Platform Name="Android">
<RemoteDir>library\lib\armeabi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidLibnativeMipsFile">
<Platform Name="Android">
<RemoteDir>library\lib\mips</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidServiceOutput">
<Platform Name="Android">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidSplashImageDef">
<Platform Name="Android">
<RemoteDir>res\drawable</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidSplashStyles">
<Platform Name="Android">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_DefaultAppIcon">
<Platform Name="Android">
<RemoteDir>res\drawable</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon144">
<Platform Name="Android">
<RemoteDir>res\drawable-xxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon36">
<Platform Name="Android">
<RemoteDir>res\drawable-ldpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon48">
<Platform Name="Android">
<RemoteDir>res\drawable-mdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon72">
<Platform Name="Android">
<RemoteDir>res\drawable-hdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon96">
<Platform Name="Android">
<RemoteDir>res\drawable-xhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage426">
<Platform Name="Android">
<RemoteDir>res\drawable-small</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage470">
<Platform Name="Android">
<RemoteDir>res\drawable-normal</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage640">
<Platform Name="Android">
<RemoteDir>res\drawable-large</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage960">
<Platform Name="Android">
<RemoteDir>res\drawable-xlarge</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="DebugSymbols">
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
<Platform Name="OSX32">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="DependencyFramework">
<Platform Name="OSX32">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
<Extensions>.framework</Extensions>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="DependencyModule">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="OSX32">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
<Extensions>.dll;.bpl</Extensions>
</Platform>
</DeployClass>
<DeployClass Required="true" Name="DependencyPackage">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="OSX32">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
<Extensions>.bpl</Extensions>
</Platform>
</DeployClass>
<DeployClass Name="File">
<Platform Name="Android">
<Operation>0</Operation>
</Platform>
<Platform Name="iOSDevice32">
<Operation>0</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>0</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>0</Operation>
</Platform>
<Platform Name="OSX32">
<RemoteDir>Contents\Resources\StartUp\</RemoteDir>
<Operation>0</Operation>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch1024">
<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>
</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>
</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>
</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>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch640">
<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_Launch640x1136">
<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>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSDeviceDebug">
<Platform Name="iOSDevice32">
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSDeviceResourceRules">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSEntitlements">
<Platform Name="iOSDevice32">
<RemoteDir>..\</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<RemoteDir>..\</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSInfoPList">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSResource">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectOSXEntitlements">
<Platform Name="OSX32">
<RemoteDir>..\</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectOSXInfoPList">
<Platform Name="OSX32">
<RemoteDir>Contents</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectOSXResource">
<Platform Name="OSX32">
<RemoteDir>Contents\Resources</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Required="true" Name="ProjectOutput">
<Platform Name="Android">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
<Platform Name="Linux64">
<Operation>1</Operation>
</Platform>
<Platform Name="OSX32">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectUWPManifest">
<Platform Name="Win32">
<Operation>1</Operation>
</Platform>
<Platform Name="Win64">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="UWP_DelphiLogo150">
<Platform Name="Win32">
<RemoteDir>Assets</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Win64">
<RemoteDir>Assets</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="UWP_DelphiLogo44">
<Platform Name="Win32">
<RemoteDir>Assets</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Win64">
<RemoteDir>Assets</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<ProjectRoot Platform="iOSDevice64" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="Win64" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="iOSDevice32" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="Linux64" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="Win32" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="OSX32" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="Android" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="iOSSimulator" Name="$(PROJECTNAME).app"/>
</Deployment>
<Platforms>
<Platform value="Android">False</Platform>
<Platform value="OSX32">False</Platform>
<Platform value="Win32">True</Platform>
<Platform value="Win64">False</Platform>
</Platforms>
</BorlandProject>
<ProjectFileVersion>12</ProjectFileVersion>
</ProjectExtensions>
<Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')"/>
<Import Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj" Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')"/>
<Import Project="$(MSBuildProjectName).deployproj" Condition="Exists('$(MSBuildProjectName).deployproj')"/>
</Project>

View file

@ -88,7 +88,9 @@ uses
CompilePackageInstaller in '..\..\global\delphi\general\CompilePackageInstaller.pas',
kmpinffile in '..\..\global\delphi\general\kmpinffile.pas',
UMD5Hash in '..\..\global\delphi\general\UMD5Hash.pas',
Keyman.Developer.System.KMConvertParameters in 'Keyman.Developer.System.KMConvertParameters.pas';
Keyman.Developer.System.KMConvertParameters in 'Keyman.Developer.System.KMConvertParameters.pas',
Keyman.Developer.System.ImportKeyboardDLL in 'Keyman.Developer.System.ImportKeyboardDLL.pas',
ScanCodeMap in '..\..\global\delphi\general\ScanCodeMap.pas';
begin
try

View file

@ -180,6 +180,8 @@
<DCCReference Include="..\..\global\delphi\general\kmpinffile.pas"/>
<DCCReference Include="..\..\global\delphi\general\UMD5Hash.pas"/>
<DCCReference Include="Keyman.Developer.System.KMConvertParameters.pas"/>
<DCCReference Include="Keyman.Developer.System.ImportKeyboardDLL.pas"/>
<DCCReference Include="..\..\global\delphi\general\ScanCodeMap.pas"/>
<BuildConfiguration Include="Release">
<Key>Cfg_2</Key>
<CfgParent>Base</CfgParent>

View file

@ -152,7 +152,7 @@ begin
FKbd.Clear;
doc := TXMLDocument.Create(nil);
doc.LoadFromStream(Stream);
doc.LoadFromStream(Stream, xetUTF_8);
header := FindNode('header');
if not Assigned(header) then