转自:http://www.cnblogs.com/walzer/archive/2007/04/08/704996.html
这里谈论的所谓技术难点,其实根本不值一提。只不过微软定了一套游戏规则,我们目前不清楚这套游戏规则,花时间去摸索而已。
BUTTON的动画效果
我们用了GWES里提供的BUTTON类,在WINCE PRODUCT DOCUMENT里的位置是
ms-help://MS.WindowsCE.500/wceshellui5/html/wce50grfButtonReference.htm
里面并没有给出太多的说明,在Button Messages里提到有WM_CTLCOLORBTN消息, 但简单试用后发现和预期效果不符。我乱翻乱点时注意到了eVC在画图时,对BUTTON点右键出的菜单里,打开Properties,里面的Styles页有个复选框"Owner draw", 我就抓住这根稻草,GOOGLE一把,方法就出来了。
当Owner draw属性被勾选时,轮到该BUTTON绘图时,程序就不会跑DefDlgProc去画个灰色突出的效果并把按钮名字写上去,而是给BUTTON的父窗口,也就是DIALOG的PROC发个消息WM_DRAWITEM,并且所带的lParam中有我们需要的所有东西。来个强制转换
LPDRAWITEMSTRUCT lpDIS = (LPDRAWITEMSTRUCT)lParam;
然后根据 lpDIS->itemAction 和 lpDIS->itemState 判断BUTTON当前状态,以决定加载哪幅图片
DRAWITEMSTRUCT的详细说明请参考 ms-help://MS.WindowsCE.500/wceshellui5/html/wce50lrfdrawitemstruct.htm
我简单试了了一下,
(1) 初始化时
itemAction == 1; // ODA_DRAWENTIRE
itemState == 16; // ODS_FOCUS
(2) BUTTON被按下时
itemAction == 2; // ODA_SELECT
itemState == 17; // ODS_FOCUS | ODS_SELECTED
(3) BUTTON被点击后松开时
itemAction == 2; // ODA_SELECT
itemState == 16; // ODS_FOCUS
ODA和ODS宏定义数值
/*** from Winuser.h ***/
#define ODT_MENU 1
#define ODT_LISTBOX 2
#define ODT_COMBOBOX 3
#define ODT_BUTTON 4
//action
#define ODA_DRAWENTIRE 0x0001
#define ODA_SELECT 0x0002
#define ODA_FOCUS 0x0004
//state
#define ODS_SELECTED 0x0001
#define ODS_GRAYED 0x0002
#define ODS_DISABLED 0x0004
#define ODS_CHECKED 0x0008
#define ODS_FOCUS 0x0010
在WM_DRAWITEM中有两点要特别注意
(1) 不能在里面用InvalidateRect(lpDIS->hwndItem, lpDIS->rcItem, NULL),这会立即再发一个WM_DRAWITEM消息过来,接着再调InvalidateRect, 进入死循环直至把设备上的内存耗光,导致死机
(2) 对itemAction和itemState作判断时,必须把两者同时都判断了才能确定CLICK状态,单独判断action或单独判断state是不够的,会导致重绘作用在不希望发生的情况下。并且不能简单地作itemAction & ODA_SELECT这样的位与判断,还必须有排他性,我干脆就用==号了。
参考代码如下
2 {
3 switch(uMsg)
4 {
5 case WM_DRAWITEM:
6 {
7 LPDRAWITEMSTRUCT lpDIS = (LPDRAWITEMSTRUCT)lParam;
8
9 if(lpDIS->CtlID == IDC_BTN_1)
10 {
11
12 if( (lpDIS->itemAction & ODA_DRAWENTIRE) // 这是初始化时的情况
13 || ( (lpDIS->itemAction == ODA_SELECT) && (lpDIS->itemState == ODS_FOCUS) ) ) // 这是按下后放开时的情况
14 {
15 // 画上未被按下时的图片
16 }
17 else if( (lpDIS->itemAction & ODA_SELECT) && (lpDIS->itemState == (ODS_FOCUS | ODS_SELECTED) ) ) // 被按下时的情况
18 {
19 // 画上被按下时的图片
20 MessageBeep(MB_OK); // 顺便响一声,比较有手感
21 }
22 }
23 return TRUE;
24 }
25 default:
26 // STUB
27 break;
28 }
29
30 return FALSE;
31 }
关键字:VC++,按钮,动画