当前位置:编程学习 > wap >>

关于用Visual Stdio设计SmartPhone全屏应用程序

目前用Visual Studio做一个基于Windows Mobile5.0的Camera应用程序.想完全设计自己风格的界面,遇到一个问题怎么也解决不了,请各位达人群策群力帮忙思考.
1.首先利用Visual Studio应用程序建立向导生成一基于Smart Device的MFC应用程序框架,生成的框架中会自动生成一CommandBar,放在最底部.由于想整个界面风格一直,在OnInitDialog中去掉了该CommandBar的生成代码
#if 0
if (!m_dlgCommandBar.Create(this) ||
    !m_dlgCommandBar.InsertMenuBar(IDR_MENU_MYMENU))
{
TRACE0("Failed to create CommandBar\n");
return FALSE;      // fail to create
}
#endif

2.通过自己响应VK_TSOFT1,VK_TSOFT2,即左右软键来弹出自己的主菜单或退出程序.
然而由于VK_TSOFT1,VK_TSOFT2被注册成系统热键,只能在PreTranslateMessage中截获到KEY_UP事件,没办法将就着用,检测到有VK_TSOFT1就用TrackPopupMenuEx弹出自己的主菜单.问题出现了,由于TrackPopupMenuEx有自己的消息循环机制,像黑洞一样吃掉了所有的按键事件包括VK_TSOFT1键,结果再也没机会通过VK_TSOFT1消除之了.经过两天的折磨,想出了如下办法解决,结果每种方案总有饶不过去的坎,简直疯狂.


解决方案一.
添加键盘勾子,在弹出菜单后监听按键事件,判断如果有VK_TSOFT1按下则收起Pop菜单.
g_hHookApiDLL = LoadLibrary(_T("coredll.dll"));
SetWindowsHookEx = (_SetWindowsHookExW)GetProcAddress(g_hHookApiDLL, _T("SetWindowsHookExW"));
g_hInstalledLLKBDhook = SetWindowsHookEx(WH_KEYBOARD_LL, LLKeyboardHookCallbackFunction,hInstance, 0);
CallNextHookEx = (_CallNextHookEx)GetProcAddress(g_hHookApiDLL, _T("CallNextHookEx"));
UnhookWindowsHookEx = (_UnhookWindowsHookEx)GetProcAddress(g_hHookApiDLL, _T("UnhookWindowsHookEx"));

然而发现SetWindowsHookEx调用不成功,在MSDN狂查一遍后才知道WinCE4.2以后已经不支持这样使用键盘勾子了.由于我在Windows Mobile5.0下开发,系统是WinCE5.0没法再继续下去.只好作罢

解决方案二.
1.解除VK_TSOFT1,VK_TSOFT2的系统热键,在自己的应用程序中定义其行为.
typedef BOOL (__stdcall *UnregisterFunc1Proc)( UINT, UINT );
HINSTANCE hCoreDll;
UnregisterFunc1Proc procUndergisterFunc;
hCoreDll = LoadLibrary(_T("coredll.dll"));
ASSERT(hCoreDll);
procUndergisterFunc = (UnregisterFunc1Proc)GetProcAddress(
hCoreDll, _T("UnregisterFunc1"));
ASSERT(procUndergisterFunc);
         procUndergisterFunc(MOD_KEYUP| MOD_WIN, VK_TSOFT1);
         BOOL bRes = RegisterHotKey(m_hWnd, VK_TSOFT1,MOD_KEYUP| 
                     MOD_WIN, VK_TSOFT1);
2.响应WM_HOTKEY
ON_MESSAGE(WM_HOTKEY,&CCeButtonDlg::OnHotKey)
在OnHotKey函数中弹出或收起Pop Menu.

这样处理后,本可以实现,但是泄气的是,当退出应用程序后,由于调用UnregisterFunc1Proc函数,VK_TSOFT1,VK_TSOFT2本来的行为恢复不了拉,Idle界面下再也响应不了VK_TSOFT1,VK_TSOFT2事件了.然而在Coredll中我又找不到恢复其默认系统热键的函数,只好放弃

解决方案三.


创建CommandBar,但使其隐藏或者高度为0,然后利用SHCMBM_OVERRIDEKEY改变VK_TSOFT1,VK_TSOFT2的行为
1.
#if 1
if (!m_dlgCommandBar.Create(this) ||
    !m_dlgCommandBar.InsertMenuBar(IDR_MENU_MYMENU))
{
TRACE0("Failed to create CommandBar\n");
return FALSE;      // fail to create
}
#endif   

