Windows 11双显示器截屏全攻略:解决缩放比例导致的截屏不全问题

程序员必备:用C++实现Windows双显示器无缝截屏的完整代码示例 本文提供了使用C++和Windows API实现双显示器无缝截屏的完整解决方案。文章深入解析了虚拟桌面、物理分辨率等核心概念,并给出了从枚举显示器、计算捕获区域到执行屏幕捕获和保存位图的详细代码示例,帮助开发者构建健壮的多屏截屏功能,有效解决自动化测试等场景中的截屏难题。 阅读详情

Windows 11双显示器截屏终极指南:精准捕获多屏内容的专业方案

当你在Windows 11系统中使用双显示器工作时,是否遇到过这样的困扰:明明想截取整个工作区的完整画面,结果得到的截图要么只包含主屏内容,要么出现奇怪的错位和缺失?这种问题在开发调试、数据分析或跨屏协作场景中尤为恼人。本文将深入解析双显示器截屏的技术原理,并提供一套完整的解决方案,帮助你实现像素级精准的多屏截取。

1. 理解Windows显示系统的核心机制

Windows的显示子系统远比表面看到的复杂。当你连接多个显示器时,系统会创建一个虚拟的"桌面空间",这个空间可能横向或纵向扩展,具体取决于显示器的排列方式。每个物理显示器在这个虚拟空间中都有其特定的位置和尺寸属性。

1.1 显示缩放与物理分辨率

现代高分辨率显示器普遍采用显示缩放技术,让UI元素在保持清晰的同时不至于太小。Windows 11默认会根据显示器PPI自动设置缩放比例(通常为125%、150%甚至200%)。这个缩放系数直接影响截屏时的尺寸计算:

// 传统获取屏幕尺寸的方法(受缩放影响)
HWND hWnd = GetDesktopWindow();
RECT re;
GetWindowRect(hWnd, &re);
int width = re.right;  // 可能不是物理像素值
int height = re.bottom;

1.2 多显示器拓扑结构

双显示器可以配置为以下几种模式:

  • 复制模式:两个显示器显示相同内容(截屏只需处理单个显示器)
  • 扩展模式:显示器组成逻辑上的大桌面(需要特殊处理)
  • 仅第二屏幕:主显示器关闭(较少见)

在扩展模式下,显示器可以有以下几种排列组合:

排列方式 主显示器坐标 副显示器坐标 虚拟桌面尺寸计算
横向扩展 (0,0) (主屏宽度,0) 宽度相加,取最大高度
纵向扩展 (0,0) (0,主屏高度) 高度相加,取最大宽度
混合排列 (0,0) (x,y) 需要计算边界值

2. 获取真实物理分辨率的专业方法

要正确截取双显示器内容,关键在于获取不受缩放影响的物理分辨率。Windows API提供了多层次的显示信息查询接口。

2.1 单显示器物理分辨率获取

首先看如何正确获取单个显示器的真实分辨率:

void GetMonitorPhysicalResolution(HMONITOR hMonitor, int& width, int& height) {
    MONITORINFOEX miex;
    miex.cbSize = sizeof(miex);
    GetMonitorInfo(hMonitor, &miex);
    
    DEVMODE dm;
    dm.dmSize = sizeof(dm);
    dm.dmDriverExtra = 0;
    EnumDisplaySettings(miex.szDevice, ENUM_CURRENT_SETTINGS, &dm);
    
    width = dm.dmPelsWidth;  // 物理宽度
    height = dm.dmPelsHeight; // 物理高度
}

2.2 枚举所有显示器的进阶方案

对于多显示器系统,我们需要枚举所有活动显示器并计算整体虚拟桌面尺寸:

struct MonitorInfo {
    long width, height;
    long x, y;
    bool isPrimary;
    std::string deviceName;
};

