目前用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给覆盖掉了
写这么多不知道有人能耐心看完不,或许我的方案从根本上就错了,按理设计一个全屏应用程序不该如此困难的吧