Applications: Creating a simple UI application from scratch, Part 1

Lets create a simple UI application for Win Mob 6 professional device, from scratch. When you create the project using the wizard you can see that basic code is already there. The main function, the window procedure etc. And then there’s stdafx. I never quite understood what they are there for, but I guess they must be important. But when I create the application from scratch, there will no stdafx’s. Just a plain simple file with a UI that shows up.

To start, create a new project for Win32 smart devices, (I have mentioned about this is my previous posts). At the last screen of the wizard, check the “Empty Project” checkbox. It will be unchecked by default. When you click finish, you’ll see that the project is empty! (-:

Ok, so the first thing we do is add a cpp file to our sources directory.  Lets call it FromScratch.cpp.  Add the following code, just to test if things are alright:

#include <windows.h>

#include <aygshell.h>

 

int WinMain(HINSTANCE hInst, HINSTANCE hPrevInst,

                  LPTSTR lpCmdLine, int nCmdShow)

{

      MessageBox(NULL, L"Hi there..", L"Info", MB_OK);

      return 0;

}

Hit compile and run. You should see a message box. windows.h is the standard header file and aygshell contains UI stuff.  WinMain is the entry point of your application and takes in 4 parameters. The first, hInst, is the handle to the instance of your module. The second is the handle to the previous instance of this program if it is already running. This param is always passed as NULL, so don’t bother. lpCmdLine is the command line arguments, if any and the last param, nCmdShow, determines how the window is to be shown. Most of the times I just ignore all the params except hInst.

Lets now add some UI to it. First create the resource file, which will hold all our application’s resources. Right click on “Resource Files” and add a new item, name it FromScratch.rc. resource.h will also be created in your project. Double click the resource file and add a new dialog to the resource by using “Add resource..”. Add a new dialog for pocket pc portrait. Change the dialog properties, I renamed the title to “From Scratch”, changed the caption of the default label and changed the ID of the dialog to IDD_PPC_FROMSCRATCH. My dialog now looks like this:

Lets add a menu bar to our application. The thing with menu bar is, you need to define the menubar in a separate text file (.rc2 file for e.g.) and then include this text file in the .rc file. This is a known bug. So add a new text file to the project, call it “FromScratch.rc2” and include it in the .rc file.

This menu bar will have two entries, the left soft key as “Exit” and the right soft key as “Refresh”. I ll let you in on refresh later.

We need two string resources for “Exit” and “Refresh” and two codes which will be sent when the user clicks on them. Define the menubar in the .rc2 file:

IDR_MENU_FROMSCRATCH SHMENUBAR DISCARDABLE

BEGIN

    IDR_MENU_FROMSCRATCH,

    2,

 

    I_IMAGENONE, IDM_EXIT, TBSTATE_ENABLED, TBSTYLE_BUTTON | TBSTYLE_AUTOSIZE,

    IDS_EXIT, 0, NOMENU,

   

    I_IMAGENONE, IDM_REFRESH, TBSTATE_ENABLED, TBSTYLE_BUTTON | TBSTYLE_AUTOSIZE,

    IDS_REFRESH, 0, NOMENU,

END

 

Add the following entries in the resource.h file:

#define IDR_MENU_FROMSCRATCH              501

#define IDS_EXIT                          502

#define IDS_REFRESH                       503

#define IDM_EXIT                          504

#define IDM_REFRESH                       505

 

And add the following stringtable in the .rc file:

 

STRINGTABLE

BEING

      IDS_EXIT                "Exit"

      IDS_REFRESH             "Refresh"

END

 

I have explained all these in my previous posts, so I am not going to repeat them.

Include resource.h in FromScratch.cpp. Add aygshell.lib in Additional dependencies (go to project properties, linker -> input). As mentioned before we need aygshell.lib for SHInitDialog, SHCreateMenuBar etc.

Now all we need to do is, add the code for FromScractchDlgProc and invoke the dialog from main.

Here is the code for FromScratchDlgProc:

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

{

      int wmID, wmEvent;

      PAINTSTRUCT ps;

      HDC hdc;

 

      switch(uMessage)

      {

            case WM_INITDIALOG:

                  {

                        SHINITDLGINFO shidi;

                        SHMENUBARINFO mbi;

 

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

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

 

                        shidi.dwMask = SHIDIM_FLAGS;

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

                        shidi.hDlg = hDlg;

                        SHInitDialog(&shidi);

 

                        mbi.cbSize = sizeof(mbi);

                        mbi.hwndParent = hDlg;

                        mbi.nToolBarId = IDR_MENU_FROMSCRATCH;

                        mbi.hInstRes = g_hInst;

 

                        if(!SHCreateMenuBar(&mbi))

                        {

                              printf("FromScratch: Error creating menu bar, errcode:0x%x\n", GetLastError());

                        }

                  }

                  return TRUE;

 

            case WM_COMMAND:

                  {

                        wmID = LOWORD(wParam);

                        wmEvent = HIWORD(wParam);

 

                        switch(wmID)

                        {

                              case IDM_EXIT:

                                    EndDialog(hDlg, uMessage);

                                    break;

 

                              case IDM_REFRESH:

                                    //for now

                                    EndDialog(hDlg, uMessage);

                                    break;

                        }

                  }

                  break;

                 

            case WM_PAINT:

                  {

                        hdc = BeginPaint(hDlg, &ps);

 

                        EndPaint(hDlg, &ps);

                  }

                  break;

 

      }

 

      return FALSE;

}

Again, I have explained about this in my previous posts. Basically, WM_INITDIALOG is where you do your initialization part, set the dialog as fullscreen, add the menubar etc. There are no controls yet, so the WM_COMMAND is empty. However, we need to add the handling for the two menus that we added before. Invoke this dialog from main function:

DialogBox(hInst, MAKEINTRESOURCE(IDD_PPC_FROMSCRATCH), NULL, FromScratchDlgProc);

Create a global variable to store the instance handle of the program:

HINSTANCE g_hInst;

And in WinMain, store the hInst in g_hInst. WinMain now looks like:

int WinMain(HINSTANCE hInst, HINSTANCE hPrevInst,

                  LPTSTR lpCmdLine, int nCmdShow)

{

      //MessageBox(NULL, L"Hi there..", L"Info", MB_OK);

 

      g_hInst = hInst;

 

      DialogBox(hInst, MAKEINTRESOURCE(IDD_PPC_FROMSCRATCH), NULL, FromScratchDlgProc);

      return 0;

}

And you’re done. Here is the screenshot:

Leave a Reply

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