Last time, I mentioned that I was working on getting the code generated by “Whidbey“ Windows CE Application Wizard to be correct for Windows CE AYGSHELL, Pocket PC 2003, and Smartphone 2003, in addtion to non-AYGSHELL (looks like Win9x rather the Pocket PC).  I also mentioned that I wasn't sure that having it spit code that worked for all four was really what folks wanted, as I wasn't sure how may device developers actually had to deal with all of the platforms, and I asked for feedback on the subject; however I have not yet gotten any.

Perhaps a concrete example will help to get folks thinking about the subject.  So, I've included the code (for the main .cpp file for the project) that will be generated by the Windows CE Application Wizard in our MDC bits.  This has been dev tested (i.e. QA has not tested it yet) on Pocket PC 2003 and Smartphone 2003, and while it wasn't retested on non-AYGSHELL Windows CE (we aren't supporting that for MDC, although oddly that's all we've really supported up until the last few weeks) it should continue to work there, so this should be fairly close to what folks will see for Beta 1, barring significant feedback from our MDC bits. 

Please feel free to provide feedback on this subject.

Josh Heitzman
Software Design Engineer
Microsoft - Visual Studio for Devices

This posting is provided "AS IS" with no warranties, and confers no rights.

// wce05.cpp : Defines the entry point for the application.

//

 

#include "stdafx.h"

#include "wce05.h"

#include <windows.h>

#include <commctrl.h>

 

#define MAX_LOADSTRING 100

 

// Global Variables:

HINSTANCE               g_hInst;                // current instance

#ifndef SHELL_AYGSHELL

HWND                    g_hwndCommandBar; // command bar handle

#else

HWND                    g_hwndMenuBar;          // menu bar handle

#endif

 

// Forward declarations of functions included in this code module:

ATOM                    MyRegisterClass(HINSTANCE, LPTSTR);

BOOL                    InitInstance(HINSTANCE, int);

LRESULT CALLBACK  WndProc(HWND, UINT, WPARAM, LPARAM);

LRESULT CALLBACK  About(HWND, UINT, WPARAM, LPARAM);

 

int WINAPI WinMain(HINSTANCE hInstance,

                   HINSTANCE hPrevInstance,

                   LPTSTR    lpCmdLine,

                   int       nCmdShow)

{

      MSG msg;

 

      // Perform application initialization:

      if (!InitInstance(hInstance, nCmdShow))

      {

            return FALSE;

      }

 

#ifndef WIN32_PLATFORM_WFSP

      HACCEL hAccelTable;

      hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_WCE05);

#endif

 

      // Main message loop:

      while (GetMessage(&msg, NULL, 0, 0))

      {

#ifndef WIN32_PLATFORM_WFSP

            if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))

#endif

            {

                  TranslateMessage(&msg);

                  DispatchMessage(&msg);

            }

      }

 

      return (int) msg.wParam;

}

 

//

//  FUNCTION: MyRegisterClass()

//

//  PURPOSE: Registers the window class.

//

//  COMMENTS:

//

ATOM MyRegisterClass(HINSTANCE hInstance, LPTSTR szWindowClass)

{

      WNDCLASS wc;

 

      wc.style         = CS_HREDRAW | CS_VREDRAW;

      wc.lpfnWndProc   = (WNDPROC)WndProc;

      wc.cbClsExtra    = 0;

      wc.cbWndExtra    = 0;

      wc.hInstance     = hInstance;

      wc.hIcon         = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WCE05));

      wc.hCursor       = 0;

      wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);

      wc.lpszMenuName  = 0;

      wc.lpszClassName = szWindowClass;

 

      return RegisterClass(&wc);

}

 

//

//   FUNCTION: InitInstance(HANDLE, int)

//

//   PURPOSE: Saves instance handle and creates main window

//

//   COMMENTS:

//

//        In this function, we save the instance handle in a global variable and

//        create and display the main program window.

//

BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)

