现在的位置: 首页 > 综合 > 正文

Windows Mobile 5.0 and Pocket PC menus (zhuan)

2013年02月07日 ⁄ 综合 ⁄ 共 5447字 ⁄ 字号 评论关闭

Q. What does eating in an restaurant in Italy have in common with writing an application for Windows Mobile 5.0?

 

A. Confusion over menus.

 

Well,
perhaps this problem is unique to me, but every time I start writing
native application for Windows Mobile 5.0, it seems like I’ve forgotten
everything about menus. So I have to work it all out from scratch all
over again. So this time, I vowed to write it down as a blog entry so
that I don’t lose it. And, you never know, it might help someone else
working on creating Windows Mobile applications.

 

Windows
Mobile 5.0 includes a big change to menus. Pocket PC developers now
have the ability to make use of Smartphone-style menus: consisting of
only two menus at the bottom of the screen, optionally linked to
hardware buttons (optionally in that your hardware may or may not have
buttons – you can always tap the screen). Pressing the buttons pops
open a traditional menu.

 

As far as I’m concern, this new Windows Mobile 5.0 approach has two big bonuses:

 

  1. You can use the same code in both Pocket PC and Smartphone applications.
  2. The two-button user interface makes more sense on a hand held device (IMHO), and can be used with hardware buttons.

So,
let’s take a look at how you can add some menus to your Windows Mobile
5.0 application. I’m going to assume that you’ve created a new Windows
Mobile 5.0 C++ native Windows application, and not yet touched the
menus.

 

It’s not a menu…

 

It’s
a toolbar. That’s the first thing you need to know. The two menu
buttons at the bottom of the screen aren’t menus, they are part of a
toolbar. In effect, they are buttons, and creating them requires the
use of toolbar APIs. In practice that means using SendMessage() to
communicate with the toolbar and make changes.

 

Once
you create a new project, you will see the menu resource in your
solution. You can edit this resource using the graphical editor, add
options, and change the element ID names and so on. By default, the
menus are called OK (and this one will close the application) and Help
(and this one will bring up the About box).

 

You will find the resource data for this menu structure in two separate places: the rc and rc2 files.

 

In
the rc file associated with your project, you will find the definition
of the menu that pops-up when you select a menu. It is, indeed, a popup
menu. This code is created by the Visual Studio IDE when you edit the
menu using the GUI. So if you add any extra menu items, this is where
they will appear. You probably won’t have to edit this code manually,
but here’s an example so you can see what it looks like:

 

IDR_MENU MENU

BEGIN

    POPUP "Menu 1"

    BEGIN

        MENUITEM "About",                       IDM_HELP_ABOUT

        MENUITEM "Option that is Checked",      ID_MENU_CHECK, CHECKED

        MENUITEM "Option to be Renamed",        ID_MENU_RENAME

        MENUITEM "Some other option",           ID_MENU1_SOMEOTHEROPTION

    END

END

 

As
you can see, I’ve added three more options (in the GUI editor). One I’m
going to check and uncheck, one I’m going to rename, and one for good
measure.

 

Now,
the other important stuff is stored in the rc2 file, as here you will
find the definition of the toolbar. The important part is the NOMENU
flag, which causes the toolbar button act as a button, rather than open
a pop-up menu. In this example, the first button is just an OK button,
but the second brings up a menu (IDR_MENU).

 

IDR_MENU RCDATA

BEGIN

    IDR_MENU,

    2,

 

    I_IMAGENONE, IDM_OK, TBSTATE_ENABLED, TBSTYLE_BUTTON | TBSTYLE_AUTOSIZE,

    IDS_OK, 0, NOMENU,

   

      I_IMAGENONE, IDM_HELP, TBSTATE_ENABLED, TBSTYLE_DROPDOWN | TBSTYLE_AUTOSIZE,

    IDS_HELP, 0, 0,

END

 

As
you can see, I’ve been too lazy to rename the menu from IDM_HELP. Watch
for that, as we’ll use it when we want to change the menu elements.

 

 

Creating the menu

 

The default project will have created code that creates this new menu structure, and it will look something like this:

 

SHMENUBARINFO mbi;

 

memset(&mbi, 0, sizeof(SHMENUBARINFO));

mbi.cbSize     = sizeof(SHMENUBARINFO);

mbi.hwndParent = hWnd;

mbi.nToolBarId = IDR_MENU;

mbi.hInstRes   = g_hInst;

 

if (!SHCreateMenuBar(&mbi))

{

g_hWndMenuBar = NULL;

}

else

{

g_hWndMenuBar = mbi.hwndMB;

}

 

 

 

Changing the name of a menu

 

Here
is how to change the name of a menu – this changes the actual text that
appears at the bottom of the screen. This code changes the menu to be
called “Renamed”. Because we’re dealing with a toolbar, we don’t use
any menu APIs, we use a SendMessage() with the correct TB_ flag.

 

// Change title of menu

memset(&tbbi,0,sizeof(tbbi));

tbbi.cbSize = sizeof(tbbi);

tbbi.dwMask = TBIF_TEXT;

tbbi.pszText = L"Renamed";

SendMessage(SHFindMenuBar(hWnd),TB_SETBUTTONINFO,IDM_HELP,(LPARAM)&tbbi);

DrawMenuBar(g_hWndMenuBar);

 

 

Checking a menu option

 

Here
is how to add a check mark to a menu element. This time we are dealing
with a menu (a pop-up menu), but we need to get a handle to the menu
before we can do anything. To get the handle, we have to use
SendMessage() with a special SHCMDM_GETSUBMENU flag. Once we get the
handle, we can use CheckMenuItem(). This code uses a bool called
menu_state for demonstration purposes.

 

 

hMenuMB = (HWND)SHFindMenuBar(hWnd);

hMenu = (HMENU) SendMessage(hMenuMB, SHCMBM_GETSUBMENU,0,IDM_HELP);

if (menu_state)

CheckMenuItem(hMenu,ID_MENU_CHECK,MF_BYCOMMAND|MF_CHECKED);

else

CheckMenuItem(hMenu,ID_MENU_CHECK,MF_BYCOMMAND|MF_UNCHECKED);

 

 

 

 

Changing the text of a menu item

 

Here is how to change the text displayed by a menu item.  As
it turns out, there is no API to modify a menu name directly. Instead
you have to (gulp) delete the menu item, and then insert a replacement.

 

In this example, I rename the text in the menu item that is at position 2 in the menu. The menu ID is “ID_MENU_RENAME”. Obviously you will need to change the position and ID for your particular menu.

 

// Rename a menu item (by deleting it and recreating it)

hMenuMB = (HWND)SHFindMenuBar(hWnd);

hMenu = (HMENU) SendMessage(hMenuMB, SHCMBM_GETSUBMENU,0,IDM_HELP);

DeleteMenu(hMenu,2,MF_BYPOSITION);

InsertMenu(hMenu,2,MF_BYPOSITION, ID_MENU_RENAME,L"Changed!");         

 

Menu Design

 

Remember
also that the two button menu design brings with it a new philosophy.
The left button is supposed to perform an action – for example, OK, to
close a window. The right button is supposed to list the options. Try
to stick to these design guidelines to avoid confusing you users.

 

The End

 

Well, I hope you found that useful. I know I did J

抱歉!评论已关闭.