11

ユーザーの UI フォント設定を取得する呼び出しを思いつきました (Borland のハードコードされた "MS Sans Serif" の選択とは対照的に)。

ユーザーのフォント設定が次のようになっているとしましょう。

Segoe Print, 15pt

すべてのアイテム、すべてのフォーム、すべてのアプリケーションのフォントを次のように設定します。

Segoe Print, 15pt

問題は、物事が断ち切られていることです。ボタンが小さすぎる - 狭すぎる、短すぎる。ラベルの文字が切れるなど。

フォームには Scaled プロパティがありますが、フォント サイズによっては変わりません。scaled プロパティは、数値「0」の高さに基づいてシリアル化されるときにフォームをスケーリングしました。

ユーザーの Windows アプリケーション設定をサポートするためにボーランドがどのように私を意図したかについてのヘルプを見つけることができません。

ユーザーのフォント設定を処理するにはどうすればよいですか?

注:エンバーガデロのニュース サーバーが機能しなくなっているか、検閲されているか、壊れているか、ログインが必要なように見えるため、エンバーガデロのニュース グループ サーバーからこれをクロス ポストしました。


更新 1

DPI 設定ではなく、ユーザーのフォント設定について話しているのです。つまり、次の言語に依存しない疑似コードを想像してください。

procedure TForm1.FormCreate(Sender: TObject);
var
    FontFace: string;
    FontHeight: Integer;
begin
    GetUserFontPreference(out FontFace, out FontHeight);
    Self.Font.Name := FontFace;
    Self.Font.Height := FontHeight;
end;

注:これは私の実際のコードではありません (結局のところ、これは言語に依存しない疑似コードです)。さらに、フォーム上のすべてのコントロールを再帰的に処理し、必要に応じてフォントを変更する必要があります。フォントに親とは異なるスタイル (太字など) が適用されていて、親から継承されなくなった場合は、手動で設定する必要があります。


lkesslerの要求に従って、ユーザーの UI フォント設定を Windows から取得するコードは次のとおりです。

procedure GetUserFontPreference(out FaceName: string; out PixelHeight: Integer);
var
    lf: LOGFONT;
begin
    ZeroMemory(@lf, SizeOf(lf));
     //Yes IconTitleFont (not SPI_GETNONCLIENTMETRICS MessageFont)
    if SystemParametersInfo(SPI_GETICONTITLELOGFONT, SizeOf(lf), @lf, 0) then
    begin
        FaceName := PChar(Addr(lf.lfFaceName[0]));
        PixelHeight := lf.lfHeight;
    end
    else
    begin
        {
            If we can't get it, then assume the same non-user preferences that
            everyone else does.
        }
        FaceName := 'MS Shell Dlg 2';
        PixelHeight := 8;
    end;
end;

関連する質問

4

6 に答える 6

9

まず、はっきりさせておくと、Borland はもう Delphi を所有していません。Embarcadero が Delphi を所有するようになり、私たちは安全に保護されています。

さて、あなたの質問に進みます。

秘訣は、TForm.AutoScroll を False に設定し、開発マシンが Small fonts に設定されていることを確認することです。TForm.Scaled をそのままにしておきます (デフォルト値は True です)。

それがここで内部的に行う方法であり、IDE はすべてをうまく処理します。

于 2008-12-30T19:02:45.250 に答える
3

この関数を使うのが好きです。Graphics.GetFontDataに基づいています

procedure SystemFont(Font: TFont);
var
  LogFont: TLogFont;
begin
  if SystemParametersInfo(SPI_GETICONTITLELOGFONT, SizeOf(TLogFont), @LogFont, 0) then
    begin
      Font.Height := LogFont.lfHeight;
      Font.Orientation := LogFont.lfOrientation;
      Font.Charset := TFontCharset(LogFont.lfCharSet);
      Font.Name := PChar(@LogFont.lfFaceName);

      Font.Style := [];

      if LogFont.lfWeight >= FW_BOLD then
        Font.Style := Font.Style + [fsBold];

      if LogFont.lfItalic = 1 then
        Font.Style := Font.Style + [fsItalic];

      if LogFont.lfUnderline = 1 then
        Font.Style := Font.Style + [fsUnderline];

      if LogFont.lfStrikeOut = 1 then
        Font.Style := Font.Style + [fsStrikeOut];

      case LogFont.lfPitchAndFamily and $F of
        VARIABLE_PITCH: Font.Pitch := fpVariable;
        FIXED_PITCH: Font.Pitch := fpFixed;
        else Font.Pitch := fpDefault;
      end;
    end;
