认识 windows mobile 的窗口部件

为了查阅MSDN、沟通交流,我们先来认识一下windows mobile的UI部分。如下图,我们需要搞清楚几个基本的概念:

  1. SIP - soft input panel, 软输入面板,就是输入法切换面板。
  2. Task bar,任务条,用来显示程序名称标题,选择程序,退出程序。
  3. Menu bar也叫Soft key bar或者Command bar,用来显示软按键菜单。

有了这些概念,以后再看文档就容易看懂了。比如要想知道如何隐藏输入法面板,就可以google一下“hide SIP windows mobile”来查找了。

全屏显示棋盘

手机屏幕很小,比如QVGA才有240x320像素,为了好看些,我们的象棋程序需要占用整个手机屏幕,也就是全屏显示。所以我们来研究一下windows mobile的全屏显示技术。

总体来说,要把一个窗口全屏显示,需要下面的步骤:

  1. 调用SHFullScreen()隐藏SIP, Task bar。
  2. 调用ShowWindow()隐藏Menu bar或者用MoveWindow()把window bar移出屏幕。用MoveWindow()的作用是保留soft key能接收消息。
  3. 调用MoveWindow()修改窗口的位置和大小,以便全屏显示。

要把一个对话框全屏显示,需要下面的步骤:

  1. 调用函数SHInitDialog()设置dwFlags为SHIDIF_FULLSCREENNOMENUBAR。
  2. 调用MoveWindow()设置对话框大小为整个屏幕的大小。
  3. 调用SetForegroundWindow()设置对话框为前景窗口。
  4. 调用SHFullScreen()隐藏Task bar和SIP bar。

或者保留menu bar,只是把它移出到屏幕外,以便接收soft key消息:

  1. 调用函数SHInitDialog()设置dwFlags为SHIDIF_SIZEDLGFULLSCREEN。
  2. 调用SHFullScreen()隐藏Task bar和SIP bar。
  3. 调用SetWindowPos()移出Menu bar。
  4. 调用MoveWindow()设置全屏的对话框。

参考资料:

  • http://support.microsoft.com/kb/266244/en-us/
  • window mobile 6 sdk的sample "Full Screen".

(欢迎转载,转载请注明来源和作者:杨波)

代码:

