GDI+ 出现以前,有个东西叫 GDI 。
某种程度上可以说, GDI+ 是对 GDI 的进一步封装,使其支持了一些新特性(例如透明度),也变得更加易用,但前者并不能完全取代后者。
本章,我们将使用 GDI 函数,以极少的代码量,写出一个比 Win10 自带放大镜显示还要准确(自带放大镜在显示屏幕边缘时会漏2px左右)的屏幕放大镜。
1.初始化一些设置
#NoEnv
SetBatchLines -1 ; 设置最速运行模式
CoordMode Mouse, Screen ; 设置屏幕坐标模式
#Include Gdip_All.ahk
2.创建 GUI 并设置放大倍率
zoom:=2, w:=580, h:=157, wz:=w/zoom, hz:=h/zoom ; 放大倍率、宽、高、取景范围宽、取景范围高
Gui +AlwaysOnTop +Resize +ToolWindow +HwndMagnifierID
Gui Show, w%w% h%h% x0 y0, Magnifier
3.获取 GUI的DC 与 屏幕的DC
source_hdc := GetDC(PrintSourceID) ; 源DC
dest_hdc := GetDC(MagnifierID) ; 目标DC
4.放大显示
SetTimer Repaint, 50 ; 不停重绘当前画面
Repaint:
MouseGetPos x, y
xz:=Min(Max(Ceil(x-wz/2), 0), Ceil(A_ScreenWidth-wz)) ; 限制坐标最大最小值。取景范围超出左边界,使用最小值。超出右边界,使用最大值。
yz:=Min(Max(Ceil(y-hz/2), 0), Ceil(A_ScreenHeight-hz))
; StretchBlt(目标DC, 目标x, 目标y, 目标w, 目标h, 源DC, 源x, 源y, 源w, 源h, 模式)
; 拉伸复制DC内容。省略最后一个参数,默认是 SRCCOPY 模式。
StretchBlt(dest_hdc, 0, 0, w, h, source_hdc, xz, yz, wz, hz)
Return
5.收工善后
GuiClose:
; 释放资源。GetDC 和 ReleaseDC 配对使用,CreateDC 和 DeleteDC 的配对使用。
ReleaseDC(dest_hdc)
ReleaseDC(source_hdc)
ExitApp
本章习题:在不引用任何库(包括Gdip库)的情况下,实现这个放大镜最少需要几行代码(参考答案:8行)?自己试试,体会一下 ahk 的简洁与强大。
全部代码与库文件下载地址:
https://ahk.lanzoux.com/b01nypnuh
密码:
?
?
source_hdc:=GetDC(PrintSourceID),老哥 这里面的printsourceID没有初始值,也没有获取,是不是放进来有点误导。
GetDC(),默认就是获取桌面最上层的DC吧
不是误导,是故意这样写的。
两个getDC里面都填了值,是传达一个理念,就是getDC这个函数需要传一个目标值才行。
而 PrintSourceID 为空,则是因为“如果该值为NULL,GetDC则检索整个屏幕的设备上下文环境。”
所以连起来就是,这个函数需要传一个值,但是刚好传空值的话,可以获取屏幕的dc。
收到,我只是有点疑惑
能出一个自动截取屏幕图片的吗
搜 ahk 截屏 就是了。这种东西一般都有的。
这东西好奇看看哈哈
GDI+ 是对 GDI 的进一步封装,使其支持了一些新特性(例如透明度),也变得更加易用,但前者并不能完全取代后者
请教下,为什么前者并不能完全取代后者?