Option check marks in menus (For Windows)

Share your advanced PureBasic knowledge/code with the community.
User avatar
Arctic Fox
Enthusiast
Enthusiast
Posts: 609
Joined: Sun Dec 21, 2008 5:02 pm
Location: Aarhus, Denmark

Option check marks in menus (For Windows)

Post 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
Last edited by Arctic Fox on Wed Dec 31, 2008 8:29 pm, edited 1 time in total.
akj
Enthusiast
Enthusiast
Posts: 668
Joined: Mon Jun 09, 2003 10:08 pm
Location: Nottingham

Post by akj »

Thank you Artic fox. I've found an immediate use for this and it works well.
Anthony Jordan
User avatar
Arctic Fox
Enthusiast
Enthusiast
Posts: 609
Joined: Sun Dec 21, 2008 5:02 pm
Location: Aarhus, Denmark

Post by Arctic Fox »

I am pleased to hear that :D
User avatar
Arctic Fox
Enthusiast
Enthusiast
Posts: 609
Joined: Sun Dec 21, 2008 5:02 pm
Location: Aarhus, Denmark

Post 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
Last edited by Arctic Fox on Mon May 25, 2009 9:30 pm, edited 1 time in total.
rsts
Addict
Addict
Posts: 2736
Joined: Wed Aug 24, 2005 8:39 am
Location: Southwest OH - USA

Post by rsts »

Very nice :)

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

Thanks
User avatar
Arctic Fox
Enthusiast
Enthusiast
Posts: 609
Joined: Sun Dec 21, 2008 5:02 pm
Location: Aarhus, Denmark

Post 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
c4s
Addict
Addict
Posts: 1981
Joined: Thu Nov 01, 2007 5:37 pm
Location: Germany

Post 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.
User avatar
Arctic Fox
Enthusiast
Enthusiast
Posts: 609
Joined: Sun Dec 21, 2008 5:02 pm
Location: Aarhus, Denmark

Post by Arctic Fox »

Do you have an extract from your project which shows it?
User avatar
Arctic Fox
Enthusiast
Enthusiast
Posts: 609
Joined: Sun Dec 21, 2008 5:02 pm
Location: Aarhus, Denmark

Post 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:)
c4s
Addict
Addict
Posts: 1981
Joined: Thu Nov 01, 2007 5:37 pm
Location: Germany

Post by c4s »

@Arctic Fox
Sorry, I forgot to answer you.
The problem was, that it's a submenu. With GetSubMenu_() everything is
fine. ;)
User avatar
Arctic Fox
Enthusiast
Enthusiast
Posts: 609
Joined: Sun Dec 21, 2008 5:02 pm
Location: Aarhus, Denmark

Post by Arctic Fox »

So it works now? That's great :D
Andesdaf
User
User
Posts: 83
Joined: Sun Mar 22, 2009 2:53 pm
Location: GER, Saxony

Post by Andesdaf »

thanks a lot :D
Post Reply