在Win32 Windows项目中更改默认窗口字体

5
我正在使用C和Win32 API创建GUI应用程序。我想知道如何将主窗口的默认字体更改为thaoma。我是从.NET背景下来的。在.NET中,如果我们更改父控件的字体,则子控件会自动继承该字体...是否有类似的方法,或者我们需要手动设置每个控件的字体...
考虑以下代码...
#include <windows.h>

#define ID_EDIT 1
#define ID_BUTTON 2

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{

  static HWND hwndEdit;
  static HWND hwndButton;
  static int len;
  static TCHAR text[30];


  switch(msg)
  {
    case WM_CREATE:
    hwndEdit = CreateWindow(TEXT("Edit"), NULL, WS_CHILD | WS_VISIBLE | WS_BORDER,
                50, 50, 150, 20, hwnd, (HMENU) ID_EDIT,
                NULL, NULL);

    hwndButton = CreateWindow(
        TEXT("button"), TEXT("Set Title"),       
        WS_VISIBLE | WS_CHILD,  
        50, 100, 80, 25,        
        hwnd, (HMENU) ID_BUTTON, NULL, NULL);      

    break;


    case WM_DESTROY:
        PostQuitMessage(0);
    break;
  }
  return DefWindowProc(hwnd, msg, wParam, lParam);
}

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
            LPSTR lpCmdLine, int nCmdShow )
{
  MSG  msg ;    
  WNDCLASS wc = {0};
  wc.lpszClassName = TEXT( "Edit Control" );
  wc.hInstance     = hInstance ;
  wc.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
  wc.lpfnWndProc   = WndProc ;
  wc.hCursor       = LoadCursor(0,IDC_ARROW);


  RegisterClass(&wc);
  CreateWindow( wc.lpszClassName, TEXT("Edit control"),
                WS_OVERLAPPEDWINDOW | WS_VISIBLE,
                220, 220, 280, 200, 0, 0, hInstance, 0);  

  while( GetMessage(&msg, NULL, 0, 0)) {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
  }
  return (int) msg.wParam;
}

如何更改上述程序中按钮和文本框的字体?

请在这里帮助我......并让我知道在win32 api编码时遵循的一般流程....

提前感谢。

2个回答

7
您可以通过发送WM_SETFONT消息来设置窗口的字体:
HWND myButton = CreateWindowEx(/* ... */);
HFONT myFont  = /* ... load font from somewhere ... */

/* Change the button font. */
SendMessage(myButton, WM_SETFONT, WPARAM(myFont), TRUE);

这种方法让你可以逐个控件地控制使用哪些字体,但每个窗口只需要执行一次。


2
我是winApi的新手,需要更改静态控件的字体。如果您能告诉我如何从其他地方加载字体,那就太好了。如何将字体放入资源中,以及应该使用哪个函数来加载它?提前致谢。 - Dipto

7
您想创建一个基于对话框的GUI应用程序,它看起来有点像.NET中的基于表单的应用程序。您可以为表单定义字体,所有子控件都继承该字体。每个对话框中也存在类似的情况。
如何使用Win32 API创建对话框,请参阅此处:http://msdn.microsoft.com/en-us/library/ms644996%28VS.85%29.aspx。与创建表单相比,对话框编程的主要区别在于,您应该使用资源编辑器(例如Visual Studio或Windows SDK)来设计对话框。结果将保存在RC文件中(尚未编译的资源文件)。结果将如下所示:
IDD_ABOUTBOX DIALOGEX 0, 0, 205, 98
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | 
    WS_SYSMENU
CAPTION "About"
FONT 8, "MS Shell Dlg 2", 400, 0, 0x1
BEGIN
    DEFPUSHBUTTON   "OK",IDOK,77,77,50,14
    LTEXT           "Trust to User (T2U) v1.0\n\n(c) Copyright 2003, 2004",
                    IDC_STATIC,72,32,120,32
    ICON            IDR_MAINFRAME,IDC_STATIC,25,27,20,20
    GROUPBOX        "",IDC_STATIC,7,3,191,69
    LTEXT           "OK soft  GmbH",IDC_OK_SOFT_GMBH,72,16,120,8
END

你可以在同一个RC文件中保存不同语言的多个资源:
IDD_ABOUTBOX DIALOGEX 0, 0, 205, 98
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | 
    WS_SYSMENU
CAPTION "バージョンの情報"
FONT 8, "MS Shell Dlg 2", 400, 0, 0x1
BEGIN
    DEFPUSHBUTTON   "OK",IDOK,77,77,50,14
    LTEXT           "Trust to User (T2U) v1.0\n\n(c) Copyright 2003, 2004",
                    IDC_STATIC,72,32,120,32
    ICON            IDR_MAINFRAME,IDC_STATIC,25,27,20,20
    GROUPBOX        "",IDC_STATIC,7,3,191,69
    LTEXT           "OK soft  GmbH",IDC_OK_SOFT_GMBH,72,16,120,8
END

如果您使用“MS Shell Dlg 2”或“MS Shell Dlg”而不是字体“Tahoma”,则在国际化方面可以获得最佳结果,但直接使用“Tahoma”也是可行的:

FONT 8, "Tahoma"