2.
::SendMessage (m_dlgCommandBar, SHCMBM_OVERRIDEKEY, VK_TSOFT2, MAKELPARAM 
(SHMBOF_NODEFAULT | SHMBOF_NOTIFY, SHMBOF_NODEFAULT | SHMBOF_NOTIFY));
::SendMessage (m_dlgCommandBar, SHCMBM_OVERRIDEKEY, VK_TSOFT1, MAKELPARAM 
(SHMBOF_NODEFAULT | SHMBOF_NOTIFY, SHMBOF_NODEFAULT | SHMBOF_NOTIFY));
m_dlgCommandBar.Show(FALSE);  
3.在OnHotKey函数中接收VK_TSOFT1,VK_TSOFT2的按键事件,弹出或收起Pop 菜单
 然而郁闷之至的是,如果CommandBar设为不可见,则OnHotKey中接收不到VK_TSOFT1,VK_TSOFT2事件,设为可见m_dlgCommandBar.Show(TRUE),虽然可以收到事件并正常弹出或收起菜单,但是底部默认的CommandBar无法消除或覆盖,影响整体的风格.我是想在底部放两个自绘的水晶按钮的. 然而按钮却被CommandBar给覆盖掉了


写这么多不知道有人能耐心看完不,或许我的方案从根本上就错了,按理设计一个全屏应用程序不该如此困难的吧 --------------------编程问答-------------------- How to: Create a Full-Screen Window
Send Feedback on this topic to the authorsSee Also
How to: Prevent Display of Smart Minimize Buttons in Application Windows
Developing an Application for Windows Mobile-Based Devices > Controls and User Interface > Full-Screen Windows
The SDK for Windows Mobile-based devices provides the SHFullScreen function to give your application full control over the screen. The Win32 sample HTMLHost demonstrates how to use SHFullScreen in your application. 
Note   If you require even more control over the display than the SHFullScreen function provides, the Game API allows full programmatic access to the display buffer. 
Remarks
Full-screen applications can be optionally designed to remove the user's access to the Start menu, in which case your application must provide a way for the user to access other applications on the device. 
Code Example
The following code example demonstrates how to call SHFullScreen from within the MFC InitInstance function.
Note   To make the following code example easier to read, security checking and error handling are not included. This code example should not be used in a release configuration unless it has been modified to include them.
BOOL rb;
BOOL chgScreen;
int rc;
RECT rect;
HWND hWnd;

rb = SystemParametersInfo(SPI_GETWORKAREA, 0, &rect, 0);
if (rb == FALSE)  // SystemParametersInfo failed.
{
    rc = MessageBox(NULL, _T("Could not get work area."),
                    _T("Error"), MB_OK);
    if (rc == 0)  // Not enough memory to create MessageBox.
        return E_OUTOFMEMORY;
    return E_FAIL;  // Replace with specific error handling.
}

hWnd = CreateWindow(szWindowClass, szTitle, WS_VISIBLE,
       CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
       CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
if (hWnd == NULL)// CreateWindow failed.
{
    rc = MessageBox(NULL, _T("Could not create main window."),
                    _T("Error"), MB_OK);
    if (rc == 0)  // Not enough memory to create MessageBox.
        return E_OUTOFMEMORY;
    return E_FAIL;  // Replace with specific error handling.
}

GetWindowRect(hWnd, &rect);
chgScreen = SHFullScreen(hWnd, SHFS_HIDETASKBAR | SHFS_HIDESIPBUTTON | 
                  SHFS_HIDESTARTICON);
if (chgScreen == FALSE)
{
    // SHFullScreen failed.
    rc = MessageBox(NULL, _T("Could not modify the window."),
                    _T("Error"), MB_OK);
    if (rc == 0)  // Not enough memory to create MessageBox.
        return E_OUTOFMEMORY;
    return E_FAIL;  // Replace with specific error handling.
}
MoveWindow( hWnd, 
            rect.left, 
            rect.top - MENU_HEIGHT, 
            rect.right, 
            rect.bottom + MENU_HEIGHT, 
            TRUE);
--------------------编程问答-------------------- 做到全屏这点容易,请看我贴子最开始部分,关键是这后对VK_TSOFT,VK_TSOFT2的事件响应,即自绘弹出菜单的弹出与收起处理,简单说就是如何做一个像底部CommandBar那样,通过左右软键弹出收拢自绘Pop Menu的控件. --------------------编程问答-------------------- up
补充:移动开发 ,  Windows Phone
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,