delphiwinapidelphi-xe4

How can I detect monospace fonts in Delphi?


How can I detect monospace fonts in Delphi?

TFont.Pitch should be fpFixed I think, but it does not work for me with Delphi XE4:

var
  Font: TFont;
begin
  Font := TFont.Create;
  Font.Name := 'Courier New';
  if Font.Pitch = fpFixed then
    ShowMessage('Monospace Font!');
  ...

Font.Pitch based on GetObject of the WinAPI. It should return in lfPitchAndFamily FIXED_PITCH, but I always get DEFAULT_PITCH for all fonts (also for Arial).


Solution

  • Yes, GetObject really returns DEFAULT_PITCH. But you can get true value through enumeration of fonts with needed name:

    function EnumFontsProc(var elf: TEnumLogFont;
                           var tm: TNewTextMetric;
                           FontType: Integer;
                           Data: LPARAM): Integer; stdcall;
    begin;
      Result := Integer(FIXED_PITCH = (elf.elfLogFont.lfPitchAndFamily and FIXED_PITCH));
    end;
    
    procedure TForm1.Button13Click(Sender: TObject);
    begin;
      if EnumFontFamilies(Canvas.Handle,
                          PChar('Courier New'),
                          @EnumFontsProc,0) then
         Caption := 'Fixed'
      else
         Caption := 'Variable';
    end;
    

    Edit: In newer Delphi versions EnumFontFamilies function is described as returning Integer result (in accordance with MSDN), as Andreas Rejbrand noticed in comments, so result should be treated as:

     if EnumFontFamilies(Canvas.Handle,
                         PChar('Courier New'),
                         @EnumFontsProc,0)  <> 0  then