Page 1 of 1

Option check marks in menus (For Windows)

Posted: Mon Dec 22, 2008 2:19 am
by Arctic Fox
This example shows how to have option check marks next to menu items using a Windows API function.
Perhaps it is of interest to some of you.

Code: Select all

; -- HOW TO USE IT --
; CheckMenuRadioItem_(hSubMenu, itemFirst, itemLast, itemCheck, flags)
; hSubMenu  = the unique ID of the menutitle - use GetSubMenu_(hMenu, nPos) to get it. Notice that nPos is 0-indexed.
; itemFirst = 0-indexed position of the first item in the option range.
; itemLast  = 0-indexed position of the last item in the option range.
; itemCheck = 0-indexed position of the item which will have an option check mark.
; flags     = #MF_BYPOSITION if you want to use item positions as above.
; -------------------

OpenWindow(0, 100, 150, 250, 150, "Option Check Mark Test")

If CreateMenu(0, WindowID(0))
MenuTitle("MenuTitle")
MenuItem(1, "First")
MenuItem(2, "Second")
MenuItem(3, "Third")
MenuItem(4, "Fourth")

MenuTitle("Another title")
MenuItem(5, "First")
MenuItem(6, "Second")
MenuItem(7, "Third")
MenuItem(8, "Fourth")
MenuItem(9, "Fifth")
MenuItem(10, "Sixth")
EndIf

