I am wondering why TFontDialog gives less fonts than Screen.Fonts? (For example, the Arial* font, the Comic font, etc, does not show in TFontDialog)
It also seems that the font list given by TFontDialog is the same as WordPad, whereas the font list given by Screen.Fonts is basically the same as Word.
Thank you very much for your insights!
PS:
Delphi XE,
Windows 7
PS: related SO topics:
Too many fonts when enumerating with EnumFontFamiliesEx function
Finding System Fonts with Delphi
How to use external fonts?
PS: related web pages:
TFontDialog to show all Fonts # borland.newsgroups.archived
TFontDialog to show all Fonts # delphigroups
unit Unit2;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm2 = class(TForm)
lst1: TListBox;
dlgFont1: TFontDialog;
Button1: TButton;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form2: TForm2;
implementation
{$R *.dfm}
procedure TForm2.FormCreate(Sender: TObject);
begin
lst1.Items.AddStrings(Screen.Fonts);
end;
procedure TForm2.Button1Click(Sender: TObject);
begin
dlgFont1.Device := fdBoth;
if dlgFont1.Execute then
begin
end;
end;
end.
Screen.Fonts returns all installed fonts, including hidden fonts as administrated in Registry\HKCU\Software\Microsoft\Windows NT\CurrentVersion\Font Management\Inactive Fonts. (Source) Apparently, TFontDialog does not display these hidden fonts.
Furthermore, some fonts listed in Screen.Fonts are not mentioned in the Font combo box of TFontDialog, but are added to the Font style combo box. Take Arial for example: the Font style lists 10 items, which seems to be the combination of the fonts Arial, Arial Black and Arial Narrow.
Different APIs, different results. Screen.Fonts uses EnumFontFamiliesEx(), which returns all installed fonts. TFontDialog uses ChooseFont() instead, which only displays the fonts that are compatible with the TFontDialog.Font and TFontDialog.Options properties.
Related
This question already has answers here:
Image covering whole page in Inno Setup
(1 answer)
Inno Setup - Image as installer background
(2 answers)
Closed 9 months ago.
I am using the following code to add a background image,
function Page1_Create: TWizardPage;
var
Page1: TWizardPage;
// Fonts
// Pictures
PictureBox2_PictureName: String;
// Controls
PictureBox2: TBitmapImage;
begin
// This is a page creator Function. You can use the Result of it to access the controls on this Page.
Page1 := CreateCustomPage(wpWelcome, 'Title', 'Subtitle');
{ PictureBox2 (TBitmapImage) }
PictureBox2 := TBitmapImage.Create(Page1);
PictureBox2.Parent := Page1.Surface;
PictureBox2.Enabled := True;
PictureBox2.Visible := True;
PictureBox2.Left := ScaleX(0);
PictureBox2.Top := ScaleY(0);
PictureBox2.Width := ScaleX(513);
PictureBox2.Height := ScaleY(302);
PictureBox2.Anchors := [akLeft, akTop, akRight, akBottom];
PictureBox2.Stretch := True;
PictureBox2_PictureName := ExpandConstant('{tmp}\purple-skin.bmp');
ExtractTemporaryFile(ExtractFileName(PictureBox2_PictureName));
PictureBox2.Bitmap.LoadFromFile(PictureBox2_PictureName);
// Result is the newly created Page (TWizardPage).
Result := Page1;
end;
procedure InitializeWizard;
begin
PageWelcome_Create()
end;
But this does not fill the entire background. It fills like as shown by the image below,
How to fill the entire background?
Also, how to add images to the Title section (fill the entire title bar) at top and command button section (fill the entire bottom bar) at bottom?
TLDR: Your code is correct, simply repeat it for each page and the title and bottom part of the form + adjust the controls positions and dimensions (posting whole code is beyond the SO, it would be hundreds of lines of code).
Detailed answer:
Filling the entire background is quite tricky. The setup form consists of several "layers" of components placed on it.
There is no such thing as "background", there is a WizardForm: TWizardForm containing OuterNotebook: TNewNotebook which contains InnerNotebook: TNewNotebook which represents the individual pages of the installer, see https://github.com/jrsoftware/issrc/blob/main/Projects/Wizard.dfm for details.
So you need to create several images: first for title section, second for all setup pages (I assume all pages have the same dimensions) and third for bottom section.
Each control has its own handle and custom position (relative to its parent so you need to play with updating control's Left and Top position) and also there is some "space" around the controls which can be minimized by adjusting the WIdth and Height of the control.
Then load these images and show them in some control e.g. TBitmapImage as you did.
Also do not forget to handle the page refreshing.
This require a lot of work in vanilla Inno Setup. As this question is quite often I have developed a 3rd party extension specially designed for this purpose.
It is called Graphical Installer: http://www.graphical-installer.com
Please try it (it is commercial but costs only few bucks and save you hundreds of hours of work) and let me know whether it suits your needs.
For a Firemokey project i'm working on a Bitmap, which should make a Bitmap on a TImage Component to get more transparent with the time. In order to do so, i want to use a procedure like the following, but it seems as if there is no way to create a change of the transparency as the following:
procedure changeBitmapTransperency(TransparencyInPercent : Integer);
begin
{Set transparency of the bitmap to (TransparencyInPercent) percent}
end;
So, my question is, if there is a way to do so. Thanks for your time and effort,
Max
I'm searching for quite a while now for an extension for Inno Setup to use a video file, for example an AVI or maybe a .png sequence as a splash-screen for my installation (the usage of an alpha channel would be a HUGE plus but is not a must have).
There are several .dll's to use static pictures with a fade-in and fade-out but I couldn't find anything to use as video file for that purpose.
As far as I know, I can use any kind of .dll with Inno Setup. For example I can use the popular bass.dll for audio playback even though it has no "real" Inno support but Inno can call the functions of that .dll.
So is there any program out there that would allow me to do this?
Any tip in that direction would be very helpful.
Edit: This may be possible with Qt, I know you can make exactly those frame based splash-screens for your applications but I'm not sure if it's possible to use Qt with Inno Setup?
I have founded the Inno Media Player project which is able to embed the video and audio playback into the InnoSetup wizard. It is based on DirectShow technology and requires at least DirectX 9 to use.
Except built-in formats it supports all DirectShow codecs, but you should consider that your target users doesn't need to have codecs for some exotic media formats and install them codec just because of the show at the installation startup would be an overkill and unfair to user.
About the transparency you wanted to have, if you find the codec that supports that, we can try to make the popup window transparent and let the DirectShow renderer draw on a layered window, but without the codec and a sample video I can't do nothing.
the libraries with a sample script you may find in the source trunk or download it from here
I wrote a simple function reference where you can find the function parameter descriptions
So to show a popup window with the video playback before the wizard form is displayed you can use the following:
Please note, that Inno Media Player is a Unicode library, and so you can use it only with Unicode versions of InnoSetup, not with ANSI ones! There is no support for ANSI versions of InnoSetup...!
[Setup]
AppName=Media Player Project
AppVersion=1.0
DefaultDirName={pf}\Media Player Project
[Files]
Source: "MediaPlayer.dll"; Flags: dontcopy
[Code]
const
EC_COMPLETE = $01;
type
TDirectShowEventProc = procedure(EventCode, Param1, Param2: Integer);
function DSPlayMediaFile: Boolean;
external 'DSPlayMediaFile#files:mediaplayer.dll stdcall';
function DSStopMediaPlay: Boolean;
external 'DSStopMediaPlay#files:mediaplayer.dll stdcall';
function DSInitializeVideoFile(FileName: WideString; WindowHandle: HWND;
var Width, Height: Integer; CallbackProc: TDirectShowEventProc): Boolean;
external 'DSInitializeVideoFile#files:mediaplayer.dll stdcall';
var
VideoForm: TSetupForm;
procedure OnMediaPlayerEvent(EventCode, Param1, Param2: Integer);
begin
if EventCode = EC_COMPLETE then
VideoForm.Close;
end;
procedure OnVideoFormShow(Sender: TObject);
begin
DSPlayMediaFile;
end;
procedure OnVideoFormClose(Sender: TObject; var Action: TCloseAction);
begin
DSStopMediaPlay;
end;
procedure InitializeWizard;
var
Width: Integer;
Height: Integer;
begin
VideoForm := CreateCustomForm;
VideoForm.Caption := 'Popup Video Window';
VideoForm.BorderStyle := bsNone;
VideoForm.FormStyle := fsStayOnTop;
VideoForm.Position := poScreenCenter;
VideoForm.OnShow := #OnVideoFormShow;
VideoForm.OnClose := #OnVideoFormClose;
if DSInitializeVideoFile('d:\Video.avi', VideoForm.Handle, Width,
Height, #OnMediaPlayerEvent)
then
begin
VideoForm.ClientWidth := Width;
VideoForm.ClientHeight := Height;
VideoForm.ShowModal;
end;
end;
procedure DeinitializeSetup;
begin
DSStopMediaPlay;
end;
Hope that it helps!
I have an application that I have been testing for internationalization support.
There is, for example, a standard TEdit control, with the font.Name = 'Arial'.
On Windows 7, it seems to automatically grab the glyphs for CJK characters, from Arial Unicode MS, or somewhere else, for EDIT common controls, if the font that is assigned to that control, does not contain a certain international character.
On Windows XP, it seems that chinese characters show up as boxes, even when Arial Unicode MS font is installed, unless I change the Font name in the delphi form, to Arial Unicode MS.
Is this something that everybody encounters with international font support on windows XP? Do windows common controls behave differently? The behaviour I see on Windows 7 is certainly friendlier than the behaviour I see on Windows XP.
This behaviour difference is not constrained just to Windows Common Controls. It seems
even Internet Explorer and the MS Explorer shell have problems doing tests like the picture here:
What do people do about this?
What is the expected platform behaviour on Windows XP? Do you have to go find what language the user wants to use, and go find a font for them to to use, that supports that language? I guess Arial Unicode MS might be a good default, since it has almost every unicode language that there is.
Update: It looks like the Microsoft term "supplemental language support" refers to the "windows doesn't show my unicode characters as boxes" feature of Windows.
Vista and Windows 7 include support for East Asian languages out of the box. To enable it on Windows XP go into the Control Panel, open Regional and Language Options dialog, switch to the Languages tab, and check Install files for East Asian languages under Supplemental language support.
You can detect whether they've been installed using IsValidLanguageGroup by checking for one of the relevant languages with the LGRIP_INSTALLED flag:
uses
Windows;
type
LGRPID = DWORD;
const
LGRPID_INSTALLED = $00000001; // installed language group ids
LGRPID_SUPPORTED = $00000002; // supported language group ids
LGRPID_WESTERN_EUROPE = $0001; // Western Europe & U.S.
LGRPID_CENTRAL_EUROPE = $0002; // Central Europe
LGRPID_BALTIC = $0003; // Baltic
LGRPID_GREEK = $0004; // Greek
LGRPID_CYRILLIC = $0005; // Cyrillic
LGRPID_TURKISH = $0006; // Turkish
LGRPID_JAPANESE = $0007; // Japanese
LGRPID_KOREAN = $0008; // Korean
LGRPID_TRADITIONAL_CHINESE = $0009; // Traditional Chinese
LGRPID_SIMPLIFIED_CHINESE = $000a; // Simplified Chinese
LGRPID_THAI = $000b; // Thai
LGRPID_HEBREW = $000c; // Hebrew
LGRPID_ARABIC = $000d; // Arabic
LGRPID_VIETNAMESE = $000e; // Vietnamese
LGRPID_INDIC = $000f; // Indic
LGRPID_GEORGIAN = $0010; // Georgian
LGRPID_ARMENIAN = $0011; // Armenian
function IsValidLanguageGroup(LanguageGroup: LGRPID; dwFlags: DWORD): BOOL; stdcall;
external kernel32;
function IsCJKInstalled: Boolean;
begin
Result := IsValidLanguageGroup(LGRPID_SIMPLIFIED_CHINESE, LGRPID_INSTALLED);
end;
I'm enumerating Windows fonts like this:
LOGFONTW lf = {0};
lf.lfCharSet = DEFAULT_CHARSET;
lf.lfFaceName[0] = L'\0';
lf.lfPitchAndFamily = 0;
::EnumFontFamiliesEx(hdc, &lf,
reinterpret_cast<FONTENUMPROCW>(FontEnumCallback),
reinterpret_cast<LPARAM>(this), 0);
My callback function has this signature:
int CALLBACK FontEnumerator::FontEnumCallback(const ENUMLOGFONTEX *pelf,
const NEWTEXTMETRICEX *pMetrics,
DWORD font_type,
LPARAM context);
For TrueType fonts, I typically get each face name multiple times. For example, for multiple calls, I'll get pelf->elfFullName and pelf->elfLogFont.lfFaceName set as "Arial". Looking more closely at the other fields, I see that each call is for a different script. For example, on the first call pelf->elfScript will be "Western" and pelf->elfLogFont.lfCharSet will be the numeric equivalent of ANSI_CHARSET. On the second call, I get "Hebrew" and HEBREW_CHARSET. Third call "Arabic" and ARABIC_CHARSET. And so on. So far, so good.
But the font signature (pMetrics->ntmFontSig) field for all versions of Arial is identical. In fact, the font signature claims that all of these versions of Arial support Latin-1, Hebrew, Arabic, and others.
I know the character sets of the strings I'm trying to draw, so I'm trying to instantiate an appropriate font based on the font signatures. Because the font signatures always match, I always end up selecting the "Western" font, even when displaying Hebrew or Arabic text. I'm using low level Uniscribe APIs, so I don't get the benefit of Windows font linking, and yet my code seems to work.
Does lfCharSet actually carry any meaning or is it a legacy artifact? Should I just set lfCharSet to DEFAULT_CHARSET and stop worrying about all the script variations of each face?
For my purposes, I only care about TrueType and OpenType fonts.
I think I found the answer. Fonts that get enumerated multiple times are "big" fonts. Big fonts are single fonts that include glyphs for multiple scripts or code pages.
The Unicode portion of the FONTSIGNATURE (fsUsb) represents all the Unicode subranges that the font can handle. This is independent of the character set. If you use the wide character APIs, you can use all the included glyphs in the font, regardless of which character set was specified when you create the font.
The code page portion of the FONTSIGNATURE (fsCsb) represents the code pages that the font can handle. I believe this is only significant when the font is not a "big" font. In that case, the fsUsb masks will be all zeros, and the fsCsb will specify the appropriate character set(s). In those cases, it's important to get the lfCharSet correct in the LOGFONT.
When instantiating a "big" font and using the wide character APIs, it apparently doesn't matter which lfCharSet you specify.