{

    HWND hWnd;

    TCHAR szTitle[MAX_LOADSTRING];        // title bar text

    TCHAR szWindowClass[MAX_LOADSTRING];  // main window class name

 

    g_hInst = hInstance; // Store instance handle in our global variable

 

    LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);

    LoadString(hInstance, IDC_WCE05, szWindowClass, MAX_LOADSTRING);

 

#if defined(WIN32_PLATFORM_PSPC) || defined(WIN32_PLATFORM_WFSP)

    //If it is already running, then focus on the window, and exit

    hWnd = FindWindow(szWindowClass, szTitle); 

    if (hWnd)

    {

        // set focus to foremost child window

        // The "| 0x00000001" is used to bring any owned windows to the foreground and

        // activate them.

        SetForegroundWindow((HWND)((ULONG) hWnd | 0x00000001));

        return 0;

    }

#endif // defined(WIN32_PLATFORM_PSPC) || defined(WIN32_PLATFORM_WFSP)

 

    if (!MyRegisterClass(hInstance, szWindowClass))

    {

      return FALSE;

    }

 

    hWnd = CreateWindow(szWindowClass, szTitle, WS_VISIBLE,

        CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);

 

    if (!hWnd)

    {

        return FALSE;

    }

 

#ifdef WIN32_PLATFORM_PSPC

    // When the main window is created using CW_USEDEFAULT the height of the menubar (if one

    // is created is not taken into account). So we resize the window after creating it

    // if a menubar is present

    if (g_hwndMenuBar)

    {

        RECT rc;

        RECT rcMenuBar;

 

        GetWindowRect(hWnd, &rc);

        GetWindowRect(g_hwndMenuBar, &rcMenuBar);

        rc.bottom -= (rcMenuBar.bottom - rcMenuBar.top);

           

        MoveWindow(hWnd, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, FALSE);

    }

#endif // WIN32_PLATFORM_PSPC

 

    ShowWindow(hWnd, nCmdShow);

    UpdateWindow(hWnd);

 

#ifndef SHELL_AYGSHELL

    if (g_hwndCommandBar)

    {

        CommandBar_Show(g_hwndMenuBar, TRUE);

    }

#endif

 

    return TRUE;

}

 

//

//  FUNCTION: WndProc(HWND, unsigned, WORD, LONG)

//

//  PURPOSE:  Processes messages for the main window.

//

//  WM_COMMAND    - process the application menu

//  WM_PAINT      - Paint the main window

//  WM_DESTROY    - post a quit message and return

//

//

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)

