【问题标题】:Replicate DOS console font (CP437) in Win32 app在 Win32 应用程序中复制 DOS 控制台字体 (CP437)
【发布时间】:2015-07-01 14:38:11
【问题描述】:

我正在将旧的控制台应用程序转换为 Win32,并希望从控制台复制字体。现有的代码库迫使我使用 C/C++ 工作。我正在尝试使用 CreateFont 和 CreateFontIndirect 来构造一个等价物。

控制台字体设置为:

感谢How to use DOS font in WinForms application这个帖子和仲裁者的回答,我想我知道光栅字体不是TTF,也不是直接支持的。

我想构造一个与12像素高度和8像素宽度匹配的固定字体。

这是我目前尝试过的一些代码。

HDC hdc = GetDC(w_child);
// "A 12-point font is 16 pixels tall." -- https://msdn.microsoft.com/en-us/library/windows/desktop/ff684173(v=vs.85).aspx
// "An n-point font is 4/3*n pixels tall"?
// I want 12 pixels tall, so 9-point, right?
int PointSize = 9;
int nHeight = -MulDiv(PointSize, GetDeviceCaps(hdc, LOGPIXELSY), 72);
ReleaseDC(w_child, hdc);

HFONT hf = CreateFont(
    -12,        //nHeight,          // Logical height
    0,      //nHeight * 2/3,    // Logical avg character width
    0,                          // Angle of escapement (0)
    0,                          // Baseline angle (0)
    FW_DONTCARE,                // Weight (0)
    FALSE,                      // Italic (0)
    FALSE,                      // Underline (0)
    FALSE,                      // Strikeout (0)
    ANSI_CHARSET,               // Character set identifier ??
    OUT_DEFAULT_PRECIS,         // Output precision
    CLIP_DEFAULT_PRECIS,        // Clip precision (0)
    DEFAULT_QUALITY,            // Output quality
    FIXED_PITCH,                // Pitch and family
    "Lucida Console"            // Pointer to typeface name string
    //"Terminal"
    //"Courier New"
);
*/

// Getting stock font, creating an indirect as a logical modification,
// seems to work better.  

// ANSI_FIXED_FONT, with lf.lfHeight = 10, results in something clear and
// readable, but a little too large. 
// And changing lfHeight seems to have no impact.
HFONT hf = (HFONT)GetStockObject(ANSI_FIXED_FONT);

// SYSTEM_FIXED_FONT at lfHeight = 10 is way too big
HFONT hf = (HFONT)GetStockObject(SYSTEM_FIXED_FONT);

// DEVICE_DEFAULT_FONT at lfHeight = 8 is way too big.  
HFONT hf = (HFONT)GetStockObject(DEVICE_DEFAULT_FONT);

LOGFONT lf;
GetObject(hf, sizeof(LOGFONT), &lf);
lf.lfHeight = 12;
HFONT nf = CreateFontIndirect(&lf);
SendMessage(w_child, WM_SETFONT, (WPARAM)nf, TRUE);

【问题讨论】:

  • 如果您获得系统字体,则 w_child 窗口可能无法处理 WM_SETFONT 消息。这并不罕见,只有内置的 Windows 控件可以处理它。在窗口过程的 WM_PAINT 消息处理程序中使用 SelectObject() 在绘制之前选择字体。
  • @HansPassant:我正在使用内置的编辑器。我非常希望不必滚动自己的控件并编写自己的 WM_PAINT。但我担心 EDIT 控件以某种方式忽略了我的 WM_SETFONT
  • 如果您希望有人为您调试代码,那么您必须发布更好的重现代码。
  • 嗯,你有没有考虑过制作一个看起来等价的等宽 TTF,然后改用它?
  • @Mike'Pomax'Kamermans:我做过,但不熟练。我找到了 vgaoem.fon 文件,最终可能会转换它。

标签: c++ winforms winapi fonts


【解决方案1】:

在我的情况下似乎成功了:

 CreateFont(12, 8, 0, 0, 0, FALSE, 0, 0, OEM_CHARSET, OUT_RASTER_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FIXED_PITCH, L"System");

【讨论】:

  • 而不是12, 8,使用-12, -8 来使用“设备单位”。
猜你喜欢
  • 1970-01-01
  • 2010-11-04
  • 1970-01-01
  • 2011-03-10
  • 1970-01-01
  • 2011-09-30
  • 2017-04-18
  • 2017-09-15
  • 2021-11-02
相关资源
最近更新 更多