Applications: Creating a simple UI application for Windows Mobile 6 using Visual Studio 2005: Part 3

So now our program displays the system width and height in a Message box. Let us see how this message box evolves into a Dialog box.

 

Instead of displaying the system metrics in a Message box, we will display the same information in a full screen dialog box. The dialog box will have a menu bar, with the left soft key as "Back" and the right soft key as "Refresh". We’ll see what "Refresh" will do later.



First lets add the dialog box resource to our project. You can add a new dialog using the resource editor. Go to Resource view, right click on Dialog and "Add Resource..", from the list select POCKETPC_PORTRAIT dialog. This will add a new dialog resource to the project. Rename the dialog id to IDD_DIALOG_SYSMETRIC and change the title to "System Metric". Now add four static texts to the dialog. 2 containing the text "System Width:" and "System Height:" and the other two will contain the actual numbers.  Lets name the controls which will contain the width and height as IDC_STATIC_SYSWIDTH and IDS_STATIC_SYSHEIGHT. The dialog will now look like:

Lets create the menu bar for our new dialog. Add the following piece of code to HelloWorldppc.rc2:


IDR_MENU_SYSMETRIC SHMENUBAR DISCARDABLE

BEGIN

    IDR_MENU_SYSMETRIC,

    2,



    I_IMAGENONE, IDM_BACK, TBSTATE_ENABLED, TBSTYLE_BUTTON | TBSTYLE_AUTOSIZE,

    IDS_BACK, 0, NOMENU,

   

    I_IMAGENONE, IDM_REFRESH, TBSTATE_ENABLED, TBSTYLE_BUTTON | TBSTYLE_AUTOSIZE,

    IDS_REFRESH, 0, NOMENU,

END

This defines the new menu bar, IDR_MENU_SYSMETRIC, for an explanation of the above see my previous post "Applications: Creating a simple UI application for Windows Mobile 6 using Visual Studio 2005: Part 2"



This menu bar does not have any popup menu. You can see that both the entries are TBSTYLE_BUTTON and NOMENU.



Now you need to #define the entries for IDR_MENU_SYSMETRIC, IDM_BACK, IDS_BACK, IDM_REFRESH, IDS_REFRESH in resourceppc.h. Make sure that the numbers you assign to these macros are unique.



The dialog and the menu bar are ready, now we just need to call DialogBox in our main code. So, in HelloWorld.cpp, replace the call to MessageBox under IDM_SYSTEM_METRIC with:



DialogBox(g_hInst, MAKEINTRESOURCE(IDD_DIALOG_SYSMETRIC), hWnd, SysMetricDlgProc);



The first parameter contains the instance handle of the module which contains the resource template of the dialog. The MAKEINTRESOURCE macro converts the number IDD_DIALOG_SYSMETRIC to a resource type, required by DialogBox. Third parameter specifies the parent window of the Dialog box. And the last parameter is the callback function which will handle the messages of our dialog.



Also, forward declare the callback function as follows:



BOOL CALLBACK SysMetricDlgProc(HWND, UINT, WPARAM, LPARAM);





Here is the code for the Dilaog proc, SysMetricDlgProc

BOOL CALLBACK SysMetricDlgProc(HWND hDlg, UINT uMessage, WPARAM wParam, LPARAM lParam)

{

    int wmId, wmEvent;



    switch (uMessage)

    {

        case WM_INITDIALOG:

            {

                // Create a Done button and size it. 

                SHINITDLGINFO shidi;

                SHMENUBARINFO mbi;



                shidi.dwMask = SHIDIM_FLAGS;

                shidi.dwFlags = SHIDIF_DONEBUTTON | SHIDIF_SIPDOWN | SHIDIF_SIZEDLGFULLSCREEN | SHIDIF_EMPTYMENU;

                shidi.hDlg = hDlg;

                SHInitDialog(&shidi);





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

                mbi.cbSize     = sizeof(SHMENUBARINFO);

                mbi.hwndParent = hDlg;

                mbi.nToolBarId = IDR_MENU_SYSMETRIC;

                mbi.hInstRes   = g_hInst;



                if (!SHCreateMenuBar(&mbi))

                {

                    printf("SHCreateMenuBar failed err code:%d\n", GetLastError());

                }

                else

                {

                }



                UpdateSystemMetric(hDlg);

            }

            return TRUE;



        case WM_COMMAND:

            wmId = LOWORD(wParam);

            wmEvent = HIWORD(wParam);



            switch(wmId)

            {

                case IDOK:

                    EndDialog(hDlg, uMessage);

                    return TRUE;



                case IDM_REFRESH:

                    //MessageBox(NULL, L"Pressed refresh",L"Info", MB_OK);

                    UpdateSystemMetric(hDlg);

                    return TRUE;



                case IDM_BACK:

                    EndDialog(hDlg, uMessage);

                    return TRUE;

            }

            break;



        case WM_CLOSE:

            EndDialog(hDlg, uMessage);

            return TRUE;



    }



    return FALSE;

}





In WM_INITDIALOG, we initialise the dialog as full screen and also add the menu bar. The UpdateSystemMetric() function updates the dialog with the system width and system height.


BOOL UpdateSystemMetric(HWND hDlg)

{

    int width = -1, height = -1;



    width =  GetSystemMetrics(SM_CXSCREEN);

    height = GetSystemMetrics(SM_CYSCREEN);



    SetDlgItemInt(hDlg, IDC_STATIC_SYSWIDTH, width, FALSE);

    SetDlgItemInt(hDlg, IDC_STATIC_SYSHEIGHT, height, FALSE);



    return TRUE;

}

UpdateSystemMetric() function uses the same api to get the screen width and height. And it uses SetDlgItemInt() api to set the contents of IDC_STATIC_SYSWIDTH static control to width, and the same for height.





Now we handle IDM_BACK and IDM_REFRESH under WM_COMMAND. IDM_BACK simply ends the dialog and returns to the main screen, IDM_REFRESH, re-calculates the width and height and updates the values in the UI.





Now when we select the "System Metric" menu item, the dialog box will show up as below:





and when we switch the emulator to landscape mode and hit "Refresh", the values are updated in the UI.

Part 1
Part 2

Leave a Reply

Your email address will not be published. Required fields are marked *