《GDI+系列教程》的作者:空

 

当我们画好了一个背景,之后需要在背景上更新内容时,难道每次都要从背景到内容全部重画一遍吗?

显然,第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

密码: 1234

声明:站内资源为整理优化好的代码上传分享与学习研究,如果是开源代码基本都会标明出处,方便大家扩展学习路径。请不要恶意搬运,破坏站长辛苦整理维护的劳动成果。本站为爱好者分享站点,所有内容不作为商业行为。如若本站上传内容侵犯了原著者的合法权益,请联系我们进行删除下架。