I made another attempt to style a Gui similar to Google's Material Design.
It's only the styled Gui at the moment, with functional window control buttons (minimize, maximize, close). No other functionality added yet.
Started with a captionless and borderless Gui, and added custom images to emulate the appearance of actual Gui controls.
Code: Select all
; Script Information ===========================================================
; Name: Material Design
; Description: Material Design inspired Gui
; AHK Version: 1.1.31.01 (Unicode 32-bit)
; OS Version: Windows 10
; Language: English (United States)
; Author: Weston Campbell (TheDewd) <[email protected]>
; Filename: Material Design.ahk
; ==============================================================================
; Revision History =============================================================
; Revision 1 (2019-11-18)
; * 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
#KeyHistory, 0 ; Keystroke and mouse click history
ListLines, Off ; The script lines most recently executed
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, 0 ; The delay to occur after modifying a window
SetControlDelay, 0 ; The delay to occur after modifying a control
OnExit("OnUnload") ; Run a subroutine or function when exiting the script
return ; End automatic execution
; ==============================================================================
; Labels =======================================================================
; TBD
; ==============================================================================
; Functions ====================================================================
OnLoad() {
Global ; Assume-global mode
Static Init := OnLoad() ; Call function
Menu, Tray, Tip, New AutoHotkey Script
; GDI+ Startup
hGdip := DllCall("Kernel32.dll\LoadLibrary", "Str", "Gdiplus.dll") ; Load module
VarSetCapacity(GdiplusStartupInput, (A_PtrSize = 8 ? 24 : 16), 0) ; GdiplusStartupInput structure
NumPut(1, GdiplusStartupInput, 0, "UInt") ; GdiplusVersion
DllCall("Gdiplus.dll\GdiplusStartup", "PtrP", pToken, "Ptr", &GdiplusStartupInput, "Ptr", 0) ; Initialize GDI+
TitleIcon := "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEVHcEz///+flKJDAAAAAXRSTlMAQObYZgAAAB9JREFUeAFj+FfP0OSIhIBcBhD5z5GBwRFIIssCFQMAWZEOVjbFLUEAAAAASUVORK5CYII="
ButtonMinimize := "iVBORw0KGgoAAAANSUhEUgAAAC0AAAAdAQMAAAAErnd0AAAABlBMVEVHcEz///+flKJDAAAAAXRSTlMAQObYZgAAAA9JREFUeAFjoAeof0APWwCLxQFgXVzsZwAAAABJRU5ErkJggg=="
ButtonMaximize := "iVBORw0KGgoAAAANSUhEUgAAAC0AAAAdAQMAAAAErnd0AAAABlBMVEVHcEz///+flKJDAAAAAXRSTlMAQObYZgAAABZJREFUeAFjoBjUPwBTDgokUzDtVAIAW/YFvwYcJbMAAAAASUVORK5CYII="
ButtonRestore := "iVBORw0KGgoAAAANSUhEUgAAAC0AAAAdAQMAAAAErnd0AAAABlBMVEVHcEz///+flKJDAAAAAXRSTlMAQObYZgAAACJJREFUeAFjoBjIPwBTAgpgqn4BmHLARz2AUA0QDUCKOgAAgGoIrt5ErioAAAAASUVORK5CYII="
ButtonClose := "iVBORw0KGgoAAAANSUhEUgAAAC0AAAAdAgMAAABDDg2kAAAACVBMVEVHcEz////////mcEUwAAAAAnRSTlMATAn5wIMAAAAtSURBVHgBYxgwoMIggeBIMqQgOGyOExAcxmkOSJoyGTA5CGWYBiCMRlg6OAAAS1UFoW2zwNkAAAAASUVORK5CYII="
ButtonHoverLight := "iVBORw0KGgoAAAANSUhEUgAAAC0AAAAdAQMAAAAErnd0AAAABlBMVEX///9HcExwQjx2AAAAAnRSTlMPAPEL0fcAAAA/SURBVHgBY/gPAj8wqAf1YIqBH0T9Y2AHUX8YmIEUEDGCqA8MDJjUAwaGeqIoTO1Qo6EWQa2FOQLhJCDAQQEA9kh/fLXD4JsAAAAASUVORK5CYII="
ButtonHoverDark := "iVBORw0KGgoAAAANSUhEUgAAAC0AAAAdCAYAAAA+YOU3AAAAW0lEQVR4Ae3XtxGAMADAQAZgLvIw7F9BRXQrR3Gn/gHHbty34hJdJPp8+lAMGoCSL8CDATgPBuA8GIAnAt+JLhLNg+8KQYsWLdp1WrQHJgDuJYCGe7FNkGgi0QdIuLX5HAI62QAAAABJRU5ErkJggg=="
hBMPTitleIcon := GdipCreateHBITMAPFromBase64(TitleIcon)
hBMPButtonMinimize := GdipCreateHBITMAPFromBase64(ButtonMinimize)
hBMPButtonMaximize := GdipCreateHBITMAPFromBase64(ButtonMaximize)
hBMPButtonRestore := GdipCreateHBITMAPFromBase64(ButtonRestore)
hBMPButtonClose := GdipCreateHBITMAPFromBase64(ButtonClose)
BMPButtonHoverLight := GdipCreateBitmapFromBase64(ButtonHoverLight)
BMPButtonHoverDark := GdipCreateBitmapFromBase64(ButtonHoverDark)
BMPButtonMinimize := GdipCreateBitmapFromBase64(ButtonMinimize)
BMPButtonMaximize := GdipCreateBitmapFromBase64(ButtonMaximize)
BMPButtonRestore := GdipCreateBitmapFromBase64(ButtonRestore)
BMPButtonClose := GdipCreateBitmapFromBase64(ButtonClose)
hBMPMinimizeHover := GdipCreateHBITMAPFromBitmap(GdiBitmapMerge(BMPButtonHoverLight, BMPButtonMinimize))
hBMPMaximizeHover := GdipCreateHBITMAPFromBitmap(GdiBitmapMerge(BMPButtonHoverLight, BMPButtonMaximize))
hBMPRestoreHover := GdipCreateHBITMAPFromBitmap(GdiBitmapMerge(BMPButtonHoverLight, BMPButtonRestore))
hBMPCloseHover := GdipCreateHBITMAPFromBitmap(GdiBitmapMerge(BMPButtonHoverLight, BMPButtonClose))
ButtonState := []
ButtonState["Minimize"] := 0
ButtonState["Maximize"] := 0
ButtonState["Restore"] := 0
ButtonState["Close"] := 0
}
OnUnload(ExitReason, ExitCode) {
Global ; Assume-global mode
; Clean up resources used by GDI+
DllCall("Gdiplus.dll\GdiplusShutdown", "Ptr", pToken)
}
GdipCreateBitmapFromBase64(B64) {
VarSetCapacity(B64Len, 0)
DllCall("Crypt32.dll\CryptStringToBinary", "Ptr", &B64, "UInt", StrLen(B64), "UInt", 0x01, "Ptr", 0, "UIntP", B64Len, "Ptr", 0, "Ptr", 0)
VarSetCapacity(B64Dec, B64Len, 0) ; pbBinary size
DllCall("Crypt32.dll\CryptStringToBinary", "Ptr", &B64, "UInt", StrLen(B64), "UInt", 0x01, "Ptr", &B64Dec, "UIntP", B64Len, "Ptr", 0, "Ptr", 0)
pStream := DllCall("Shlwapi.dll\SHCreateMemStream", "Ptr", &B64Dec, "UInt", B64Len, "UPtr")
VarSetCapacity(pBitmap, 0)
DllCall("Gdiplus.dll\GdipCreateBitmapFromStreamICM", "Ptr", pStream, "PtrP", pBitmap)
ObjRelease(pStream)
return pBitmap
}
GdipCreateHBITMAPFromBitmap(pBitmap) {
VarSetCapacity(hBitmap, 0)
DllCall("Gdiplus.dll\GdipCreateHBITMAPFromBitmap", "UInt", pBitmap, "UInt*", hBitmap, "Int", 0XFFFFFFFF)
return hBitmap
}
GdipCreateHICONFromBitmap(pBitmap) {
VarSetCapacity(hIcon, 0)
DllCall("Gdiplus.dll\GdipCreateHICONFromBitmap", "Ptr", pBitmap, "PtrP", hIcon, "UInt", 0)
return hIcon
}
GdipCreateHBITMAPFromBase64(B64) {
pBitmap := GdipCreateBitmapFromBase64(B64)
return GdipCreateHBITMAPFromBitmap(pBitmap)
}
GuiCreate() {
Global ; Assume-global mode
Static Init := GuiCreate() ; Call function
; Window Options -----------------------------------------------------------
Gui, +LastFound -Resize -Caption -Border +HWNDhMaterialDesign +MinSize800x600
Gui, Margin, 0, 0
; Window Border ------------------------------------------------------------
Gui, Add, Text, x0 y0 w800 h1 +0x4E HWNDhBorderTop
Gui, Add, Text, x0 y599 w800 h1 +0x4E HWNDhBorderBottom
Gui, Add, Text, x0 y1 w1 h598 +0x4E HWNDhBorderLeft
Gui, Add, Text, x799 y1 w1 h598 +0x4E HWNDhBorderRight
; Titlebar -----------------------------------------------------------------
Gui, Add, Text, x1 y1 w798 h30 +0x4E HWNDhTitlebar
Gui, Add, Picture, x8 y8 w16 h16 HWNDhTitleIcon +BackgroundTrans, % "HBITMAP:*" hBMPTitleIcon
Gui, Add, Text, x1 y31 w798 h1 +0x4E HWNDhTitlebarLine
Gui, Font, s9 cFFFFFF, Segoe UI
Gui, Add, Text, x30 y1 h30 w400 0x200 HWNDhTitlebarText +BackgroundTrans, Application
; Window Controls ----------------------------------------------------------
Gui, Add, Picture, x662 y1 w45 h29 HWNDhButtonMinimize +BackgroundTrans, % "HBITMAP:*" hBMPButtonMinimize
Gui, Add, Picture, x708 y1 w45 h29 HWNDhButtonMaximize +BackgroundTrans, % "HBITMAP:*" hBMPButtonMaximize
Gui, Add, Picture, x754 y1 w45 h29 HWNDhButtonClose +BackgroundTrans, % "HBITMAP:*" hBMPButtonClose
; Appbar -------------------------------------------------------------------
Gui, Add, Text, x1 y32 w798 h64 +0x4E HWNDhAppbar
; Body ---------------------------------------------------------------------
Gui, Add, Text, x1 y96 w200 h504 +0x4E HWNDhPanelLeft
Gui, Add, Text, x201 y96 w1 h504 +0x4E HWNDhDividerVert
Gui, Add, Text, x202 y96 w597 h504 +0x4E HWNDhPanelRight
;Gui, Font, s18 c000000
;Gui, Add, Text, x1 y700 +BackgroundTrans, TEST
CreatePixel(hBorderTop, "2E81D3")
CreatePixel(hBorderBottom, "2E81D3")
CreatePixel(hBorderLeft, "2E81D3")
CreatePixel(hBorderRight, "2E81D3")
CreatePixel(hTitlebar, "0069C0")
CreatePixel(hTitlebarLine, "48A8F4")
CreatePixel(hAppbar, "2196F3")
CreatePixel(hPanelLeft, "FAFAFA")
CreatePixel(hDividerVert, "D2D2D2")
CreatePixel(hPanelRight, "F5F5F5")
Gui, Show, w800 h600, Example
}
GuiSize(GuiHwnd, EventInfo, Width, Height) {
Global ; Assume-global mode
If (ErrorLevel = 1) { ; Window minimized
return
}
GuiControl, Move, % hBorderTop, % "w" Width " h1"
GuiControl, Move, % hBorderBottom, % "y" Height - 1 " w" Width
GuiControl, Move, % hBorderLeft, % "h" Height - 2
GuiControl, Move, % hBorderRight, % "x" Width - 1 " h" Height - 2
GuiControl, Move, % hTitlebar, % "w" Width - 2
GuiControl, Move, % hTitlebarText, % "w" Width - 170
GuiControl, Move, % hTitlebarLine, % "w" Width - 2
GuiControl, Move, % hAppbar, % "w" Width - 2
GuiControl, Move, % hPanelLeft, % "h" Height - 97
GuiControl, Move, % hPanelRight, % "w" Width - 204 " h" Height - 97
GuiControl, Move, % hDividerVert, % "h" Height - 97
GuiControl, MoveDraw, % hButtonClose, % "x" Width - 46
GuiControl, MoveDraw, % hButtonMaximize, % "x" Width - 92
GuiControl, MoveDraw, % hButtonMinimize, % "x" Width - 138
}
GuiEscape(GuiHwnd) {
ExitApp ; Terminate the script unconditionally
}
GuiClose(GuiHwnd) {
ExitApp ; Terminate the script unconditionally
}
WM_SIZE(wParam, lParam, Msg, Hwnd) {
Global ; Assume-global mode
Static Init := OnMessage(0x0005, "WM_SIZE") ; Call function
If (A_Gui = 1) {
Width := lParam & 0xFFFF, Height := lParam >> 16
WinGet, WinMax, MinMax
If (WinMax = 1) {
GuiControl,, % hButtonMaximize, % "HBITMAP:*" hBMPButtonRestore
} Else If (WinMax = 0) {
GuiControl,, % hButtonMaximize, % "HBITMAP:*" hBMPButtonMaximize
}
}
}
WM_MOUSEMOVE(wParam, lParam, Msg, Hwnd) {
Global ; Assume-global mode
Static Init := OnMessage(0x0200, "WM_MOUSEMOVE")
MouseGetPos, MouseX, MouseY, MouseWin, MouseCtl, 2
VarSetCapacity(TME, 16, 0)
NumPut(16, TME, 0)
NumPut(2, TME, 4) ; TME_LEAVE
NumPut(MouseWin, TME, 8)
DllCall("User32.dll\TrackMouseEvent", "UInt", &TME)
If (MouseCtl = hButtonMinimize && ButtonState["Minimize"] <> 1) {
GuiControl,, % hButtonMinimize, % "HBITMAP:*" hBMPMinimizeHover
ButtonState["Minimize"] := 1
} Else If (MouseCtl <> hButtonMinimize && ButtonState["Minimize"] = 1) {
GuiControl,, % hButtonMinimize, % "HBITMAP:*" hBMPButtonMinimize
ButtonState["Minimize"] := 0
}
If (MouseCtl = hButtonMaximize) {
WinGet, WinMax, MinMax
If (WinMax = 1 && ButtonState["Restore"] <> 1) {
GuiControl,, % hButtonMaximize, % "HBITMAP:*" hBMPRestoreHover
ButtonState["Restore"] := 1
} Else If (WinMax <> 1 && ButtonState["Maximize"] <> 1) {
GuiControl,, % hButtonMaximize, % "HBITMAP:*" hBMPMaximizeHover
ButtonState["Maximize"] := 1
}
} Else If (MouseCtl <> hButtonMaximize) {
WinGet, WinMax, MinMax
If (WinMax = 1 && ButtonState["Restore"] = 1) {
GuiControl,, % hButtonMaximize, % "HBITMAP:*" hBMPButtonRestore
ButtonState["Restore"] := 0
} Else If (WinMax <> 1 && ButtonState["Maximize"] = 1) {
GuiControl,, % hButtonMaximize, % "HBITMAP:*" hBMPButtonMaximize
ButtonState["Maximize"] := 0
}
}
If (MouseCtl = hButtonClose && ButtonState["Close"] <> 1) {
GuiControl,, % hButtonClose, % "HBITMAP:*" hBMPCloseHover
ButtonState["Close"] := 1
} Else If (MouseCtl <> hButtonClose && ButtonState["Close"] = 1) {
GuiControl,, % hButtonClose, % "HBITMAP:*" hBMPButtonClose
ButtonState["Close"] := 0
}
}
WM_MOUSELEAVE(wParam, lParam, Msg, Hwnd) {
Global ; Assume-global mode
Static Init := OnMessage(0x02A3, "WM_MOUSELEAVE")
If (ButtonState["Minimize"] <> 0) {
GuiControl,, % hButtonMinimize, % "HBITMAP:*" hBMPButtonMinimize
ButtonState["Minimize"] := 0
} Else If (ButtonState["Maximize"] <> 0) {
GuiControl,, % hButtonMaximize, % "HBITMAP:*" hBMPButtonMaximize
ButtonState["Maximize"] := 0
} Else If (ButtonState["Restore"] <> 0) {
GuiControl,, % hButtonMaximize, % "HBITMAP:*" hBMPButtonRestore
ButtonState["Restore"] := 0
} Else If (ButtonState["Close"] <> 0) {
GuiControl,, % hButtonClose, % "HBITMAP:*" hBMPButtonClose
ButtonState["Close"] := 0
}
}
WM_LBUTTONDOWN(wParam, lParam, Msg, Hwnd) {
Global ; Assume-global mode
Static Init := OnMessage(0x0201, "WM_LBUTTONDOWN") ; Call function
If (A_Gui = 1) {
If (MouseCtl = hTitleIcon) {
PostMessage, 0x112, 0xF100, 0x20 ; WM_SYSCOMMAND := 0x112 ;SC_KEYMENU := 0xF100
} Else If (MouseCtl = hTitlebarText) {
PostMessage, 0xA1, 2 ; 0xA1 := WM_NCLBUTTONDOWN / 2 := HTCAPTION
}
}
}
WM_LBUTTONUP(wParam, lParam, Msg, Hwnd) {
Global ; Assume-global mode
Static Init := OnMessage(0x0202, "WM_LBUTTONUP")
If (A_Gui = 1) {
If (MouseCtl = hButtonClose) {
ExitApp
} Else If (MouseCtl = hButtonMaximize) {
WinGet, WinMax, MinMax
If (WinMax = 1) {
WinRestore
} Else If (WinMax = 0) {
Gui, +Caption
WinMaximize
Gui, -Caption
}
} Else If (MouseCtl = hButtonMinimize) {
WinMinimize
}
}
}
WM_RBUTTONUP(wParam, lParam, Msg, Hwnd) {
Global ; Assume-global mode
Static Init := OnMessage(0x0205, "WM_RBUTTONUP") ; Call function
If (A_Gui = 1) {
If (MouseCtl = hTitleIcon) {
PostMessage, 0x112, 0xF100, 0x20 ; SysMenu
}
}
}
WM_LBUTTONDBLCLK(wParam, lParam, Msg, Hwnd) {
Global ; Assume-global mode
Static Init := OnMessage(0x0203, "WM_LBUTTONDBLCLK")
If (A_Gui = 1) {
If (MouseCtl = hTitlebarText) {
WinGet, WinMax, MinMax
If (WinMax = 1) {
WinRestore
} Else If (WinMax = 0) {
Gui, +Caption
WinMaximize
Gui, -Caption
}
}
}
}
WM_NCHITTEST(wParam, lParam, Msg, Hwnd) { ; Define sizing borders
Static Init := OnMessage(0x0084, "WM_NCHITTEST") ; Call function
Static BSZ := 6 ; Border Size
If (A_Gui = 1) {
WinGetPos, gX, gY, gW, gH
X := (lParam << 48 >> 48)
Y := (lParam << 32 >> 48)
HL := (X < (gX + BSZ))
HR := (X >= ((gX + gW) - BSZ))
HT := (Y < (gY + BSZ))
HB := (Y >= ((gY + gH) - BSZ))
; Enable window resizing
If (HL || HR || HT || HB)
|| (HT & HL || HT & HR || HB & HL || HB & HR) {
WinGet, Style, Style
If !(Style & 0x40000) {
Gui, +Resize
}
}
If (HT) {
return (HL ? 0xD : HR ? 0xE : 0xC)
} Else If (HB) {
return (HL ? 0x10 : HR ? 0x11 : 0xF)
} Else If (HL) {
return 0xA
} Else If (HR) {
return 0xB
}
}
}
WM_NCCALCSIZE(wParam, lParam, Msg, Hwnd) { ; Size the client area to fill entire window
Static Init := OnMessage(0x0083, "WM_NCCALCSIZE") ; Call function
If (A_Gui = 1) {
return 0
}
}
WM_NCACTIVATE(wParam, lParam, Msg, Hwnd) { ; Prevent drawing border when activating window
Static Init := OnMessage(0x0086, "WM_NCACTIVATE") ; Call function
If (A_Gui = 1) {
return 1
}
}
CreatePixel(HWND, HexColor) {
hBitmap := DllCall("Gdi32.dll\CreateBitmap", "Int", 1, "Int", 1, "UInt", 1, "UInt", 24, "Ptr", 0, "Ptr")
hBM := DllCall("User32.dll\CopyImage", "Ptr", hBitmap, "UInt", 0, "Int", 0, "Int", 0, "UInt", 8, "Ptr")
VarSetCapacity(BMBITS, 5, 0)
Numput("0x" HexColor, &BMBITS, 0, "UInt")
DllCall("Gdi32.dll\SetBitmapBits", "Ptr", hBM, "UInt", 4, "Ptr", &BMBITS)
DllCall("User32.dll\SendMessage", "Ptr", HWND, "UInt", 0x0172, "Ptr", 0, "Ptr", hBM, "Ptr")
DllCall("Gdi32.dll\DeleteObject", "Ptr", hBitmap)
}
GdiBitmapMerge(Bitmap1, Bitmap2) {
DllCall("Gdiplus.dll\GdipGetImageWidth", "UPtr", Bitmap1, "UInt*", Width)
DllCall("Gdiplus.dll\GdipGetImageHeight", "UPtr", Bitmap1, "UInt*", Height)
DllCall("Gdiplus.dll\GdipCreateBitmapFromScan0", "Int", Width, "Int", Height, "Int", 0, "Int", 0x26200A, "UPtr", 0, "UPtr*", BitmapNew)
DllCall("Gdiplus.dll\GdipGetImageGraphicsContext", "UPtr", BitmapNew, "UPtr*", pGraphics)
DllCall("Gdiplus.dll\GdipDrawImageRectRect", "Ptr", pGraphics, "Ptr", Bitmap1, "Float", 0, "Float", 0, "Float", Width, "Float", Height, "Float", 0, "Float", 0, "Float", Width, "Float", Height, "Int", 2, "Ptr", 0, "Ptr", 0, "Ptr", 0)
DllCall("Gdiplus.dll\GdipDrawImageRectRect", "Ptr", pGraphics, "Ptr", Bitmap2, "Float", 0, "Float", 0, "Float", Width, "Float", Height, "Float", 0, "Float", 0, "Float", Width, "Float", Height, "Int", 2, "Ptr", 0, "Ptr", 0, "Ptr", 0)
DllCall("Gdiplus.dll\GdipDeleteGraphics", "UPtr", pGraphics)
return BitmapNew
}
; ==============================================================================