《Windows API每日一练》4.2 设备环境

news2025/4/17 23:04:33

在第三章我们已经使用设备环境句柄在窗口客户区绘图了。在图形输出设备(比如屏幕或者打印机)上绘制图形,必须首先获取设备环境,即DC的句柄。当 Windows把这个句柄交给你的程序,Windows同时也就给予你使用这个设备的权限。接着,在GDI函数中将这个句柄作为一个参数,告诉 Windows在哪个设备上进行绘图。

本节必须掌握的知识点:

        获取设备环境句柄

        获取设备环境信息

        第22练:获取设备环境信息

4.2.1 获取设备环境句柄

设备环境包含许多决定GDI函数如何工作的属性。这些属性使得GDI函数只需要提供少量的参数(如起始坐标),而不需要提供 Windows在设备上显示对象时需要的所有信息。例如,当你调用 TextOut函数时,仅需要在函数中指定设备环境句柄、起始坐标、文本以及文本的长度,不需要指定字体、文本的颜色、文本背景的颜色或者字符间距。所有这些属性都是设备环境的一部分。当你想改变这些属性时,可以调用函数来执行,之后调用的TextOut函数就会使用新的设备环境的属性。

WM_PAINT消息中获取

       在处理 WM_PAINT消息时使用 BeginPaint函数和 EndPaint函数:

hdc = BeginPaint (hwnd, &ps) ;

其他行程式

EndPaint (hwnd, &ps) ;

在其他消息中获取

hdc = GetDC (hwnd) ;

其他行程式

ReleaseDC (hwnd, hdc) ;

EndPaint函数组合与GetDC函数组合的主要差别是:

EndPaint函数获取无效区域的设备环境句柄。

GetDC函数返回的是整个窗口客户区的设备环境句柄。并且GetDC和 ReleaseDC函数并不使任何客户区的无效区域变为有效。

获取屏幕设备环境句柄

hdc = CreateDC (pszDriver, pszDevice, pszOutput, pData) ;

其他行程式

DeleteDC (hdc) ;

例如,可以通过调用下面的函数获取当前整个屏幕的设备环境句柄:

hdc = CreateDC (TEXT ("DISPLAY"), NULL, NULL, NULL) ;

此外,我们还将在第十三章使用CreateDC函数获取打印机设备环境句柄。

获取内存设备环境句柄

hdcMem = CreateCompatibleDC (hdc) ;

其他行程式

DeleteDC (hdcMem) ;

可以把一个位图选入内存设备环境,并且调用GDl函数绘制这个位图。我将在第十四章介绍这些技术。

获取整个窗口设备环境句柄

hdc = GetWindowDC (hwnd) ;

其他行程式

ReleaseDC (hwnd, hdc) ;

这里的设备环境除了包括客户区,还包含窗口标题栏、菜单、滚动条和客户区的外框。应用程序很少使用 GetWindowDC函数。如果你想尝试使用它,则还应当捕获WM_NCPAINT( nonclient paint,非客户区绘制)消息,Windows使用这个消息在窗口的非客户区绘图。

获取设备环境信息

CreateIC 函数为指定设备创建信息上下文。信息上下文提供了一种快速获取有关设备的信息的方法,而无需创建设备上下文 (DC) 。但是,GDI 绘图函数不能接受信息上下文的句柄。

HDC CreateIC(

  LPCTSTR lpszDriver,         // 驱动程序的名称或驱动程序文件名

  LPCTSTR lpszDevice,         // 设备的名称

  LPCTSTR lpszOutput,         // 输出端口的名称

  const DEVMODE *lpInitData   // 设备的初始化数据

);

获取图元文件设备环境句柄

hdcMeta = CreateMetaFile (pszFilename) ;

其他行程式

hmf = CloseMetaFile (hdcMeta) ;

在图元文件设备环境有效时,使用 hdcMeta所做的任何GDI调用都不会被直接显示出来,它们都会变成图元文件的一部分。当你调用 CloseMetaFile时,图元文件设备环境句柄变为无效,该函数返回一个图元文件句柄(hmf)。我将在第十七章讨论图元文件。

4.2.2 获取设备环境信息

