当我们画好了一个背景,之后需要在背景上更新内容时,难道每次都要从背景到内容全部重画一遍吗?
显然,第7章的《将画布内容保存为文件》,再从文件中读取内容是一个办法。
那么,有没有不存为文件,直接在内存中保存内容并复用的方法呢?
本章,就讲这个方法。
1.初始化 GDI+ 并创建 GUI
; Uncomment if Gdip.ahk is not in your standard library
#Include Gdip_All.ahk
; 初始化 GDI+ 并创建 GUI
; 此 GUI 用于显示 hdc 的内容
Gui, +HwndhWin +E0x80000
Gui, Show
pToken := Gdip_Startup()
hdc := CreateCompatibleDC()
hbm := CreateDIBSection(100, 100)
obm := SelectObject(hdc, hbm)
2.在 hdc 中画一个黄色的圆
; draw something in hdc
; 在 hdc 中画一个黄色的圆
G := Gdip_GraphicsFromHDC(hdc)
pPen := Gdip_CreatePen(0xffffff00, 3)
Gdip_DrawEllipse(G, pPen, 0, 0, 80, 80)
Gdip_DeletePen(pPen)
3.存档 hdc 的内容到 hdc2
; 创建 hdc2 ,用于保存 hdc 的内容
hdc2 := CreateCompatibleDC()
; 使用 CreateCompatibleBitmap() 创建一个兼容于 hdc 的位图
; 注意,是兼容于 hdc 的位图,而不是兼容于 hdc2 的位图
; hbm2 尺寸跟 hbm 不一致也是可以的,但一定要兼容
hbm2 := CreateCompatibleBitmap(hdc, 100, 100)
; in this case, hbm is created by CreateDIBSection()
; so hbm2 can created by CreateDIBSection() also
; 因为 hbm 是用 CreateDIBSection() 创建的,所以在这里使用 CreateDIBSection() 创建 hbm2 也是可以的
; 但多数情况下,依然推荐使用 CreateCompatibleBitmap() 来创建 hbm2
; 因为很多时候你不知道 hbm 是通过什么方式创建的
; hbm2 := CreateDIBSection(100, 100)
obm2 := SelectObject(hdc2, hbm2)
; copy hdc to hdc2
; 将此刻 hdc 的内容(也就是黄色的圆)复制到 hdc2 ,即存档图像
BitBlt(hdc2, 0, 0, 100, 100, hdc, 0, 0)
4.继续在 hdc 中画一个方形
; draw something in hdc again, so you can see the difference between hdc and hdc2
; 在 hdc 中画一个方形,以便区分 hdc 和 hdc2
; 此时 hdc 内容为黄色的圆+方形,而 hdc2 内容为黄色的圆
pPen := Gdip_CreatePen(0xffffff00, 3)
Gdip_DrawRectangle(G, pPen, 0, 0, 80, 80)
Gdip_DeletePen(pPen)
5.显示 hdc 和 hdc2
; display hdc
; 显示 hdc
UpdateLayeredWindow(hWin, hdc, 0, 200, 100, 100)
; 显示 hdc2
gosub, displayHDC2
6.从 hdc2 读档并恢复到 hdc
; 将 hdc 的内容恢复为 hdc2 ,即读档图像也即复用图像
MsgBox
BitBlt(hdc, 0, 0, 100, 100, hdc2, 0, 0)
UpdateLayeredWindow(hWin, hdc, 0, 200, 100, 100)
return
7.收工善后
displayHDC2:
w:=500, h:=150
Gui, 2:+HwndhWin2
Gui, 2:Show, w%w% h%h% x0 y0
source_hdc := hdc2
dest_hdc := GetDC(hWin2)
; display hdc2
BitBlt(dest_hdc, 0, 0, w, h, source_hdc, 0, 0)
return
2GuiClose:
Gdip_DeleteGraphics(G)
SelectObject(hdc, obm)
DeleteObject(hbm)
DeleteDC(hdc)
SelectObject(hdc2, obm2)
DeleteObject(hbm2)
DeleteDC(hdc2)
ReleaseDC(dest_hdc)
Gdip_Shutdown(pToken)
ExitApp
return
0.CreateCompatibleBitmap() 函数
; 此函数如果不在 Gdip_All.ahk 中,则需自行复制补充
CreateCompatibleBitmap(hdc, w, h) {
return DllCall("gdi32\CreateCompatibleBitmap", "UPtr", hdc, "Int", w, "Int", h)
}
本章习题:画出棋盘并存档,在复用棋盘图像的基础上更新两颗棋子。
全部代码与库文件下载地址:
https://ahk.lanzoux.com/b01nypnuh
密码:
太棒了,我正好需要这个。请问怎么删除图像?用一个空的hdc吗?有没有什么更好的办法?