BOOL CALLBACK MonitorEnumP
Win11最佳缩放比例设置指南 缩放比例是Windows 11中一个非常实用的功能,它允许用户根据自己的显示器尺寸和视力需求,自由调整界面元素的大小。通过简单的设置步骤,你可以轻松找到最适合自己的缩放比例,从而获得更佳的视觉体验和使用感受。希望本文能对你有所帮助,让你在Windows 11的使用过程中更加得心应手。 阅读详情

相关推荐

Windows下双显示器截屏方法

网上的Windows环境下截屏的源代码很多,但是看到的都是只能适应单显示器,无法截取桌面扩展到双显示器情况下的完整屏幕。过查找资料和摸索,发现问题的关键就在于正确获得截屏的长宽尺寸。通常,计算屏幕实际大小可以用: HWND hWnd = GetDesktopWindow(); RECT re; GetWindowRect(window, &re); int width = re.rig...

kingfox的专栏 7094

多显示器DPI适配全解析:Win10/Win11跨屏开发那些坑

本文深入解析了Windows 10/11多显示器DPI适配的核心原理与实战解决方案,帮助开发者解决跨屏开发中的UI错位、模糊等问题。从DPI虚拟化机制到现代开发策略,涵盖Win32/MFC、WPF、UWP等技术栈的适配要点,并提供调试技巧与验证清单,助力提升开发效率。

efc123456的博客 870

从模糊到清晰:一次搞懂Windows 11的DPI缩放原理与‘系统(增强)’模式到底强在哪

本文深入解析Windows 11的DPI缩放机制,特别是‘系统(增强)’模式的技术优势。通过对比传统‘系统’模式,揭示其如何通过混合渲染技术解决高DPI显示器上的模糊问题,提升老旧应用程序的显示效果。适合需要优化高DPI设置的用户和开发者阅读。

weixin_30697239的博客 629

window10 原生截屏功能双屏状态

window10 原生截屏功能双屏状态 问题来源: 我经常使用Windows的截屏快捷键。但当我换成双屏状态,它默认同时截取两个屏幕: 但我往往只需要截取一半的屏幕(如右边的屏幕) 之前的处理方法是通过Windows10自带的照片软件裁剪 人生苦短,我用Python 一两次手动裁剪下来,太麻烦了 解决方案: 文件夹下照片批量命名: 为什么要重新命名呢?为了避免Python对中文路径的报错,首先把图片的名称(e.g.屏幕截图(4).png)改成数字命名: def re_name(path): files = os.listdir(path) for i, file in enum

孤读paper——《GhostNet:More Features from Cheap Operations》

《GhostNet:More Features from Cheap Operations》   发现一个点并解决就是一篇CVPR,该文章主要发现了优秀的网络的特点是feature map提取过程中的冗余性,这种冗余性体现在很多成对的feature map间很像,就好像彼此的“ghost”,而这种特征冗余性对于理解图像来说还是必要的,所以文章把feature map分为两种,一种是本质特征,一...

雄关漫道真如铁 而今迈步从头越 5149

个人信息保护合规审计人员(中级)能力测试试卷

本文是关于个人信息保护合规考试的试题解析,内容涵盖《个人信息保护法》相关规定。试卷包含单选题、多选题、判断题、简答题和案例分析题五种题型,总分100分,考试时间120分钟。试题重点考察个人信息处理的基本原则、敏感个人信息处理要求、合规审计流程、个人信息保护影响评估等内容。通过案例分析题详细解析了人脸识别登录、数据共享、跨境传输等场景下的合规要求。参考答案均严格依据《个人信息保护法》等法律法规,为个人信息处理活动提供了明确的合规指引。

qq_41525079的博客 848

SAP特殊采购类80实战:跨工厂生产配置避坑指南(附完整测试流程)

