《GDI+系列教程》的作者:空
前7章里,我们已经学会用绘画工具画出各种东西,也能保存起来,但却不能和它们有什么交互。
所以本章,我们会创建一个可以拖动的圆角矩形文字框。
1.使用定式直接创建出画布
#SingleInstance, Force #NoEnv SetBatchLines, -1 ; Uncomment if Gdip.ahk is not in your standard library #Include, Gdip_All.ahk ; 初始化 gdi+ 需要的一切 gosub, init
2.画圆角矩形
; Create a partially transparent, black brush (ARGB = Transparency, red, green, blue) to draw a rounded rectangle with ; Fill the graphics of the bitmap with a rounded rectangle using the brush created ; Filling the entire graphics - from coordinates (0, 0) the entire width and height ; The last parameter (20) is the radius of the circles used for the rounded corners ; Delete the brush as it is no longer needed and wastes memory ; 创建画刷 pBrush := Gdip_BrushCreateSolid(0xaa000000) ; 填充圆角矩形 ; 特别注意,要想画出完美的圆角矩形,需要提前做 Gdip_SetPixelOffsetMode(G, 2) 这个设置。 ; 我已经在 init 阶段就做了设置,故这里直接画了。 ; Gdip_FillRoundedRectangle(画布, 画刷, x, y, 矩形宽, 矩形高, 圆角) Gdip_FillRoundedRectangle(G, pBrush, 0, 0, Width, Height, 20) Gdip_DeleteBrush(pBrush)
3.写字
; We can specify the font to use. Here we use Arial as most systems should have this installed Font = 微软雅黑 ; Next we can check that the user actually has the font that we wish them to use ; If they do not then we can do something about it. I choose to give a wraning and exit! ; 注意,这里仅仅检查是否存在字体而已,真正对字体的使用,是在后面的 Gdip_TextToGraphics() 中! If !Gdip_FontFamilyCreate(Font) { MsgBox, 48, Font error!, The font you have specified does not exist on the system ExitApp } ; There are a lot of things to cover with the function Gdip_TextToGraphics ; The 1st parameter is the graphics we wish to use (our canvas) ; The 2nd parameter is the text we wish to write. It can include new lines `n ; The 3rd parameter, the options are where all the action takes place... ; You can write literal x and y coordinates such as x20 y50 which would place the text at that position in pixels ; or you can include the last 2 parameters (Width and Height of the Graphics we will use) and then you can use x10p ; which will place the text at 10% of the width and y30p which is 30% of the height ; The same percentage marker may be used for width and height also, so w80p makes the bounding box of the rectangle the text ; will be written to 80% of the width of the graphics. If either is missed (as I have missed height) then the height of the bounding ; box will be made to be the height of the graphics, so 100% ; Any of the following words may be used also: Regular,Bold,Italic,BoldItalic,Underline,Strikeout to perform their associated action ; To justify the text any of the following may be used: Near,Left,Centre,Center,Far,Right with different spelling of words for convenience ; The rendering hint (the quality of the antialiasing of the text) can be specified with r, whose values may be: ; SystemDefault = 0 ; SingleBitPerPixelGridFit = 1 ; SingleBitPerPixel = 2 ; AntiAliasGridFit = 3 ; AntiAlias = 4 ; The size can simply be specified with s ; The colour and opacity can be specified for the text also by specifying the ARGB as demonstrated with other functions such as the brush ; So cffff0000 would make a fully opaque red brush, so it is: cARGB (the literal letter c, follwed by the ARGB) ; The 4th parameter is the name of the font you wish to use ; As mentioned previously, you don not need to specify the last 2 parameters, the width and height, unless ; you are planning on using the p option with the x,y,w,h to use the percentage Options = x10p y30p w80p Centre cbbffffff r4 s20 Underline Italic ; Gdip_TextToGraphics(画布, 要显示的文字, 显示设置, 字体, 宽, 高) ; 第2个参数 要显示的文字 使用 `n 换行 ; =====================================以下都是在说第3个参数====================================== ; 第3个参数 显示设置 是此函数的精华,也是很复杂的一个参数。 ; 文字位置可以使用 “x” “y” 来指定,例如 “x20 y50” 。 ; 当设置了第5、6个参数时,还可以用百分比模式。例如 “x10p y30p” 则表示将文字放置在 x=10%宽 y=30%高 的位置。 ; 同时 “w” “h” 也支持百分比模式。例如 “w80p” 表示文字显示的宽度范围是第5个参数的80%,也就是左右各留10%的空出来。 ; 如果只指定了 “w” “h” 中的一个,那么另一个将是 100% 。例如只设置了 “w80p”,那么 h 会被自动设置为 “h100p” 。 ; 字体属性(常规、粗体、斜体、粗斜体、下划线、删除线)可以用以下词来指定。 ; Regular,Bold,Italic,BoldItalic,Underline,Strikeout ; 文字水平对齐方式(左对齐、左对齐、居中、居中、右对齐、右对齐)可以用以下词来指定。 ; Near,Left,Centre,Center,Far,Right ; 文字纵向对齐方式(贴顶、贴顶、贴底、贴底、居中、居中) ; Top,Up,Bottom,Down,vCentre,vCenter ; 文字的抗锯齿效果可以用 r 来指定,例如 r0 。其值可以是以下这些(具体效果看图片演示吧)。 ; SystemDefault = 0 ; SingleBitPerPixelGridFit = 1 ; SingleBitPerPixel = 2 ; AntiAliasGridFit = 3 ; AntiAlias = 4 ; 字号可以用 s 来指定,例如 s14 。 ; 颜色和透明度用 c 来指定,例如 cffff0000 。注意,这里 ARGB 格式的颜色。 ; =====================================以上都是在说第3个参数===================================== ; 第4个参数 是字体名字 ; 第5、6个参数可以省略,除非你在第3个参数指定 “文字位置” 时用到了百分比模式,那么就需要给第5、6个参数传值。否则不需要。 Gdip_TextToGraphics(G, "教程 8`n`nThank you for trying this example", Options, Font, Width, Height)
不同文字抗锯齿选项的效果
4.显示出来
; Update the specified window we have created (hwnd1) with a handle to our bitmap (hdc), specifying the x,y,w,h we want it positioned on our screen ; With some simple maths we can place the gui in the centre of our primary monitor horizontally and vertically at the specified heigth and width ; 显示出来 UpdateLayeredWindow(hwnd1, hdc, (A_ScreenWidth-Width)//2, (A_ScreenHeight-Height)//2, Width, Height)
5.实现拖动效果
; By placing this OnMessage here. The function WM_LBUTTONDOWN will be called every time the user left clicks on the gui ; 实现拖动效果 ; 当我们的程序接收到 “0x201” 消息时,会自动跳到下面的 “WM_LBUTTONDOWN()” 中运行。 ; 0x201 = WM_LBUTTONDOWN 即鼠标左键按下的消息。 ; 再换一句话说就是,当程序发现自己被左键按下时,会自动跳到下面的 “WM_LBUTTONDOWN()” 中运行。 OnMessage(0x201, "WM_LBUTTONDOWN") Return ;####################################################################### ; This function is called every time the user clicks on the gui ; The PostMessage will act on the last found window (this being the gui that launched the subroutine, hence the last parameter not being needed) ; 当左键在界面中按下时,发送消息 “0xA1 ,2” 即 “WM_NCLBUTTONDOWN , HTCAPTION” ; WM_NCLBUTTONDOWN , WM = 窗口消息(Window Message), NC = 非客户区(Non Client), 即标题栏或者边缘。 LBUTTONDOWN = 左键按下 ; HTCAPTION = 命中标题栏 ; 连起来就是,当鼠标左键在我们的自绘界面中被按下时,告诉系统,鼠标左键在标题栏被按下了,此时移动鼠标位置,自然就实现拖动效果了。 ; 参考资料: ; https://stackoverflow.com/questions/8781862/what-does-wm-nclbuttondown-do ; https://docs.microsoft.com/zh-cn/windows/win32/inputdev/wm-nclbuttondown?redirectedfrom=MSDN ; https://docs.microsoft.com/zh-cn/windows/win32/inputdev/wm-nchittest WM_LBUTTONDOWN() { PostMessage, 0xA1, 2 } ;#######################################################################
6.收工善后
ExitGdip: ; Select the object back into the hdc SelectObject(hdc, obm) ; Now the bitmap may be deleted DeleteObject(hbm) ; Also the device context related to the bitmap may be deleted DeleteDC(hdc) ; The graphics may now be deleted Gdip_DeleteGraphics(G) ; gdi+ may now be shutdown on exiting the program Gdip_Shutdown(pToken) ExitApp Return
0.定式
init: ; Start gdi+ If !pToken := Gdip_Startup() { MsgBox, 48, gdiplus error!, Gdiplus failed to start. Please ensure you have gdiplus on your system ExitApp } OnExit, ExitGdip ; Set the width and height we want as our drawing area, to draw everything in. This will be the dimensions of our bitmap Width := 300, Height := 200 ; Create a layered window (+E0x80000 : must be used for UpdateLayeredWindow to work!) that is always on top (+AlwaysOnTop), has no taskbar entry or caption Gui, 1: -Caption +E0x80000 +LastFound +AlwaysOnTop +ToolWindow +OwnDialogs ; Show the window Gui, 1: Show, NA ; Get a handle to this window we have created in order to update it later hwnd1 := WinExist() ; Create a gdi bitmap with width and height of what we are going to draw into it. This is the entire drawing area for everything hbm := CreateDIBSection(Width, Height) ; Get a device context compatible with the screen hdc := CreateCompatibleDC() ; Select the bitmap into the device context obm := SelectObject(hdc, hbm) ; Get a pointer to the graphics of the bitmap, for use with drawing functions G := Gdip_GraphicsFromHDC(hdc) ; Set the smoothing mode to antialias = 4 to make shapes appear smother (only used for vector drawing and filling) Gdip_SetSmoothingMode(G, 4) ; Set the PixelOffsetMode to Half pixel offset = 2 to draw a perfect Rounded Rectangle ; 此参数是画出完美圆角矩形的关键 Gdip_SetPixelOffsetMode(G, 2) Return
本章习题:让文字框在鼠标右键按下时退出。
全部代码与库文件下载地址:
https://ahk.lanzoux.com/b01nypnuh
密码:1234
声明:站内资源为整理优化好的代码上传分享与学习研究,如果是开源代码基本都会标明出处,方便大家扩展学习路径。请不要恶意搬运,破坏站长辛苦整理维护的劳动成果。本站为爱好者分享站点,所有内容不作为商业行为。如若本站上传内容侵犯了原著者的合法权益,请联系我们进行删除下架。
评论(0)