织梦CMS - 轻松建站从此开始!

罗索

Windows Mobile 开发识别屏幕方向的应用程序

落鹤生 发布于 2010-07-11 16:17 点击:次 
Windows Mobile 开发识别屏幕方向的应用程序 编写目的: 现在 Windows Mobile 的屏幕分辨率支持非常多。最新的 Windows Mobile6.5 支持 240*240 , 240*320 , 240*400 , 320*320 , 480*480 , 480*640 , 480*800 , 480*854 。当我们开发的窗体程序想适应如此多的
TAG:

编写目的:

现在Windows Mobile的屏幕分辨率支持非常多。最新的Windows Mobile6.5支持240*240,240*320,240*400,320*320,480*480,480*640,480*800,480*854。当我们开发的窗体程序 想适应如此多的分辨率时,往往要为一个对话框建立多个对话框模板。最常用的方法就是用RelayoutDialog。来重新layout对话框。这样使我们陷入了不断的摆放控件,然后编译查看效果。往往为 了支持,方屏、肖像模式、风景画模式要建立三个模板。此文的目的就是用代码的方式来Layout窗体,使支持不同的分辨率。

 
更改屏幕方向:引MSDN

通常,屏幕方向仅在用户使用 “屏幕方向”控制面板,或按下某硬件按钮来旋转屏幕时才改变。

此外,应用程序也可通过ChangeDisplaySettingsEx 函数以编程方式更改屏幕方向。该函数使用方法见 MSDN 中“Rotating the Content of the Screen”(旋转屏幕内容的方向)一文。例如,如果使用的应用程序只能在竖向模式下操作,则可通过编程改变屏幕方向。但是,如 果屏幕方向的改变很突然,通过编程改变屏幕方向会让用户搞不清楚。应用程序应始终要求用户在旋转屏幕前确认显示模式。

为了在竖向模式下显示,将dmDisplayOrientation 字段中的DEVMODE结构设置为 DMDO_0。对于右手横向模式,使用 DMDO_270。对于左手横向模式,使用 DMDO_90

 
应用程序窗口如何识别屏幕方向:引MSDN

屏幕方向如果改变,或当“输入 面板”出现时,应用程序的所有全屏顶层窗口都要适应新的取向。

注意: 如果窗口的上、左、右坐标在工作区域边界之上或之外,该窗口被认为是全屏窗口。工作区域是标题栏下的整个屏幕区域。顶层窗口是无父窗口的窗口,即有一个 NULL 父窗口。

如果窗口大小改变,窗口将收到 WM_SIZE 通知。WM_SIZE 消息的 lParam 参数的低位字指定了客户端区域的新宽度,高位字指定了客户端区域的新高度。应用程序应识别窗 口大小的改变,并相应地更新窗口布局。此外,也应重新确定所包含任何子窗口的布局。

如果应用程序没有全屏窗口,它收 不到 WM_SIZE 通知。相反,它应在 wParam 参数设置为 SETTINGCHANGE_RESET 时监听 WM_SETTINGCHANGE消息。

注意: 如果应用程序有顶层窗口,或使用 SHHandleWMSettingChange、SHInitDialog 和 SHFullScreen 方 法创建了窗口,它会同时收到 WM_SIZE 和 WM_SETTINGCHANGE 消息。但是,如果应用程序创建了子窗口,子窗口收不到 WM_SIZE 消息,即使子窗口是全屏窗口。

