第一章 HelloCE

      我也不免俗的设计了HelloCE程序,用VS2008设计了三次win32项目,第一次选择了<空项目>项结果生成了一个空项目,项目中除了三个空文件夹,再什么也没有;第二次是一步一步执行下去,生成了应用程序的基本框架,窗口设计、窗口过程都有了,基本就是做个填空题就能生成一个小程序。自动生成的程序中,饱受责难的地方就是在窗口过程中总是使用巨大的switch语句。switch语句分析传给窗口过程的消息,这样每个消息可以被独立的处理。这种标准结果的优势之一是强制把一个类似的结构加到几乎所有Windows应用程序中,这使一个程序员可以更容易理解另一个人的代码。劣势是 整个窗口过程的所有的变量通常会比较杂乱的出现在过程的开头。我又建了第三个程序,结合第二个程序,并参考了wince程序设计提出的架构,将窗口过程被分解为几个独立过程,每个处理一个具体的消息。窗口过程自身是一个代码框架,只是查找传入的消息,看是否有过程来处理这个消息。如果有,则调用该过程;如果没有,则把消息传递给默认的窗口过程。下面介绍一下我的程序:

      .h文件

 #pragma once
#ifdef POCKETPC2003_UI_MODEL
#include "resourceppc.h"
#endif

#define MAX_LOADSTRING 100
#define dim(x) (sizeof(x) / sizeof(x[0]))

struct decodeUINT {                            // Structure associates
    UINT Code;                                 // messages
                                               // with a function.
    LRESULT (*Fxn)(HWND, UINT, WPARAM, LPARAM);
};
struct decodeCMD {                             // Structure associates
    UINT Code;                                 // menu IDs with a
    LRESULT (*Fxn)(HWND, WORD, HWND, WORD);    // function
};

 

const TCHAR szAppName[] = TEXT("HelloCE");

 

 

.cpp文件

 

 

 // HelloCEME.cpp : 定义应用程序的入口点。
//

#include "stdafx.h"
#include "HelloCEME.h"

 

// 全局变量:
HINSTANCE   g_hInst;   // 当前实例
HWND    g_hWndMenuBar;  // 菜单栏句柄

// 此代码模块中包含的函数的前向声明:
ATOM   MyRegisterClass(HINSTANCE, LPTSTR);
BOOL   InitInstance(HINSTANCE, int);

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

// Message handlers
LRESULT DoPaintMain (HWND, UINT, WPARAM, LPARAM);
LRESULT DoDestroyMain (HWND, UINT, WPARAM, LPARAM);
LRESULT DoCreateMain(HWND, UINT, WPARAM, LPARAM);
const struct decodeUINT MainMessages[] = {
    WM_PAINT, DoPaintMain,
    WM_DESTROY, DoDestroyMain,
 WM_CREATE,  DoCreateMain,
};

 

int WINAPI WinMain(HINSTANCE hInstance,
                   HINSTANCE hPrevInstance,
                   LPTSTR    lpCmdLine,
                   int       nCmdShow)
{
 MSG msg;

 // 执行应用程序初始化:
 if (!InitInstance(hInstance, nCmdShow))
 {
  return FALSE;
 }

 HACCEL hAccelTable;
 //hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_HELLOCEME));

 // 主消息循环:
 while (GetMessage(&msg, NULL, 0, 0))
 {
  if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
  {
   TranslateMessage(&msg);
   DispatchMessage(&msg);
  }
 }

 return (int) msg.wParam;
}

//
//  函数: MyRegisterClass()
//
//  目的: 注册窗口类。
//
//  注释:
//
ATOM MyRegisterClass(HINSTANCE hInstance, LPTSTR szWindowClass)
{
 WNDCLASS wc;

 wc.style         = CS_HREDRAW | CS_VREDRAW;
 wc.lpfnWndProc   = WndProc;
 wc.cbClsExtra    = 0;
 wc.cbWndExtra    = 0;
 wc.hInstance     = hInstance;
 wc.hIcon         = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_HELLOCEME));
 wc.hCursor       = 0;
 wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
 wc.lpszMenuName  = 0;
 wc.lpszClassName = szAppName;

 return RegisterClass(&wc);
}

//
//   函数: InitInstance(HINSTANCE, int)
//
//   目的: 保存实例句柄并创建主窗口
//
//   注释:
//
//        在此函数中,我们在全局变量中保存实例句柄并
//        创建和显示主程序窗口。
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
    HWND hWnd;
    TCHAR szTitle[MAX_LOADSTRING]=TEXT("HelloCE");  // 标题栏文本
    TCHAR szWindowClass[MAX_LOADSTRING]=TEXT("HelloCE"); // 主窗口类名

    g_hInst = hInstance; // 将实例句柄存储在全局变量中

#if defined(WIN32_PLATFORM_PSPC) || defined(WIN32_PLATFORM_WFSP)
    // 在应用程序初始化期间,应调用一次 SHInitExtraControls 以初始化
    // 所有设备特定控件,例如,CAPEDIT 和 SIPPREF。
    SHInitExtraControls();
#endif // WIN32_PLATFORM_PSPC || WIN32_PLATFORM_WFSP

//    LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
//    LoadString(hInstance, IDC_HELLOCEME, szWindowClass, MAX_LOADSTRING);

#if defined(WIN32_PLATFORM_PSPC) || defined(WIN32_PLATFORM_WFSP)
    //如果它已经在运行,则将焦点置于窗口上,然后退出
    hWnd = FindWindow(szWindowClass, szTitle); 
    if (hWnd)
    {
        // 将焦点置于最前面的子窗口
        // “| 0x00000001”用于将所有附属窗口置于前台并
        // 激活这些窗口。
        SetForegroundWindow((HWND)((ULONG) hWnd | 0x00000001));
        return 0;
    }
#endif // WIN32_PLATFORM_PSPC || 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
    // 使用 CW_USEDEFAULT 创建主窗口时,将不会考虑菜单栏的高度(如果创建了一个
    // 菜单栏)。因此,我们要在创建窗口后调整其大小
    // 如果菜单栏存在
    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);


    return TRUE;
}

//
//  函数: WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  目的: 处理主窗口的消息。
//
//  WM_COMMAND - 处理应用程序菜单
//  WM_PAINT - 绘制主窗口
//  WM_DESTROY - 发送退出消息并返回
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
{
    INT i;
    //
    // Search message list to see if we need to handle this
    // message.  If in list, call procedure.
    //
    for (i = 0; i < dim(MainMessages); i++) {
        if (wMsg == MainMessages[i].Code)
            return (*MainMessages[i].Fxn)(hWnd, wMsg, wParam, lParam);
    }
    return DefWindowProc (hWnd, wMsg, wParam, lParam);


}


LRESULT DoPaintMain (HWND hWnd, UINT wMsg, WPARAM wParam,
                     LPARAM lParam) {
    PAINTSTRUCT ps;
    RECT rect;
    HDC hdc;
  
         // Get the size of the client rectangle
    GetClientRect (hWnd, &rect);
  
    hdc = BeginPaint (hWnd, &ps);
    DrawText (hdc, TEXT ("Hello Windows CE!"), -1, &rect,
              DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  
    EndPaint (hWnd, &ps);
    return 0;
}
//----------------------------------------------------------------------
// DoDestroyMain - Process WM_DESTROY message for window.
//
LRESULT DoDestroyMain (HWND hWnd, UINT wMsg, WPARAM wParam,
                       LPARAM lParam) {
    PostQuitMessage (0);
    return 0;
}

LRESULT DoCreateMain (HWND hWnd, UINT wMsg, WPARAM wParam,
                       LPARAM lParam) {
          static SHACTIVATEINFO s_sai;
   #ifdef SHELL_AYGSHELL
            SHMENUBARINFO mbi;

            memset(&mbi, 0, sizeof(SHMENUBARINFO));
            mbi.cbSize     = sizeof(SHMENUBARINFO);
            mbi.hwndParent = hWnd;

            mbi.hInstRes   = g_hInst;

            if (!SHCreateMenuBar(&mbi))
            {
                g_hWndMenuBar = NULL;
            }
            else
            {
                g_hWndMenuBar = mbi.hwndMB;
            }

            // 初始化外壳程序激活信息结构
            memset(&s_sai, 0, sizeof (s_sai));
            s_sai.cbSize = sizeof (s_sai);
#endif // SHELL_AYGSHELL
           
    return 0;
}

     

 

过程很简单:

winmain函数、注册窗体、初始化、窗体过程。

 

 

posted @ 2010-02-09 09:56  张兴业  阅读(252)  评论(0编辑  收藏  举报