; Sets some option check marks
CheckMenuRadioItem_(GetSubMenu_(MenuID(0), 0), 0, 3, 1, #MF_BYPOSITION)
CheckMenuRadioItem_(GetSubMenu_(MenuID(0), 1), 0, 2, 2, #MF_BYPOSITION)
CheckMenuRadioItem_(GetSubMenu_(MenuID(0), 1), 3, 5, 5, #MF_BYPOSITION)

; Sets a standard check mark to make a comparison with the option check marks when using GetMenuItemState()
SetMenuItemState(0, 5, 1)

Repeat
Event = WaitWindowEvent()

If Event = #PB_Event_Menu
; The option check mark acts like the standard check mark when using GetMenuItemState()
MessageRequester("", "The checked state of the selected item:" + Chr(13) + Str(GetMenuItemState(0, EventMenu())))
EndIf

Until Event = #PB_Event_CloseWindow
End

Posted: Mon Dec 22, 2008 3:31 am
by akj
Thank you Artic fox. I've found an immediate use for this and it works well.

Posted: Mon Dec 22, 2008 3:34 am
by Arctic Fox
I am pleased to hear that :D

Posted: Sun May 10, 2009 1:50 am
by Arctic Fox
Almost a half year later I realize that you can use the internal menuitem numbers (those from MenuItem()) with the API function and the #MF_BYCOMMAND flag :lol:
Well, here's an update with an OptionCheckMenuItem()-procedure 8)

Updated with an OptionCheckPopupMenuItem()-procedure for popup menus :o

Code: Select all

Procedure OptionCheckMenuItem(MenuNumber, MenuTitleNumber, FirstItem, LastItem, CheckItem)
; MenuNumber          = #Menu - not the system handle from MenuID()
; MenuTitleNumber     = zero-indexed number of the menutitle as in GetMenuTitleText()
; FirstItem           = first item in the option range - PureBasic MenuItemID from e.g. MenuItem() and EventMenu()
; LastItem            = last item in the option range
; CheckItem           = item to check
ProcedureReturn CheckMenuRadioItem_(GetSubMenu_(MenuID(MenuNumber), MenuTitleNumber), FirstItem, LastItem, CheckItem, #MF_BYCOMMAND)
EndProcedure

Procedure OptionCheckPopupMenuItem(MenuNumber, FirstItem, LastItem, CheckItem)
; Same as above except that a popup menu hasn't got menu titles, of course :)
ProcedureReturn CheckMenuRadioItem_(MenuID(MenuNumber), FirstItem, LastItem, CheckItem, #MF_BYCOMMAND)
EndProcedure

OpenWindow(0, 100, 150, 250, 150, "OptionCheck Menu Test")

If CreateMenu(0, WindowID(0))
MenuTitle("Menu title")
MenuItem(1, "First")
MenuItem(2, "Second")
MenuItem(3, "Third")
MenuItem(4, "Fourth")

MenuTitle("Another title")
MenuItem(5, "First")
MenuItem(6, "Second")
MenuItem(7, "Third")
MenuBar()
OpenSubMenu("Sub menu")
MenuItem(8, "Fourth")
MenuItem(9, "Fifth")
MenuItem(10, "Sixth")
CloseSubMenu()
MenuBar()
MenuItem(11, "Seventh")
MenuItem(12, "Eighth")
EndIf

If CreatePopupMenu(1)
MenuItem(13, "First")
MenuItem(14, "Second")
MenuItem(15, "Third")
MenuItem(16, "Fourth")
MenuItem(17, "Fifth")
EndIf

; Sets option check marks using the OptionCheckMenuItem()-procedure
OptionCheckMenuItem(0, 0, 1, 4, 2)      ; range: 1 to 4    check: 2
OptionCheckMenuItem(0, 1, 5, 7, 7)      ; range: 5 to 7    check: 7
OptionCheckMenuItem(0, 1, 8, 10, 9)     ; range: 8 to 10   check: 9
OptionCheckMenuItem(0, 1, 11, 12, 11)   ; range: 11 to 12  check: 11

; Sets option check marks in the popup menu using the OptionCheckPopupMenuItem()-procedure
OptionCheckPopupMenuItem(1, 13, 14, 13) ; range: 13 to 14  check: 13
OptionCheckPopupMenuItem(1, 15, 17, 16) ; range: 15 to 17  check: 16

; Sets a standard check mark to make a comparison with the option check marks when using GetMenuItemState()
SetMenuItemState(0, 5, 1)

Repeat
Event = WaitWindowEvent()

If Event = #PB_Event_Menu
; The option check mark acts like the standard check mark when using GetMenuItemState()
EventMenu = EventMenu()

If EventMenu < 13
MessageRequester("Selected item: " + Str(EventMenu), "State of selected item: " + Str(GetMenuItemState(0, EventMenu)))
Else
MessageRequester("Selected item: " + Str(EventMenu), "State of selected item: " + Str(GetMenuItemState(1, EventMenu)))
EndIf
EndIf

; Displays the popup menu when right-clicking in the window
If Event = #WM_RBUTTONDOWN : DisplayPopupMenu(1, WindowID(0)) : EndIf

Until Event = #PB_Event_CloseWindow
End

Posted: Sun May 10, 2009 1:56 am
by rsts
Very nice :)

Don't know how I missed this the first time.

Thanks

Posted: Sun May 10, 2009 2:06 am
by Arctic Fox
Thanks a lot rsts!
Forgot to mention that it also works with sub menus and menubars (no need to count menubars as items as in my first post) :D

Posted: Sun May 10, 2009 12:41 pm
by c4s
This code - included in my project - doesn't want to work...
I just get the standard checkmark where the round option checkmark should
be instead.

Posted: Sun May 10, 2009 2:45 pm
by Arctic Fox
Do you have an extract from your project which shows it?

Posted: Mon May 25, 2009 9:40 pm
by Arctic Fox
Updated the example with support for popup menus :D
c4s wrote:This code - included in my project - doesn't want to work...
I just get the standard checkmark where the round option checkmark should
be instead.
This happens if you're using ownerdrawn menus which do not support option/radio check marks (among them the Office-menu example in The Code Archive and http://www.purebasic.fr/english/viewtop ... 188#196188, they use the standard check mark :cry:)

Posted: Tue May 26, 2009 11:11 am
by c4s
@Arctic Fox
Sorry, I forgot to answer you.
The problem was, that it's a submenu. With GetSubMenu_() everything is
fine. ;)

Posted: Tue May 26, 2009 2:13 pm
by Arctic Fox
So it works now? That's great :D

Posted: Tue May 26, 2009 3:38 pm
by Andesdaf
thanks a lot :D