[转贴]在Pocket PC中编程实现全屏

前言
    一些资格较老的CE软件开发师应该还记得CE2.11版的系统界面吧。那时,系统界面比较忠实于PC版的WINDOWS系统界面,导航栏在最下方,“开始”菜单在导航栏的左侧,建立的单文档应用程序占据除导航栏外的整个屏幕,对话框程序带上标题栏后就可以随意拖动,一切都是那么的符合习惯,那么的舒服!
    然而好景不常在,2001年,CE系统进行了一次革命性的升级,推出针对PDA的掌上系统PPC,版本提升到了3.0。这次的升级改变了整个系统界面,导航栏被安排在屏幕的最上方,但最下方还有一个用来放置输入键盘等工具的任务栏。这就使得本来就不大的程序显示界面变得更为紧张!但微软的工程师用了一些小技巧来解决单文档显示界面的紧张问题,方法就是把单文档中的菜单栏默认安置在任务栏。下面是两张效果图,大家可以对比一下:
点击弹出图片原始大小
CE2.11的单文档显示界面
点击弹出图片原始大小
CE3.0的单文档显示界面

单文档全屏
    虽然这种方式的改变对对话框程序是一种“难言的痛”,但对于单文档程序,改变也不算大,只是一些使用习惯的问题而已。可是,谁都希望自己的程序能够在这个巴掌大的PDA上占据尽量大的显示空间,所以,我们可以做一些技术处理,隐藏掉导航栏,实现真正的全屏。
    当菜单栏与最下面的任务栏合并在一起时,要实现单文档全屏,总的来说,只需要在几个位置加一些简单的代码。第一个位置是在CMainFrame::OnCreate函数(如果是SDK编程,相当于WM_CREATE的消息处理部分),在这里,需要添加一个移动窗口的动作,目的就是把程序的窗口移到屏幕的最顶端,代码如下:
RECT          rc; //建立一个矩形变量
GetWindowRect(&rc ); //获取程序框架的窗口矩形位置
rc.top -= 26; //上移26个像素(导航栏的高度正好是26)
MoveWindow(rc.left, rc.top, rc.right, rc.bottom, TRUE ); //移动窗口
移动窗口后,还不能实现全屏,因为还有一个导航栏遮盖在程序的前面。所以我们要增加隐藏导航栏的代码,考虑到要在任何情况下都要隐藏导航栏,所以这些代码需要加在程序活动的时候。因此,我们在CMainFrame::DefWindowProc函数中增加对消息WM_ACTIVATE的处理,代码如下:
switch ( message )
{
case WM_ACTIVATE:
SHFullScreen( this->m_hWnd, SHFS_HIDETASKBAR);
break;
}
很明显,上面最为重要的代码行就是对SHFullScreen函数的调用,该函数属于Shell编程的一部分,第一个参数是程序框架句柄,第二个参数是状态申明,有以下申明(自己的一些翻译,也许会有一点小差异,^_^!):
SHFS_SHOWTASKBAR 使任务栏位于所有的窗口之上。
SHFS_HIDETASKBAR 隐藏任务栏,一个游戏或应用程序需要接管整个屏幕时应该使用该标志。但在使用该标志前应确保其有FULL SCREEN的大小,否则任务栏还是会出现。.
SHFS_SHOWSIPBUTTON 显示键盘
SHFS_HIDESIPBUTTON 隐藏键盘
SHFS_SHOWSTARTICON 显示导航栏上的“开始”。
SHFS_HIDESTARTICON 隐藏导航栏上的“开始”,当隐藏了“开始”,点击导航栏的时候将不会出现下拉“开始”菜单。
    试运行一下,程序已可以全屏显示了,但刹那的光辉不代表灿烂的永恒,这么容易就可以解决的话,也就不叫问题了。
    事实上,对于某些应用程序,输入键盘是一定要的,所以它不可能隐藏键盘,但操作过程中发现,如果弹出键盘后,导航栏将再次出现!前面所做的就犹如“竹篮打水一场空”!
    因此,下面一步至关重要!
    首先,在你的框架声明文件中(默认名字是MainFrm.h)加入一句申明:
afx_msg int OnSettingChange();
    然后,在你的框架实现文件中(默认名字是MainFrm.cpp)加入消息映射:
        BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
