DPI感知屏幕捕获

时间:2016-10-13 19:25:10

标签: windows-10 scaling autoit dpi screen-capture

之前我使用过AutoIt的_ScreenCapture_Capture()没有遇到任何麻烦。但在具有4k分辨率屏幕的Windows 10上,我使用200%的DPI缩放。 _ScreenCapture_capture()现在获得2倍放大的内容和我要求的位置的一半。

例如:

 _ScreenCapture_Capture("c:\a.bmp", 100, 100, 200, 200)
;                             Path,  X1,  Y1,  X2,  Y2

不返回屏幕的100x100像素平方(100,100200,200)。它会返回一个100x100像素的正方形(50,50100,100)。

我确实找到了解决方案:

DllCall("User32.dll", "bool", "SetProcessDPIAware")

然而,这会搞砸GUI看起来。然后我找到了this code

GUISetFont(8.5 * _GDIPlus_GraphicsGetDPIRatio()[0])
Func _GDIPlus_GraphicsGetDPIRatio($iDPIDef = 96)
  Local $aResults[2] = [1, 1]
  _GDIPlus_Startup()
  Local $hGfx = _GDIPlus_GraphicsCreateFromHWND(0)
  If @error Then Return SetError(1, @extended, $aResults)
  #forcedef $__g_hGDIPDll, $ghGDIPDll
  $aResult = DllCall($__g_hGDIPDll, "int", "GdipGetDpiX", "handle", $hGfx, "float*", 0)
  If @error Then Return SetError(2, @extended, $aResults)
  Local $iDPI = $aResult[2]
  Local $aresults[2] = [$iDPIDef / $iDPI, $iDPI / $iDPIDef]
  _GDIPlus_GraphicsDispose($hGfx)
  _GDIPlus_Shutdown()
  Return $aresults
EndFunc   ;==>_GDIPlus_GraphicsGetDPIRatio

哪个适用于GUI,但对_ScreenCapture_Capture()次调用没有帮助。似乎我可以有一个好看的或有效的程序,而不是两者。

我如何将这两种解决方案结合起来,以获得良好的GUI和正常运行的程序?如果我知道如何做相反的事情:

DllCall("User32.dll", "bool", "SetProcessDPIAware")

然后,当我需要捕获屏幕部分时,我可以打开兼容性,然后在完成捕获后立即将其关闭。但我不知道如何使用UNsetprocessdpiaware'。

1 个答案:

答案 0 :(得分:2)

如果您使用的是Windows 10 A更新(10.0.14393),您可以启动一个单独的线程并使该线程独立于Per Monitor DPI,并将您的主GUI保持为dpi不知道。

SetThreadDpiAwarenessContext function

如果您在2015年之前使用Visual Studio版本构建,则可以声明指向函数原型的指针

DPI_AWARENESS_CONTEXT WINAPI SetThreadDpiAwarenessContext(
  _In_  DPI_AWARENESS_CONTEXT  dpiContext
);

并在调用之前使用GetProcAddress测试函数是否存在。如果您使用

,该线程中的任何内容都将为您提供原始物理信息
DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE

请注意,此功能在Windows 10 10.0.10586上不可用。您必须测试其可用性。