There's actually an example in Adventure of a toolbar button with drop-down menu: the Execute button, but it is not implemented in a simple way, so it cannot be accounted as a recommended example.
Code: Select all
#SingleInstance Force
#NoEnv
SetWorkingDir %A_ScriptDir%
SetBatchLines -1
CoordMode Menu, Screen
Gui Font, s9, Segoe UI
Gui Show, w357 h149, Toolbar Button Drop-down Menu Example
Menu ToolbarMenu, Add, Item 1, MenuHandler
Menu ToolbarMenu, Add, Item 2, MenuHandler
Global g_hToolbar := CreateToolbar()
Return ; End of the auto-execute section.
MenuHandler:
Return
GuiEscape:
GuiClose:
ExitApp
CreateToolbar() {
ImageList := IL_Create(1)
IL_Add(ImageList, "shell32.dll", 4)
Buttons =
(LTrim
-
Open,,, DROPDOWN SHOWTEXT
)
Return Toolbar_Create("OnToolbar", Buttons, ImageList, "Flat List Tooltips", "+E0x200", "", 0x10000)
}
; Event handling
OnToolbar(hWnd, Event, Text, Pos, Id, Left, Bottom) {
If (Event == "DropDown") {
Menu ToolbarMenu, Show, %Left%, %Bottom%
Return
}
If (Event != "Click") {
Return
}
If (Text == "Open") {
MsgBox
}
}
; Toolbar.ahk
Toolbar_Create(Handler, Buttons, ImageList := "", Options := "Flat List ToolTips", Extra := "", Pos := "", Padding := "", ExStyle := 0x9) {
Local fShowText, fTextOnly, Styles, hWnd, TBB_Size, cButtons, TBBUTTONS
, Index, Button, iBitmap, idCommand, fsState, fsStyle, iString, Offset, SIZE,
Static TOOLTIPS := 0x100, WRAPABLE := 0x200, FLAT := 0x800, LIST := 0x1000
, TABSTOP := 0x10000, BORDER := 0x800000, TEXTONLY := 0, BOTTOM := 0x3
, ADJUSTABLE := 0x20, NODIVIDER := 0x40, VERTICAL := 0x80
, CHECKED := 1, HIDDEN := 8, WRAP := 32, DISABLED := 0 ; States
, CHECK := 2, CHECKGROUP := 6, DROPDOWN := 8, AUTOSIZE := 16
, NOPREFIX := 32, SHOWTEXT := 64, WHOLEDROPDOWN := 128 ; Styles
StrReplace(Options, "SHOWTEXT", "", fShowText, 1)
fTextOnly := InStr(Options, "TEXTONLY")
Styles := 0
Loop Parse, Options, %A_Tab%%A_Space%, %A_Tab%%A_Space% ; Parse toolbar styles
IfEqual A_LoopField,, Continue
Else Styles |= A_LoopField + 0 ? A_LoopField : %A_LoopField%
If (Pos != "") {
Styles |= 0x4C ; CCS_NORESIZE | CCS_NOPARENTALIGN | CCS_NODIVIDER
}
Gui Add, Custom, ClassToolbarWindow32 hWndhWnd gToolbar_Handler -Tabstop %Pos% %Styles% %Extra%
Toolbar_Store(hWnd, Handler)
TBB_Size := A_PtrSize == 8 ? 32 : 20
Buttons := StrSplit(Buttons, "`n")
cButtons := Buttons.Length()
VarSetCapacity(TBBUTTONS, TBB_Size * cButtons , 0)
Index := 0
Loop %cButtons% {
Button := StrSplit(Buttons[A_Index], ",", " `t")
If (Button[1] == "-") {
iBitmap := 0
idCommand := 0
fsState := 0
fsStyle := 1 ; BTNS_SEP
iString := -1
} Else {
Index++
iBitmap := (fTextOnly) ? -1 : (Button[2] != "" ? Button[2] - 1 : Index - 1)
idCommand := (Button[5]) ? Button[5] : 10000 + Index
fsState := InStr(Button[3], "DISABLED") ? 0 : 4 ; TBSTATE_ENABLED
Loop Parse, % Button[3], %A_Tab%%A_Space%, %A_Tab%%A_Space% ; Parse button states
IfEqual A_LoopField,, Continue
Else fsState |= %A_LoopField%
fsStyle := fTextOnly || fShowText ? SHOWTEXT : 0
Loop Parse, % Button[4], %A_Tab%%A_Space%, %A_Tab%%A_Space% ; Parse button styles
IfEqual A_LoopField,, Continue
Else fsStyle |= %A_LoopField%
iString := &(ButtonText%Index% := Button[1])
}
Offset := (A_Index - 1) * TBB_Size
NumPut(iBitmap, TBBUTTONS, Offset, "Int")
NumPut(idCommand, TBBUTTONS, Offset + 4, "Int")
NumPut(fsState, TBBUTTONS, Offset + 8, "UChar")
NumPut(fsStyle, TBBUTTONS, Offset + 9, "UChar")
NumPut(iString, TBBUTTONS, Offset + (A_PtrSize == 8 ? 24 : 16), "Ptr")
}
If (Padding) {
SendMessage 0x457, 0, %Padding%,, ahk_id %hWnd% ; TB_SETPADDING
}
If (ExStyle) { ; 0x9 = TBSTYLE_EX_DRAWDDARROWS | TBSTYLE_EX_MIXEDBUTTONS
SendMessage 0x454, 0, %ExStyle%,, ahk_id %hWnd% ; TB_SETEXTENDEDSTYLE
}
SendMessage 0x430, 0, %ImageList%,, ahk_id %hWnd% ; TB_SETIMAGELIST
SendMessage % A_IsUnicode ? 0x444 : 0x414, %cButtons%, % &TBBUTTONS,, ahk_id %hWnd% ; TB_ADDBUTTONS
If (InStr(Options, "VERTICAL")) {
VarSetCapacity(SIZE, 8, 0)
SendMessage 0x453, 0, &SIZE,, ahk_id %hWnd% ; TB_GETMAXSIZE
} Else {
SendMessage 0x421, 0, 0,, ahk_id %hWnd% ; TB_AUTOSIZE
}
Return hWnd
}
Toolbar_Store(hWnd, Callback := "") {
Static o := {}
Return (o[hWnd] != "") ? o[hWnd] : o[hWnd] := Callback
}
Toolbar_Handler(hWnd) {
Static n := {-2: "Click", -5: "RightClick", -20: "LDown", -713: "Hot", -710: "DropDown"}
Local Handler, Code, ButtonId, Pos, Text, Event, RECT, Left, Bottom
Handler := Toolbar_Store(hWnd)
Code := NumGet(A_EventInfo + 0, A_PtrSize * 2, "Int")
If (Code != -713) {
ButtonId := NumGet(A_EventInfo + (3 * A_PtrSize))
} Else {
ButtonId := NumGet(A_EventInfo, A_PtrSize == 8 ? 28 : 16, "Int") ; NMTBHOTITEM idNew
}
SendMessage 0x419, ButtonId,,, ahk_id %hWnd% ; TB_COMMANDTOINDEX
Pos := ErrorLevel + 1
VarSetCapacity(Text, 128, 0)
SendMessage % A_IsUnicode ? 0x44B : 0x42D, ButtonId, &Text,, ahk_id %hWnd% ; TB_GETBUTTONTEXT
Event := (n[Code] != "") ? n[Code] : Code
VarSetCapacity(RECT, 16, 0)
SendMessage 0x433, ButtonId, &RECT,, ahk_id %hWnd% ; TB_GETRECT
DllCall("MapWindowPoints", "Ptr", hWnd, "Ptr", 0, "Ptr", &RECT, "UInt", 2)
Left := NumGet(RECT, 0, "Int")
Bottom := NumGet(RECT, 12, "Int")
%Handler%(hWnd, Event, Text, Pos, ButtonId, Left, Bottom)
}