[Win] Set/GetMenuItemTextEx()

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Benutzeravatar
HeX0R
Beiträge: 3042
Registriert: 10.09.2004 09:59
Computerausstattung: AMD Ryzen 7 5800X
96Gig Ram
NVIDIA GEFORCE RTX 3060TI/8Gig
Win11 64Bit
G19 Tastatur
2x 24" + 1x27" Monitore
Glorious O Wireless Maus
PB 3.x-PB 6.x
Oculus Quest 2 + 3
Kontaktdaten:

[Win] Set/GetMenuItemTextEx()

Beitrag von HeX0R »

Da es leider immernoch keine Möglichkeit gibt, die Texte eines Submenüs nachträglich zu ändern,
kommt hier, bis es soweit ist, Abhilfe.

Bei Imagemenüs war es ein wenig knifflig, und ich weiss nicht,
ob ich das so mit dem LocalReAlloc_() einfach so machen kann/darf,
aber es funktioniert.

Der Index wird einfach immer, unabhängig von der ID, von 0 von oben nach unten gezählt.

Code: Alles auswählen

Procedure.s GetMenuItemTextEx(Menu, Item)
	Protected menufile, minfo.MENUITEMINFO, a$

	If IsMenu_(MenuID(Menu))
		menufile = GetSubMenu_(MenuID(Menu), 0)
		If Item < GetMenuItemCount_(menufile)
			minfo\cbSize     = SizeOf(MENUITEMINFO)
			minfo\fmask      = #MIIM_TYPE | #MIIM_DATA
			GetMenuItemInfo_(menufile, Item, #True, @minfo)
			If minfo\fType = 0
				;Normal Menu
				a$ = Space(256)
				GetMenuString_(menufile, Item, @a$, 256, #MF_BYPOSITION)
			ElseIf minfo\fType = #MFT_OWNERDRAW
				;Image menu
				If minfo\dwItemData
					a$ = PeekS(PeekI(minfo\dwItemData))
				EndIf
			EndIf
		EndIf
	EndIf

	ProcedureReturn a$
EndProcedure

Procedure SetMenuItemTextEx(Menu, Item, Text.s)
	Protected menufile, minfo.MENUITEMINFO, *mem

	If IsMenu_(MenuID(Menu))
		menufile = GetSubMenu_(MenuID(Menu), 0)
		If Item < GetMenuItemCount_(menufile)
			minfo\cbSize     = SizeOf(MENUITEMINFO)
			minfo\fmask      = #MIIM_TYPE | #MIIM_DATA
			GetMenuItemInfo_(menufile, Item, #True, @minfo)
			If minfo\fType = 0
				;Normal Menu
				minfo\fmask      = #MIIM_STRING
				minfo\fType      = #MFT_STRING
				minfo\dwTypeData = @Text
				SetMenuItemInfo_(menufile, Item, #True, @minfo)
			ElseIf minfo\fType = #MFT_OWNERDRAW
				;Image menu
				If minfo\dwItemData
					*mem = PeekI(minfo\dwItemData)
					If LocalSize_(*mem) < StringByteLength(Text) + SizeOf(CHARACTER)
						*mem = LocalReAlloc_(*mem, StringByteLength(Text) + SizeOf(CHARACTER), #LMEM_MOVEABLE)
						If *mem
							PokeI(minfo\dwItemData, *mem)
						EndIf
					EndIf
					If *mem
						PokeS(*mem, Text)
						SetMenuItemInfo_(menufile, Item, #True, @minfo)
					EndIf
				EndIf
			EndIf
		EndIf
	EndIf

EndProcedure
Ein Beispiel:

Code: Alles auswählen

OpenWindow(0, 400, 200, 200, 100, "Menu Example")
CreateImageMenu(0, WindowID(0))
MenuTitle("Project")
MenuItem(1, "Open")
MenuItem(2, "Save")
MenuItem(3, "Save as")
OpenSubMenu("Bla")
MenuItem(4, "Blubb")
CloseSubMenu()
MenuItem(5, "Close")

Debug GetMenuItemTextEx(0, 3)
SetMenuItemTextEx(0, 3, "Affenbrotbäume wachsen nicht aufm Dachboden")

Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow