基于decodeUINT结构体的hello程序

来源:互联网 发布:网络配线架的作用 编辑:程序博客网 时间:2024/05/17 22:06

//======================================================================
// Header file:helloce.h
//======================================================================
// 返回元素的数量,主要用于搜索消息列表
#define dim(x) (sizeof(x) / sizeof(x[0]))
//----------------------------------------------------------------------
//数据类型定义
//
struct decodeUINT { //消息和消息函数的关联结构
 UINT Code;
 LRESULT (*Fxn)(HWND, UINT, WPARAM, LPARAM); //这里用到了函数指针
};
struct decodeCMD { //菜单和处理函数的关联结构
 UINT Code;
 LRESULT (*Fxn)(HWND, WORD, HWND, WORD); //这里用到了函数指针
};

//----------------------------------------------------------------------
#define IDC_CMDBAR 1 // 命令条ID

//----------------------------------------------------------------------
// 函数原型
//
int InitApp (HINSTANCE); //初始化应用函数原型
HWND InitInstance (HINSTANCE, LPWSTR, int); //初始化实例函数原型
int TermInstance (HINSTANCE, int); //实例终止函数原型
// 窗口处理函数原型
LRESULT CALLBACK MainWndProc (HWND, UINT, WPARAM, LPARAM);
// 消息句柄
LRESULT DoCreateMain (HWND, UINT, WPARAM, LPARAM);
LRESULT DoPaintMain (HWND, UINT, WPARAM, LPARAM);
LRESULT DoHibernateMain (HWND, UINT, WPARAM, LPARAM);
LRESULT DoActivateMain (HWND, UINT, WPARAM, LPARAM);
LRESULT DoDestroyMain (HWND, UINT, WPARAM, LPARAM);

//======================================================================
// HelloCE - helloce.c
//======================================================================
//----------------------------------------------------------------------
// 全局数据
//
const TCHAR szAppName[] = TEXT ("HelloCE");
HINSTANCE hInst; // 程序的实例句柄
//主窗口过程函数的消息映射表用到decodeUINT结构
const struct decodeUINT MainMessages[] = {
 WM_CREATE, DoCreateMain,
 WM_PAINT, DoPaintMain,
 WM_HIBERNATE, DoHibernateMain,
 WM_ACTIVATE, DoActivateMain,
 WM_DESTROY, DoDestroyMain,
};