// cchess_teacher.cpp : 定义应用程序的入口点。 // #include "stdafx.h" #include "cchess_teacher.h" #define MAX_LOADSTRING 100 // 全局变量: HINSTANCE g_hInst; // 当前实例 HWND g_hWndMenuBar; // 菜单栏句柄 HBITMAP g_hBoard; // 棋盘位图句柄 BOOL g_bFullScreen; int g_iMenuHeight; // 此代码模块中包含的函数的前向声明: ATOM MyRegisterClass(HINSTANCE, LPTSTR); BOOL InitInstance(HINSTANCE, int); LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM); void LoadImages(HINSTANCE hInst); void UnloadImages(); void DrawBoard(HDC hdc); void FullScreen ( HWND hWnd, // In: Window BOOL bFullScreen // In: TRUE = Size to full screen. FALSE = Undo ); int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { MSG msg; LoadImages(hInstance); // 执行应用程序初始化: if (!InitInstance(hInstance, nCmdShow)) { return FALSE; } HACCEL hAccelTable; hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_CCHESS_TEACHER)); // 主消息循环: while (GetMessage(&msg, NULL, 0, 0)) { if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } } UnloadImages(); 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_CCHESS_TEACHER)); wc.hCursor = 0; wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH); wc.lpszMenuName = 0; wc.lpszClassName = szWindowClass; return RegisterClass(&wc); } // // 函数: InitInstance(HINSTANCE, int) // // 目的: 保存实例句柄并创建主窗口 // // 注释: // // 在此函数中,我们在全局变量中保存实例句柄并 // 创建和显示主程序窗口。 // BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) { HWND hWnd; TCHAR szTitle[MAX_LOADSTRING]; // 标题栏文本 TCHAR szWindowClass[MAX_LOADSTRING]; // 主窗口类名 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_CCHESS_TEACHER, 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); g_iMenuHeight = rcMenuBar.bottom - rcMenuBar.top; rc.bottom -= g_iMenuHeight; 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 message, WPARAM wParam, LPARAM lParam) { int wmId, wmEvent; PAINTSTRUCT ps; HDC hdc; SIZE size; TCHAR msg[256] = L""; RECT rect; static SHACTIVATEINFO s_sai; switch (message) { case WM_COMMAND: wmId = LOWORD(wParam); wmEvent = HIWORD(wParam); // 分析菜单选择: switch (wmId) { case IDM_HELP_ABOUT: DialogBox(g_hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, About); break; case IDM_FULLSCREEN: FullScreen(hWnd, true); break; #ifdef WIN32_PLATFORM_PSPC case IDM_OK: SendMessage (hWnd, WM_CLOSE, 0, 0); break; #endif // WIN32_PLATFORM_PSPC default: return DefWindowProc(hWnd, message, wParam, lParam); } break; case WM_CREATE: #ifdef SHELL_AYGSHELL SHMENUBARINFO mbi; memset(&mbi, 0, sizeof(SHMENUBARINFO)); mbi.cbSize = sizeof(SHMENUBARINFO); mbi.hwndParent = hWnd; mbi.nToolBarId = IDR_MENU; 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 break; case WM_PAINT: hdc = BeginPaint(hWnd, &ps); // TODO: 在此添加任意绘图代码... DrawBoard(hdc); EndPaint(hWnd, &ps); // debug GetWindowExtEx(hdc, &size); wsprintf(msg, L"win ext: x=%d, y=%d/n", size.cx, size.cy); OutputDebugString(msg); GetViewportExtEx(hdc, &size); wsprintf(msg, L"viewport ext: x=%d, y=%d/n", size.cx, size.cy); OutputDebugString(msg); wsprintf(msg, L"screen: cx=%d, cy=%d/n", GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN)); OutputDebugString(msg); GetWindowRect(hWnd, &rect); wsprintf(msg, L"win rect: left=%d, top=%d, right=%d, bottom=%d/n", rect.left, rect.top, rect.right, rect.bottom); OutputDebugString(msg); SystemParametersInfo(SPI_GETWORKAREA, 0, &rect, FALSE); wsprintf(msg, L"work area: left=%d, top=%d, right=%d, bottom=%d/n", rect.left, rect.top, rect.right, rect.bottom); OutputDebugString(msg); break; case WM_DESTROY: #ifdef SHELL_AYGSHELL CommandBar_Destroy(g_hWndMenuBar); #endif // SHELL_AYGSHELL PostQuitMessage(0); break; case WM_ACTIVATE: // 向外壳程序通知我们的激活消息 SHHandleWMActivate(hWnd, wParam, lParam, &s_sai, FALSE); break; case WM_SETTINGCHANGE: SHHandleWMSettingChange(hWnd, wParam, lParam, &s_sai); break; case WM_HOTKEY: switch(HIWORD(lParam)) { case VK_TSOFT1: case VK_TSOFT2: { // if we are in full screen mode we want to exit // when the user presses a softkey. if (g_bFullScreen) { //SendMessage(GetDlgItem(hWnd,IDC_EDIT), WM_SETTEXT, 0, (LPARAM)L"[Softkey] Exiting Full Screen"); FullScreen(hWnd, FALSE); } } break; } break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; } // “关于”框的消息处理程序。 INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_INITDIALOG: #ifdef SHELL_AYGSHELL { // 创建一个“完成”按钮并调整其大小。 SHINITDLGINFO shidi; shidi.dwMask = SHIDIM_FLAGS; shidi.dwFlags = SHIDIF_DONEBUTTON | SHIDIF_SIPDOWN | SHIDIF_SIZEDLGFULLSCREEN | SHIDIF_EMPTYMENU; shidi.hDlg = hDlg; SHInitDialog(&shidi); } #endif // SHELL_AYGSHELL return (INT_PTR)TRUE; case WM_COMMAND: #ifdef SHELL_AYGSHELL if (LOWORD(wParam) == IDOK) #endif { EndDialog(hDlg, LOWORD(wParam)); return (INT_PTR)TRUE; } break; case WM_CLOSE: EndDialog(hDlg, message); return (INT_PTR)TRUE; } return (INT_PTR)FALSE; } // yangbo // void LoadImages(HINSTANCE hInst) { g_hBoard = LoadBitmap(hInst, (LPCWSTR) IDB_BOARD); } void UnloadImages() { if(g_hBoard != NULL) { DeleteObject(g_hBoard); } } void DrawBoard(HDC hdc) { HDC hMemDC; hMemDC = CreateCompatibleDC(hdc); SelectObject(hMemDC, g_hBoard); BitBlt(hdc, 0, 0, 240, 320, hMemDC, 0, 0, SRCCOPY); DeleteDC(hMemDC); } // full screen: ms-help://MS.WindowsMobile.6/WindowsMobile6SDK/html/d4cb5890-0d2c-4c6d-adbb-672c7acf3680.htm // 获取工作区域大小:SystemParametersInfo(SPI_GETWORKAREA, 0, &rc, FALSE); //screen: cx=240, cy=320 //win rect: left=0, top=26, right=240, bottom=294 //work area: left=0, top=26, right=240, bottom=320 // // FUNCTION: SizeFullScreen // // PURPOSE: Change the specified window size to full screen // void SizeFullScreen ( HWND hWnd, // In: Window BOOL bFullScreen // In: TRUE = Size to full screen. FALSE = Undo ) { RECT rc; if (bFullScreen) { // Full screen size SetRect(&rc, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN)); } else { // Normal size SystemParametersInfo(SPI_GETWORKAREA, 0, &rc, FALSE); rc.bottom -= g_iMenuHeight; } MoveWindow( hWnd, rc.left, rc.top, rc.right, rc.bottom, FALSE); } // // FUNCTION: HideShellUI // // PURPOSE: Hide Shell UI components // void HideShellUI ( HWND hWnd, // In: Window BOOL bHide // In: FALSE to show. TRUE to hide. ) { DWORD dwState; dwState = bHide ? (SHFS_HIDETASKBAR | SHFS_HIDESIPBUTTON) : (SHFS_SHOWTASKBAR | SHFS_SHOWSIPBUTTON); // Show/Hide Shell UI SHFullScreen(hWnd, dwState); // We need to hide the tray manually for 2003 SE // and earlier versions of Smartphone. /*if (IsSmartphone2003SEOrOlder()) { HWND hwndTray = FindWindow(L"Tray", NULL); if (hwndTray) { HWND pos = bHide ? HWND_BOTTOM : HWND_TOP; SetWindowPos(hwndTray, pos, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); } } */ } // // FUNCTION: SetSoftkeyBarForFullScreen // // PURPOSE: Setup the softkey for full screen/non full screen mode // void SetSoftkeyBarForFullScreen ( HWND hwndSoftKeyBar, // In: Softkeybar BOOL bFullScreen // In: TRUE = set for full screen. FALSE = undo ) { if (bFullScreen) { // Move softkey bar off-screen. Don't hide it because // a hidden softkey bar will not receive key override // messages. SetWindowPos(hwndSoftKeyBar, NULL, -1, -1, 0, 0, SWP_NOZORDER | SWP_NOACTIVATE ); } else { // Move softkey bar on-screen. int iSoftkeysHeight = g_iMenuHeight; SetWindowPos(hwndSoftKeyBar, NULL, 0, GetSystemMetrics(SM_CYSCREEN) - iSoftkeysHeight, GetSystemMetrics(SM_CXSCREEN), iSoftkeysHeight, SWP_NOZORDER | SWP_NOACTIVATE ); } // Override/Undo softkeys for key press notifications, so we can // display taskbar & softkeys on SK1/SK2 press in full screen. DWORD dwBits; dwBits = bFullScreen ? SHMBOF_NODEFAULT | SHMBOF_NOTIFY : 0; SendMessage(hwndSoftKeyBar, SHCMBM_OVERRIDEKEY, VK_TSOFT1, MAKELPARAM(SHMBOF_NODEFAULT | SHMBOF_NOTIFY, dwBits)); SendMessage(hwndSoftKeyBar, SHCMBM_OVERRIDEKEY, VK_TSOFT2, MAKELPARAM(SHMBOF_NODEFAULT | SHMBOF_NOTIFY, dwBits)); } // // FUNCTION: FullScreen // // PURPOSE: Change the specified window to full screen // void FullScreen ( HWND hWnd, // In: Window BOOL bFullScreen // In: TRUE = Size to full screen. FALSE = Undo ) { g_bFullScreen = bFullScreen; HideShellUI(hWnd, g_bFullScreen); SetSoftkeyBarForFullScreen(g_hWndMenuBar, g_bFullScreen); SizeFullScreen(hWnd, g_bFullScreen); }