以下 WindowProc 模板的代码示例利用了 WM_SIZE 和 WM_SETTINGCHANGE 消息。
  1. switch (uMessage) 
  2. case WM_SIZE: 
  3. // 重新 计算所有子窗口的布局;重新设置 
  4. // 列出 视图和编辑框的大小,重新确定按钮、 
  5. // 静态 文字和其他控件的位置。 
  6. break
  7. case WM_SETTINGCHANGE: 
  8. if (SETTINGCHANGE_RESET == wParam) { 
  9.     // 屏幕方向改变。此时 
  10.     // 执行 WM_SIZE 不能执行的处理, 
  11.     // 如重新调整全屏子窗口的大小,对 
  12.     // 顶层窗口调用 MoveWindow 等等。 
  13.     // 如果不需要处理 WM_SETTINGCHANGE 消息,可以 
  14.     // 忽略它。 
  15. break

开发识别屏幕方向的应用程序

    我们先来看下微软的“今日” 设置界面。

 

上面这两个图分别是肖像模式和风 景画模式的UI布局。如果用DRA中的RelayoutDialog来实 现,我们起码需要两个对话框模板。代码如下

  1. WM_SIZE: 
  2. DRA::RelayoutDialog(g_hInst,hDlg,DRA::GetDisplayMode() != DRA::Portrait ? 
  3.  MAKEINTRESOURCE(IDD_TODAY_WIDE) : MAKEINTRESOURCE(IDD_TODAY)); 

如果要你放到方屏的机器上,你又要添加一个对话框模板。并要修改相应的代码。

  1. WM_SIZE: 
  2. UINT uIDDialog= IDD_TODAY_WIDE; 
  3. Switch(DRA::GetDisplayMode()) 
  4. DRA::RelayoutDialog( 
  5. g_hInst, 
  6. hDlg, 
  7. DRA::GetDisplayMode() == DRA::Portrait ? 
  8.  MAKEINTRESOURCE(IDD_TODAY) : (DRA::GetDisplayMode() == 
  9.  DRA::Square? MAKEINTRESOURCE(IDD_ TODAY_SQUARE): 
  10.  MAKEINTRESOURCE(IDD_TODAY_WIDE)); 

用RelayoutDialog来开发支持屏幕方向应用十分的麻烦。那么有没有通过代码实现,用一个 对话框模板就可以实现的呢。

我 们可以来分析下上面的两个Layout好的对话框。可以发现右边的三个按钮”上移”、“下移”、“选项”都是靠右的。而最下面的Checkbox和Combox。是下靠其的。然后中 间留出的位置给list view来摆放。上面的对话框从肖像模式到风景画模式可以这样改变。

向右对于控件实现如下:

1.     记 录要移动控件的位置

2.     找 出除list view,最left和最right的控件。标记为MinLeft,MaxRight

3.     计 算最right的控件移动右边的位移。并保存为MoveX. MoveX =(rcClient.right - nMargin) - MaxRight.right. nMargin为边缘空白 的距离,默认设置为8个像素。

4.     保 存最left控件到list控件的距离,并 保存,这样保证list控件到其他控件的相对位置不变。cListMargin = MinLeft.left - rcPrimary.right;

5.     根据计算出的MoveX,把所有控件向右移动MoveX(除list).

6.     计算list控件的宽度。MinLeft.left - cListMargin + MoveX - rcPrimary.left

7.     高度不变,左上顶点左边不变。用MoveWindow改变宽度。

同样的,向下对其也是同样的道 理。

之前在网上看到过一个CScreenlib的类,是用来Layout窗体 的。我在其基础上扩展了三个比较实用的接口

static void DockControl(HWND hwndDlg, UINT nIDAffectedCtl, DockType nType = dtFill);

static void OptimizeWidth(HWND hwndDlg, int cAffectedCtls, UINT nIDAffectedCtl, ...);

static void OptimizeHeight(HWND hwndDlg, UINT nIDAffectedCtl);

 static void AlignControls(HWND hwndDlg, AlignType nType, int cAffectedCtls, UINT nIDFixedCtl, UINT nIDAffectedCtl, ...);

static void MakeSameSize(HWND hwndDlg, SizeType nType, int cAffectedCtls, UINT nIDFixedCtl, UINT nIDAffectedCtl, ...);

static void OptimizeListRight(HWND hwndDlg, UINT nIDPrimaryCtl, int cControlCount, ...);

static void OptimizeListBottom(HWND hwndDlg, UINT nIDPrimaryCtl, int cControlCount, ...);

static void AlignFixControls(HWND hwndDlg, AlignType nType, UINT nIDPrimaryCtl, int cControlCount, ...);

下面来介绍下各个函数的使用方法。
DockControl: 自动拉伸
OptimizeWidth: 自动把控件拉伸到右边
OptimizeHeight:把控件拉伸到底部

AlignControls:其他控件根据nIDFixedCtl的位置 向左、向右、向下、向上对其。

MakeSameSize:使其他跟nIDFixedCtl一样大小
关于上面这几个函数的使用,见MSDN视频
下面介绍下
OptimizeListRight、OptimizeListBottom和AlignFixControls

OptimizeListRight把一组控件和list控 件向右靠其

我们在VS2005中layout一个如下对话框。

用OptimizeListRight来对其到右边。nIDPrimaryCtl为列表控件,cControlCount为 其他控件个数。在WM_SIZE中添加

CScreenLib::OptimizeListRight(hDlg, IDC_LIST, 2, IDC_SEND, IDC_DELETE);

 
  

这样实现了控件的又靠其。但是发现下面两个按钮没显示出来。我们使用OptimizeListBottom来进行按钮的 下对其。

在WM_SIZE中添加

CScreenLib::OptimizeListRight(hDlg, IDC_LIST, 2, IDC_SEND, IDC_DELETE);

CScreenLib::OptimizeListBottom(hDlg, IDC_LIST, 3, IDC_CHECK, IDC_LEFT, IDC_RIGHT);

运行结果如下:
  

这样图标已经下对其了。但是”向右”按 钮没有和删除按钮右对其。接口AlignFixControls

把一组控件对其到某个控件,nIDPrimaryCtl为目标控件。这组控件间的 相对位置不变,如果是向右对其,则把这组控件最右的控件对其到目标控件,然后移动其他控件,并保持这组控件相对位置不变。

在WM_SIZE中添加

CScreenLib::OptimizeListRight(hDlg, IDC_LIST, 2, IDC_SEND, IDC_DELETE);

CScreenLib::OptimizeListBottom(hDlg, IDC_LIST, 3, IDC_CHECK, IDC_LEFT, IDC_RIGHT);

CScreenLib::AlignFixControls(hDlg, CScreenLib::atRight,IDC_DELETE, 2,IDC_LEFT, IDC_RIGHT);

运行效果如下:
 
CScreenlib在

 

(jinhaijian)
本站文章除注明转载外,均为本站原创或编译欢迎任何形式的转载,但请务必注明出处,尊重他人劳动,同学习共成长。转载请注明:文章转载自:罗索实验室 [http://www.rosoo.net/a/201007/9809.html]
本文出处:CSDN博客 作者:jinhaijian
顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片
栏目列表
将本文分享到微信
织梦二维码生成器
推荐内容