//======================================================================
// 程序的入口
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPWSTR lpCmdLine, int nCmdShow) {
 MSG msg;
 int rc = 0;
 HWND hwndMain;
 // 初始应用
 rc = InitApp (hInstance);
 if (rc) return rc;
  // 初始化实例
  hwndMain = InitInstance (hInstance, lpCmdLine, nCmdShow);
  if (hwndMain == 0)
   return 0x10;
  // 应用程序消息循环
  while (GetMessage (&msg, NULL, 0, 0)) {
   TranslateMessage (&msg);
   DispatchMessage (&msg);
  }
  //实例清除
  return TermInstance (hInstance, msg.wParam);
 }
 //----------------------------------------------------------------------
 // 应用程序初始化函数
 //
 int InitApp (HINSTANCE hInstance) {
  WNDCLASS wc;
  //注册应用程序的主窗口类
  wc.style = 0; // 窗口样式
  wc.lpfnWndProc = MainWndProc; // 回调函数
  wc.cbClsExtra = 0; // 扩展的类数据
  wc.cbWndExtra = 0; // 扩展的窗口数据
  wc.hInstance = hInstance; //实例句柄
  wc.hIcon = NULL, // 图标
  wc.hCursor = NULL; // 鼠标
  wc.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);
  wc.lpszMenuName = NULL; //菜单
  wc.lpszClassName = szAppName; //窗口类的名字

  if (RegisterClass (&wc) == 0) return 1;
   return 0;
  }
  //----------------------------------------------------------------------
  //初始化实例
  //
  HWND InitInstance (HINSTANCE hInstance, LPWSTR lpCmdLine,
  int nCmdShow) {
   HWND hWnd;
   // 存储程序实例句柄到全局变量
   hInst = hInstance;
   // 建立主窗口
   hWnd = CreateWindow (szAppName, // 窗口类
    TEXT("你好蜥蜴"), //窗口标题
    WS_VISIBLE, //样式
    CW_USEDEFAULT, // x坐标
    CW_USEDEFAULT, // y 坐标
    CW_USEDEFAULT, // 初始宽度
    CW_USEDEFAULT, // 初始高度
    NULL, // 父窗口
    NULL, //菜单,必须为NULL,WINCE窗口不支持菜单。
    hInstance, // 实例
    NULL); //建立参数的指针,用于WM_CRATE消息期间。
  // 如果不能建立主窗口返回失败
  if (!IsWindow (hWnd)) return 0;
   // 显示和更新窗口函数
   ShowWindow (hWnd, nCmdShow);
   UpdateWindow (hWnd);
   return hWnd;
  }
 //----------------------------------------------------------------------
 // TermInstance -程序清除
 //
 int TermInstance (HINSTANCE hInstance, int nDefRC) {
  return nDefRC;
 }
 //======================================================================
 // 下面是主窗口的消息处理函数
 //
 //----------------------------------------------------------------------
 // MainWndProc - 主过程函数,这是一个回调函数
 //
 LRESULT CALLBACK MainWndProc (HWND hWnd, UINT wMsg, WPARAM wParam,
 LPARAM lParam) {
  INT i;
  //搜索消息列表,如果编写了对应的函数来处理这个消息则调用这个函数
  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); //没有编写对应的函数则调用默认的
 }
 //----------------------------------------------------------------------
 // DoCreateMain - 处理窗口建立(WM_CREATE)消息的函数.
 //
 LRESULT DoCreateMain (HWND hWnd, UINT wMsg, WPARAM wParam,
 LPARAM lParam) {
  HWND hwndCB;
  // 建立命令条.
  hwndCB = CommandBar_Create (hInst, hWnd, IDC_CMDBAR);
  // 添加退出按钮到命令条上
  CommandBar_AddAdornments (hwndCB, 0, 0);
  return 0;
 }
 //----------------------------------------------------------------------
 // DoPaintMain - 处理窗口重画(WM_PAINT)消息的函数
 //
 LRESULT DoPaintMain (HWND hWnd, UINT wMsg, WPARAM wParam,
 LPARAM lParam) {
  PAINTSTRUCT ps;
  RECT rect;
  HDC hdc;
  // 调整客户区域的大小并考虑命令条的高度
  GetClientRect (hWnd, &rect);
  rect.top += CommandBar_Height (GetDlgItem (hWnd, IDC_CMDBAR));
  hdc = BeginPaint (hWnd, &ps);
  DrawText (hdc, TEXT ("你好晕倒的蜥蜴!"), -1, &rect, //被改成了中文
  DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  EndPaint (hWnd, &ps);
  return 0;
 }
 //----------------------------------------------------------------------
 // DoHibernateMain - 处理窗口挂起消息(WM_HIBERNATE)的函数,这是WINCE独有的消息,目的//是将内存的使用量将到最小.
 //
 LRESULT DoHibernateMain (HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam) {
  // 如果窗口不是活动的,则取消命令条,释放内存
  if (GetActiveWindow () != hWnd)
   CommandBar_Destroy (GetDlgItem (hWnd, IDC_CMDBAR));
   return 0;
 }
 //----------------------------------------------------------------------
 // DoActivateMain - 处理窗口激活(WM_ACTIVATE)消息的函数
 //
 LRESULT DoActivateMain (HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam) {
  HWND hwndCB;
  // 如果窗口正处在活动状态而没有命令条则建立它
  if ((LOWORD (wParam) != WA_INACTIVE) && (GetDlgItem (hWnd, IDC_CMDBAR) == 0)) {
   // 建立命令条
   hwndCB = CommandBar_Create (hInst, hWnd, IDC_CMDBAR);
   // 添加退出按钮到命令条
   CommandBar_AddAdornments (hwndCB, 0, 0);
  }
  return 0;
 }
 //----------------------------------------------------------------------
 // DoDestroyMain - 处理窗口销毁(WM_DESTROY)消息函数.
 //
 LRESULT DoDestroyMain (HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam) {
  PostQuitMessage (0);
  return 0;
 }

 

在编译程序之前还需要做一些工作,当然这不是完全必须的,它是需要根据你的开发环境来进行的一系列设置工作,我的环境是,我需要编译Pocket PC 2002下的,而且是中文的环境,因为我装了Pocket PC 2002 SDK的中文IMAGE。因此首先我需要改变Download directory,因为中文的默认目录已经不是WindowsStart Menu,我个人习惯改为My Documents,当然你也可以设成其他的你愿意的目录,不过要注意的是如果不使用WindowsStart Menu(默认的目录)你需要通过资源管理器来运行它。


另外一个需要修改的地方是修改Project Setings对话框的资源选项卡,将语言选项设为中文。如下图:


好了编译执行,我们便完成了第一个WINCE程序,当我把它装到我的568上时,运行成功后,心情和第一次编程序调试通过的感觉一样。不过真正的收获不再此,虽然这是一个非常简单的程序,但是我们可以学到一些好的编程思路。

  收获一:全部程序代码均依照匈牙利命名法,我们几乎不用看注释便可以知道代码的作用。

  收获二:改变了我们一直使用的窗口过程函数用大量的Switch语句来分列窗口消息的方法。而采用把窗口过程分解成单个过程,每个过程处理一个特定的消息,余下的窗口过程是一个代码片段,这段代码用来检查是否编写了对应的过程来处理消息,如果有就调用该过程,没有则将消息传递给默认的窗口过程。这种结构的优势是将消息处理分成独立的块,一是避免了所有的窗口过程的变量都混杂的出现在过程的顶部;二是便于理解,我们可以很清楚的理解处理特定消息的代码,最重要的是这样的结构便于代码移植,每一个独立的消息处理函数如果需要,都可以几乎不用修改而直接拷贝过去用。我记不清在那里看到过,如果一段代码的功能有可能被重复使用超过三次,便应该将它进行封装。函数也许是封装代码的最小形式。收获三:从头文件的消息句柄、结构定义和程序文件的全局消息映射,主窗口过程函数的消息映射表我们可以看到和一个简单的框架,也许通过这些我们对MFC的消息映射机制理解有所帮助。

  好了这次我们看了一个非常简单的,但是我认为是非常优美的WINCE应用程序代码(好的代码读起来也是享受)。并且掌握了用eMbedded VC++编写应用程序的一般步骤。很有收获吧,不过我们还有很多的东西要学,别松劲,继续努力吧,你和我都是。
本文转自[水平网]:http://www.goalercn.com/article/article.php?id=2977

原创粉丝点击