{

    int wmId, wmEvent;

    PAINTSTRUCT ps;

    HDC hdc;

#if defined(SHELL_AYGSHELL) && !defined(WIN32_PLATFORM_WFSP)

    static SHACTIVATEINFO s_sai;

#endif

     

    switch (message)

    {

        case WM_COMMAND:

            wmId    = LOWORD(wParam);

            wmEvent = HIWORD(wParam);

            // Parse the menu selections:

            switch (wmId)

            {

#if !defined(WIN32_PLATFORM_WFSP)

                case IDM_HELP_ABOUT:

                    DialogBox(g_hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);

                    break;

#endif

#if !defined(WIN32_PLATFORM_PSPC) || !defined(WIN32_PLATFORM_WFSP)

                case IDM_FILE_EXIT:

#else // !defined(WIN32_PLATFORM_PSPC) || !defined(WIN32_PLATFORM_WFSP)

                case IDOK:

#if defined(WIN32_PLATFORM_PSPC)

                    SendMessage (hWnd, WM_CLOSE, 0, 0);                      

                    break;

#endif

                case IDM_OK:

#endif // !defined(WIN32_PLATFORM_PSPC) || !defined(WIN32_PLATFORM_WFSP)

                    DestroyWindow(hWnd);

                    break;

                default:

                    return DefWindowProc(hWnd, message, wParam, lParam);

            }

            break;

        case WM_CREATE:

#ifndef SHELL_AYGSHELL

            g_hwndCommandBar = CommandBar_Create(g_hInst, hWnd, 1);

            CommandBar_InsertMenubar(g_hwndCommandBar, g_hInst, IDM_MENU, 0);

            CommandBar_AddAdornments(g_hwndCommandBar, 0, 0);

#else // SHELL_AYGSHELL

            SHMENUBARINFO mbi;

 

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

            mbi.cbSize     = sizeof(SHMENUBARINFO);

            mbi.hwndParent = hWnd;

            mbi.nToolBarId = IDM_MENU;

            mbi.hInstRes   = g_hInst;

 

            if (!SHCreateMenuBar(&mbi))

            {

                g_hwndMenuBar = NULL;

            }

            else

            {

                g_hwndMenuBar = mbi.hwndMB;

            }

 

#if defined(SHELL_AYGSHELL) && !defined(WIN32_PLATFORM_WFSP)

            // Initialize the shell activate info structure

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

            s_sai.cbSize = sizeof (s_sai);

#endif

 

#endif // SHELL_AYGSHELL

            break;

        case WM_PAINT:

            hdc = BeginPaint(hWnd, &ps);

           

            // TODO: Add any drawing code here...

           

            EndPaint(hWnd, &ps);

            break;

        case WM_DESTROY:

#ifndef SHELL_AYGSHELL

            CommandBar_Destroy(g_hwndCommandBar);

#else

            CommandBar_Destroy(g_hwndMenuBar);

#endif

            PostQuitMessage(0);

            break;

#if defined(SHELL_AYGSHELL) && !defined(WIN32_PLATFORM_WFSP)

        case WM_ACTIVATE:

            // Notify shell of our activate message

            SHHandleWMActivate(hWnd, wParam, lParam, &s_sai, FALSE);

            break;

        case WM_SETTINGCHANGE:

            SHHandleWMSettingChange(hWnd, wParam, lParam, &s_sai);

            break;

#endif // defined(SHELL_AYGSHELL) && !defined(WIN32_PLATFORM_WFSP)

        default:

            return DefWindowProc(hWnd, message, wParam, lParam);

    }

    return 0;

}

 

#ifndef WIN32_PLATFORM_WFSP

// Message handler for about box.

LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)

{

    switch (message)

    {

        case WM_INITDIALOG:

#ifndef SHELL_AYGSHELL

            RECT rectChild, rectParent;

            int DlgWidth, DlgHeight;      // dialog width and height in pixel units

            int NewPosX, NewPosY;

 

            // trying to center the About dialog

            if (GetWindowRect(hDlg, &rectChild))

            {

                GetClientRect(GetParent(hDlg), &rectParent);

                DlgWidth      = rectChild.right - rectChild.left;

                DlgHeight     = rectChild.bottom - rectChild.top ;

                NewPosX       = (rectParent.right - rectParent.left - DlgWidth) / 2;

                NewPosY       = (rectParent.bottom - rectParent.top - DlgHeight) / 2;

                       

                // if the About box is larger than the physical screen

                if (NewPosX < 0) NewPosX = 0;

                if (NewPosY < 0) NewPosY = 0;

                SetWindowPos(hDlg, 0, NewPosX, NewPosY,

                    0, 0, SWP_NOZORDER | SWP_NOSIZE);

            }

#else // SHELL_AYGSHELL

            {

            // Create a Done button and size it. 

            SHINITDLGINFO shidi;

            shidi.dwMask = SHIDIM_FLAGS;

            shidi.dwFlags = SHIDIF_DONEBUTTON | SHIDIF_SIPDOWN | SHIDIF_SIZEDLGFULLSCREEN;

            shidi.hDlg = hDlg;

            SHInitDialog(&shidi);

            }

#endif // SHELL_AYGSHELL

            return TRUE;

 

        case WM_COMMAND:

#ifndef SHELL_AYGSHELL

            if ((LOWORD(wParam) == IDOK) || (LOWORD(wParam) == IDCANCEL))

#else

            if (LOWORD(wParam) == IDOK)

#endif

            {

                EndDialog(hDlg, LOWORD(wParam));

                return TRUE;

            }

            break;

    }

    return FALSE;

}

#endif // WIN32_PLATFORM_WFSP