Delphi Firemonkey does not display fonts correctly - windows

I'm building cross-platform desktop app with additional font (Abilene). On startup I check is the font installed and if it is not, I install it and use it. For Mac everything seems to be fine, but Windows version (and the IDE!!) does not display the font correctly. Here is the font installation procedure:
procedure InstallFont;
const
REG_NT = 'SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts';
var
Reg: TRegistry;
res: Boolean;
installName,FileName: UnicodeString;
begin
Reg := TRegistry.Create(KEY_ALL_ACCESS);
try
Reg.RootKey := HKEY_LOCAL_MACHINE;
res := Reg.OpenKey(REG_NT, False);
if not Res then Exit;
installName := 'Abilene Regular (TrueType)';
FileName:=ExtractFilePath(ParamCount(0)+'\Abilene.ttf';
Reg.WriteString(installName, FileName);
Reg.CloseKey;
finally
Reg.Free;
end;
AddFontResourceW(PWideChar(FileName));
SendMessage(HWND_BROADCAST, WM_FONTCHANGE,0,0);
end;
After installing the font it is displayed as shortcut in the Control panel, but all other programs can use it. Even Delphi can, but with VCL, not FMX applications (see attached pictures). I've attached pictures from the IDE. In the runtime it's the same.
Is there anything that must be done additionally for the font installation especially for FMX apps? Or this is just a bug which must be reported to Embarcaderro QC?
Edit: Adding some details: If I install the font by downloading it, clicking with the right mouse button and choose 'Install' then everything is OK. If I install it by my proc then the font is visible and usable for the whole world except the Delphi FMX. Delphi VCL can use it also. To test this I install ed the font with my proc in my %APPDATA% folder. Word, Excel, Delphi VCL can use it. Delphi FMX cannot.
Edit2: Added SendMessage(HWND_BROADCAST, WM_FONTCHANGE,0,0). No change.
Edit3: In the Font dialog the font is displayed correctly (image 3)

Obviously this is some sort of bug, because I've found a workaround: if I first copy the font to %windir%\Fonts folder then everything is OK. Even if I made a subfolder of the \windows\fonts folder and copy the font in it everything is fine also.
Why Firemonkey does not want to display fonts outside that folder I have no idea. And, as I said, this is for Windows only. Mac OS is OK (I use ~/Library/Fonts).

Related

Why I can't display some site with TWebBrowser

I use Delphi Rio (Windows Desktop App) and need to display in a TWebBrowser some webpages.
I ran into a problem with this WooCommerce site, https://merletdance.com/eshop.
When I ask for this one, I can't pass the cookies dialog. I understand it's in relation with JScript and/or JQuery, but is there a way to bypass or better (some parameters of TwebBrowser) ?
[Edit] Works with Delphi 11 (Alexandria) using Edge
Found a solution, even if for my users with heterogeneous park it's not a cure-all: Embarcadero's documentation on TWebBrowser hints to edit the registry:
Supporting JavaScript Integration on Windows Platform
On Windows target platforms (WIN32 and WIN64), TWebBrowser may incorrectly display some Web pages if a Web site uses JavaScript dialog boxes, panels, and other elements for various purposes.
To work around this issue, your application should display Web pages in the IE11 edge mode using the FEATURE_BROWSER_EMULATION feature of Internet Explorer.
Open the Registry Editor.
Open the following key: HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION
On the Edit menu, point to New, and then click DWORD (32-bit) Value.
Set the name of this new entry to your executable file name, such as MyApps.exe.
Select the newly created entry, and on the Edit menu, click Modify.
In the Edit dialog box that opens, do the following:
In the Value data text box, enter 11011
Under Base, select Decimal
Click OK to save your changes
You can also cause your application to make the above described changes when the application starts. For example, in your project, the FormCreate event handler can call the following TForm1.SetPermissions method:
procedure TForm1.FormCreate(Sender: TObject);
begin
{$IFDEF MSWINDOWS}
SetPermissions;
{$ENDIF}
end;
{$IFDEF MSWINDOWS}
procedure TForm1.SetPermissions;
const
cHomePath = 'SOFTWARE';
cFeatureBrowserEmulation =
'Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION\';
cIE11 = 11001;
var
Reg: TRegIniFile;
sKey: string;
begin
sKey := ExtractFileName(ParamStr(0));
Reg := TRegIniFile.Create(cHomePath);
try
if Reg.OpenKey(cFeatureBrowserEmulation, True) and
not(TRegistry(Reg).KeyExists(sKey) and (TRegistry(Reg).ReadInteger(sKey)
= cIE11)) then
TRegistry(Reg).WriteInteger(sKey, cIE11);
finally
Reg.Free;
end;
end;
{$ENDIF}
Note: You should make these appropriate changes to the registry before starting the application. After you start your application for the first time, close it, and then start again.

Inno Setup window preview in taskbar

All of the programs and opened files have a preview when you hover the mouse on their icons inside the taskbar.
But for Inno Setup made installers it seems there is no preview. Any fix or trick to solve this issue?
Though some game installers with custom design (which use Inno Setup) have a preview in the taskbar. For example:
http://fs2.filegir.com/cuttlas/setup.exe
I believe it's because the taskbar button is linked to an invisible internal window of Inno Setup and not to the visible wizard window. That also explains how it is possible that the taskbar button has a different title than the wizard window. Note that those always match for the windows, where the preview works.
Nothing you can do about it without modifying code of Inno Setup itself.
The link you have posted in not the standard Inno Setup. Note the "5.5.1*.ee2**"* in their log file. They have probably modified Inno Setup significantly. Note how, when (in Windows 10) you hover mouse over their preview window, the wizard window stays visible (and other windows blur). While with standard Inno Setup, all windows blur, including the wizard. This is because their taskbar button in linked to the wizard window. While in standard Inno Setup, it's not.
I have found a great library to solve this:
https://mega.co.nz/#F!RcQkhSxI!_ZsnpdapAeoVVWEgVw2iMQ
using WinTB v2.0 you can easily turn on the preview on the Taskbar:
#include "WinTB.iss"
[Setup]
AppName=Wintb.dll example
AppVersion=2.0
DefaultDirName={pf}\Wintb.dll example
DefaultGroupName=Wintb.dll example
OutputDir=.
[files]
Source: wintb.dll; Flags: dontcopy;
[code]
procedure InitializeWizard();
begin
ExtractTemporaryFile('wintb.dll');
Win7TaskBar11();
end;
without any external plugin or dll, it can be solved by this trick:
[Code]
function SetWindowLong(Wnd: HWnd; Index: Integer; NewLong: Longint): Longint; external 'SetWindowLongW#user32.dll stdcall';
function GetWindowLong(Wnd: HWnd; Index: Integer): Longint; external 'GetWindowLongA#user32.dll stdcall';
Function GetWindow (HWND: Longint; uCmd: cardinal): Longint;external 'GetWindow#user32.dll stdcall';
procedure InitializeWizard();
begin
SetWindowLong(WizardForm.Handle, -8,GetWindowLong(GetWindow(WizardForm.Handle, 4),-8));
end;

CEF4Delphi - My program doesn't get visible again using Alt-Tab when browser is active

I have a Windows program, let's call it 'MyApp', written in Delphi, with embedded chromium on a certain tab. I use CEF4Delphi and I have a problem.
When I use 'MyApp' and the embedded browser is active, I can activate another program (using Alt-Tab or click the icon in the task bar). That's no problem. But when I want to activate 'MyApp' again, it won't get visible or brought to the front. I can not see 'MyApp'. The other program remains visible, however the icon in the taskbar is highlighted. To use 'MyApp', I will have to minimize the other program, so I will see it again.
This problem only occurs when the embedded browser in 'MyApp' is activated.
The chromium is running as a different process and created like recommended in the documentation: https://www.briskbard.com/index.php?lang=en&pageid=cef#usage
The dpr looks like this:
program MyApp;
{$R *.dres}
// uses files
{$SetPEFlags IMAGE_FILE_RELOCS_STRIPPED or IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP or IMAGE_FILE_NET_RUN_FROM_SWAP}
{$SetPEOptFlags IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE}
{$SetPEFlags IMAGE_FILE_LARGE_ADDRESS_AWARE}
begin
NullStrictConvert := System.false;
GlobalCEFApp := TCefApplication.Create;
if GlobalCEFApp.StartMainProcess then
begin
PauseMadExcept;
Application.Initialize;
// ... create forms ...
Application.Run;
It seems to be a Windows 10 bug!
Try this (which helped me with another software, Magix Video Edit Pro):
Disable the "Snap windows" under System > Settings > Multitasking and now the ALT + TAB works again. The software gets focused.
Update: The bug reappeared but still, it worked some time after disabling "Snap windwos". Anyone with some more hints, please comment below.

Suppress Windows dialog in ShellLink Resolve with missing target in ShellLink?

In Delphi XE7, I want to use the following code to replace the link target of a shell link file (.lnk):
uses
JclShell;
...
procedure ShellLinkReplaceLinkTarget(const AShellLinkFile, ANewTarget: string);
var
ThisShellLink: JclShell.TShellLink;
begin
if (JclShell.ShellLinkResolve(AShellLinkFile, ThisShellLink) = S_OK) then // Windows error dialog
begin
ThisShellLink.Target := ANewTarget;
JclShell.ShellLinkCreate(ThisShellLink, AShellLinkFile);
end
else CodeSite.Send('ShellLinkResolve Failed!');
end;
However, when the link target does not exist anymore, then at ShellLinkResolve the well known Link problem Windows error dialog comes up telling that the link target has been deleted etc. Here is the dialog in German:
So how can I suppress this dialog? Because the program needs to replace the missing link target with another one, not Windows.
Windows 7 x64 SP1
EDIT:
BTW: When I click on the Restore button (the leftmost button in the above dialog screenshot), then the missing target is restored from the waste basket - but the dialog is NOT being closed after the successful restore or at least the Restore button disabled after the restore. An example of bad UI design by Microsoft.
Try the following code:
if (JclShell.ShellLinkResolve(AShellLinkFile, ThisShellLink,
SLR_ANY_MATCH or SLR_NO_UI) = S_OK) then

How to disable the little touch-keyboard on Windows edit controls

In a windows version with tablet support, a small keyboard icon appears when an edit control gets focus. If you touch it the touch keyboard pops up.
Is there a way to disable this? It's rather inconvenient if you have your own touch keyboard.
I want to disable it for certain edit controls in code, ie. I'm not looking for a Windows setting.
Giel
Well, I guess a late answer is better than no answer, so here it comes:
You can disable the Windows onscreen-keyboard for your application.
To do so, start Regedit and navigate to the Key [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\TabletTIP\DisableInPlace]. There you create a new String Value, set its name to the full application Path (e.g. "C:\Progam Files\My App\MyApp.exe") and set its value to "1".
Edit: Recently I had to rethink my solution... By setting the Registry value, you disable the onscreen-keyboard for the whole application. But should you need a keyboard for some seldom used function of your program and just happend to forget including an onscreen-keyboard, you have to control the Windows TextInputPanel via SDK / API. See this link: Disabling the Input Panel Programmatically.
Use the PenInputPanel for handwriting and the TextInputPanel for an onscreen-keyboard.
For all those Delphi programmers out there: import the Type Library "Microsoft PenInputPanel" and FIX A BUG in the imported *_TLB.pas: change the parameter type of the two methods of IPenInputPanel:
function Get_AttachedEditWindow: SYSINT; safecall;
procedure Set_AttachedEditWindow(AttachedEditWindow: SYSINT); safecall;
Disable the "Touch Keyboard and Handwriting Panel Service"

Resources