手机软件开发入门 - 中国象棋(2)090311相关推荐

  1. 手机软件开发入门 - 中国象棋(1)090308

    最近迷恋起中国象棋来了.我棋力很一般,但是总感觉人生如棋,每一个决定都会影响将来局势的发展.深思熟虑者,后势就比较占优.沉着应战,方显人生力量.刚好,2月份的时候把我的一部使用了快两年的三星普通手机换 ...

  2. 手机软件开发入门 [转]

    昨天在<程序员>上看到一篇访谈文章,孟岩就3G手机软件采访科泰世纪的陈榕.看了后,第一个感觉就是陈榕没做过手机软件.其实"不知为不知"也无所谓,但陈榕扯了一堆&quo ...

  3. 第一章 软件开发入门引导及概述

    第一章 软件开发入门引导及概述 前言 计算机系统是由硬件和软件组成,所谓硬件是指组成计算机系统的物理设备,包括电子的.机械的.磁的.光的设备的总和. 我们的电脑.手机.电子设备都算一个小的计算机. 而 ...

  4. 从事手机软件开发需要掌握什么知识

    与其说事先掌握好什么知识,不如说有没有不断学习掌握新知识的心态和思想准备.体力准备更重要.给自己找准一个方向最重要. 从开发的角度上简单的说手机软件可以分成应用软件.用户界面.操作系统.底层与设备驱动 ...

  5. (转载)H5 手机 App 开发入门:概念篇

    H5 手机 App 开发入门:概念篇 一.H5 的含义 二.原生应用 2.1 概念 2.2 优点 2.3 缺点 三.Web 应用 3.1 概念 3.2 优点和缺点 3.3 Web APP 的劣势 3. ...

  6. 开源力作, 使用 C# 开发的中国象棋

    Chess Chess 是一个基于 C# WPF开发的功能完善的中国象棋软件, 已开源全部源码,开箱即用.代码中含有大量注释,能够快速理解程序流程.可用于二次开发和学习. 功能特性 1. 人机对战,测 ...

  7. Android手机软件开发的前景

    Android手机软件开发的前景 今天是3G 的年代,中国拥有超过7亿的手机用户,而全球更是将近50亿,这样一个庞大的用户市场.而随着运营商语音话费的下降,手机上的各类增值应用已经成为了这个行业各环节 ...

  8. 海思软件开发入门篇 (一)

    标题 海思软件开发入门篇 (一)   (第一次写博客,有错别字与写的不好的地方敬请谅解.)   加过很多群,也逛过很多论坛,很多人在问,第一次接触海思不知道从而入手,的确,现在一个SDK动不动上G,还 ...

  9. 手把手教你iPhone 3G手机软件开发

    手把手教你iPhone 3G手机软件开发 "iPhone 是一款革命性的.不可思议的产品,比市场上其它任何移动电话整整领先了五年,"苹果公司首席执行官史蒂夫·乔布斯如是说,&quo ...