设备环境通常指的是物理的显示设备,如视频显示器或者打印机。经常需要获取这些设备的某些信息,包括显示器的大小(以像素或者物理尺寸的方式)和它的色彩能力。这些信息可以通过调用 GetDeviceCaps(意思为获取设备的能力)函数来获取。

iValue = GetDeviceCaps (hdc, iIndex) ;

其中,参数 iIndex是定义在 WINGDL.H头文件中的29个标识符之一。例如,当 iIndex的值为 HORZRES时, GetDeviceCaps函数以像素为单位返回设备的宽度;使用ⅤERTRES参数值会以像素为单位返回设备的高度。如果hdc是一个屏幕设备环境的句柄,这里所获取的信息和从 GetSystemMetrics函数获取的信息是一样的。如果hdc是一个打印机设备环境,那么 GetDevice Caps将以像素为单位返回打印机显示区域的高度和宽度。

还可以使用 GetDeviceCaps函数来确定设备处理各种类型图形的能力。通常这对于视频显示器并不重要,但是对于打印机却非常重要。例如,大多数的绘图仪不能绘制位图图像,通过调用 GetDeviceCaps函数可以让你提前知道这一情况。我们将在接下来的实例中演示GetDeviceCaps函数的使用方法。

4.2.3 第22练:获取设备环境信息

/*------------------------------------------------------------------

022. 编程达人win32 API每日一练

     第22个例子DEVCAPS1.C:获取显示器设备环境信息

      GetDeviceCaps函数

(c) www.bcdaren.com, 2020

----------------------------------------------------------------*/

#include <windows.h>

#define NUMLINES ((int)(sizeof devcaps / sizeof devcaps[0])) //行数

struct 

{

     int iIndex;         //索引

     TCHAR *szLable;     //系统信息

     TCHAR *szDesc;      //描述

}

devcaps[]=     //结构数组

{

     HORZSIZE,      TEXT("HORZSIZE"),       TEXT("Width in millimeters:"),

     VERTSIZE,      TEXT("VERTSIZE"),       TEXT("Height in millimeters:"),

     HORZRES,       TEXT("HORZRES"),        TEXT("Width in pixels:"),

     VERTRES,       TEXT("VERTRES"),        TEXT("Height in raster lines:"),

     BITSPIXEL,     TEXT("BITSPIXEL"),      TEXT("Color bits per pixel:"),

     PLANES,        TEXT("PLANES"),         TEXT("Number of color planes:"),

     NUMBRUSHES,    TEXT("NUMBRUSHES"),     TEXT("Number of device brushes:"),

     NUMPENS,       TEXT("NUMPENS"),        TEXT("Number of device pens:"),

     NUMMARKERS,    TEXT("NUMMARKERS"),     TEXT("Number of device markers:"),

     NUMFONTS,      TEXT("NUMFONTS"),       TEXT("Number of device fonts:"),

     NUMCOLORS,     TEXT("NUMCOLORS"),      TEXT("Number of device colors:"),

     PDEVICESIZE,   TEXT("PDEVICESIZE"),    TEXT("Size of devicestructure:"),

     ASPECTX,       TEXT("ASPECTX"),        TEXT("Relative width of pixel:"),

     ASPECTY,       TEXT("ASPECTY"),        TEXT("Relative height of pixel:"),

     ASPECTXY,      TEXT("ASPECTXY"),      TEXT("Relative diagonal of pixel:"),

     LOGPIXELSX,    TEXT("LOGPIXELSX"),     TEXT("Horizontal dots per inch:"),

     LOGPIXELSY,    TEXT("LOGPIXELSY"),     TEXT("Vertical dots per inch:"),

     SIZEPALETTE,   TEXT("SIZEPALETTE"),    TEXT("Number of palette entries:"),

     NUMRESERVED,   TEXT("NUMRESERVED"),    TEXT("Reserved palette entries:"),

     COLORRES, TEXT("COLORRES"), TEXT("Actual color resolution:")

};

/*****************************************************************************/

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,

 PSTR szCmdLine, int iCmdShow)

{

     static TCHAR szAppName[] = TEXT ("DEVCAPS1.C") ;

     (略)

     return msg.wParam ;

}

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)

