慢羊羊的空间

工作做不完了,300出,无瑕。

实现桌面截图 铜牌收录

本文讲解怎样截取整个桌面的图像。对于控制台程序,执行后首先会创建一个黑色的控制台窗口,然后才会启动你的程序。因此这时候抓到的图,会包括一个黑色的控制台窗口,我想,这是大多数人不希望看到的。因此,实现抓图,要建立的项目需要是 Win32 Application,而不能是平时用的 Win32 Console Application。

使用程序代码输出常见的字体图标(标志图片) 铜牌收录

程序中经常会使用一些常规的标志(图标、Logo)图片,例如,音量开关、各种方向箭头、扑克牌花色、邮件、电话、磁盘、笑脸/哭脸、五星等等。通常做法是,制作好图片,然后在特定的位置将图片显示出来。本文讲述如何通过输出文字的形式将这些常规的标志图片进行输出。

创建一个不受系统缩放设置(DPI)影响的绘图窗口 铜牌收录

现在的屏幕分辨率都比较高,为了使屏幕字体不至于太小,通常在 Win10 的显示设置里面设为放大 125% 或 150% 或更大,这样就会导致像素实际上被放大了。

如果你的程序不希望受系统缩放设置影响,你需要使用一个新的 API 函数:SetProcessDpiAwareness

注意这个 API 函数的使用条件:

  • Win8.1 及以上版本
  • 头文件 ShellScalingApi.h
  • 库文件 Shcore.lib

以下是一个完整的范例程序,该范例创建一个不受系统缩放设置影响的绘图窗口,并画一个圆:

// 编译环境:Win10 + VS2019 + EasyX_20200727
//

// 设定操作系统版本为 Win10(需要放到 #include <graphics.h> 前面)
#define WINVER 0x0A00
#define _WIN32_WINNT 0x0A00

...

关于编程中“绝对路径”和“相对路径”的使用 铜牌收录

基本概念

加载图片、音乐等各种文件的时候,都要指定文件路径。通常,可以用绝对路径和相对路径两种方式来指定文件。

先解释一下概念:

  • 绝对路径,就是从盘符开始的路径,例如:“C:\Windows\system32\mfc42.dll”。
  • 相对路径,就是从当前路径开始的路径,例如,当前路径是“C:\Windows”,那么指定前面范例的文件,可以直接写“system32\mfc42.dll”。
    注意,路径分隔符“&rdquo;在 C 语言里面是转义字符,所以表达路径分隔符需要用“\”。

从功能上讲:

  • 访问每台电脑上路径都固定不变的文件,需要用绝对路径,例如访问 C:\Windows\system.ini。
  • 如果程序所在路径不固定,访问的文件和程序放在一起,就要用相对路径。例如和程序放在一起的图片文件。

项目范例

以下用 VC2010 的项目来说明绝对路径和相对路径如何使用。

...

解决鼠标左键拖放和双击会触发 _getch() 的问题 铜牌收录

有网友反馈说,鼠标左键按下并拖动后,会相当于一次键盘按键,使 _getch() 触发。鼠标双击也会使 _getch() 触发。经过排查后,发现该问题是某些翻译软件的划词翻译功能引起的。

解决方法:关掉翻译软件的划词翻译功能(比如有道词典就有这个功能)。

或者,使用 getmessage(EM_CHAR) 替代 _getch() 实现按任意键继续。

快速画点的原理简述,以及写一个自己的快速画点函数 铜牌收录

EasyX 自带的 putpixel 函数源自 Windows GDI 函数 SetPixel,由于要考虑裁剪区、缩放、原点坐标、坐标方向等等诸多因素,所以性能很低,在一些只要求速度的场合很不实用。这篇文章就教你写一个自己的画点函数。

总的思想,是通过直接操作显示缓冲区来避免额外的运算。

在 EasyX 绘图窗口的显示缓冲区中,每个点占用 4 个字节,用 DWORD 指针指向显示缓冲区就可以像一维数组一样访问了。然后就是将二维坐标 (x, y) 映射到一维数组中,很简单,y * 640 + x 就是。另外需要注意的是,显示缓冲区中颜色的保存和 COLORREF 相比,蓝色和红色是相反的,需要用 BGR 宏转换一下(BGR 宏执行两次就会还原为原值)。

然后,我们整理出画点和读点的函数:
(记得要获取显示缓冲区指针并保存为全局变量)

DWORD* g_pBuf;

// 在 main 函数中
g_pBuf = GetImageBuffer();

void 
...

为什么屏幕分辨率是 640x480? 铜牌收录

常见的屏幕分辨率很奇怪,为什么总用一些不零不整的数字?比如以前最常见的分辨率是 640 x 480,当初为什么这么设计?

因为这个分辨率运算速度比较快,人也相对比较好记。

大家知道,屏幕上的每一个点,都会对应内存中的一个位置。比如 640x480@256色,表示每个点占用一个字节,整个屏幕有 640 x 480 = 300k 个点,占用 300KB 内存。屏幕的每一个像素的保存,在内存中是线性存储结构。在屏幕上的坐标 (x, y) 画一个点,就相当于在对应内存偏移 y * 640 + x 的位置赋值。

PS:在这篇文章中有一段代码,可以实践一下通过内存赋值来直接画点:https://codebus.cn/yangw/fast-putpixel

每绘制一个点,都需要执行一次乘法和一次加法运算。所有的绘图操作都需要调用画点函数,因此提高画点的效率,将会提升所有绘图操作的速度。

现在我们将计算内存偏移量的算法修改一下:

d = y * 640 +
...

打开帮助文件 EasyX_Help.chm 后,内容为空白的解决办法 铜牌收录

有些同学遇到这样的问题,打开 EasyX 的帮助文档 EasyX_Help.chm 之后,发现所有的内容点击后都是空白的,就像下面这样:

这是由于 Windows 的安全机制造成的,当你从网上直接下载一个 chm 文件,或者用 Windows 资源管理器从压缩包里面解压出来 chm 文件,都会被 Windows 认为目标文件不够安全,然后默认被锁定。

所以,只需要简单解锁就可以了。

这样做:右击 EasyX_Help.chm 文件,在属性页中,会看到底部的“安全”一项,“解除锁定”没有勾选,如下图:

只需要简单的勾选“解除锁定”,然后点击确定,就可以正常浏览 chm 文件了。

弹出一个简单的对话框显示信息 铜牌收录

有时候程序中会需要一个弹出窗口显示信息,还有些小游戏结束的时候,会简单的弹出一个对话框询问用户是否要重新来一句,如下图:

这篇文章就简单讲解一下这个功能如何实现。

首先,我们需要使用一个 Windows API 函数:MessageBox。该函数原型如下:

int MessageBox(
	HWND hWnd,          // handle to owner window
	LPCTSTR lpText,     // text in message box
	LPCTSTR lpCaption,  // message box title
	UINT uType          // message box style
);

第一个参数 hWnd 是指向父窗口的句柄,可以通过 EasyX 的函数 GetHWnd() 得到绘图窗口的句柄;

第二个参数 lpText 是要显示的字符串;

第三个参数

...