Wednesday, July 25, 2007

SHMENUBAR and MF_GRAYED

My WTL 8.0 experience with Windows Mobile development is going just great. The application wizard worked out correctly with only a very minor issue: the WTL include directory is not set up either for C++ compilation nor for resource compilation. As I said, this is a minor issue that you overcome quite easily.

While working for the new Microsoft Bluetooth device inquiry and service discovery (these seem to be the appropriate Bluetooth terms) I found out that Sergey Solozhentsev's WTL Helper tool works like a charm in Windows Mobile projects under VS 2005. All of the message handling functions for the main frame window were generated with this tool and it makes it very easy to write all the UI code - this tool just rocks.

Today I found out about something that does not seem to be documented anywhere: when using the SHMENUBAR resource, never specify a menu resource with a grayed (MF_GRAYED) menu item - the menu will not show up. The WTL code is very straight forward and uses the SHCreateMenuBar API, so this was not where the problem lied. After removing the grayed style from the resource editor the menu magically showed up! So is this a bug on the shell or on the compiler?

3 comments:

Pedro Lamas said...

I'm not in the mood to check the assembly code, so I'll just bet on a shell bug...

AR said...
This comment has been removed by the author.
Tim B. said...

Were you trying to gray the whole bar or disable an item? If the latter, or for those who are looking at how to do that, you need to:
1) Create a bitmap with your grayed or disabled look. Most image editing tools can convert a bitmap to grayscale or black and white. Obviously, do this to a copy because you need both bitmaps.
2) Add an imagelist and create it with or load the "disabled" bitmap from above.
3) In the RCDATA (.rc2 in VS2005) file set the button state of the button to 0 (vs. TBSTATE_ENABLED)
4) Use sendmessage to notify the toolbar part of the menubar of the disabled images to use:
SendMessage(m_hWndToolBar, TB_SETDISABLEDIMAGELIST, 0, (LPARAM) m_imgDisabled.m_hImageList);
..where m_hWndToolBar is just the HWND of the MenuBar (which you can get from the hwndMB member of the SHMENUBARINFO struct or by calling ::SHFindMenuBar(m_hWnd))

This is what I use to gray and disable a single or multiple menubar buttons....

Again, not sure if this is what you were trying to do but I know it took me a bit to figure out...

regards
tim