Geeks With Blogs
Prabhu Kumar a tech twaddler..
Ok now that we have our basic application up and running, lets make some changes. First, I want to change the right soft key from "HELP" to "Menu", somehow "HELP" is not very appealing. One more thing, I use the resource editor only to add new resources to the project, any further changes or modification I like to do it by manually editing the resource files (To do that, just right click on the .rc file and select "View Code").


If you open HelloWorld.cpp and in function WndProc go to the case where WM_CREATE is handled, you will see that the menu bar is getting created there using the SHCreateMenuBar api. The nToolBarId member of SHMENUBARINFO contains IDR_MENU, which is the resource identifier of the menu bar. Now open HelloWorldppc.rc2 and you will see that the menu bar is defined as below:


IDR_MENU SHMENUBAR DISCARDABLE
BEGIN
    IDR_MENU_POPUP,
    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

The first line says that IDR_MENU is a menubar. Everything in between BEGIN and END defines the menu bar. The first line under BEGIN identifies the popup menu which will be displayed when the user clicks on the MENU. If your MENUBAR does not have any popup menu's, then you can specify a value of 0 here. In this case, the popup menu that will be displayed here, when the user clicks on "Menu" is IDR_MENU_POPUP, which we will define later. "2" specifies that the menu bar will have two entries, one left soft key and one right soft key. The first entry after "2" defines the left soft key and the next entry defines the right softkey. You can see that the left entry is for "OK" and the right entry is for "HELP". We will not change the first entry. Lets modify the second entry so that it defines our new entry, which is "Menu". So we change


    I_IMAGENONE, IDM_HELP, TBSTATE_ENABLED, TBSTYLE_DROPDOWN | TBSTYLE_AUTOSIZE, IDS_HELP, 0, 0,

to


       I_IMAGENONE, IDM_MENU, TBSTATE_ENABLED, TBSTYLE_DROPDOWN | TBSTYLE_AUTOSIZE, IDS_MENU, 0, 0,

This change is not absolutely necessary but I like to name my variables just right.


Now open resourceppc.h and make the same changes. Rename IDS_HELP to IDS_MENU and IDM_HELP to IDM_MENU. A few more changes and we are done. Open HelloWorld.rc and search for the string table that defines the value for IDS_HELP. Will be something like:


STRINGTABLE 
BEGIN
   .
   .
   IDS_HELP    "HELP"
END

Change this to:

STRINGTABLE 
BEGIN
   .
   .
   IDS_MENU    "Menu"
END


The items under the popup menu will be defined in HelloWorld.rc file. Although you can define it .rc2 file as well, but by default it will be present in the .rc file.


IDR_MENU_POPUP MENU DISCARDABLE
BEGIN
    POPUP "Help"
    BEGIN
        MENUITEM "About",        IDM_HELP_ABOUT
    END
END

This defines our original right soft key menu which is a popup. Change this entry so that "Menu" shows up instead of "HELP":


IDR_MENU_POPUP MENU DISCARDABLE
BEGIN
    POPUP "Menu"
    BEGIN
        MENUITEM "About",        IDM_HELP_ABOUT
    END
END

Thats it. The right soft key should now be renamed to "Menu". You might think that this is a lot of work just to rename a menu entry. But its not much. The changes in the .rc2 file were just for the sake of naming convention and you can leave that part if you wish but make sure that all your ID*_ macros are in sync.


Build the project and run. The application should now look like this:




Lets quickly add one more entry under Menu called "System Metric", which will show the screen width and height in a message box. Adding a menu entry is simple. Open HelloWorld.rc file where the popup items for the right menu are defined. They will be defined like this:


IDR_MENU_POPUP MENU DISCARDABLE
BEGIN
    POPUP "Menu"
    BEGIN
       MENUITEM "About",            IDM_HELP_ABOUT
    END
END

Just add another MENUITEM entry for "System Metric":


IDR_MENU_POPUP MENU DISCARDABLE
BEGIN
    POPUP "Menu"
    BEGIN
        MENUITEM "System Metric",    IDM_SYSTEM_METRIC
        MENUITEM "About",            IDM_HELP_ABOUT
    END
END

IDM_SYSTEM_METRIC is the command (or simply a number) that will be sent to our application when the user selects it. So you need to define this in the resourceppc.h header file so that the compiler can find it. You can add a menu separator by adding MENUITEM SEPARATOR as one of the items in the menu.


Add  "#define IDM_SYSTEM_METRIC 40003" to resourceppc.h. I chose 40003 because that number wasn't yet used in my header file. The number doesn't matter, just make sure that the number you use is unique and is not used already in this or some other header file. In large projects with many resources this could get messy, manually keeping track of numbers. When creating resources using the resource editor these entries are automatically created and unique.


Now we need to handle this menu item. That is, what happens when the user clicks on it. When the user selects the menu item, a WM_COMMAND will be sent to our application. This will end up in WndProc function. The LPARAM and WPARAM parameters will contain more information about which item in our application caused the WM_COMMAND message to be sent. In the WndProc function go the section which is handling WM_COMMAND. Under WM_COMMAND handling you will see that other messages like IDM_HELP_ABOUT and ID_OK are already being handled. This is where we need to add the entry for our IDM_SYSTEM_METRIC. Create the following entry just after the IDM_OK case:


