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

Delphi技术问题:已设SetProcessDPIAware时缩放主窗口及XE6取色器截图

Delphi DPI感知后主窗口缩放与全屏截图优化

一、SetProcessDPIAware后如何缩放主应用窗口

刚调用SetProcessDPIAware开启进程DPI感知后,系统就不会再自动帮你缩放窗口和控件了——毕竟你告诉系统“我自己能处理高DPI”嘛。结合XE6的VCL特性,咱可以这么搞:

  • 手动计算缩放比例调整控件:先拿当前DPI值,用GetDeviceCaps(Canvas.Handle, LOGPIXELSX)获取横向DPI(纵向一般和横向一致),然后算出缩放比例Scale := CurrentDPI / 96(96是系统默认DPI)。接着在窗体的OnCreate事件里,遍历所有控件,把它们的Left、Top、Width、Height都乘以这个Scale,字体大小也按比例调。注意别重复缩放,可以加个标记位判断是否已经处理过。
  • 试试VCL自带的ScaleForDPI:XE6虽然不像高版本Delphi那样有完善的高DPI支持,但也提供了TForm.ScaleForDPI方法。你可以在窗体创建时,获取当前DPI,然后调用ScaleForDPI(DesignDPI, CurrentDPI)(DesignDPI就是你设计窗体时的DPI,一般是96)。不过这个方法对自定义控件或者第三方控件兼容性可能一般,得自己测测。
  • 修正最大化/最小化的窗口尺寸:开了DPI感知后,窗体最大化可能会不对,这时候可以用GetSystemMetricsForDPI(需要手动声明这个API,因为XE6的Windows单元可能没包含)来获取适配DPI后的屏幕尺寸,然后手动调整窗体的BoundsRect。

二、全屏截图代码优化(不再支持XP/Vista)

看了你贴的旧代码,确实有不少可以优化的地方,而且既然放弃了XP/Vista,咱可以用更简洁高效的实现,还能避免资源泄漏:

原始代码片段

var hDesktopWindow: THandle; DesktopCanvas: TCanvas; DeskRect, SourceRect: TRect;
begin
  DesktopCanvas := TCanvas.Create;
  try
    hDesktopWindow := GetDesktopWindow;
    DesktopCanvas.Handle := GetDC(hDesktopWindow);
    try
      // 1. On XP/Vista De...的内容

优化后的完整实现

procedure CaptureFullScreen(ABitmap: TBitmap);
var
  hDesktop: HWND;
  hDesktopDC: HDC;
  DesktopRect: TRect;
begin
  // 先确保传入的位图对象不为空
  Assert(ABitmap <> nil, 'CaptureFullScreen: Bitmap parameter cannot be nil');
  
  // 获取桌面窗口句柄
  hDesktop := GetDesktopWindow;
  // 获取桌面的实际像素尺寸(自动适配DPI)
  GetWindowRect(hDesktop, DesktopRect);
  
  // 获取桌面设备上下文
  hDesktopDC := GetDC(hDesktop);
  try
    // 设置位图尺寸和桌面一致
    ABitmap.SetSize(DesktopRect.Width, DesktopRect.Height);
    // 把桌面图像复制到位图上
    BitBlt(ABitmap.Canvas.Handle, 0, 0, DesktopRect.Width, DesktopRect.Height,
           hDesktopDC, DesktopRect.Left, DesktopRect.Top, SRCCOPY);
  finally
    // 必须释放DC,否则会造成资源泄漏
    ReleaseDC(hDesktop, hDesktopDC);
  end;
end;

// 使用示例
procedure TMainForm.btnCaptureClick(Sender: TObject);
var
  FullScreenBmp: TBitmap;
begin
  FullScreenBmp := TBitmap.Create;
  try
    CaptureFullScreen(FullScreenBmp);
    // 这里可以做你需要的操作,比如保存到文件
    FullScreenBmp.SaveToFile('FullScreenCapture.png');
    ShowMessage('截图已保存!');
  finally
    FullScreenBmp.Free;
  end;
end;

优化点说明

  • 去掉了冗余的TCanvas创建,直接复用传入的位图Canvas,减少内存开销
  • 用ReleaseDC正确释放获取的DC,解决了原始代码里的资源泄漏隐患
  • 增加断言检查,提前发现参数错误,让代码更健壮
  • 分离了截图逻辑和资源管理,代码更清晰,也方便复用
  • 用GetWindowRect获取真实的桌面尺寸,适配DPI感知后的屏幕像素

内容的提问来源于stack exchange,提问作者Vlastimil Burián

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 07:40:01