Finding out Inno Setup WizardForm Caption Font Siz

2019-04-02 11:03发布

I need to find what is the Font.Color , Font.Size and Font.Name of Inno Setup WizardForm.Caption to get its (It is a String) Extent Point using GetTextExtentPoint32.

Please let me know how can I find the above properties of WizardForm. (Not the System Font Properties). I want to get current Font Information of WizardForm according to the .cjstyles Skin I am using.

And I also like to know how to center Wizard Window Title using Pascal Script after knowing those font information.

Thanks in Advance.

2条回答
beautiful°
2楼-- · 2019-04-02 11:14

The Window Title Properties of WizardForm is internally loaded by the ISSkin.DLL according to your Visual Styles Skin. So, if there were any System Metrics for Window Titles user configured in Advanced Appearance Settings in Control Panel like:

Window Title - Font Name Segoe UI and Font Size 10

all those will be overridden by the ISSKin.DLL when loading the specified Visual Style because it has different fonts and font size configurations in their .INI Files whose loaded by the function LoadSkin like shown below.

procedure LoadSkin(lpszPath: String; lpszIniFileName: String);

The .INI file you're providing here has almost all information on how Skin is to loaded from the resources like Bitmpas stored in Skin File.


However you can center WizardForm Caption using two different options.

Using Resource Hacker:

Using Resource Hacker, it is possible to set the Skin's Window Title (Caption) Alignment to Center very easily.

1.Open your Visual Styles Skin (.cjstyles or .msstyles) File using Resource Hacker and look for a Resource group named TEXTFILE.

2.Expand it and find the .INI File according to what color scheme is loaded default by ISSkin.dll. In most situations and if your system font size is 100% (default), it should be the Normal Color scheme. So click on the .INI File which has the word NORMAL in its name like shown below:

For example, if your Skin File name is Elegance.cjstyles, the .INI File with Normal color scheme should be like NORMALELEGANCE_INI or something including the word NORMAL.

3.Open this .INI File in internal text editor comes with Resource Hacker and find the line Window.Caption like shown below:

enter image description here

4.And make sure its ContentAlignment is set to Center. If it isn't by default, change it to Center.

Now, the Window Title of the Wizard should be centered after the Skin is loaded by ISSkin.DLL.

NOTE: This centering is not accurate because the centering is done between caption left and minimize button, so caption may still near to left side even after Centering it this way.


Using Pascal Script [Code] Section:

You can center WizardForm Caption by adding white spaces into its front.(but not recommended.)

A Code like this will do what you need.

[Code]
Type
  TSize = Record
    cx, cy: Integer;
end;

function GetTextExtentPoint32(hdc: THandle; s: string; c: Integer; var Size: TSize): Boolean;
    external 'GetTextExtentPoint32W@Gdi32.dll stdcall';
function GetDC(hWnd: THandle): THandle;
    external 'GetDC@User32.dll stdcall';
function SelectObject(hdc: THandle; hgdiobj: THandle): THandle;
    external 'SelectObject@Gdi32.dll stdcall';

function AlignStringToCenter(S: String; const FontName: String; const MaxWidth, FontSize: Integer): String;
var
  SWidth, SX, NSWidth: Integer;
  SFont, SHandle: THandle;
  StringModifier: TNewStaticText;
  StringDimensions: TSize;
  SHandleEx: TForm;
begin
  if S = '' then
    RaiseException('The specified Caption is an empty String')
  else begin
    Try
      SHandleEx := TForm.Create(nil);
      StringModifier := TNewStaticText.Create(SHandleEx);
      StringModifier.Font.Name := FontName;
      StringModifier.Font.Size := FontSize;
      StringModifier.Parent := SHandleEx;
      SX := 0;
      StringModifier.Caption := S;
      SHandle := GetDC(StringModifier.Handle);
      SFont := SelectObject(SHandle, StringModifier.Font.Handle);
      GetTextExtentPoint32(SHandle, StringModifier.Caption, Length(StringModifier.Caption), StringDimensions);
      SelectObject(SHandle, SFont);
      SWidth := StringDimensions.cx;
      Repeat
        Insert(' ', S, SX);
        StringModifier.Caption := S;
        Result := S;
        SHandle := GetDC(StringModifier.Handle);
        SFont := SelectObject(SHandle, StringModifier.Font.Handle);
        GetTextExtentPoint32(SHandle, StringModifier.Caption, Length(StringModifier.Caption), StringDimensions);
        SelectObject(SHandle, SFont);
        NSWidth := StringDimensions.cx;
        SX := SX + 1;
      Until (NSWidth - SWidth) >= (MaxWidth - NSWidth);
    Finally
      StringModifier.Caption := '';
      StringModifier.Free;
      SHandleEx.Free;
      SHandleEx.Close;
    end;
  end;
end;

Above Code keeps adding spaces in front to the String you want to be centered until it is properly centered in the Max String Width you given, and outputs the modified string with added spaces.

NOTE: The MaxWidth Parameter here should be the Width you want to center the String. A string which has a higher width than you specify here can not be centered correctly. And a Visual Styles Skin is not necessary to center Wizard Window Title using above function.

Usage:

If you want to use this function to center Wizard Window Title, use it like:

If you don't use a Visual Styles Skin:

[Code]
Const
  SM_CYSIZEFRAME = 33;
  SM_CXSMICON = 49;

function GetSystemMetrics(nIndex : Integer): Integer;  
  external 'GetSystemMetrics@User32 stdcall';

procedure InitializeWizard;
begin
  { MaxWidth = WizardForm.Width - 2 * (WizardForm.FrameWidth + WizardForm.SmallIconWidth + WizardForm.CaptionLeft + WizardForm.CaptionRight) }
  WizardForm.Caption := AlignStringToCenter(WizardForm.Caption, 'Segoe UI', WizardForm.Width - (2 * (GetSystemMetrics(SM_CYSIZEFRAME) + GetSystemMetrics(SM_CXSMICON) + 10 + 10)), 9);
end;

If you use a Visual Styles Skin:

[Code]
Const
  SM_CYSIZEFRAME = 33;
  SM_CXSMICON = 49;

function GetSystemMetrics(nIndex : Integer): Integer;  
  external 'GetSystemMetrics@User32 stdcall';

procedure InitializeWizard;
begin
  { MaxWidth = WizardForm.Width - 2 * (WizardForm.FrameWidth + WizardForm.SmallIconWidth + WizardForm.CaptionLeft + WizardForm.CaptionRight) }
  WizardForm.Caption := AlignStringToCenter('Setup - {#MyAppName}', 'Window Title Font Name of your Visual Styles Skin', WizardForm.Width - (2 * (GetSystemMetrics(SM_CYSIZEFRAME) + GetSystemMetrics(SM_CXSMICON) + 10 + 10)), Window Title Font Size of your Visual Styles Skin);
end;

Centered Wizard Window Title:

enter image description here

However, centering Wizard Window Title using above function (Hacking it by adding spaces) causes the following bad effect in Windows Taskbar Tooltips:

enter image description here

NOTE: WizardForm.CaptionLeft and CaptionRight should vary with the Size of your Visual Styles Skin's Left Caption Margin if you use a Visual Styles Skin.

查看更多
一纸荒年 Trace。
3楼-- · 2019-04-02 11:28

I do not think this is possible.

The window title is custom-drawn by the ISSkin DLL. So Windows does not know the font size, hence you cannot use Windows API.

And ISSkin does not export any function to retrieve this information.

查看更多
登录 后发表回答