添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

windows系统下为了满足不同场景的应用,坐标系主要分为两类:逻辑坐标系和设备坐标系,一般而言GDI的文本和图形处理使用逻辑坐标系,而窗口以及鼠标的移动一般采用设备坐标系进行管理。

逻辑坐标系

逻辑坐标系是面向GDI绘制是主要使用的对象DC(Device Context)应用,这种坐标系不考虑设备的具体类型,在绘制图形和文字时,windows会根据当前设置的映射模式将逻辑坐标自动转为设备坐标。

设备坐标系

设备坐标是面向物理设备的坐标系,比如显示器,打印机等,这种坐标以像素或者设备所能表示的最小度量单位为基本单位。这种坐标系采用向下向右为正,横向为x轴方向,纵向为y轴方向,坐标原点根据
具体的设备链接和设置的不同存在一定差异。其中设备坐标系又可细分为屏幕坐标系、窗口坐标系和客户区坐标系三种相互独立的坐标系。三种坐标系示意图如下图所示。

  • 1.屏幕坐标系

    屏幕坐标系是以主屏幕左上角为坐标原点,向右向下为正,见上图黑色字体。在多屏场景中,windows系统存在主副屏概念
    ,当前显示器的标识和是否为主屏可以通过[win7:桌面下鼠标右键->屏幕分辨率->设为主显示器]、[win10:设置->显示->设置为主显示器]进行主显示器设置,与此同时,当不清楚当前显示器具体位置时可以通过点击标识按钮,
    系统将会在每个显示器界面上标识出1,2,…的数字字样。同时可以通过拖动虚拟显示器位置改变显示器在屏幕坐标系的位置。
    当主屏在其他屏幕的左上侧时,此时屏幕上所显示的位置在屏幕坐标系的坐标均为正值,当一个显示器位于屏幕主显示器的左上角时,该显示器的点在坐标系中的位置存在负值。具体来说,当屏幕位于主显示器左侧时,
    x轴值为负值,当显示器位于主显示器上侧时,y轴坐标系为负值。一些与整个屏幕有关的函数均采用屏幕坐标系,如:GetCursorPos()、SetCursorPos()、CreateWindow()、MoveWindow()等。

  • 2.窗口坐标系

    窗口坐标系与屏幕坐标系相似,不同的是窗口坐标系是以当前窗口的左上角为坐标系的原点,向右向下为正。窗口包括标题栏、菜单栏、工具栏以及客户区等。坐标轴如上图所示。

  • 3.客户区坐标系

    在窗口的大部分区域也即是客户区,客户区坐标系比窗口坐标系更加细化,如上图所示。在该区域是窗口主要功能的展示区,其中包括客户区的绘图输出和窗口消息的处理等。

本文主要记录在多屏场景中屏幕坐标系相关内容,尤其是高分屏场景的适配场景。

在介绍高分屏适配之前需要了解2个概念,也即是DPI和DWM。其中DPI也即是(Dots Per Inch)每英寸像素点数量,在显示器上就是每英寸的像素个数,Window上一般默认是96 dpi 作为100% 的缩放比率,其他平台略有不同,例如mac端默认为72。
在windows系统中为了满足不同DPI屏幕显示自适应缩放,保证应用程序界面在不同的DPI显示器下正常显示,关于高DPI的支持, Windows XP时代就开始有了,
那时关于高DPI的支持比较简单,仅仅通过手动设置的方式进行文字或图片显示比例的调整,
但是从Vista/Win7 到现在Win8 /Win8.1, Windows关于高DPI的支持已经发生了很大的变化,也就是我们需要了解的另外一个概念DWM。

DWM(Desktop Window Manager),该技术其实是用于实现当应用程序不能进行高DPI适应或者未禁止DWM虚拟化时,系统自动通过DWM进行调整,具体来说就是应用程序不需要自己实现不同分辨率显示器的文字或图片的缩放,只需要按照相同的处理逻辑按照100%显示比例进行应用程序界面的绘制,在最终显示之前系统会通过DWM自动将应用程序进行缩放,保证同样一个应用程序在1080p显示器上能看到正常的画面,但是在4K屏上就变的极其小的情况。
对于win8.1以上系统DPI设置可以根据不同的需要设置当前应用程序是否开启DPI感知,以及开启DPI感知的具体级别。

typedef enum _Process_DPI_Awareness {
  Process_DPI_Unaware            = 0,
  Process_System_DPI_Aware       = 1,
  Process_Per_Monitor_DPI_Aware  = 2
} Process_DPI_Awareness;

  第一种Unaware, 该种方式是告诉系统, 我的程序不支持DPI aware, 请通过DWM虚拟化帮我们实现。 该方式通过GetWindowRect取到的坐标都是经过DWM缩放后的, 无论对方窗口是不是支持DWM虚拟化。

  第二种方式是System DPI aware, 该方式下告诉系统, 我的程序会在启动的显示器上自己支持DPI aware, 所以不需要对我进行DWM 虚拟化。 但是当我的程序被拖动到其他DPI不一样的显示器时, 请对我们先进行system DWM虚拟化缩放。

  第三种方式是Per Monitor DPI aware, 该方式是告诉系统, 请永远不要对我进行DWM虚拟化,我会自己针对不同的Monitor的DPi缩放比率进行缩放。 这种方式需要自己完成对高DPI的支持。