{

     static int cxChar, cxCaps, cyChar;

     HDC hdc ;

     int i;

     PAINTSTRUCT ps ;

     TCHAR szBuffer[10] ;

     TEXTMETRIC tm

     switch (message)

     {

     case WM_CREATE:

          hdc = GetDC (hwnd) ;

          GetTextMetrics (hdc, &tm) ;

          cxChar = tm.tmAveCharWidth ; //字符平均宽度

          //平均字符宽度cxCaps设为cxChar的1.5倍。1表示变宽字体

          cxCaps = (tm.tmPitchAndFamily & 1 ? 3 : 2) * cxChar / 2 ;

          cyChar = tm.tmHeight + tm.tmExternalLeading ; //字符行距

          ReleaseDC (hwnd, hdc) ;

          return 0 ;

     case WM_PAINT :

           hdc = BeginPaint (hwnd, &ps) ; 

          for (i = 0 ; i < NUMLINES ; i++)

          {

               TextOut(hdc, 0, cyChar * i,devcaps[i].szLable,

                    lstrlen(devcaps[i].szLable));

               TextOut(hdc, 14 * cxCaps, cyChar*i,devcaps[i].szDesc,

                    lstrlen(devcaps[i].szDesc));

               SetTextAlign(hdc, TA_RIGHT | TA_TOP);

               TextOut(hdc, 14 * cxCaps + 35 * cxChar, cyChar * i, szBuffer,

                    wsprintf(szBuffer, TEXT("%5d"),

                         GetDeviceCaps(hdc,devcaps[i].iIndex)));

               SetTextAlign(hdc, TA_LEFT | TA_TOP);

          }

          EndPaint(hwnd, &ps);

          return 0;

     case WM_DESTROY:

          PostQuitMessage(0);

          return 0;

     }

     return DefWindowProc(hwnd, message, wParam, lParam);

}

/*****************************************************************

GetDeviceCaps功能检索指定设备的设备特定的信息

int GetDeviceCaps(

  HDC hdc,     //设备环境句柄

  int index    //设备环境信息索引

);

返回值指定所需项目的值。

******************************************************************

类似的API:

GetSystemMetrics函数:检索指定的系统指标或系统配置设置。

int GetSystemMetrics(int nIndex   //要检索的系统指标或配置设置);

*/

       运行结果:

图4-1 获取显示设备信息

 

总结

       DEVCAPS1.C的代码实现非常简单,定义了一个显示设备信息的结构数组,然后在WM_PAINT消息中循环输出GetDeviceCaps(hdc,devcaps[i].iIndex)));获取的显示设备信息。

       GetDeviceCaps 函数用于检索指定设备上下文的设备能力信息。它可以查询设备的各种能力,如分辨率、颜色深度、支持的功能等。

int GetDeviceCaps(

  HDC hdc,      // 设备上下文句柄

  int nIndex    // 设备能力的索引

);

返回值:

如果函数成功,返回设备能力的值,具体取决于 nIndex 参数。

如果函数失败,返回值为 0。

iIndex

iValue(返回值)

备注

HORZRES

以像素为单位的设备宽度

1、当hdc为整个屏幕DC时,与GetSystemMetrics获得的信息一致。

2、当hdc为打印机时,获得的是打机印显示区域的宽度和高度。

VERTRES

以像素为单位的设备高度

HORZSIZE

以毫米为单位的屏幕宽度

1、Windows98下:

HORZSIZE = 25.4×HORZRES/LOGPIXELSX.

VERTSIZE = 25.4×VERTRES/LOGPIXELSY

2、Windows NT下:为"标准显示器”的大小,即320×240,但可通过上述公式算出这两个真实的值出来。

3、对于打印机是物理尺寸,对于显示器是逻辑尺寸。

VERTSIZE

以毫米为单位的屏幕高度

LOGPIXELSX

每英寸的水平像素数

1、对于打印机:可以用上述公式运算出来。

2、对于显示器:与Windows设置的字体有关:正常字体96dpi,大字体为120dpi

LOGPIXELSX

