Code archives/BlitzPlus Gui/Advance Popup Menu extras

This code has been declared by its author to be Public Domain code.

Download source code

Advance Popup Menu extras by gman2004
adds the following functions to the Advance PopupMenu by Ed From Mars:

GetPopupMenuText$(menu_id%) - returns the text of a menu item based on its assigned ID.

FindPopupHandle%(menu_id%) - returns the handle of a menu item based on its assigned ID.

SetPopupDataItem(item$,value$,ppmenu%) - sets a KEY=VALUE format string that can later be used after an item has been selected. this can be called multiple times with different KEY=VALUE pairs. they are seperated using the | character.

GetPopupDataItem$(item$,ppmenu%) - gets a value from the data section that was previously set by SetPopupDataItem().

ClearMenu() - clears out the POPUP_MENU collection.

** NOTES **
- the user32.decls file i use has api_ preceding all the function names. if yours does not have this, you will get a compile error. you will need to change all functions that begin with api_ to match the corrosponding function in your .decls file.

** REQUIREMENTS **
- the GetPopupDataItem() and SetPopupDataItem() functions make use of gettok$(word$,token,seperator) by skn3[ac].
- user32.decls file with the following functions defined (note my function calls are preceded by api_ ):
- CreatePopupMenu
- ModifyMenu
- AppendMenu
- DestroyMenu
- TrackPopupMenuEx
- SetForegroundWindow
- PostMessage

** MODIFICATIIONS **
- the GetPopupDataItem() and SetPopupDataItem() functions make use of a new mndata$ field added to the POPUP_MENU type. i also added defaulting of this new field in the PopupMenu() function.

Type POPUP_MENU
	Field txt$ = ""
	Field flag
	Field menu_id = 0
	Field popup.POPUP_MENU = Null
	Field parent.POPUP_MENU = Null
	Field root =  0
	Field mndata$=""	; 2004_08_10 (gman) - added string to hold extra data
End Type

; 2004_08_10 (gman) -  added passing and setting of new mndata value
Function PopupMenu%(txt$="",menu_id=0,parent=0,mndata$="")
	Local pm.POPUP_MENU=New POPUP_MENU
	Local p.POPUP_MENU=Object.POPUP_MENU(parent)
	If p=Null
		;root
		pm\popup=pm
		pm\parent=Null
	Else
		;link parent to root of new popupmenu
		If p\popup=Null 
			p\popup=New POPUP_MENU
			p\popup\parent=Null
		EndIf 
		;node
		pm\txt=txt
		pm\menu_id=menu_id
		pm\parent=p\popup
		pm\mndata=mndata    ; 2004_08_10 (gman) - set the new mndata field
	EndIf 

	Local ppmenu=Handle(pm)
	Return ppmenu
End Function 


- updated ShowPopupMenu to take X,Y as a parameter. they default to the original MouseX(),MouseY() if not passed.
- updated ShowPopupMenu to take a new lTray parameter and added corrosponding tray popup code. this is False by default, make True if using the popup from a tray icon. this is a fix as detailed in MSKB Q135788.