//{{AFX_MSG_MAP(CMainFrame)
ON_WM_SETTINGCHANGE()
//}}AFX_MSG_MAP
        END_MESSAGE_MAP()
    这里就是重点,是对系统参数改变消息的处理,如果你是SDK编程,就是对WM_SETTINGCHANGE消息的处理。好,下面我们为该消息添加处理代码:
        int CMainFrame::OnSettingChange()
        {
       return 1;
        }
    有意思吧,代码处理就是什么都不做,直接就给它返回1。
    再运行程序试试,弹出键盘,怎么样?全屏百分百!

还有很多情况处理,待续……


接续……



  上面说的是菜单栏与最下面的任务栏合并在一起时的解决方法,对于菜单栏在程序顶端的情况,上面的处理方法还未能实现完全全屏的目标,因为还没有隐藏任务栏,图示如下:      
      点击弹出图片原始大小
     没有隐藏任务栏
  所以,我们还要对任务栏做隐藏处理。下面我就详细讲解实现的方法和步骤。
  我们第一步要了解的是结构SHINITDLGINFO。这个结构的定义如下:
     typedef struct tagSHINITDIALOG{ 
          DWORD dwMask; 
          HWND hDlg; 
          DWORD dwFlags; 
     } SHINITDLGINFO;
  dwMask:具体什么意思,我也不是很清楚,估计是掩码之类。事实上,现在只有一个取值,就是0x0001。可以用符号SHIDIM_FLAGS代表。
  hDlg:英文翻译就是对话框的句柄,但是在单文档程序中取的是框架的句柄。
  dwFlags:一个至关重要的标志参数。
        SHIDIF_DONEBUTTON -- 在导航栏上显示能关闭程序的“OK”按钮;
        SHIDIF_SIZEDLG --对话框的尺寸,不包括输入面板的位置;
        SHIDIF_SIZEDLGFULLSCREEN ― 全屏尺寸,但忽略输入面板;
        SHIDIF_SIPDOWN - 收起输入面板;
        SHIDIF_FULLSCREENNOMENUBAR - 全屏尺寸,且占据最下部菜单栏的空间。
  明白这个结构后就好办了,只需要加入以下代码就可以实现真正的全屏:
        SHINITDLGINFO     shidi;
        shidi.dwMask = SHIDIM_FLAGS;
        shidi.dwFlags = SHIDIF_SIPDOWN | SHIDIF_FULLSCREENNOMENUBAR;
        shidi.hDlg = this->m_hWnd;
        SHInitDialog( &shidi );
  注意了,以上代码要加在MoveWindow语句之前。
  顺便提醒一下,如果你还想隐藏输入面板的话,就把
          SHFullScreen( this->m_hWnd, SHFS_HIDETASKBAR); 
  改为:
          SHFullScreen( this->m_hWnd, SHFS_HIDETASKBAR | SHFS_HIDESIPBUTTON );
  最后实现的单文档全屏图示如下:
      点击弹出图片原始大小


下次讲解对话框全屏的原理。待续……


对话框假全屏的关闭和真正全屏的实施

    对话框在PPC2000以上也是默认全屏的,无论你的对话框有多小,它就是自动全屏,但遗憾的是,这个全屏不是真正的全屏,因为它始终需要搭配个导航栏和任务栏,把界面搞得非常难看。幸运的是,这只是个默认值,不是固定值。我们可以通过实施某些手段来改变这种状态。
    最简单的方法就是使用对话框新增的一个内部属性m_bFullScreen。这是个布尔变量,当它为TRUE时,对话框全屏;为FALSE时,对话框为实际大小。那么,如何使用该变量呢?这也很简单,只需要在初始对话框前,给这个属性赋值就行了,如下:
        BOOL CXXXDlg::OnInitDialog() 
        {
                m_bFullScreen = FALSE;
                CDialog::OnInitDialog();
        
                return TRUE;
        }
    如果是SDK编程,你就在初始化消息下处理就行了。
    当然,如果这么简单就完了,也就不需要写这种费力不讨好的文章了,屏蔽这个全屏后,你会发现一旦使用键盘,对话框就会回复原型。这是不可接受的,所以,我们还要做一些消息处理,这个消息就是WM_SETTINGCHANGE,处理的地方和方法请参考上面单文档的描述。

    上面说了如何屏蔽假全屏,接着就是对话框全屏的实施了,可是,我不打算在这里又罗里罗嗦地把单文档全屏所说的话重复一遍。所以,你如果需要实施对话框的真正全屏,完全可以参照单文档的做法,这里我就偷懒略去了。

[habit]在对话框下用上述方法不能把屏幕下方那个供输入的那行关闭,不能实现真正的全屏。把下边这句加入OnInitDialog()即可:
m_pWndEmptyCB->ShowWindow(SW_HIDE);
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值