每英寸的垂直像素数

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1825487.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【机器学习】机器学习与物流科技在智能配送中的融合应用与性能优化新探索

文章目录 引言机器学习与物流科技的基本概念机器学习概述监督学习无监督学习强化学习 物流科技概述路径优化车辆调度需求预测 机器学习与物流科技的融合应用实时物流数据分析数据预处理特征工程 路径优化与优化模型训练模型评估 车辆调度与优化深度学习应用 需求预测与优化强化…

vue2 + element-ui,前端配置化表单封装(2024-06-14)

技术栈是 vue2 element-ui&#xff0c;主要能解决的问题就是 提高代码复用能力、提升开发效率&#xff0c;特别是需要开发多个大型表单系统的&#xff0c;配置化可以极大的提升效率&#xff0c;让你上班摸鱼不再是梦想&#xff01;为了早点下班&#xff0c;我们接着往下看吧&a…

C#客户端

控件 打开链接 Socket socket; // 打开连接 private void button1_Click(object sender, EventArgs e) {button1.Enabled false;button2.Enabled true;//1 创建socket客户端对象socket new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);// 2…

基于C#开发web网页管理系统模板流程-主界面统计功能完善

点击返回目录-> 基于C#开发web网页管理系统模板流程-总集篇-CSDN博客 前言 紧接上篇->基于C#开发web网页管理系统模板流程-主界面管理员入库和出库功能完善_c#web程序设计-CSDN博客 统计功能是管理系统很常见的功能&#xff0c;例如仓库管理系统要统计某时间段的出入库以…

【计算机视觉】人脸算法之图像处理基础知识(四)

图像的几何变换 图像的几何变换是指在不改变图像内容的前提下对图像的像素进行空间几何变换。主要包括图像的平移变换、镜像变换、缩放和旋转等。 1.插值算法 插值通常用来放缩图像大小&#xff0c;在图像处理中常见的插值算法有最邻近插值法、双线性插值法、二次立方、三次…

【仪器仪表/电源专题】浮地信号的测试的四种方案对比

接地信号和浮地信号区别 所有的电压测量都是差分测量&#xff0c;差分测量定义为两点之间的电压差。所以会分成两类&#xff1a; 1.参考地电平测量&#xff08;有时也叫接地信号&#xff09; 2.非参考地电平测量&#xff08;也称为浮地测量&#xff09; 测试信号可以分为接地信…

SSM 基于大数据技术的创业推荐系统-计算机毕业设计源码02979

摘 要 科技进步的飞速发展引起人们日常生活的巨大变化&#xff0c;电子信息技术的飞速发展使得电子信息技术的各个领域的应用水平得到普及和应用。信息时代的到来已成为不可阻挡的时尚潮流&#xff0c;人类发展的历史正进入一个新时代。在现实运用中&#xff0c;应用软件的工作…

基于Matlab停车场车牌识别计时计费管理系统 【W2】

简介 停车场车牌识别计时计费管理系统在现代城市管理中具有重要意义。随着城市化进程的加快和车辆数量的增加&#xff0c;传统的人工管理停车场的方式已经难以满足效率和精确度的要求。因此引入车牌识别技术的自动化管理系统成为一种趋势和解决方案。 背景意义 提升管理效率&a…

从零开始开发知识付费APP:在线教育系统源码详解

今天&#xff0c;小编将从零开始&#xff0c;详细讲解在线教育系统的源码开发过程&#xff0c;帮助你打造一款功能完善的知识付费APP。 一、需求分析与规划 1.1 市场调研 在开始开发之前&#xff0c;首先要进行市场调研&#xff0c;了解当前市场上的主要竞争对手和用户需求。…

Linux笔记--权限与属性命令、查找指令、压缩命令、网络指令

权限 使用ls指令查看详细信息时 rwx分别代表读写执行三种权限&#xff0c;book代表book用户&#xff0c;对于权限来说三种权限分别代表二进制一位&#xff0c;即同时拥有rwx就是111&#xff0c;此时这个文件权限为775 改变权限为rw-rwxr-w指令 book100ask:~/Desktop$ chmod …

[Kubernetes] etcd 单机和集群部署

