分类: WINDOWS
2010-07-28 12:03:33
前段时间涉及到实现自绘多种状态按钮问题,目前解决办法有两个:一个是使用ImageList_Draw方法,另一个是使用DRAWITEMSTRUCT结构体。不知道各位看官有什么好的建议?
第一种方法Windows Mobile 6.0 SDK自带的Samples里面的Crossword就有,代码简单标记下:
//创建一个自绘按钮:
CreateWindow(_T("Button"), _T(""),
WS_VISIBLE | WS_CHILD | BS_OWNERDRAW,
183, 4, 50, 20,
hWnd, (HMENU)IDC_MAIN_ENTER_BUTTON, g_hInst, 0);
//载入一个绘有按钮不同状态的位图,这里表示了按钮的两种状态:Up和Down。
g_hImageList = ImageList_LoadImage(
g_hInst,
MAKEINTRESOURCE(IDB_ENTERBTN),
46,
0,
CLR_NONE,
IMAGE_BITMAP,
0);
//DrawEdge实现按钮的阴影。红色即是选择要绘制的图像的索引,0表示第一个。(The zero-based index of the image to draw.)
LPDRAWITEMSTRUCT lpDis = (LPDRAWITEMSTRUCT)lParam;
DrawEdge(lpDis->hDC, &lpDis->rcItem,
(lpDis->itemState & ODS_SELECTED) ? EDGE_SUNKEN : EDGE_RAISED,
BF_RECT);
ImageList_Draw(g_hImageList,
(lpDis->itemState & ODS_SELECTED) ? 0 : 1,
lpDis->hDC, 2, 2, ILD_NORMAL);
第二种方法绘制多个按钮时更好点,等我把两种方法比较一下再写上来。
Value | Description |
---|---|
ODT_BUTTON | Owner-drawn button |
ODT_LISTVIEW | Owner-draw list view control |
ODT_MENU | Owner-drawn menu |
ODT_TAB | Tab control |
Value | Description |
---|---|
ODA_DRAWENTIRE | The entire control needs to be drawn. |
ODA_FOCUS | The control has lost or gained the keyboard focus. You should check the itemState member to determine whether the control has the focus. |
ODA_SELECT | The selection status has changed. You should check the itemState member to determine the new selection state. |
Value | Description |
---|---|
ODS_CHECKED | The menu item is to be checked. Use this value only in a menu. |
ODS_COMBOBOXEDIT | The drawing takes place in the edit control of an owner-drawn combo box. |
ODS_DEFAULT | The item is the default item. |
ODS_DISABLED | The item is to be drawn as disabled. |
ODS_FOCUS | The item has the keyboard focus. |
ODS_GRAYED | The item is to be grayed. Use this value only in a menu. |
ODS_SELECTED | The status of the menu item is selected. |
//如果处理该消息,则必须返回TRUE
return(TRUE);
OwnerDrawButton函数的定义如下:
BOOL OwnerDrawButton(DRAWITEMSTRUCT* pdis, HINSTANCE hInstance)
{
static RECT rect;
static int iCount = 0;
// Icon handles:
static HICON hCurrIcon, hUpIconI, hDnIconI, hUpIconA, hDnIconA;
// Use copy of rectangle:
rect = pdis->rcItem;
//只载入一次Icon
if (iCount < 1) {
// LoadIcon only loads once, but LoadImage does not,
// so in case you call the latter, use a static counter:
iCount++;
// Inactive buttons:
hUpIconI = (HICON) LoadIcon(hInstance, MAKEINTRESOURCE(ID_UP_ICONI));
if (!hUpIconI) {
MessageBox(NULL, L"Loading ID_UP_ICONI icon fails", L"Message", MB_OK);
}
hDnIconI = (HICON) LoadIcon(hInstance, MAKEINTRESOURCE(ID_DN_ICONI));
if (!hDnIconI) {
MessageBox(NULL, L"Loading ID_DN_ICONI icon fails", L"Message", MB_OK);
}
// Active buttons:
hUpIconA = (HICON) LoadIcon(hInstance, MAKEINTRESOURCE(ID_UP_ICONA));
if (!hUpIconA) {
MessageBox(NULL, L"Loading ID_UP_ICONA icon fails", L"Message", MB_OK);
}
hDnIconA = (HICON) LoadIcon(hInstance, MAKEINTRESOURCE(ID_DN_ICONA));
if (!hDnIconA) {
MessageBox(NULL, L"Loading ID_DN_ICONA icon fails", L"Message", MB_OK);
}
}
// If the control's id is that of the "Up" button:
if (IDC_LEVELUPBUTTON == pdis->CtlID) {
// If the button is selected, display the
// "active" icon, else the "inactive" icon:
if (pdis->itemState & ODS_SELECTED) hCurrIcon = hUpIconA;
else hCurrIcon = hUpIconI;
}
// If the control's id is that of the "Down" button:
if (IDC_LEVELDNBUTTON == pdis->CtlID) {
// If the button is selected, display the
// "active" icon, else the "inactive" icon:
if (pdis->itemState & ODS_SELECTED) hCurrIcon = hDnIconA;
else hCurrIcon = hDnIconI;
}
// Center the icon inside the control's rectangle:
if (!DrawIconEx(
pdis->hDC,
(int) 0.5 * (rect.right - rect.left - ICON_WIDTH),
(int) 0.5 * (rect.bottom - rect.top - ICON_HEIGHT),
(HICON) hCurrIcon,//根据上面指定的Icon绘制
ICON_WIDTH,
ICON_HEIGHT,
0, NULL, DI_NORMAL
)) {
MessageBox(NULL, L"Drawing icon fails", L"Message", MB_OK);
}
return TRUE;
}