Delphi desktop screenshot in Windows10, issue with GetDeviceCaps

北城以北 提交于 2020-01-29 08:45:25

问题


How can I get the correct screen size to take a screenshot in Windows10? it seems to get incorrect values (maybe DPI issue?)

i.e

// screenshot
b := TBitmap.Create;
DC := GetDC(GetDesktopWindow);
try
  b.Width  := GetDeviceCaps (DC, HORZRES) ;
  b.Height := GetDeviceCaps (DC, VERTRES) ;
  BitBlt(b.Canvas.Handle, 0, 0, b.Width, b.Height, DC, 0, 0, SRCCOPY) ;
finally
  ReleaseDC (GetDesktopWindow, DC) ;
end;

on a 4K screen will only capture a small portion on the upper left corner.


回答1:


You need to make your application fully High DPI aware in order to get proper values for taking screen snapshot.

You can do that by adding following section into your application manifest

  <asmv3:application>
    <asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
      <dpiAware>true/PM</dpiAware>
    </asmv3:windowsSettings>
  </asmv3:application>

Complete example of custom manifest for Windows 10

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">

  <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> 
      <application> 
            <!-- Windows 10 --> 
            <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>

            <!-- Windows 8.1 -->
            <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>

            <!-- Windows 8 -->
            <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>

            <!-- Windows 7 -->
            <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>

            <!-- Windows Vista -->
            <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/> 
      </application> 
  </compatibility>

  <assemblyIdentity
    type="win32"
    name="MyApplication"
    version="1.0.0.0" 
    processorArchitecture="*"/>

  <dependency>
    <dependentAssembly>
      <assemblyIdentity
        type="win32"
        name="Microsoft.Windows.Common-Controls"
        version="6.0.0.0"
        publicKeyToken="6595b64144ccf1df"
        language="*"
        processorArchitecture="*"/>
    </dependentAssembly>
  </dependency>

  <asmv3:application>
    <asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
      <dpiAware>true/PM</dpiAware>
    </asmv3:windowsSettings>
  </asmv3:application>

<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
    <security>
      <requestedPrivileges>
        <requestedExecutionLevel
          level="asInvoker"
          uiAccess="false"/>
        </requestedPrivileges>
       </security>
  </trustInfo>

</assembly>

Note: Windows 10 have introduced Per-monitor DPI awareness. Above manifest turns that awareness on with true/PM value (PM - Per Monitor).

Since Delphi introduced support for Per-Monitor DPI in Seattle, applications compiled with older versions will not properly scale in multi-monitor setups that have different DPI settings for each monitor on Windows 10. Depending on the purpose of your application and user base you can either live with such behavior or you would have to upgrade to newest Delphi (it is also important to note that this is new feature and it does have some bugs that may or not be relevant in your case)



来源:https://stackoverflow.com/questions/35587364/delphi-desktop-screenshot-in-windows10-issue-with-getdevicecaps

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!