在PPC和Smartphone上创建自己的Menubar

其实这个是一直想做的事情, 要写一个Menubar的控件,有了Graphics的抽象层,有了Menubar就可以让这个控件同时工作在Symbian和Windows Mobile上面了.

 

做这个控件第一件事情就是把系统的Menubar去掉!

在PPC上面还是有点问题的. 当然不显示这个Bar比较简单,你只要不调用SHCreateMenu来实例化应该差不多了.但是这个输入法还是时不时地跳出来.前一个window如果是打开SIP的状态,切换到我的程序时候,这个SIP总是很突兀地显示出来. 适用了那些SIP相关的接口都不管用,后来干脆在主窗口受到WM_ACTIVE消息的时候直接hide SIP窗口,就像下面的代码这样:

case WM_ACTIVATE: // Notify shell of our activate message ShowWindow(FindWindow( _T("MS_SIPBUTTON"), 0 ),SW_HIDE); break;

Smartphone上还有一点不一样.最开始时候看到的是两个menubar,一个自己画的,一个系统默认话的.去掉这个,需要moveWIndow的帮助:在CreateWindow创建完主窗口之后可以Move一下就好了:

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); return E_FAIL; // Replace with specific error handling. } GetWindowRect(hWnd, &rect); chgScreen = SHFullScreen(hWnd, SHFS_HIDESIPBUTTON ); TCHAR szPlatform[30]; SystemParametersInfo(SPI_GETPLATFORMTYPE, sizeof(szPlatform), szPlatform, 0); if (_tcscmp(szPlatform, _T("SmartPhone")) == 0) MoveWindow( hWnd, rect.left, rect.top, rect.right, rect.bottom, TRUE); ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd);
注意这里还动态地取得了当前的平台,如果是Smartphone就移动,不是的话就不要移动了.不然你的Menubar就画到屏幕外面去了.

 

第二步就是处理按键消息. 这里比较特殊的一点是SOFT1和SOFT2.也就是VK_F1和VK_F2在默认的情况下是拿不到KEY_DOWN这样的消息的.你可以拿到的就是KEY_UP. 那怎么办呢? 对RegiesterHotkey.

typedef BOOL (__stdcall *UnregisterFunc1Proc)(UINT, UINT); HINSTANCE hCoreDll; UnregisterFunc1Proc procUndergisterFunc; hCoreDll = LoadLibrary(_T("coredll.dll")); procUndergisterFunc = (UnregisterFunc1Proc)GetProcAddress(hCoreDll, _T("UnregisterFunc1")); if(procUndergisterFunc != NULL) { procUndergisterFunc(NULL, VK_F1); procUndergisterFunc(NULL, VK_F2); } FreeLibrary(hCoreDll); RegisterHotKey(hWnd, 0, NULL, VK_F1); RegisterHotKey(hWnd, 1, NULL, VK_F2);

在WM_CREATE消息来的时候就在这里注册了Hotkey.那样到那两个按键按下的时候就来了WM_HOTKEY的消息.那时候的wParam里面就是你现在的0,1了. 这样按键也就可以了.

 

第三步就是画了.

为了画出一点系统的Menubar的感觉,还是下了一点功夫的:) 把这个高度为26的bar分成上下2个半去.上半区就是用GradientFill来画. (这个函数的的参数非常恶心). 可以看到这里的颜色Red,Green都是16位的.也就是说你的ColorRef取到对应的RGB以后不要忘记左移八位(<<8)!!!!

typedef struct _TRIVERTEX { LONG x; LONG y; COLOR16 Red; COLOR16 Green; COLOR16 Blue; COLOR16 Alpha; }TRIVERTEX,*PTRIVERTEX, *LPTRIVERTEX;

下面一半就是FillRect就行了.最后把对应的文字透明的画上去就好了. 在这个MenuItem被选中以后,这个画法还有不同.文字的颜色要变化.还是GradientFill的方向也要转变. 总而言之,想一下子非常理想还真不容易! 后面就有一张效果图. 黄色是被激活着的MenuItem.看着其实自己也挺得意的. 呵呵

你可能感兴趣的:(windows,struct,null,mobile,输入法,Symbian)