case IDM_SYSTEM_METRIC:
{
    int width = -1, height = -1;
    WCHAR wOutStr[64] = L"";
    WCHAR wCaption[16] = L"";

    width =  GetSystemMetrics(SM_CXSCREEN);
    height = GetSystemMetrics(SM_CYSCREEN);

    if(!width || !height)
    {
        wsprintf(wOutStr, L"Failed to get system metrics.");
        wsprintf(wCaption, L"Error");
    }
    else
    {
        wsprintf(wOutStr, L"System width :%d\nSystem Height:%d", width, height);
        wsprintf(wCaption, L"Info");
    }

    MessageBox(hWnd, wOutStr, wCaption, MB_OK);

}
break;

In the message handling I use the GetSystemMetrics api to get the system width and system height values. If the api's return error (zero) I contruct an error string otherwise I construct a string with the values I got and then show the string using a MessageBox. Simple.


This is how the UI looks:



and,




Part 1
Part 3

Posted on Thursday, April 16, 2009 12:11 AM Applications | Back to top


Comments on this post: Applications: Creating a simple UI application for Windows Mobile 6 using Visual Studio 2005: Part 2

# re: Applications: Creating a simple UI application for Windows Mobile 6 using Visual Studio 2005: Part 2
Requesting Gravatar...
Hi there ;)

I'm trying to get into WinMob programming for couple of last days (started with SIP, got problems, so decided to create some standard app before SIP), so I google a lot and also found your blog.

I have a question about SHMENUBAR (RCDATA) structure. I have spent some time on analyzing it, as I tried to play with some menus (tried to get menu on left button instead of right button as it is in examples - no problems; tried to get menus on *both* buttons instead of just one - well, that's something I couldn't do with resources), and I found a conflict between what you're saying and what I have found.

You say: "The first line says that IDR_MENU is a menubar. Everything in between BEGIN and END defines the menu bar. The first line under BEGIN should be the same as the menu bar identifier."

I agree that first line is an ID of menubar, but I don't think that first line under 'BEGIN' should be the same. Those are completely different things - first one is ID of menubar (the one with 2 soft keys), the other one is ID of popup menu that pops up when user presses one of soft keys. In your example you have the same ID for both menubar and popup menu, so it works, but I think that different things should be named differently, shouldn't they? ;) You could even leave the line below 'BEGIN' empty (i.e., 0) if you have only buttons with no menus.

What do you think?
Left by binary on Jul 05, 2009 9:27 AM

# re: Applications: Creating a simple UI application for Windows Mobile 6 using Visual Studio 2005: Part 2
Requesting Gravatar...
In my previous comment I wrote that I couldn't find a way to get menus on both soft keys - well, I found a sollution couple of minutes after posting that comment... while washing food :)

Instead of RCDATA, just a MENU is needed with two POPUP structures in it (one for left soft key, one for right key), and SHMENUBARINFO structure needs dwFlags to be set to SHCMBF_HMENU before passing it to SHCreateMenuBar().
Left by binary on Jul 05, 2009 10:22 AM

# re: Applications: Creating a simple UI application for Windows Mobile 6 using Visual Studio 2005: Part 2
Requesting Gravatar...
Hi,

Well, yes. I was wrong in saying that "the first line under BEGIN should be the same as the Menu bar identifier". It could be the same, I have updated my post to reflect the changes. Thanks for noticing that (: And I was just experimenting with getting popup menus on both left and right soft key when I got your second reply (:

Prabhu
Left by Prabhu on Jul 05, 2009 11:08 AM

# re: Applications: Creating a simple UI application for Windows Mobile 6 using Visual Studio 2005: Part 2
Requesting Gravatar...
Hi,

I am developing an app using win32 dev environment for wmobile phones.
I wondering about using resource manager in win32.Can't i keep .rc and .h files independent of executable.

The resource string added are always treated as embedded resources.I want to maintain these resource file independent of executable so that i can load it as required.

I am implementing Localization with around 1000 string resources.
Left by swapnil on Jul 20, 2009 12:49 PM

# re: Applications: Creating a simple UI application for Windows Mobile 6 using Visual Studio 2005: Part 2
Requesting Gravatar...
You might want to consider using Multilingual User Interface (MUI) DLL's to store all your localized resources. Take a look at http://msdn.microsoft.com/en-us/library/ms904030.aspx for more information.

I haven't worked on localization before, can't help you much there.
Left by Prabhu on Jul 21, 2009 11:09 AM

# re: Applications: Creating a simple UI application for Windows Mobile 6 using Visual Studio 2005: Part 2
Requesting Gravatar...
how to deploy it to my device ?
Left by Rc on Oct 18, 2011 8:34 AM

# re: Applications: Creating a simple UI application for Windows Mobile 6 using Visual Studio 2005: Part 2
Requesting Gravatar...
To deploy it to your device, first connect your windows mobile device to your PC using Active Sync and then from Visual Studio select "Windows Mobile 6.5 Device" instead of the emulator. This option is usually present below the menu bar towards the center of the screen in Visual Studio.
Left by Techtwaddle on Oct 25, 2011 8:23 PM

Your comment:
 (will show your gravatar)


Copyright © TechTwaddle | Powered by: GeeksWithBlogs.net