#include CreateImageButton.ahk Gui, New Gui, font, s20, 方正兰亭黑_GBK Gui, Add, Button, w200 ,默认样式 Gui, Add, Button, w200 hwndHBT1 ,新样式 BT1Options:= [{BC: "99D1D3|00A6AD", TC: "Black", 3D: 1, G: 0}] BT1Options[2] := {BC: "008C5E|00AE72", TC: "000000", 3D: 0, G: 1} CreateImageButton(HBT1,BT1Options) Gui, Show ; ================================================================================?====================================== ; Create images and assign them to be shown within pushbuttons ; ================================================================================?====================================== ; Function: Create images and assign them to be shown within pushbuttons. ; AHK version: 1.1.05.05 (U32 / U64) ; Language: English ; Tested on: Win XPSP3, Win VistaSP2 (32 bit), Win 7 (64 bit) ; Version: 0.9.00.01/2011-04-02/just me ; ; How to use: 1. Create a push button with e.g. "Gui, Add, Button, vMyButton hwndHwndButton, Caption" using the ; hwnd option to get its HWND. ; ; 2. Call CreateImageButton passing up to three parameters: ; Mandatory: ; HWND - Button's HWND (Pointer) ; Options - 1-based array containing up to 6 option objects (Object) ; see below ; Optional: ; Margins - Distance between the bitmaps and the border in pixel (Integer) ; to keep parts of Windows' button animation visible ; Valid values: 0, 1, 2, 3, 4 ; Default: 0 ; ; The index of each option object determines the corresponding button state on which the bitmap ; will be shown. MSDN defines 6 states (http://msdn.microsoft.com/en-us/windows/bb775975): ; enum PUSHBUTTONSTATES { ; PBS_NORMAL = 1, ; PBS_HOT = 2, ; PBS_PRESSED = 3, ; PBS_DISABLED = 4, ; PBS_DEFAULTED = 5, ; PBS_STYLUSHOT = 6, <- used only on tablet computers ; }; ; If you don't want the button to be "animated", just pass one option object with index 1. ; ; Each option object may contain the following key/value pairs: ; Mandatory: ; BC - Background Color(s): ; 6-digit RGB hex value ("RRGGBB") or HTML color name ("Red"). ; Pass 2 pipe (|) separeted values for start and target colors of a gradient. ; If only one color is passed for 3D = 1 thru 3, black ("000000") will be used ; as default start color and the color value will be used as target color. ; In case of 3D = 9 BC must contain a picture's path or HBITMAP handle ; Optional: ; TC - Text Color: ; 6-digit RGB hex value ("RRGGBB") or HTML color name ("Red"). ; Default: "000000" (black) ; 3D - 3D Effects: ; 0 = none (just colored) ; 1 = raised ; 2 = vertical "3D" gradient ; 3 = horizontal "3D" gradient ; 9 = background picture (BC contains the picture's path or HBITMAP handle) ; Default: 0 ; G - Gamma Correction: ; 0 = no ; 1 = yes ; Default: 0 ; ; Whenever the The button has a caption it is drawn above the bitmap or picture. ; ; Credits: THX tic for GDIP.AHK : http://www.autohotkey.com/forum/post-198949.html ; THX tkoi for ILBUTTON.AHK : http://www.autohotkey.com/forum/topic40468.html ; THX Lexikos for AHK_L ; ================================================================================?====================================== ; This software is provided 'as-is', without any express or implied warranty. ; In no event will the authors be held liable for any damages arising from the use of this software. ; ================================================================================?====================================== ; ================================================================================?====================================== ; FUNCTION CreateImageButton() ; ================================================================================?====================================== ;~ 完整的函数: ;~ CreateImageButton(HWND, Options,Margins=0) ;~ 有三个需要输入的参数 : ;~ [必填]第一个是按钮的句柄值 ;~ [必填]参数数组 ;~ [可填]按钮的边界宽度 0 1 2 3 4 值越高边框越宽 不填的话默认为0 ;~ 参数数组: ;~ 1 数组序号 如BT1Options[3]代表鼠标按住按钮时按钮的参数 ;~ 1 普通状态下 ;~ 2 鼠标悬停在按钮上 不按下 ;~ 3 鼠标按住按钮 ;~ 4 按钮在 disable 状态下 按钮无效化 ;~ 5 按钮在 Default 状态下 按钮默认 ;~ 6 used only on tablet computers ;~ 其中数组的第一个必须有 也就是上边的BT1Options 后边的根据需要添加 ;~ 2 BC是BackgroundColor的缩写 按钮颜色 ;~ 可用: RBG色 如00FF00 或 HTML色 如"Red" ;~ "外围颜色|中心颜色" ;~ 也可以里外用一种颜色 如BC: "600000" ;~ 3 TC是Text Color的缩写 文字颜色 ;~ 参照背景颜色BC ;~ 4 3D表示的是按钮的样式 ;~ 0 普通 ;~ 1 中间鼓起 如果BC只有一个参数,颜色向中心会过渡到黑色 ;~ 2 垂直纹理 ;~ 3 水平纹理 ;~ 9 背景图片 要求BC必须包含位图句柄或图片路径 ;~ 默认为 0 ;~ 5 G代表Gamma Correction 图像灰度矫正 ;~ 0 表示否 ;~ 1 代表是 ;~ 默认为 0 ;~ 示例 ;~ #include -填入路径-\CreateImageButton.ahk ;~ Gui, New ;~ Gui, font, s20, 方正兰亭黑_GBK ;~ Gui, Add, Button, w200 ,默认样式 ;~ Gui, Add, Button, w200 hwndHBT1 ,新样式 ;~ BT1Options:= [{BC: "99D1D3|00A6AD", TC: "Black", 3D: 1, G: 0}] ;~ BT1Options[2] := {BC: "008C5E|00AE72", TC: "000000", 3D: 0, G: 1} ;~ CreateImageButton(HBT1,BT1Options) ;~ Gui, Show CreateImageButton(HWND, Options, Margins = 0) { ; HTML colors Static HTML := {BLACK: "000000", GRAY: "808080", SILVER: "C0C0C0", WHITE: "FFFFFF" , MAROON: "800000", PURPLE: "800080", FUCHSIA: "FF00FF", RED: "FF0000" , GREEN: "008000", OLIVE: "808000", YELLOW: "FFFF00", LIME: "00FF00" , NAVY: "000080", TEAL: "008080", AQUA: "00FFFF", BLUE: "0000FF"} ; Windows constants Static BS_CHECKBOX := 0x2 , BS_RADIOBUTTON := 0x4 , BS_GROUPBOX := 0x7 , BS_AUTORADIOBUTTON := 0x9 , BS_LEFT := 0x100 , BS_RIGHT := 0x200 , BS_CENTER := 0x300 , BS_TOP := 0x400 , BS_BOTTOM := 0x800 , BS_VCENTER := 0xC00 , BS_BITMAP := 0x0080 , SA_LEFT := 0x0 , SA_CENTER := 0x1 , SA_RIGHT := 0x2 , WM_GETFONT := 0x31 , IMAGE_BITMAP := 0x0 , BITSPIXEL := 0xC , RCBUTTONS := BS_CHECKBOX | BS_RADIOBUTTON | BS_AUTORADIOBUTTON , BCM_SETIMAGELIST := 0x1602 , BUTTON_IMAGELIST_ALIGN_LEFT := 0 , BUTTON_IMAGELIST_ALIGN_RIGHT := 1 , BUTTON_IMAGELIST_ALIGN_CENTER := 4 ; Options Static OptionKeys := ["TC", "BC", "3D", "G"] ; Defaults Static Defaults := {TC: "000000", BC: "000000", 3D: 0, G: 0} ; ------------------------------------------------------------------------------------------------------------------- ErrorLevel := "" ; ------------------------------------------------------------------------------------------------------------------- ; Check the availability of Gdiplus.dll GDIPDll := DllCall("Kernel32.dll\LoadLibrary", "Str", "Gdiplus.dll", "Ptr") VarSetCapacity(SI, 24, 0) Numput(1, SI) DllCall("Gdiplus.dll\GdiplusStartup", "PtrP", GDIPToken, "Ptr", &SI, "Ptr", 0) If (!GDIPToken) { ErrorLevel := "GDIPlus could not be started!`n`nImageButton won't work!" Return False } ; ------------------------------------------------------------------------------------------------------------------- ; Check HWND If !(DllCall("User32.dll\IsWindow", "Ptr", HWND)) { GoSub, CreateImageButton_GDIPShutdown ErrorLevel := "Invalid parameter HWND!" Return False } ; ------------------------------------------------------------------------------------------------------------------- ; Check Options If !(IsObject(Options)) || (Options.MinIndex() = "") || (Options.MinIndex() > 1) || (Options.MaxIndex() > 6) { GoSub, CreateImageButton_GDIPShutdown ErrorLevel := "Invalid parameter Options!" Return False } ; ------------------------------------------------------------------------------------------------------------------- ; Check Margins Margins := SubStr(Margins, 1, 1) If (Margins = "") || !(Instr("01234", Margins)) Margins := 0 ; ------------------------------------------------------------------------------------------------------------------- ; Get and check control's class and styles WinGetClass, BtnClass, ahk_id %HWND% ControlGet, BtnStyle, Style, , , ahk_id %HWND% If (BtnClass != "Button") || ((BtnStyle & 0xF ^ BS_GROUPBOX) = 0) || ((BtnStyle & RCBUTTONS) > 1) { GoSub, CreateImageButton_GDIPShutdown ErrorLevel := "You can use ImageButton only for PushButtons!" Return False } ; ------------------------------------------------------------------------------------------------------------------- ; Get the button's font GDIPFont := 0 DC := DllCall("User32.dll\GetDC", "Ptr", HWND, "Ptr") BPP := DllCall("Gdi32.dll\GetDeviceCaps", "Ptr", DC, "Int", BITSPIXEL) HFONT := DllCall("User32.dll\SendMessage", "Ptr", HWND, "UInt", WM_GETFONT, "Ptr", 0, "Ptr", 0, "Ptr") DllCall("Gdi32.dll\SelectObject", "Ptr", DC, "Ptr", HFONT) DllCall("Gdiplus.dll\GdipCreateFontFromDC", "Ptr", DC, "PtrP", GDIPFont) DllCall("User32.dll\ReleaseDC", "Ptr", HWND, "Ptr", DC) If !(GDIPFont) { GoSub, CreateImageButton_GDIPShutdown ErrorLevel := "Couldn't get button's font!" Return False } ; ------------------------------------------------------------------------------------------------------------------- ; Get the button's RECT VarSetCapacity(RECT, 16, 0) If !(DllCall("User32.dll\GetClientRect", "Ptr", HWND, "Ptr", &RECT)) { GoSub, CreateImageButton_GDIPShutdown ErrorLevel := "Couldn't get button's rectangle!" Return False } W := NumGet(RECT, 8, "Int") - (Margins * 2) H := NumGet(RECT, 12, "Int") - (Margins * 2) ; ------------------------------------------------------------------------------------------------------------------- ; Get the button's caption BtnCaption := "" Len := DllCall("User32.dll\GetWindowTextLength", "Ptr", HWND) + 1 If (Len > 1) { ; Button has a caption VarSetCapacity(BtnCaption, Len * (A_IsUnicode ? 2 : 1), 0) If !(DllCall("User32.dll\GetWindowText", "Ptr", HWND, "Str", BtnCaption, "Int", Len)) { GoSub, CreateImageButton_GDIPShutdown ErrorLevel := "Couldn't get button's caption!" Return False } VarSetCapacity(BtnCaption, -1) } ; ------------------------------------------------------------------------------------------------------------------- ; Create the BitMap(s) BitMaps := [] While (A_Index <= Options.MaxIndex()) { If !(Options.HasKey(A_Index)) Continue Option := Options[A_Index] ; Check mandatory keys If !(Option.HasKey("BC")) { GoSub, CreateImageButton_FreeBitmaps GoSub, CreateImageButton_GDIPShutdown ErrorLevel := "Missing option BC in Options[" . A_Index . "]!" Return False } ; Check for defaults For Each, K In Defaults { If !(Option.HasKey(K)) || (Option[K] = "") Option[K] := Defaults[K] } ; Check options BitMap := "" GC := SubStr(Option.G, 1, 1) If !InStr("01", GC) GC := Defaults.G 3D := SubStr(Option.3D, 1, 1) If !InStr("01239", 3D) 3D := Defaults.3D If (3D < 4) { BkgColor := Option.BC If InStr(BkgColor, "|") { StringSplit, BkgColor, BkgColor, | } Else { BkgColor1 := Option.3D = 0 ? BkgColor : Defaults.BC BkgColor2 := BkgColor } If HTML.HasKey(BkgColor1) BkgColor1 := HTML[BkgColor1] If HTML.HasKey(BkgColor2) BkgColor2 := HTML[BkgColor2] } Else { Image := Option.BC } TxtColor := Option.TC If HTML.HasKey(TxtColor) TxtColor := HTML[TxtColor] ; ---------------------------------------------------------------------------------------------------------------- ; Create a GDI+ bitmap DllCall("Gdiplus.dll\GdipCreateBitmapFromScan0", "Int", W, "Int", H, "Int", 0 , "UInt", 0x26200A, "Ptr", 0, "PtrP", PBITMAP) ; Get the pointer to it's graphics DllCall("Gdiplus.dll\GdipGetImageGraphicsContext", "Ptr", PBITMAP, "PtrP", PGRAPHICS) ; Set SmoothingMode to system default DllCall("Gdiplus.dll\GdipSetSmoothingMode", "Ptr", PGRAPHICS, "UInt", 0) If (3D < 4) { ; Create a BitMap ; Create a PathGradientBrush VarSetCapacity(POINTS, 4 * 8, 0) NumPut(W - 1, POINTS, 8, "UInt"), NumPut(W - 1, POINTS, 16, "UInt") NumPut(H - 1, POINTS, 20, "UInt"), NumPut(H - 1, POINTS, 28, "UInt") DllCall("Gdiplus.dll\GdipCreatePathGradientI", "Ptr", &POINTS, "Int", 4, "Int", 0, "PtrP", PBRUSH) ; Start and target colors Color1 := "0xFF" . BkgColor1 Color2 := "0xFF" . BkgColor2 ; Set the PresetBlend VarSetCapacity(COLORS, 12, 0) NumPut(Color1, COLORS, 0, "UInt"), NumPut(Color2, COLORS, 4, "UInt") VarSetCapacity(RELINT, 12, 0) NumPut(0.00, RELINT, 0, "Float"), NumPut(1.00, RELINT, 4, "Float") DllCall("Gdiplus.dll\GdipSetPathGradientPresetBlend", "Ptr", PBRUSH, "Ptr", &COLORS, "Ptr", &RELINT, "Int", 2) ; Set the FocusScales DH := H / 2 XScale := (3D = 1 ? (W - DH) / W : 3D = 2 ? 1 : 0) YScale := (3D = 1 ? (H - DH) / H : 3D = 3 ? 1 : 0) DllCall("Gdiplus.dll\GdipSetPathGradientFocusScales", "Ptr", PBRUSH, "Float", XScale, "Float", YScale) ; Set the GammaCorrection DllCall("Gdiplus.dll\GdipSetPathGradientGammaCorrection", "Ptr", PBRUSH, "Int", GC) ; Fill button's rectangle DllCall("Gdiplus.dll\GdipFillRectangleI", "Ptr", PGRAPHICS, "Ptr", PBRUSH, "Int", 0, "Int", 0 , "Int", W, "Int", H) ; Free the brush DllCall("Gdiplus.dll\GdipDeleteBrush", "Ptr", PBRUSH) } Else { ; Create a bitmap from HBITMAP or file If (Image + 0) DllCall("Gdiplus.dll\GdipCreateBitmapFromHBITMAP", "Ptr", Image, "Ptr", 0, "PtrP", PBM) Else DllCall("Gdiplus.dll\GdipCreateBitmapFromFile", "WStr", Image, "PtrP", PBM) ; Draw the bitmap DllCall("Gdiplus.dll\GdipDrawImageRectI", "Ptr", PGRAPHICS, "Ptr", PBM, "Int", 0, "Int", 0 , "Int", W, "Int", H) ; Free the bitmap DllCall("Gdiplus.dll\GdipDisposeImage", "Ptr", PBM) } ; ---------------------------------------------------------------------------------------------------------------- ; Draw the caption If (BtnCaption) { ; Create a StringFormat object DllCall("Gdiplus.dll\GdipCreateStringFormat", "Int", 0x5404, "UInt", 0, "PtrP", HFORMAT) ; Text color DllCall("Gdiplus.dll\GdipCreateSolidFill", "UInt", "0xFF" . TxtColor, "PtrP", PBRUSH) ; Horizontal alignment HALIGN := (BtnStyle & BS_CENTER) = BS_CENTER ? SA_CENTER : (BtnStyle & BS_CENTER) = BS_RIGHT ? SA_RIGHT : (BtnStyle & BS_CENTER) = BS_Left ? SA_LEFT : SA_CENTER DllCall("Gdiplus.dll\GdipSetStringFormatAlign", "Ptr", HFORMAT, "Int", HALIGN) ; Vertical alignment VALIGN := (BtnStyle & BS_VCENTER) = BS_TOP ? 0 : (BtnStyle & BS_VCENTER) = BS_BOTTOM ? 2 : 1 DllCall("Gdiplus.dll\GdipSetStringFormatLineAlign", "Ptr", HFORMAT, "Int", VALIGN) ; Set render quality to system default DllCall("Gdiplus.dll\GdipSetTextRenderingHint", "Ptr", PGRAPHICS, "Int", 0) ; Set the text's rectangle NumPut(0.0, RECT, 0, "Float") NumPut(0.0, RECT, 4, "Float") NumPut(W, RECT, 8, "Float") NumPut(H, RECT, 12, "Float") ; Draw the text DllCall("Gdiplus.dll\GdipDrawString", "Ptr", PGRAPHICS, "WStr", BtnCaption, "Int", -1 , "Ptr", GDIPFont, "Ptr", &RECT, "Ptr", HFORMAT, "Ptr", PBRUSH) } ; Create a HBITMAP handle from the bitmap DllCall("Gdiplus.dll\GdipCreateHBITMAPFromBitmap", "Ptr", PBITMAP, "PtrP", HBITMAP, "UInt", 0X00FFFFFF) ; Free resources DllCall("Gdiplus.dll\GdipDisposeImage", "Ptr", PBITMAP) DllCall("Gdiplus.dll\GdipDeleteBrush", "Ptr", PBRUSH) DllCall("Gdiplus.dll\GdipDeleteStringFormat", "Ptr", HFORMAT) DllCall("Gdiplus.dll\GdipDeleteGraphics", "Ptr", PGRAPHICS) BitMaps[A_Index] := HBITMAP } ; Now free the font object DllCall("Gdiplus.dll\GdipDeleteFont", "Ptr", GDIPFont) ; ------------------------------------------------------------------------------------------------------------------- ; Create the ImageList HIL := DllCall("Comctl32.dll\ImageList_Create", "UInt", W, "UInt", H, "UInt", BPP, "Int", 6, "Int", 0, "Ptr") Loop, % (BitMaps.MaxIndex() > 1 ? 6 : 1) { HBITMAP := BitMaps.HasKey(A_Index) ? BitMaps[A_Index] : BitMaps[1] DllCall("Comctl32.dll\ImageList_Add", "Ptr", HIL, "Ptr", HBITMAP, "Ptr", 0) } ; Create a BUTTON_IMAGELIST structure VarSetCapacity(BIL, 20 + A_PtrSize, 0) NumPut(HIL, BIL, 0, "Ptr") Numput(BUTTON_IMAGELIST_ALIGN_CENTER, BIL, A_PtrSize + 16, "UInt") ; Hide buttons's caption GuiControl, , %HWND% ; WinXP GuiControl, +%BS_BITMAP%, %HWND% ; Assign the ImageList to the button SendMessage, BCM_SETIMAGELIST, 0, 0, , ahk_id %HWND% SendMessage, BCM_SETIMAGELIST, 0, &BIL, , ahk_id %HWND% ; Free the bitmaps GoSub, CreateImageButton_FreeBitmaps ; ------------------------------------------------------------------------------------------------------------------- ; All done successfully GoSub, CreateImageButton_GDIPShutdown Return True ; ------------------------------------------------------------------------------------------------------------------- ; Free BitMaps CreateImageButton_FreeBitmaps: For I, HBITMAP In BitMaps { DllCall("Gdi32.dll\DeleteObject", "Ptr", HBITMAP) } Return ; ------------------------------------------------------------------------------------------------------------------- ; Shutdown GDIPlus CreateImageButton_GDIPShutdown: DllCall("Gdiplus.dll\GdiplusShutdown", "Ptr", GDIPToken) DllCall("Kernel32.dll\FreeLibrary", "Ptr", GDIPDll) Return }
感谢大神分享。十分感谢。太有用了。
?