chrome 是设置的Per Monitor DPI aware 猜测其UI应该自己内部实现了对高DPI的支持,基于CEF的开发 建议设置System DPI aware 来完成对高DPI的支持。

  在windows8.1以上系统可以通过以下API获取或设置系统DPI相关的信息:

GetDpiForMonitor	    # Queries the DPI information associated with a monitor.
GetDpiForSystem	        # Returns the system DPI.
GetDpiForWindow	        # Returns the current DPI for the specified window.
GetProcessDpiAwareness	# Retrieves the DPI virtualization mode of the specified process.
GetSystemMetricsForDpi	# A variant of GetSystemMetrics that returns values scaled to a specific DPI.
SetProcessDpiAwareness	# Sets the DPI virtualization mode for the current process.
GetSystemDpiForProcess	# Retrieves the system DPI associated with a given process.

更多详细的函数信息,可以参阅这个链接:https://docs.microsoft.com/zh-cn/windows/win32/hidpi/high-dpi-reference

就先记录到这里吧,下篇我们将整理一下windows高DPI下鼠标坐标相关问题。

  windows系统下为了满足不同场景的应用,坐标系主要分为两类:逻辑坐标系和设备坐标系,一般而言GDI的文本和图形处理使用逻辑坐标系,而窗口以及鼠标的移动一般采用设备坐标系进行管理。逻辑坐标系  逻辑坐标系是面向GDI绘制是主要使用的对象DC(Device Context)应用,这种坐标系不考虑设备的具体类型,在绘制图形和文字时,windows会根据当前设置的映射模式将逻辑坐标自动转为设备...
本项目分享的是0.96OLED模块资料,包括OLED液晶上位机及应用和STM32 控制代码等。该OLED液晶高分辨率(128*64),和12864 LCD相同分辨率,但该OLED 的单位面积像素更多。128*64 OLED液晶特点: 可视角度:大于160° 功耗:正常显示时0.06W(远低于TFT显示) 供电范围:直流3V-5V,直接兼容3.3V和5V供电系统 使用2线的I2C接口,一般的IO口模拟I2C也能控制 兼容3.3V和5V控制芯片的I/O电平(无需设置,直接兼容) 字模制作上位机截图: 附件内容截图: (demohttp://download.csdn.net/detail/problc/3841959包含多显示器支持,窗口亮,十字放大等) 其实多显示的截跟主显示器的截区别并不大,甚至根本不需要EnumDisplayMonitors之类的调用。只是因为网上有了源码,我们就懒得想了。 1. DC的问题。 hScrDC = CreateDC( _T("DISPLAY"),NULL,NULL...
Windows应用程序绘制图形时使用的是一种逻辑单位,每个逻辑单位的大小由映射模式决定,这个逻辑单位既可以与设备单位(屏幕或打印机上的一个像素点)相同,也可以是一种物理单位(如毫米),还可以是用户自定义的一种单位。在Windows应用程序,只要与输出有关系,都要使用映射模式。 首先谈谈映射模式基本知识,当Windows应用程序在其客户区绘制图形时,必须给出在客户区的位置,其位置用x和y
主机上另外再连接一个监视器,这样主机就可以检测到两个显示器,设置显示器属性,将屏幕扩展到第二(采用扩展模式)。在VC编程时,可以检测到第二的信息(甚至多屏),比如的个数,各个的分辨率,各个的句柄,获得了这些信息后,就可以在第二上操作了,比如 画图之类。        在编程要用到相关的结构体和函数,这些都已经包装好,在multimom.h头文件,该头文件VC自带有。在要用的的
下面三种都是显示设备的物理坐标,它们在屏幕上用真实的物理像素表示 。 屏幕坐标 Screen coordinates: 原点(0,0)位于屏幕的左上角窗口坐标 Window coordinates: 原点(0,0)位于窗口的左上角(包括非客户区,如标题条) 客户区坐标Client-window coordinates: 原点(0,0)位于客...
Qt5.13的适配Windows DPI可以通过以下几个步骤实现: 1. 在Qt应用程序使用DPI感知API。这些API可以检测到系统DPI,并针对高分辨率设备进行调整。使用这些API可以确保应用程序在各种DPI下保持一致性,而不会缩放或扭曲。 2. 使用Qt提供的QHighDpiScaling类。该类可以自动缩放Qt部件和图像,以适应高分辨率设备。它使用当前屏幕DPI设置来计算缩放因子,并将其应用于应用程序的所有内容。 3. 使用QScreen类进行自定义缩放。该类提供了一些方法来检测和控制当前屏幕DPI设置。您可以使用这些方法来实现自定义缩放策略,以更好地适应不同的屏幕分辨率。 总之,Qt5.13的适配Windows DPI可以通过以上几个方法来实现。这将确保您的应用程序在不同的高分辨率设备上具有一致的外观和用户体验。