文章目录 1.etcd基本概念2.etcd的基本知识3.etcd优势4.etcd单机部署4.1 linux部署4.2 windows部署4.3 docker安装etcd 5.etcd集群部署 1.etcd基本概念 etcd是一个高可用的分布式键值存储系统&#xff0c;是CoreOS&#xff08;现在隶属于Red Hat&#xff09;公司开发的一个开源…

TLE9879的基于Arduino调试板SWD刷写接口

官方的Arduino评估板&#xff0c;如下图所示&#xff1a; 如果你有官方的调试器&#xff0c;应该不用关注本文章&#xff0c;如下图连接就是&#xff1a; 如果&#xff0c;您和博主一样需要自己飞线的话&#xff0c;如下图所示&#xff1a;PCB的名称在右边整理&#xff0c;SWD的…

代码随想录算法训练营day22|701.二叉搜索树中的插入操作、 450.删除二叉搜索树中的节点、 235. 二叉搜索树的最近公共祖先

701.二叉搜索树中的插入操作 这道题较为简单&#xff0c;只需要通过递归找到符合要求的叶子节点&#xff0c;并将节点插入即可。 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode(…

师彼长技以助己(6)递归思维

师彼长技以助己&#xff08;6&#xff09;递归思维 递归思维-小游戏 思维小游戏 思维 小游戏&#xff1a;1 玩一个从1或2开始往上加的游戏&#xff0c;谁加到20就赢 如何保证一定赢呢&#xff1f;我们倒推&#xff0c;要先到20的话&#xff0c;谁先到17就赢&#xff0c;如此…

【计算机视觉】人脸算法之图像处理基础知识(五)

图像的几何变换 3.图像的旋转 图像的旋转就是让图像按照某一点旋转到指定的角度。需要确定3个参数&#xff1a;图像的旋转中心、旋转角度和缩放因子。在openv中通过getRotationMatrix2D()函数来实现图像的旋转。 import cv2 import numpy as npimgpath "images/img1.j…

《Fundamentals of Power Electronics》——理想变压器基本公式推导

接下去推导理想变压器的基本公式。理想变压器满足以下三个条件&#xff1a; 1、无铜损。假设原副边线圈均无纯电阻&#xff0c;则不会因在铜导线中产生焦耳热引起能量损耗&#xff0c;另外也不考虑回路中的分布电容。 2、无铁损。忽略通过铁芯的磁通量变化引起的涡流损耗&…

0613,基本数据类型,表达式

题目1&#xff0c;选做&#xff1a; 假设 int n 0xCAFE; 请用表达式完成下面操作 (拓展题&#xff1a;不要求每个同学都写) (a) 测试最后 4 位中是不是最少有 3 位为 1. (b) 逆转字节序(i.e.,使 n 0xFECA) (c) 旋转 4 位 (i.e., 使 n 0xECAF) 答案代码/补&#xff1a; …

【算法-力扣】73.矩阵置零,一文彻底搞懂!

目录 一、题目描述 二、解题思路 三、参考答案 一、题目描述 矩阵置零 给定一个 m x n 的矩阵&#xff0c;如果一个元素为 0 &#xff0c;则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 进阶&#xff1a; 一个直观的解决方案是使用 O(mn) 的额外空间&#x…

网络通信的两大支柱:TCP与UDP协议详解(非常详细)零基础入门到精通,收藏这一篇就够了

在构建现代互联网通信的基石中&#xff0c;TCP&#xff08;传输控制协议&#xff09;和UDP&#xff08;用户数据报协议&#xff09;起着至关重要的作用。本文将深入探讨两者的区别及应用场景。 1 TCP和UDP的共同点 传输层协议&#xff1a; TCP和UDP都是传输层协议&#xff…

生产中的 RAG:使你的生成式 AI 项目投入运营

作者&#xff1a;来自 Elastic Tim Brophy 检索增强生成 (RAG) 为组织提供了一个采用大型语言模型 (LLM) 的机会&#xff0c;即通过将生成式人工智能 (GenAI) 功能应用于其自己的专有数据。使用 RAG 可以降低固有风险&#xff0c;因为我们依赖受控数据集作为模型答案的基础&…