This is owner draw object based & fully customizable ( as much as it is now ) popup menu. I've tried to make this module easy to use, and, possibly, change for anyone.
it currently works with AHK_L Unicode x32/64
Download ( .zip ) - just run test.ahk to check how it works
Documentation
I feel myself bad in any docs writing or explaining the things, so if you don't understand any feature, just let me know, i'll explain it better.
PUM module was partially inspired by majkentor's MMenu, so thanks to him too.
Here is the content of test.ahk:
#NoEnv #Include PUM_API.ahk #Include PUM.ahk ; parameters of the PUM object, the manager of the menus pumParams := { "SelMethod" : "fill" ;item selection method, may be frame,fill ;~ ,"selTColor" : -1 ;selection text color ;~ ,"selBGColor" : -1 ;selection background color, -1 means invert current color ,"oninit" : "PUM_out" ;function which will be called when any menu going to be opened ,"onuninit" : "PUM_out" ;function which will be called when any menu going to be closing ,"onselect" : "PUM_out" ;;function which will be called when any item selected with mouse (hovered) ,"onrbutton" : "PUM_out" ;function which will be called when any item right clicked ,"onmbutton" : "PUM_out" ;function which will be called when any item clicked with middle mouse button ,"onrun" : "PUM_out" ;function which will be called when any item clicked with left mouse button , "onshow" : "PUM_out" ;function which will be called before any menu shown using Show method , "onclose" : "Pum_out" ;function called just before quitting from Show method ,mnemonicCMD : "select"} ;PUM_Menu parameters menuParams1 := { "bgcolor" : 0x36311f ;background color of the menu , "iconssize" : 32 ;size of icons in the menu , "tcolor" : 0xafc9d3 } ;text color of the menu items menuParams2 := { "bgcolor" : 0x1C3150 , "iconssize" : 16 , "tcolor" : 0xFFFFFF } ;create an instance of PUM object, it is best to have only one of such in the program pm := new PUM( pumParams ) ;creating popup menu, represented by PUM_Menu object with given parameters menu := pm.CreateMenu( menuParams1 ) ;create a three othe menus newmenu1 := pm.CreateMenu( menuParams2 ) newmenu2 := pm.CreateMenu( menuParams2 ) newmenu3 := pm.CreateMenu( menuParams2 ) ;adding submenu items to the first menu, item SubItem1 will open "newmenu1" menu, and SubItem2 will open "newmenu2" menu.add( { "name" : "SubItem1", "submenu" : newmenu1, "icon" : "shell32.dll:8" } ) menu.add( { "name" : "SubItem2", "submenu" : newmenu2, "icon" : "shell32.dll:8" } ) menu.Add() ;adding separator ;adding a submenu item "SubItem3" to the "newmenu2" menu, which opens "newmenu3" menu newmenu2.add( { "name" : "SubItem3", "icon" : "shell32.dll:8", "submenu" : newmenu3 } ) ;adding five items to the first menu loop, 5 menu.Add( { "name" : "i&tem" A_Index , "bold" : 1 , "icon" : "shell32.dll:" A_index+20 } ) ;adding five items to the newmenu1 loop,5 newmenu1.add( { "name" : "item" A_index, "icon" : "shell32.dll:3" A_index } ) ;adding five items to the newmenu2 loop,5 newmenu2.add( { "name" : "item" A_index, "icon" : "shell32.dll:4" A_index } ) ;adding five items to the newmenu3 loop,5 newmenu3.add( { "name" : "item" A_index, "icon" : "shell32.dll:2" A_index, disabled : 1 } ) ;showing the first menu at the center of screen (~) if ( item := menu.Show( A_ScreenWidth/3, A_ScreenHeight/3 ) ) msgbox % "Choosen item: " item.name ;Destroying all menus/items created ;Use Destroy() method for the PUM_Menu object if you want to destroy specific menu pm.Destroy() ExitApp return PUM_out( msg, obj ) { if ( msg = "onselect" ) { rect := obj.GetRECT() CoordMode, ToolTip, Screen tooltip,% "Selected: " obj.name,% rect.right,% rect.top } if ( msg ~= "oninit|onuninit|onshow|onclose" ) tooltip % "menu " msg ": " obj.handle if ( msg = "onrbutton" ) tooltip % "Right clicked: " obj.name if ( msg = "onmbutton" ) tooltip % "Middle clicked: " obj.name if ( msg = "onrun" ) tooltip % "Item runned: " obj.name }
Update 31/01/2012
All PUM functions moved to separate class, so no need to care about similar functions ( but include PUM_API.ahk first )
-performance improved
new handlers for PUM object added:
onshow - called when menu's Show() method used before menu shown itself
onclose - called when menu's Show() method used after menu closed
new methods for PUM_Item and PUM_menu:
GetTColor()
GetBGColor()
new methods for PUM_Item:
GetIconHandle()
new parameter for PUM_Item:
"iconUseHandle" - to avoid deleting of iconHandle passed as "icon" parameter on item destroy
Update 12/20/2011
Fixed bug when changed through SetParams() item had lost it's attached menu
Update 12/14/2011
-Added GetItemByID() method to PUM object
-Added "textMargin" option for menus
-Default colors changed to system's
-Added "disabled" item option
-Added GetPos() item method
-Added GetRect() item method
-Added Update() item method
-Added EndMenu() menu method
-Added IsMenu() menu method
-PUM_Menu.Show() method now save & restore active window after menu was closed
-Changed Add() method of PUM_Menu object to allow adding items at specific position
-To check how is new features work, refer to documentation