You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用GetObject获取LOGFONT返回0,参数值全为-MAXINT,求排查

问题:GetObject获取LOGFONT失败返回0且值为-MAXINT

我在运行Windows 11的64位笔记本上使用VS2019 Community版本,尝试实现通用字体缩放函数,调整HFONT属性但效果有限,编写了如下代码:

//==============================================================================
#include "stdafx.h"
//X #include <ocidl.h>   // PATH is C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Include\ocidl.h

//==============================================================================
// Function ScaleFont().  
//==============================================================================
HFONT ScaleFont(
    HFONT hFont
  , HWND  hWnd
  , double PctAdjustmentSPEC
  )
{
  double PctAdjustment    = min(max(PctAdjustmentSPEC,0.875),1.125);
  LOGFONT lf;
  int NumBytes = GetObject((HGDIOBJ)hFont,sizeof(lf),(void*)(&lf));
  double WidthHeightRatio = double(lf.lfWidth)/double(lf.lfHeight);
  lf.lfHeight = LONG(floor(lf.lfHeight * PctAdjustment));
  lf.lfWidth  = LONG(floor(lf.lfWidth * PctAdjustment * WidthHeightRatio));
  HDC hdc = GetDC(hWnd);
  DeleteObject((HGDIOBJ)hFont);
  hFont = (HFONT)CreateFontIndirect(&lf);  
  SelectObject(hdc,hFont);
  ReleaseDC(hWnd,hdc);
  return hFont;
}

当前问题出在语句int NumBytes = GetObject((HGDIOBJ)hFont,sizeof(lf),(void*)(&lf));,该语句返回NumBytes==0,且LOGFONT对象所有值等于-MAXINT,请问哪里出错了?

已尝试的方案:

  • 使用IFont方法但编译失败;
  • 用HANDLE替换HGDIOBJ可正常编译;
  • 尝试用GetLogicalFont替代GetObject,但VS2019不识别该函数名。

问题原因及解决办法

  1. 无效句柄或类型不匹配:GetObject返回0最常见的原因是传入的hFont无效,或者并非合法的GDI字体句柄。先确认调用ScaleFont时传入的hFont是通过CreateFont、CreateFontIndirect、GetStockObject或SendMessage(hWnd, WM_GETFONT, 0, 0)等方式正确获取的有效句柄,而非已被释放的句柄或COM接口指针。

  2. 结构体初始化缺失:调用GetObject前未初始化LOGFONT结构体,内存中可能存在垃圾值,建议先执行ZeroMemory(&lf, sizeof(lf))清空结构体,避免干扰后续判断。

  3. 错误码定位问题:在GetObject返回0后,立即调用GetLastError()获取具体错误码,比如:

    • ERROR_INVALID_PARAMETER:说明传入的参数(如结构体大小、句柄类型)不匹配;
    • ERROR_INVALID_HANDLE:说明hFont是无效句柄;
      这能精准定位问题根源。
  4. 函数逻辑的潜在错误:

    • 不要在函数内直接DeleteObject(hFont),原字体句柄的生命周期应由调用方管理,否则会导致调用方后续使用该句柄时出现错误;
    • 调用SelectObject(hdc, hFont)后未恢复DC的原字体,会导致DC状态异常,正确做法是保存原字体句柄并恢复:
      HDC hdc = GetDC(hWnd);
      HFONT hOldFont = (HFONT)SelectObject(hdc, hFont);
      // 若需使用DC执行绘制操作,在此处完成
      SelectObject(hdc, hOldFont); // 恢复DC的原字体
      ReleaseDC(hWnd, hdc);
      

内容的提问来源于stack exchange,提问作者The Bard of Chelsea

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 15:47:01