Тема: AHK: Class_PictureButton
Предисловие
Раньше подобного не замечал, в основном люди вручную делали кнопки из изображений. Код по итогу выглядел громоздко.
И я написал класс для облегчения. Вот пример громоздкого кода: (прошу обратить внимание на строки Gui, Add, Picture)
; Script Information ===========================================================
; Name: Windows 10 Gui
; Description: Custom Gui inspired by Windows 10
; AHK Version: AHK 1.1.25.02 (Unicode 32-bit)
; OS Version: Windows 2000+
; Language: English (United States)
; Author: Weston Campbell <westoncampbell@gmail.com>
; Filename: Windows10.ahk
; ==============================================================================
; Revision History =============================================================
; Revision 1 (2017-05-23)
; * Initial release
; ==============================================================================
; Auto-Execute =================================================================
#SingleInstance, Force ; Allow only one running instance of script
#Persistent ; Keep the script permanently running until terminated
#NoEnv ; Avoid checking empty variables for environment variables
#Warn ; Enable warnings to assist with detecting common errors
;#NoTrayIcon ; Disable the tray icon of the script
SetWorkingDir, % A_ScriptDir ; Set the working directory of the script
SetBatchLines, -1 ; The speed at which the lines of the script are executed
SendMode, Input ; The method for sending keystrokes and mouse clicks
DetectHiddenWindows, On ; The visibility of hidden windows by the script
SetWinDelay, -1 ; The delay to occur after modifying a window
SetControlDelay, -1 ; The delay to occur after modifying a control
OnExit("OnUnload") ; Run a subroutine or function when exiting the script
return ; End automatic execution
; ==============================================================================
; Labels =======================================================================
GuiEscape:
GuiClose:
ExitSub:
ExitApp ; Terminate the script unconditionally
return
; ==============================================================================
; Functions ====================================================================
OnLoad() {
Global ; Assume-global mode
Static Init := OnLoad() ; Call function
Menu, Tray, Tip, New AutoHotkey Script
OnMessage(0x0083, "WM_NCCALCSIZE")
OnMessage(0x0086, "WM_NCACTIVATE")
OnMessage(0x0084, "WM_NCHITTEST")
}
OnUnload(ExitReason, ExitCode) {
Global ; Assume-global mode
}
GuiCreate() {
Global ; Assume-global mode
Static Init := GuiCreate() ; Call function
Gui, +LastFound +Resize -Caption -Border -DPIScale +MinSize600x400 +HwndGuiHwnd
Gui, Margin, 10, 10
Gui, Color, FFFFFF
Gui, Add, Picture, vBorderTop, images\border-top-normal.png
Gui, Add, Picture, vBorderBottom, images\border-outer-normal.png
Gui, Add, Picture, vBorderLeft, images\border-outer-normal.png
Gui, Add, Picture, vBorderRight, images\border-outer-normal.png
Gui, Add, Picture, vBtnBackN HwndhBtnBackN Hidden1, images\button-back-normal.png
Gui, Add, Picture, vBtnBackH HwndhBtnBackH Hidden1, images\button-back-hover.png
Gui, Add, Picture, vBtnBackP HwndhBtnBackP Hidden1, images\button-back-pressed.png
Gui, Add, Picture, vBtnCloseN HwndhBtnCloseN, images\button-close-normal.png
Gui, Add, Picture, vBtnCloseH HwndhBtnCloseH Hidden1, images\button-close-hover.png
Gui, Add, Picture, vBtnCloseP HwndhBtnCloseP Hidden1, images\button-close-pressed.png
Gui, Add, Picture, vBtnMaxN HwndhBtnMaxN, images\button-maximize-normal.png
Gui, Add, Picture, vBtnMaxH HwndhBtnMaxH Hidden1, images\button-maximize-hover.png
Gui, Add, Picture, vBtnMaxP HwndhBtnMaxP Hidden1, images\button-maximize-pressed.png
Gui, Add, Picture, vBtnRestoreN HwndhBtnRestoreN Hidden1, images\button-restore-normal.png
Gui, Add, Picture, vBtnRestoreH HwndhBtnRestoreH Hidden1, images\button-restore-hover.png
Gui, Add, Picture, vBtnRestoreP HwndhBtnRestoreP Hidden1, images\button-restore-pressed.png
Gui, Add, Picture, vBtnMinN HwndhBtnMinN, images\button-minimize-normal.png
Gui, Add, Picture, vBtnMinH HwndhBtnMinH Hidden1, images\button-minimize-hover.png
Gui, Add, Picture, vBtnMinP HwndhBtnMinP Hidden1, images\button-minimize-pressed.png
Gui, Font, s9, Segoe UI
Gui, Add, Text, x14 y8 vTitleText BackgroundTrans, Example
Gui, Add, Tab2, vTab x0 y0 w0 h0 +Theme -Wrap AltSubmit Choose1, Tab1|Tab2|Tab3|Tab4|Tab5|Tab6
Gui, Tab, 1
Gui, Font, s14, Segoe UI
Gui, Add, Text, x360 y100 BackgroundTrans, Page 1
Gui, Font
Gui, Add, Button, xp y+40 w200 h32 vClickBtn HwndhClickBtn, Click Here!
Gui, Tab, 2
Gui, Font, s14, Segoe UI
Gui, Add, Text, x360 y100 BackgroundTrans, Page 2
Gui, Tab, 3
Gui, Font, s14, Segoe UI
Gui, Add, Text, x360 y100 BackgroundTrans, Page 3
Gui, Tab, 4
Gui, Font, s14, Segoe UI
Gui, Add, Text, x360 y100 BackgroundTrans, Page 4
Gui, Tab, 5
Gui, Font, s14, Segoe UI
Gui, Add, Text, x360 y100 BackgroundTrans, Page 5
Gui, Tab, 6
Gui, Font, s14, Segoe UI
Gui, Add, Text, x360 y100 BackgroundTrans, Page 6
Gui, Tab
Gui, Add, Picture, vMenuHover HwndhMenuHover Hidden1, images\button-menu-hover.png
Gui, Add, Picture, vMenuPressed HwndhMenuPressed Hidden1, images\button-menu-pressed.png
Gui, Add, Picture, vMenuSelect HwndhMenuSelect, images\button-menusel.png
Gui, Font, s11, Segoe UI
Gui, Add, Text, vMenuText1 HwndhMenuText1 BackgroundTrans 0x200 c0078D7, % " Menu 1"
Gui, Add, Text, vMenuText2 HwndhMenuText2 BackgroundTrans 0x200, % " Menu 2"
Gui, Add, Text, vMenuText3 HwndhMenuText3 BackgroundTrans 0x200, % " Menu 3"
Gui, Add, Text, vMenuText4 HwndhMenuText4 BackgroundTrans 0x200, % " Menu 4"
Gui, Add, Text, vMenuText5 HwndhMenuText5 BackgroundTrans 0x200, % " Menu 5"
Gui, Add, Text, vMenuText6 HwndhMenuText6 BackgroundTrans 0x200, % " Menu 6"
VarSetCapacity(TME, 16, 0), NumPut(16, TME, 0), NumPut(2, TME, 4), NumPut(GuiHwnd, TME, 8)
Gui, Show, w800 h600, Example
SetTimer, WinActiveCheck, 100
}
GuiSize(GuiHwnd, EventInfo, Width, Height) {
Global ; Assume-global mode
GuiControl, MoveDraw, BorderTop, % "x" 1 " y" 0 " w" Width - 2 " h" 1
GuiControl, MoveDraw, BorderBottom, % "x" 1 " y" Height - 1 " w" Width - 2 " h" 1
GuiControl, MoveDraw, BorderLeft, % "x" 0 " y" 0 " w" 1 " h" Height
GuiControl, MoveDraw, BorderRight, % "x" Width - 1 " y" 0 " w" 1 " h" Height
GuiControl, MoveDraw, BtnBackN, % "x" 1 " y" 1 " w" 48 " h" 31
GuiControl, MoveDraw, BtnBackH, % "x" 1 " y" 1 " w" 48 " h" 31
GuiControl, MoveDraw, BtnBackP, % "x" 1 " y" 1 " w" 48 " h" 31
GuiControl, MoveDraw, BtnMinN, % "x" (Width - 1) - 138 " y" 1 " w" 46 " h" 31
GuiControl, MoveDraw, BtnMinH, % "x" (Width - 1) - 138 " y" 1 " w" 46 " h" 31
GuiControl, MoveDraw, BtnMinP, % "x" (Width - 1) - 138 " y" 1 " w" 46 " h" 31
GuiControl, MoveDraw, BtnMaxN, % "x" (Width - 1) - 92 " y" 1 " w" 46 " h" 31
GuiControl, MoveDraw, BtnMaxH, % "x" (Width - 1) - 92 " y" 1 " w" 46 " h" 31
GuiControl, MoveDraw, BtnMaxP, % "x" (Width - 1) - 92 " y" 1 " w" 46 " h" 31
GuiControl, MoveDraw, BtnRestoreN, % "x" (Width - 1) - 92 " y" 1 " w" 46 " h" 31
GuiControl, MoveDraw, BtnRestoreH, % "x" (Width - 1) - 92 " y" 1 " w" 46 " h" 31
GuiControl, MoveDraw, BtnRestoreP, % "x" (Width - 1) - 92 " y" 1 " w" 46 " h" 31
GuiControl, MoveDraw, BtnCloseN, % "x" (Width - 1) - 46 " y" 1 " w" 46 " h" 31
GuiControl, MoveDraw, BtnCloseH, % "x" (Width - 1) - 46 " y" 1 " w" 46 " h" 31
GuiControl, MoveDraw, BtnCloseP, % "x" (Width - 1) - 46 " y" 1 " w" 46 " h" 31
GuiControl, MoveDraw, MenuHover, % "x" 1 " y" 1 " w" 320 " h" 48
GuiControl, MoveDraw, MenuPressed, % "x" 1 " y" 1 " w" 320 " h" 48
GuiControl, MoveDraw, MenuSelect, % "x" 1 " y" 112 " w" 4 " h" 24
GuiControl, MoveDraw, MenuText1, % "x" 1 " y" 100 " w" 320 " h" 48
GuiControl, MoveDraw, MenuText2, % "x" 1 " y" 100 + 48 " w" 320 " h" 48
GuiControl, MoveDraw, MenuText3, % "x" 1 " y" 100 + 96 " w" 320 " h" 48
GuiControl, MoveDraw, MenuText4, % "x" 1 " y" 100 + 144 " w" 320 " h" 48
GuiControl, MoveDraw, MenuText5, % "x" 1 " y" 100 + 192 " w" 320 " h" 48
GuiControl, MoveDraw, MenuText6, % "x" 1 " y" 100 + 240 " w" 320 " h" 48
}
GuiRestore() {
WinRestore
CtlShowHide("Hide", "BtnRestoreN,BtnRestoreH,BtnRestoreP")
CtlShowHide("Show", "BtnMaxN")
}
GuiMaximize() {
WinMaximize
CtlShowHide("Hide", "BtnMaxN,BtnMaxH,BtnMaxP")
CtlShowHide("Show", "BtnRestoreN")
}
CtlShowHide(ShowHide, Controls*) {
Static K, V
For K, V In Controls {
Split := StrSplit(V, ",")
Loop % Split.MaxIndex() {
GuiControl, % ShowHide, % Split[A_Index]
}
}
}
WM_MOUSEMOVE(wParam, lParam, Msg, Hwnd) {
Global ; Assume-global mode
Static Init := OnMessage(0x0200, "WM_MOUSEMOVE"), Hover := 0, Curr := ""
DllCall("User32.dll\TrackMouseEvent", "UInt", &TME)
MouseGetPos, MouseX, MouseY,, MouseCtrl, 2
If (MouseCtrl ~= hBtnBackH "|" hBtnMinH "|" hBtnMaxH "|" hBtnRestoreH "|" hBtnCloseH) {
return
}
If (MouseCtrl ~= hMenuText1 "|" hMenuText2 "|" hMenuText3 "|" hMenuText4 "|" hMenuText5 "|" hMenuText6) {
CtlShowHide("Show", "MenuHover")
IfEqual, Hover, 1, IfEqual, Curr, % MouseCtrl, return
GuiControlGet, MenuPos, Pos, % MouseCtrl
GuiControl, MoveDraw, MenuHover, % " y" MenuPosY
GuiControl, MoveDraw, MenuPressed, % " y" MenuPosY
Hover := 1, Curr := MouseCtrl
} Else {
CtlShowHide("Hide", "MenuHover"), Hover := 0
}
GuiControl, % (MouseCtrl = hBtnBackN ? "Show" : "Hide"), BtnBackH
GuiControl, % (MouseCtrl = hBtnMinN ? "Show" : "Hide"), BtnMinH
GuiControl, % (MouseCtrl = hBtnMaxN ? "Show" : "Hide"), BtnMaxH
GuiControl, % (MouseCtrl = hBtnRestoreN ? "Show" : "Hide"), BtnRestoreH
GuiControl, % (MouseCtrl = hBtnCloseN ? "Show" : "Hide"), BtnCloseH
IfEqual, MouseCtrl,, Try CtlShowHide("Hide", "BtnBackH,BtnBackP,BtnMinH,BtnMinP,BtnMaxH,BtnMaxP,BtnCloseH,BtnCloseP")
}
WM_LBUTTONDOWN(wParam, lParam, Msg, Hwnd) {
Global ; Assume-global mode
Static Init := OnMessage(0x0201, "WM_LBUTTONDOWN")
If (MouseCtrl ~= hBtnBackP "|" hBtnMinP "|" hBtnMaxP "|" hBtnRestoreP "|" hBtnCloseP) {
return
}
If (MouseCtrl ~= hMenuText1 "|" hMenuText2 "|" hMenuText3 "|" hMenuText4 "|" hMenuText5 "|" hMenuText6) {
CtlShowHide("Show", "MenuPressed")
}
GuiControl, % (MouseCtrl = hBtnBackH ? "Show" : "Hide"), BtnBackP
GuiControl, % (MouseCtrl = hBtnMinH ? "Show" : "Hide"), BtnMinP
GuiControl, % (MouseCtrl = hBtnMaxH ? "Show" : "Hide"), BtnMaxP
GuiControl, % (MouseCtrl = hBtnRestoreH ? "Show" : "Hide"), BtnRestoreP
GuiControl, % (MouseCtrl = hBtnCloseH ? "Show" : "Hide"), BtnCloseP
If (!MouseCtrl) {
cX := X - gX, cY := Y - gY
If (cY < 31) {
PostMessage, 0xA1, 2
}
}
}
WM_LBUTTONDBLCLK(wParam, lParam, Msg, Hwnd) {
Global ; Assume-global mode
Static Init := OnMessage(0x0203, "WM_LBUTTONDBLCLK")
If (!MouseCtrl) {
If (cY < 31) {
WinGet, MinMaxState, MinMax
If (MinMaxState = 1) {
GuiRestore()
} Else {
GuiMaximize()
}
}
}
}
WM_LBUTTONUP(wParam, lParam, Msg, Hwnd) {
Global ; Assume-global mode
Static Init := OnMessage(0x0202, "WM_LBUTTONUP")
If (MouseCtrl = hBtnBackP) {
CtlShowHide("Hide", "BtnBackN")
GuiControl,, TitleText, Example
GuiControl, MoveDraw, TitleText, x14
GuiControl,, ClickBtn, Click Here!
}
If (MouseCtrl ~= hMenuText1 "|" hMenuText2 "|" hMenuText3 "|" hMenuText4 "|" hMenuText5 "|" hMenuText6) {
GuiControlGet, MenuVar, Name, % MouseCtrl
GuiControl, Choose, Tab, % SubStr(MenuVar, 9)
Loop, 6 {
GuiControl, +c000000 +Redraw, % "MenuText" A_Index
GuiControl, MoveDraw, % "MenuText" A_Index
}
GuiControl, +c0078D7 +Redraw, % MouseCtrl
GuiControl, MoveDraw, % MouseCtrl
GuiControl, MoveDraw, MenuSelect, % " y" MenuPosY+12
}
If (MouseCtrl = hClickBtn) {
GuiControl, Show, BtnBackN
GuiControl, MoveDraw, TitleText, x60
GuiControl,, ClickBtn, Back Button Added! :-)
}
IfEqual, MouseCtrl, % hBtnMinP, WinMinimize
IfEqual, MouseCtrl, % hBtnCloseP, GoSub, ExitSub
IfEqual, MouseCtrl, % hBtnMaxP, Try GuiMaximize()
IfEqual, MouseCtrl, % hBtnRestoreP, Try GuiRestore()
CtlShowHide("Hide", "BtnBackP,BtnMinP,BtnMaxP,BtnRestoreP,BtnCloseP,MenuPressed")
}
WM_MOUSELEAVE(wParam, lParam, Msg, Hwnd) {
Global ; Assume-global mode
Static Init := OnMessage(0x2A3, "WM_MOUSELEAVE")
CtlShowHide("Hide", "BtnBackH,BtnMinH,BtnMaxH,BtnRestoreH,BtnCloseH,MenuHover")
CtlShowHide("Hide", "BtnBackP,BtnMinP,BtnMaxP,BtnRestoreP,BtnCloseP,MenuPressed")
}
WM_NCCALCSIZE(wParam, lParam, Msg, Hwnd) {
return (A_Gui ? 0 : "")
}
WM_NCACTIVATE(wParam, lParam, Msg, Hwnd) {
return (A_Gui ? 1 : "")
}
WM_NCHITTEST(wParam, lParam, Msg, Hwnd) {
Global X, Y, gX, gY
WinGetPos, gX, gY, gW, gH
X := lParam << 48 >> 48, Y := lParam << 32 >> 48
HL := X < gX + 6, HR := X >= (gX + gW) - 6
HT := Y < gY + 6, HB := Y >= (gY + gH) - 6
IfEqual, HT, 1, return "0x" (HL ? "D" : HR ? "E" : "C")
IfEqual, HB, 1, return "0x" (HL ? "10" : HR ? "11" : "F")
IfEqual, HL, 1, return 0xA
IfEqual, HR, 1, return 0xB
}
WinActiveCheck() {
Global ; Assume-global mode
Static Normal := 0, Disabled := 0, Count := 0
IsActive := WinActive("ahk_id " GuiHwnd)
If (IsActive) {
If (Normal) || (!Count) {
return
}
GuiControl,, BorderTop, images\border-top-normal.png
GuiControl,, BorderBottom, images\border-outer-normal.png
GuiControl,, BorderLeft, images\border-outer-normal.png
GuiControl,, BorderRight, images\border-outer-normal.png
GuiControl,, BtnBackN, images\button-back-normal.png
GuiControl,, BtnMinN, images\button-minimize-normal.png
GuiControl,, BtnMaxN, images\button-maximize-normal.png
GuiControl,, BtnRestoreN, images\button-restore-normal.png
GuiControl,, BtnCloseN, images\button-close-normal.png
GuiControl, +c000000, TitleText
GuiControl, MoveDraw, TitleText
Disabled := 0, Normal := 1, Count++
} Else {
If (Disabled) {
return
}
GuiControl,, BorderTop, images\border-top-disabled.png
GuiControl,, BorderBottom, images\border-outer-disabled.png
GuiControl,, BorderLeft, images\border-outer-disabled.png
GuiControl,, BorderRight, images\border-outer-disabled.png
GuiControl,, BtnBackN, images\button-back-disabled.png
GuiControl,, BtnMinN, images\button-minimize-disabled.png
GuiControl,, BtnMaxN, images\button-maximize-disabled.png
GuiControl,, BtnRestoreN, images\button-restore-disabled.png
GuiControl,, BtnCloseN, images\button-close-disabled.png
GuiControl, +c999999, TitleText
GuiControl, MoveDraw, TitleText
Normal := 0, Disabled := 1, Count++
}
}
; ==============================================================================
Представляю вам класс Class_PictureButton. Выкладываю две версии.
------------------------------------------------------------------------------------
Class_PictureButton_v1.ahk
Плюсы:
- Не использует/требует сторонних библиотек. Написан на встроенных функциях AHK
Минусы:
- Появляются мерцания при смене картинки(то бишь при наведении/при нажатии/при отключении/включении кнопки)
------------------------------------------------------------------------------------
Class_PictureButton_v2.ahk
Плюсы:
- Без мерцаний
- При создании -> возможность задать для картинки, как Bitmap, так и путь к изображению
- При удалении -> возможность очистить Bitmap, тем самым освободить память, или нет
Минусы:
- Использует GDIp (не так страшно)
------------------------------------------------------------------------------------
Ссылка на скачивание: https://github.com/Ne0n-git/Class_PictureButton
P.S. на оценку. Не конечная версия.
UPD:
2018.08.31 19:35 - залил на Github