本文深入解析SAP特殊采购类80在跨工厂生产场景下的实战应用与配置要点。文章从核心业务逻辑出发,详细拆解了后台配置、主数据与BOM的“双工厂”思维模式,并提供了从创建需求到成品收货的完整测试流程。重点揭示了多层BOM下的需求传递陷阱及常见报错解决方案,旨在帮助SAP顾问及用户规避实施风险,实现资源的灵活调度与流程自动化。

wind6的博客 1137

储能电站 BMS 与车载动力电池 BMS 核心差异:工况、保护策略、控制逻辑对比

储能电站BMS与车载动力电池BMS虽同名,实为针对不同赛道量身定制的产品。简单地将车载BMS方案套用于储能,或将储能BMS思路用于车载,都可能带来性能、安全或成本上的严重问题。在选择和设计BMS时,必须回归其应用场景的本质需求储能BMS是**“资产管理者”**,精打细算,追求在长达十余年的服役期内稳定、高效地创造收益。车载BMS是**“性能与安全卫士”**,反应敏捷,确保在车辆全生命周期内动力澎湃且万无一失。

小帽子的博客 422

C8T6和ZET6选型更换过程中出现.\Obj\Project.sct(7): error: L6235E: More than one section matches selector - cann

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录前言一、问题原因二、解决方法三、现象总结 前言 又一件离谱的事情发生了,我之前转换过程中没有发生的错误,今天拿出来程序重新编译了一下,结果他奶奶滴一个新的错误出现了,而且我还完全不知道是什么原因导致的,先上图: 一、问题原因 之前我已经尝试过更换芯片选型,但是没有出现此类问题,今天更改的时候发现了,我还以为是个偶然错误,结果换来换去,还是有这个问题,那我之前说c8t6的程序更改成zet6上跑只需改芯片选型和宏定义岂不是啪啪打.

wx18045623090的博客 1488

openlayers6【十九】vue HeatmapLayer热力图层实现热力图效果详解

文章目录1. 写在前面2. Heatmap 类实现热力图2.1 Heatmap 参数2.2 实现热力图3. 完整代码4. 添加删除map图层的方法5. 热力图自身的get,set方法 1. 写在前面 我们主要看热力图的效果,区域绘制效怎么设置详细内容可以访问 openlayers6【十七】vue VectorLayer矢量图层画地图省市区,多省市区(粤港澳大湾区)效果详解 在 openlayers 中,图层是使用 layer 对象表示的,主要有 WebGLPoints Layer、热度图(HeatMap L

@必意玲 1万+

【FastDDS】Layer DDS之Subscriber ( 09-Accessing received data)

Fast DDS提供了多种接收数据访问方式:通过读取(read)或提取(take)操作获取数据,其中提取会移除数据而读取保留数据。应用程序可通过序列高效借用接收队列内存,但需及时归还。数据处理时需检查SampleInfo的有效性,可通过监听器回调或等待集机制异步获取数据。等待集允许线程专门等待新数据到达,通过条件触发和超时控制实现可靠的数据接收处理。

Ray Home 862

第0章 《机器人工程师带你入门SLAM》专栏所有文章目录汇总(截止目前115篇文章),方便大家查看阅读

《机器人工程师带你入门SLAM》专栏文章汇总:优快云热销专栏已更新100+篇优质内容,涵盖SLAM技术全栈知识体系。文章分为三大类:1)基础工具与环境配置,包括Ubuntu、Git等必备技能;2)C++编程从入门到进阶,详解变量、类、模板等核心概念;3)SLAM核心库实战,深入解析ROS、Eigen、PCL等关键库的应用。专栏提供从计算机基础到项目实战的系统学习路径,并附代码实例。点击专栏主页可订阅查看全部内容,后续将保持更新。

行知SLAM 1062

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

上一篇: 避坑指南:用bs4爬取小说网站时常见的5个问题及解决方案
下一篇: 避坑指南:OrCAD Capture导出网表时你一定会遇到的5个错误(附17.4版本实测)
rust6ferris
博客等级 码龄4年 56粉丝 2232原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值