; ================================
; Show popupmenu at mouse position
; changes:
;	- 2004_08_10 (gman) - added X,Y positioning capabilities
;	- 2004_08_17 (gman) - added new tray parameter and called functions as described in MSKB Q135788
;		(http://support.microsoft.com/support/kb/articles/q135/7/88.asp)
; ================================

Function ShowPopupMenu%(ppmenu,win=0,nX=0,nY=0,lTray=False)	
Local TPM_RETURNCMD = $100
Local pm.POPUP_MENU=Object.POPUP_MENU(ppmenu)
Local hmenu=pm\root

If win=0 Then win=ActiveWindow()

; 2004_08_10 (gman) - if X,Y not passed, default to MouseX,MouseY
If nX=0 Then nX=MouseX()
If nY=0 Then nY=MouseY()

If lTray Then api_SetForegroundWindow(QueryObject(win,1)) ; 2004_08_17 (gman) - fix for tray menus per Q135788

Local menu_id=api_TrackPopupMenuEx(hmenu,TPM_RETURNCMD,nX,nY,QueryObject(win,1),0)

If lTray Then api_PostMessage(QueryObject(win,1),$0000,0,0) ; 2004_08_17 (gman) - fix for tray menus per Q135788

Return menu_id
End Function
; ================================
; Author: gman
; Date: 2004_08_10
; Title: FindPopupHandle
; Description:	- addon For the Advance PopupMenu by Ed From Mars (ID: 697)
;			- gets the popupmenu Handle based on menu_id
;
; Requirements: - stock Advance PopupMenu
; ================================
Function FindPopupHandle(menu_id%)
	Local pm_find.POPUP_MENU
	
	For pm_find=Each POPUP_MENU
		If pm_find\menu_id=menu_id
			Return Handle(pm_find)
		EndIf
	Next
	RuntimeError "Invalid menu_id passed to FindPopupHandle !"
End Function

; ================================
; Author: gman
; Date: 2004_08_10
; Title: GetPopupMenuText
; Description:	- addon For the Advance PopupMenu by Ed From Mars (ID: 697)
;			- gets the text of a popupmenu based on its menu_id
;
; Requirements: - stock Advance PopupMenu
;			- FindPopupHandle by gman
; ================================
Function GetPopupMenuText$(menu_id%)
	; get the popup based on menu_id.  will fail during find if menu_id doesnt exist.
	Local pm.POPUP_MENU=Object.POPUP_MENU(FindPopupHandle(menu_id))
	
	If pm\parent=Null Then RuntimeError "GetPopupMenuText does not work with popupmenu root !"
		
	Return pm\txt$
End Function

; ================================
; Author: gman
; Date: 2004_08_10
; Title: SetPopupDataItem
; Description: 	- addon for the Advance PopupMenu by Ed From Mars (ID: 697)
;			- sets a value in the mndata$ field
;
; Requirements: - Advance PopupMenu, modified to have a mndata$ field in the POPUP_MENU type
;			- gettok function by skn3[ac] (ID: 290)
;			- GetPopupDataItem function by gman
; ================================
Function SetPopupDataItem(item$,value$,ppmenu)

	Local pm.POPUP_MENU=Object.POPUP_MENU(ppmenu)
	If (Handle(pm)<=0) Then RuntimeError "Invalid handle passed to SetPopupDataItem !"

	item$=Upper(item$)

	If (item$="") Then RuntimeError "Empty item passed to SetPopupDataItem !"

	Local curval$=GetPopupDataItem(item$,ppmenu)

	If (Instr(pm\mndata$,"|"+item$+"=")=0)
		pm\mndata$=pm\mndata$+"|"+item$+"="+value$
	Else
		pm\mndata$=Replace(pm\mndata$,"|"+item$+"="+curval$,"|"+item$+"="+value$)
	EndIf 

End Function

; ================================
; Author: gman
; Date: 2004_08_10
; Title: GetPopupDataItem
; Description: 	- addon for the Advance PopupMenu by Ed From Mars (ID: 697)
;			- gets a value from the mndata$ field
;
; Requirements: - Advance PopupMenu, modified to have a mndata$ field in the POPUP_MENU type
;			- gettok function by skn3[ac] (ID: 290)
; ================================
Function GetPopupDataItem$(item$,ppmenu)
	Local pm.POPUP_MENU=Object.POPUP_MENU(ppmenu)
	If (Handle(pm)<=0) Then RuntimeError "Invalid handle passed to GetPopupDataItem !"

	item$=Upper(item$)

	If (item$="") Then RuntimeError "Empty item passed to GetPopupDataItem !"

	Local nCnt=0
	Local temp$=""
	
	Repeat 
		nCnt=nCnt+1
		temp$=gettok(pm\mndata$,nCnt,"|")
		If gettok(temp$,1,"=")=item$ Then Return gettok(temp$,2,"=")
	Until (temp$="")

	Return ""
End Function

; ================================
; Author: gman
; Date: 2004_11_12
; Title: ClearMenu
; Description: 	- addon for the Advance PopupMenu by Ed From Mars (ID: 697)
;				- clears out the POPUP_MENU list
;				- this is a must if you are building dynamic menus that rebuild each time
;
; Requirements: - Advance PopupMenu
; ================================
Function ClearMenu()
	Delete Each POPUP_MENU
End Function

Comments

gman2004
changes for SetPopupDataItem:

- fixed replace not storing back to mndata$
- changed to better handle setting an existing value to empty


gman2004
changes for ShowPopupMenu:

- changed to take a new lTray parameter and added corrosponding tray popup code. this is False by default, make True if using the popup from a tray icon. this is a fix as detailed in MSKB Q135788.


gman2004
- added ClearMenu(). if you dynamically add menu items potentially each time the menu is shown , this is a must. call it after you process the current menu event.


Code Archives Forum