2024/10/20(Sun) 21:22:16 編集(投稿者)
■No103403 (アブサン さん) に返信
FontDialog に初期表示されるフォントは LOGFONT構造体によります。
Nirmala UI で中細フォントを選択するには LOGFONT 構造体を初期化するときに
lfFaceName : "Nirmala UI"
lfWeight : 350
と指定する必要があるのですが、FontDialog では指定できないので、
FontDialog、または CommonDialog 継承したクラスを作成し、RunDialog を
オーバーライドする必要があるでしょう。
CommonDialog を継承したクラスを書いておきます。
using System.Runtime.InteropServices;
#nullable disable
public class FontDialogEx : CommonDialog
{
public Font Font { get; set; }
public int FontWeight { get; set; }
public FontDialogEx() {
Reset();
}
public override void Reset() {
Font = Control.DefaultFont;
}
// フォント名からスタイルを示すキーワードを削除
private static string GetBaseFontName(string fontName) {
string[] fontStyles = { "Semilight", "Bold", "Italic", "Regular", "Light", "Medium" };
foreach (var style in fontStyles) {
if (fontName.Contains(style)) {
fontName = fontName.Replace(style, "").Trim();
break;
}
}
return fontName;
}
protected override bool RunDialog(nint hwndOwner) {
NativeMethods.LOGFONT logFont = new();
Font.ToLogFont(logFont);
logFont.lfFaceName = GetBaseFontName(logFont.lfFaceName);
logFont.lfWeight = FontWeight;
NativeMethods.CHOOSEFONT cf = new();
IntPtr logFontPtr = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(NativeMethods.LOGFONT)));
try {
Marshal.StructureToPtr(logFont, logFontPtr, false);
cf.lpLogFont = logFontPtr;
cf.hwndOwner = hwndOwner;
cf.hDC = IntPtr.Zero;
cf.hInstance = NativeMethods.GetModuleHandle(null);
cf.Flags = NativeMethods.CF_INITTOLOGFONTSTRUCT;
var result = NativeMethods.ChooseFont(cf);
if (result) {
logFont = Marshal.PtrToStructure<NativeMethods.LOGFONT>(logFontPtr);
Font = Font.FromLogFont(logFont);
FontWeight = logFont.lfWeight;
}
return result;
} finally {
if (logFontPtr != IntPtr.Zero) {
Marshal.FreeCoTaskMem(logFontPtr);
}
}
}
static class NativeMethods
{
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public class LOGFONT
{
public int lfHeight;
public int lfWidth;
public int lfEscapement;
public int lfOrientation;
public int lfWeight;
public byte lfItalic;
public byte lfUnderline;
public byte lfStrikeOut;
public byte lfCharSet;
public byte lfOutPrecision;
public byte lfClipPrecision;
public byte lfQuality;
public byte lfPitchAndFamily;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string lfFaceName;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public class CHOOSEFONT
{
public int lStructSize = Marshal.SizeOf(typeof(CHOOSEFONT));
public IntPtr hwndOwner;
public IntPtr hDC;
public IntPtr lpLogFont;
public int iPointSize = 0;
public int Flags;
public int rgbColors;
public IntPtr lCustData = IntPtr.Zero;
public IntPtr lpfnHook;
public string lpTemplateName = null;
public IntPtr hInstance;
public string lpszStyle = null;
public short nFontType = 0;
public short ___MISSING_ALIGNMENT__ = 0;
public int nSizeMin;
public int nSizeMax;
}
[DllImport("comdlg32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern bool ChooseFont([In, Out] CHOOSEFONT cf);
[DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr GetModuleHandle(string modName);
public const int CF_INITTOLOGFONTSTRUCT = 0x00000040;
}
}
FontDialog と同等の機能を持たせたい場合は .NET Framework のソース
https://referencesource.microsoft.com/#System.Windows.Forms/winforms/Managed/System/WinForms/FontDialog.cs,c5fa98b3849668dd
が参考になると思います。