最新文章

  1. perfect book
  2. 教师课堂教学必备的100个妙招,总有一个适合你!
  3. PCI BAR设置过程
  4. Linux执行yum不显示时间图形,Linux停的yum命令详解(朝花夕拾)
  5. 控制游戏中物体的移动速度
  6. 用vmware-converter4把linux 迁移到ESX4.1中
  7. 牛客网Java刷题知识点之插入排序(直接插入排序和希尔排序)、选择排序(直接选择排序和堆排序)、冒泡排序、快速排序、归并排序和基数排序(博主推荐)...
  8. C语言试题十九之根据以下公式求p的值,结果由函数值带回。M与n为两个正整数,且要求m>n。 p=m!/n!(m-n)!
  9. ubuntu18.04 用xhell连接失败
  10. android 连续调用方法是,android – SwitchPreferences多次调用onPreferenceChange()方法
  11. Linux系统各个目录的一般作用
  12. PDFDOC365工具箱
  13. 良品铺子的2021:营收创新高后的“战术调整”
  14. 85. Maximal Rectangle最大矩形
  15. 【面试招聘】超强整理,非科班小硕的进击之路
  16. word转图片,pdf转图片,doc转图片,docx转图片
  17. time秒和年月日时分秒的转化
  18. 向U盘中安装Linux系统的经验(不是制作安装盘)
  19. NOIP 提高组 2012 / 洛谷P1080 国王游戏 题解
  20. oracle+ebs+om+流程,Oracle EBS OM Order is not eligible for booking

热门文章

  1. npm 查看指定 package 的依赖关系
  2. 3个月内第4起 香港一辆特斯拉Model S再次起火自燃
  3. 点对点网络与广播式网络的区别
  4. NGUI自适应屏幕分辨率
  5. 中医门诊电子病历xml文档数据读入数据库实验流程演示
  6. Ubuntu搭建全分布式Hadoop
  7. 微软 MSR Image Recognition Challenge 2016(IRC@ICME) 测试demo
  8. a标签去掉下划线_HTML 所有标签列表
  9. 教堂环境风琴-Marcos Ciscar Ethereal Keys Kontakt
  10. vant中uploader上传图片