end;

すべてのTForm.OnCreateイベントで使用するだけです。別の方法として、Screen.Formsの作成またはループ時にこれを行う新しいクラスを作成することもできます。

フォーム上のコントロールのデフォルトフォントのプロパティの一部を変更しても、古いフォントが引き続き使用されます。一部のコントロールにカスタムプロパティが必要な場合は、SystemFontを呼び出した後でそれらを調整する必要があります。

フォームデザイナが変更されたプロパティのみを.dfmファイルに書き込んだ場合は、実行時にGraphics.DefFontDataを変更すると役立つことがあります。

于 2009-01-15T21:43:45.570 に答える
3

私はあなたと一緒に感じています。しかし、公平を期して言えば、VCL で採用されているピクセルベースのレイアウト メカニズムでは、適切な GUI レイアウトを作成することはできません。必要なのは、動的レイアウト エンジンです。

  1. 各コントロールに適切なフォントが設定されている (これは、Windows のバージョン、ユーザー設定、およびコントロールの種類によって異なります)。と

  2. コントロールに必要なスペースが増減する可能性があるため、コントロール内のテキストは現在のロケールに翻訳されています。

これはすべて実行時のプロパティに依存するため、コントロールを配置してダイアログを作成することはできません。GTK や QT のようなレイアウト メカニズム、または wxWidgets のサイザーが適しています。

私は、Delphi プログラムについてそのようなことを知りません。一部のプログラムでは、フォントの設定とテキストの翻訳後に手動でコントロールのサイズと位置を調整しています。多くの作業が必要ですが、視聴者によっては、それだけの価値がある場合があります。

Jordan Russell が Inno Setup のために書いたコードを調べることもできます。彼はフォームの Scaled プロパティを使用していませんが、コントロールのカスタム スケーリング用のコードを記述しています。おそらく、高 DPI 画面上の非常に大きなフォントでも機能するでしょう。少なくとも私の 124 DPI ラップトップでは、画面設定ダイアログが非常によく見えることに気付きました。

于 2008-12-30T20:24:06.257 に答える
2

これを正しく行うには、次のことを行う必要があると思います。

1 - ユーザーのフォント設定を読み込む

2 - 説明したとおりに適用します

3 - すべてのキャプションの幅と高さ (ピクセル単位) を決定し、それをコントロールの幅と高さと比較して、それに応じて調整します。

残念ながら、「それに応じて調整する」部分は難しいです。ボタンを広げることはできますが、それが別のコントロールと重なっているかどうかを確認する必要があります。

最善の策は、少し大きめのコントロールを作成し、ユーザーが 32 ポイントのフォント サイズを選択しないようにすることです。

于 2008-12-30T21:03:36.253 に答える
1

Kogus は正しい考えを持っていましたが、使用する必要がある関数を除外しました。Windows のGetTextExtentPoint32ルーチンになります。文字列を渡すと、現在選択されているフォントを使用して文字列の幅と高さが計算されます。Windows.pas にあります。

許可するフォントに必要な最大スペースを事前に計算することをお勧めします。

または、関数を使用して、テキストを表示する領域のサイズを動的に調整し、収まるようにすることもできます。

これは 1 つまたは 2 つのコントロールの場合は問題ありませんが、ユーザー インターフェイス全体でこれを実行しようとすると、どちらの方法も大変な作業になります。

于 2008-12-30T23:59:14.997 に答える
0

これは翻訳に似ていると思います。私たちのアプリでは、一部の言語で必要とされる長い単語を簡単に収容できるように、ボタン、ラベル、編集などすべてを少し大きくしました。デザインを少し損ないません。

于 2008-12-31T10:13:25.303 に答える