GetSystemMetrics获取到的虚拟屏幕大小不太对

蠓虫带着秤砣飞 2021-04-08 07:31:43
使用GetSystemMetrics获取屏幕的大小,想整个屏幕截图
int cx = GetSystemMetrics(SM_CXVIRTUALSCREEN);
int cy = GetSystemMetrics(SM_CYVIRTUALSCREEN);
屏幕没有缩放时结果时正常的,如果屏幕有缩放,那么缩放的屏幕就尺寸不正常了。
和PrintScreen键解出来的屏幕不一样。总是缺少点东西。
查看了一下PrintScreen键,截图出来的大小缩放屏幕也是按照分辨率大小截取的。
而GetSystemMetrics获取到的大小是缩放的屏幕缩放过的。
怎么获取到真正的全屏幕大小呢?
...全文
1639 11 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2021-04-30
  • 打赏
  • 举报
回复
引用 10 楼 zjq9931 的回复:
使用EnumDisplaySettings获取的各个屏幕的坐标。
EnumDisplaySettings The EnumDisplaySettings function obtains information about one of a display device's graphics modes. You can obtain information for all of a display device's graphics modes by making a series of calls to this function. BOOL EnumDisplaySettings( LPCTSTR lpszDeviceName, // specifies the display device DWORD iModeNum, // specifies the graphics mode LPDEVMODE lpDevMode // points to structure to receive settings ); Parameters lpszDeviceName Pointer to a null-terminated string that specifies the display device whose graphics mode the function will obtain information about. This parameter can be NULL. A NULL value specifies the current display device on the computer that the calling thread is running on. If lpszDeviceName is not NULL, the string must be of the form \\.\DisplayX, where X can have the values 1, 2, or 3. Windows 95 and Windows 98: lpszDeviceName must be NULL. iModeNum Indicates the type of information to retrieve. This value can be a graphics mode index or one of the following values. Value Meaning ENUM_CURRENT_SETTINGS Retrieve the current settings for the display device. ENUM_REGISTRY_SETTINGS Retrieve the settings for the display device that are currently stored in the registry. Graphics mode indexes start at zero. To obtain information for all of a display device's graphics modes, make a series of calls to EnumDisplaySettings, as follows: Set iModeNum to zero for the first call, and increment iModeNum by one for each subsequent call. Continue calling the function until the return value is zero. When you call EnumDisplaySettings with iModeNum set to zero, the operating system initializes and caches information about the display device. When you call EnumDisplaySettings with iModeNum set to a non-zero value, the function returns the information that was cached the last time the function was called with iModeNum set to zero. lpDevMode Pointer to a DEVMODE structure into which the function stores information about the specified graphics mode. Before calling EnumDisplaySettings, set the dmSize member to sizeof(DEVMODE), and set the dmDriverExtra member to indicate the size, in bytes, of the additional space available to receive private driver-data. The EnumDisplaySettings function sets values for the following five DEVMODE members: dmBitsPerPel dmPelsWidth dmPelsHeight dmDisplayFlags dmDisplayFrequency Return Values If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. Windows NT: To get extended error information, callGetLastError. Remarks The function fails if iModeNum is greater than the index of the display device's last graphics mode. As noted in the description of the iModeNum parameter, you can use this behavior to enumerate all of a display device's graphics modes. QuickInfo Windows NT: Requires version 3.51 or later. Windows: Requires Windows 95 or later. Windows CE: Unsupported. Header: Declared in winuser.h. Import Library: Use user32.lib. Unicode: Implemented as Unicode and ANSI versions on Windows NT. See Also Device Contexts Overview, Device Context Functions, ChangeDisplaySettings, ChangeDisplaySettingsEx, CreateDC,CreateDesktop, DEVMODE, EnumDisplayDevices
  • 打赏
  • 举报
回复
使用EnumDisplaySettings获取的各个屏幕的坐标。
  • 打赏
  • 举报
回复
引用 7 楼 qzjhjxj 的回复:
是否是用这个方法,先取得系统的dpi:
float GetDPI(){
    HDC hdcScreen;
    hdcScreen = CreateDC("DISPLAY",NULL,NULL,NULL);
    int iX    = GetDeviceCaps(hdcScreen, HORZRES); //pixel
    int iY    = GetDeviceCaps(hdcScreen, VERTRES); //pixel
    int iPhsX = GetDeviceCaps(hdcScreen, HORZSIZE);//mm
    int iPhsY = GetDeviceCaps(hdcScreen, VERTSIZE);//mm
    if (NULL != hdcScreen){DeleteDC(hdcScreen);}
    float iTemp = iPhsX * iPhsX + iPhsY * iPhsY;
    float fInch = sqrt(iTemp) * INCH;
    iTemp = iX * iX + iY * iY;
    float fPixel = sqrt(iTemp);
    float iDPI = fPixel/fInch;//dpi=pixel/inch
    cout<<"DPI:"<<iDPI<<endl;
    return iDPI;
}
不是,这个方法能获取单个屏幕的大小,但无法获取所有屏幕一起的大小(屏幕的排列方式不同长宽就不同,不规则的排列方式影响也挺大的)。 而且这个方法无法获取单个屏幕在所有屏幕里面的坐标,坐标很重要。
qzjhjxj 2021-04-10
  • 打赏
  • 举报
回复
补充上面的:
#define INCH 0.03937
qzjhjxj 2021-04-10
  • 打赏
  • 举报
回复
是否是用这个方法,先取得系统的dpi:
float GetDPI(){
    HDC hdcScreen;
    hdcScreen = CreateDC("DISPLAY",NULL,NULL,NULL);
    int iX    = GetDeviceCaps(hdcScreen, HORZRES); //pixel
    int iY    = GetDeviceCaps(hdcScreen, VERTRES); //pixel
    int iPhsX = GetDeviceCaps(hdcScreen, HORZSIZE);//mm
    int iPhsY = GetDeviceCaps(hdcScreen, VERTSIZE);//mm
    if (NULL != hdcScreen){DeleteDC(hdcScreen);}
    float iTemp = iPhsX * iPhsX + iPhsY * iPhsY;
    float fInch = sqrt(iTemp) * INCH;
    iTemp = iX * iX + iY * iY;
    float fPixel = sqrt(iTemp);
    float iDPI = fPixel/fInch;//dpi=pixel/inch
    cout<<"DPI:"<<iDPI<<endl;
    return iDPI;
}
  • 打赏
  • 举报
回复
问已经解决,看看能否有人知道用什么方法来解决的,比我的方法如何。
  • 打赏
  • 举报
回复
引用 1 楼 qzjhjxj 的回复:
供参考:https://blog.csdn.net/problc/article/details/7063324?ops_request_misc=&request_id=&biz_id=102&utm_term=GetSystemMetrics%EF%BC%88SM_YVIRTUALSC&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-7-7063324.first_rank_v2_pc_rank_v29
这个没用,我就是这么做的。 屏幕不缩放的时候没问题,一缩放就错了。 看到微软官网的有GetSystemMetricsForDpi Minimum supported client Windows 10, version 1607 [desktop apps only] 只有win10 1607才支持。 所以目前通过笨办法解决了。但感觉不好。期待更简洁的解决办法。
  • 打赏
  • 举报
回复
引用 3 楼 Cynhard85 的回复:
试试 GetMonitorInfo 是否可行?
一两个屏幕还好,三个屏幕也可以,四个屏幕的时候,我就头大了。 加上缩放,数值很不准确。
  • 打赏
  • 举报
回复
引用 3 楼 Cynhard85 的回复:
试试 GetMonitorInfo 是否可行?
也是不行的,我快绝望了。 不缩放的时候,都很准,一旦缩放,坐标乱动,甚至出现不连续的情况。
Cynhard 2021-04-09
  • 打赏
  • 举报
回复
试试 GetMonitorInfo 是否可行?

65,189

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