你应该使用 "MS Shell Dlg 2" 与标志 DS_SHELLFONT 或组合使用 DS_FIXEDSYSDS_SETFONT(参见 http://blogs.msdn.com/oldnewthing/archive/2005/02/07/368423.aspx),这些都是在大多数计算机上使用 "Tahoma" 后的选择(在注册表键 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\FontSubstitutes 下验证 "MS Shell Dlg 2" 的值)。阅读 http://msdn.microsoft.com/en-us/library/dd374112%28v=VS.85%29.aspxhttp://support.microsoft.com/kb/282187/en 了解更多信息。
顺便说一下,您可以使用Visual Studio打开保存在EXE、DLL或EXE.MUI/DLL.MUI中的资源。您只需要打开文件并选择“打开方式”,然后选择“资源编辑器”。在Windows 7上,您可以搜索C:\Windows\winsxs\x86_microsoft-windows-notepad,并像打开文件C:\Windows\winsxs\x86_microsoft-windows-notepad.resources_31bf3856ad364e35_6.1.7600.16385_en-us_1dbc2e35304db501\notepad.exe.mui一样打开。然后,您可以将文件保存为notepad.rc,然后在文本编辑器中打开notepad.rc文件,您将找到以下片段。
15 DIALOGEX 30, 17, 300, 22
STYLE DS_SETFONT | DS_3DLOOK | DS_CONTROL | WS_CHILD | WS_CLIPSIBLINGS
FONT 8, "MS Shell Dlg", 0, 0, 0x0
BEGIN
    LTEXT           "&Encoding:",259,68,1,40,40,NOT WS_GROUP
    COMBOBOX        257,130,0,164,100,CBS_DROPDOWNLIST | WS_VSCROLL | WS_GROUP | WS_TABSTOP
END

51200 DIALOGEX 0, 0, 324, 140
STYLE DS_SETFONT | DS_3DLOOK | WS_CHILD | WS_CAPTION
CAPTION "Software Licensing"
FONT 9, "Segoe UI", 0, 0, 0x0
BEGIN
    LTEXT           "To use this feature without interruption, this computer needs to be running genuine Windows.",-1,0,10,250,20
    LTEXT           "With genuine Windows you have access to all Windows updates and can be confident that your Windows software has the latest security and reliability enhancements from Microsoft.",-1,0,35,250,30
    CONTROL         51209,-1,"Static",SS_BITMAP,260,10,100,55
    CONTROL         "&Resolve online now",51201,"Button",BS_COMMANDLINK | BS_LEFT | WS_TABSTOP,0,75,250,24
    CONTROL         "<a>Read the privacy statement online</a>",51202,"SysLink",WS_TABSTOP,0,128,120,10
END

更新:尝试修改您的WndProc函数如下:

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
  static HWND hwndEdit;
  static HWND hwndButton;
  static int len;
  static TCHAR text[30];
  HFONT hFont;
  LOGFONT lf;

  switch(msg)
  {
    case WM_CREATE:
    hwndEdit = CreateWindow(TEXT("Edit"), NULL, WS_CHILD | WS_VISIBLE | WS_BORDER,
                50, 50, 150, 20, hwnd, (HMENU) ID_EDIT,
                NULL, NULL);
    GetObject (GetStockObject(DEFAULT_GUI_FONT), sizeof(LOGFONT), &lf); 
    hFont = CreateFont (lf.lfHeight, lf.lfWidth, 
        lf.lfEscapement, lf.lfOrientation, lf.lfWeight, 
        lf.lfItalic, lf.lfUnderline, lf.lfStrikeOut, lf.lfCharSet, 
        lf.lfOutPrecision, lf.lfClipPrecision, lf.lfQuality, 
        lf.lfPitchAndFamily, lf.lfFaceName); 

    SendMessage (hwndEdit, WM_SETFONT, (WPARAM)hFont, TRUE);

    hwndButton = CreateWindow(
        TEXT("button"), TEXT("Set Title"),       
        WS_VISIBLE | WS_CHILD,  
        50, 100, 80, 25,        
        hwnd, (HMENU) ID_BUTTON, NULL, NULL);      

    SendMessage (hwndButton, WM_SETFONT, (WPARAM)hFont, TRUE);
    break;


    case WM_DESTROY:
        PostQuitMessage(0);
    break;
  }
  return DefWindowProc(hwnd, msg, wParam, lParam);
}

但我的问题不在于对话框,我想改变主窗口(不是对话框)中所有控件的字体,且该窗口不包含任何资源文件... 请给我解释一下,谢谢。 - Vineel Kumar Reddy
@Vineel Kumar Reddy: 如果您发布一些代码或者更详细地描述如何创建主窗口和子控件,那将会更好。有一种通用的方法:您可以向任何窗口发送一个带有字体句柄(HFONT)的WM_SETFONT消息,这个句柄应该被用作WPARAMTRUE作为LPARAM立即重绘控件以设置字体。大多数控件都支持此消息。某些控件具有限制。例如对于树形控件(请参见http://msdn.microsoft.com/en-us/library/bb773409%28VS.85%29.aspx),您应该在插入任何项之前发送此消息。 - Oleg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接