navbutton.cpp
来自「EVC环境下用SDK开发WINCE的应用程序」· C++ 代码 · 共 499 行
CPP
499 行
// NavButton.cpp: implementation of the NavButton class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "navgpS.h"
#include "NavButton.h"
//**#include "ParameterFrame.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CNavButton::CNavButton()
{
m_bPressed = FALSE;
m_bVisible = TRUE;
m_bEnable = TRUE;
m_bChecked = FALSE;
m_hIcon = NULL;
m_hIconDisable = NULL;
// set default value;
m_euBkStyle = BK_STD_MENU;
m_usIconCode = 0xFFFF;
m_uIconFormat = 0; // draw icon on the top in default.
// if true call TransparentBlt() function to blt button bkgnd.
m_bTransBlt = TRUE;
}
CNavButton::~CNavButton()
{
DestroyIcon(m_hIcon);
DestroyIcon(m_hIconDisable);
m_hIcon = NULL;
m_hIconDisable = NULL;
}
void CNavButton::OnDrawItem(int /*nIDCtl*/, LPDRAWITEMSTRUCT lpDrawItemStruct)
{
//Sleep(200);
UINT uState = lpDrawItemStruct->itemState;
HDC hDC = lpDrawItemStruct->hDC;
BOOL bPressed = ODS_SELECTED & lpDrawItemStruct->itemState;
BOOL bEnabled = !(ODS_DISABLED & lpDrawItemStruct->itemState);
int nWidth, nHeight; // button width and height
int x, y;
DWORD dwIconWidth = 0, dwIconHeight = 0; // windows icon size
WORD usIconWidth = 0, usIconHeight = 0; // kiwi icon size
// when a button lost or gain focus, we don't redraw it.
if(ODA_FOCUS & lpDrawItemStruct->itemAction )
return;
// step 1. Load Background bitmap and StretchBlt it to the button
HDC hDCMem = NGetTempMemDC();
HBITMAP hbmBtn,hOldBitmap;
// Load the bkground depending on current status.
hbmBtn = LoadBkBitmap(bEnabled, bPressed, m_bChecked);
ASSERT(NULL != hbmBtn);
hOldBitmap = (HBITMAP)SelectObject(hDCMem, hbmBtn);
RECT rect;
GetClientRect(&rect);
nWidth = rect.right - rect.left;
nHeight = rect.bottom - rect.top;
if( m_bTransBlt )
TransparentBlt(hDC, rect.left,rect.top, nWidth,nHeight,hDCMem,0,0,nWidth,nHeight,KEY_COLOR);
else
BitBlt(hDC, rect.left,rect.top, nWidth,nHeight,hDCMem,0,0,SRCCOPY);
// clean up
SelectObject(hDCMem, hOldBitmap);
// step 2. Draw icon. including windows icon and kiwi icon.
// if both of them are setted, only display kiwi icon.
CNString strWindowText;
GetWindowText(strWindowText);
if (0xFFFF != m_usIconCode)
{
//** KWGetSymbolSize(&usIconWidth, &usIconHeight);
// Draw the icon
if ( strWindowText.IsEmpty() )
{
// Centralize the icon if the button's caption is empty.
if (m_euButtonStyle == BS_ANGLE)
{
x = rect.left + (nWidth - usIconWidth) / 2 + nHeight / 4;
}
else
{
x = rect.left + (nWidth - usIconHeight) / 2;
}
}
else
{
x = rect.left + ICONMARGIN;
if (m_euButtonStyle == BS_ANGLE)
{
x += nHeight / 2 - ICONMARGIN;
}
}
y = rect.top + (nHeight - usIconHeight) / 2;
// adjust x,y to point to center point
x += usIconWidth/2;
y += usIconHeight/2;
if (!bPressed)
{
//** KWDrawSymbol(hDC, x, y, m_usIconCode);
}
else
{
//** KWDrawSymbol(hDC, x + 2, y + 2, m_usIconCode);
}
} // end of draw kivi icon
else if(m_hIcon) // draw window icon
{
GetIconPos(&x, &y);
GetIconSize(dwIconWidth, dwIconHeight);
// if button is pressed.
if(bPressed)
{
x += 2;
y += 2;
}
// If button is in normal status or m_hIconDisable not set,
// display normal icon.
if ( bEnabled || !m_hIconDisable) // normal status
DrawIconEx (hDC, x, y, m_hIcon, dwIconWidth, dwIconHeight, 0, NULL, DI_NORMAL );
else // disable status
DrawIconEx (hDC, x, y, m_hIconDisable, dwIconWidth, dwIconHeight, 0, NULL, DI_NORMAL );
} // end of draw window icon
// step 3. Draw window text
RECT rcText = rect;
GetTextPos(&rcText);
int nOldMode = SetBkMode(hDC,TRANSPARENT);
// HFONT hOldFont = (HFONT)SelectObject(hDC, /*NGetNavFont()*/GetFont());
if (bPressed && m_euBkStyle != BK_RADIO )
{
rcText.left += 2;
rcText.top += 2;
}
// draw button caption depending upon button state
if ( bEnabled )
{
if(m_euBkStyle == BK_STD_OPER || m_euBkStyle == BK_RADIO)
{
SetTextColor(hDC, TEXTCOLOR_WHITE);
}
else
{
SetTextColor(hDC, TEXTCOLOR_BLACK);
}
if (IsIconButton() && m_uIconFormat == 1) // draw icon on left
{
DrawText(hDC, strWindowText, strWindowText.GetLength(), &rcText, DT_LEFT);
}
else
{
DrawText(hDC, strWindowText, strWindowText.GetLength(),&rcText, DT_CENTER);
}
}
else
{
SetTextColor(hDC, RGB(75,81,129));
if (IsIconButton() && m_uIconFormat == 1 ) // draw icon on left
{
DrawText(hDC, strWindowText, _tcslen(strWindowText), &rcText, DT_LEFT);
}
else
{
DrawText(hDC, strWindowText, _tcslen(strWindowText), &rcText, DT_CENTER);
}
}
// SelectObject(hDC, hOldFont);
SetBkMode(hDC, nOldMode);
// TRACE(_T("%s: %x state=%x\n"),strWindowText.GetString(), lpDrawItemStruct->itemAction, uState);
}
//
// FUNCTION: LoadBkBitmap(BOOL, BOOL, BOOL)
// PURPOSE: Load the bkground depending on current status.
// COMMENTS:
// According to button status and its bkstyle, we load corresponding
// bkground bitmap. It provides a cache mechanism, after loading a
// bitmap, we stored in cache for reuse. when loading, we first find it
// in cache, if found, return it directly, if not, load it from resouces.
// notice: it can only cache BS_KINDS(max num of the kinds used in our
// application) kinds of buttons.
//
HBITMAP CNavButton::LoadBkBitmap(BOOL bEnabled, BOOL bPressed, BOOL bChecked)
{
static HBITMAP s_hbmBkgnd[BS_KINDS][4]; // four status: disabled,checked,pressed,normal
static int s_nWidth[BS_KINDS];
static int s_nHeight[BS_KINDS];
static EU_BK_STYLE s_euBkStyle[BS_KINDS];
static int s_nNext = 0; // index of the record that could be used to store bmp for button.
HBITMAP hbmBkgnd;
RECT rect;
GetClientRect(&rect);
for(int i=0; i<s_nNext; i++)
{
// find the record, then exit the loop.
if(s_nWidth[i] == rect.right - rect.left
&& s_nHeight[i] == rect.bottom - rect.top
&& s_euBkStyle[i] == m_euBkStyle)
break;
}
if(i >= s_nNext) // not found
{
ASSERT(s_nNext<BS_KINDS); // don't
i = s_nNext;
s_nWidth[i] = rect.right - rect.left;
s_nHeight[i] = rect.bottom - rect.top;
s_euBkStyle[i] = m_euBkStyle;
s_nNext++;
}
if(!bEnabled) // disabled
{
// not loaded yet, load it now.
if(s_hbmBkgnd[i][DISABLED] == NULL)
{
if(s_euBkStyle[i] == BK_STD_MENU) // BK_STD_MENU
s_hbmBkgnd[i][DISABLED] = NavLoadBitmap(s_nWidth[i], s_nHeight[i], IDB_BMP_BTNDISABLED_STDMENU);
else if(s_euBkStyle[i] == BK_STD_OPER)// BK_STD_OPER
s_hbmBkgnd[i][DISABLED] = NavLoadBitmap(s_nWidth[i], s_nHeight[i], IDB_BMP_BTNDISABLED_STDOPER);
else if(s_euBkStyle[i] == BK_LITTLE_OPER)// BK_LITTLE_OPER
s_hbmBkgnd[i][DISABLED] = NavLoadBitmap(s_nWidth[i], s_nHeight[i], 0/*not used now, if need add it then*/);
else if(s_euBkStyle[i] == BK_RADIO)// BK_RADIO
s_hbmBkgnd[i][DISABLED] = NavLoadBitmap(s_nWidth[i], s_nHeight[i], 0/*not used now, if need add it then*/);
else // Unkown style
{
TRACE(_T("unknow button style\n"));
ASSERT(FALSE);
}
}
hbmBkgnd = s_hbmBkgnd[i][DISABLED];
} else if(bPressed) // pressed
{
if(s_hbmBkgnd[i][PRESSED] == NULL)
{
if(s_euBkStyle[i] == BK_STD_MENU)
s_hbmBkgnd[i][PRESSED] = NavLoadBitmap(s_nWidth[i], s_nHeight[i], IDB_BMP_BTNDOWN_STDMENU);
else if(s_euBkStyle[i] == BK_STD_OPER)// BK_STD_OPER
s_hbmBkgnd[i][PRESSED] = NavLoadBitmap(s_nWidth[i], s_nHeight[i], IDB_BMP_BTNDOWN_STDOPER);
else if(s_euBkStyle[i] == BK_LITTLE_OPER) // BK_LITTLE_OPER
s_hbmBkgnd[i][PRESSED] = NavLoadBitmap(s_nWidth[i], s_nHeight[i], IDB_BMP_BTNDOWN_LITTLEOPER);
else if(s_euBkStyle[i] == BK_RADIO) // BK_RADIO
s_hbmBkgnd[i][PRESSED] = NavLoadBitmap(s_nWidth[i], s_nHeight[i], IDB_BMP_BTNDOWN_RADIO/*same with checked status*/);
else
{
TRACE(_T("unknow button style\n"));
ASSERT(FALSE);
}
}
hbmBkgnd = s_hbmBkgnd[i][PRESSED];
} else if(bChecked) // checked
{
if(s_hbmBkgnd[i][CHECKED] == NULL)
{
if(s_euBkStyle[i] == BK_STD_MENU)
s_hbmBkgnd[i][CHECKED] = NavLoadBitmap(s_nWidth[i],s_nHeight[i],IDB_BMP_BTNCHECKED_STDOPER);//same this mode
else if(s_euBkStyle[i] == BK_STD_OPER)
s_hbmBkgnd[i][CHECKED] = NavLoadBitmap(s_nWidth[i],s_nHeight[i],IDB_BMP_BTNCHECKED_STDOPER);
else if(s_euBkStyle[i] == BK_LITTLE_OPER)// BK_LITTLE_OPER
s_hbmBkgnd[i][CHECKED] = NavLoadBitmap(s_nWidth[i], s_nHeight[i], 0/*not used now, if need add it then*/);
else if(s_euBkStyle[i] == BK_RADIO) // BK_RADIO
s_hbmBkgnd[i][CHECKED] = NavLoadBitmap(s_nWidth[i], s_nHeight[i], IDB_BMP_BTNCHECKED_RADIO/*same with checked status*/);
else // little oper button has no check status.
{
TRACE(_T("unknow button style\n"));
ASSERT(FALSE);
}
}
hbmBkgnd = s_hbmBkgnd[i][CHECKED];
} else // normal
{
if(s_hbmBkgnd[i][NORMAL] == NULL)
{
if(s_euBkStyle[i] == BK_STD_MENU)
s_hbmBkgnd[i][NORMAL] = NavLoadBitmap(s_nWidth[i],s_nHeight[i],IDB_BMP_BTNNORMAL_STDMENU);
else if(s_euBkStyle[i] == BK_STD_OPER)
s_hbmBkgnd[i][NORMAL] = NavLoadBitmap(s_nWidth[i],s_nHeight[i],IDB_BMP_BTNNORMAL_STDOPER);
else if(s_euBkStyle[i] == BK_LITTLE_OPER)
s_hbmBkgnd[i][NORMAL] = NavLoadBitmap(s_nWidth[i],s_nHeight[i],IDB_BMP_BTNNORMAL_LITTLEOPER);
else if(s_euBkStyle[i] == BK_RADIO)
s_hbmBkgnd[i][NORMAL] = NavLoadBitmap(s_nWidth[i],s_nHeight[i],IDB_BMP_BTNNORMAL_RADIO);
else
{
TRACE(_T("unknow button style\n"));
ASSERT(FALSE);
}
}
hbmBkgnd = s_hbmBkgnd[i][NORMAL];
}
return hbmBkgnd;
}
/***
*BOOL SetIcon() - set the icon resource ordinal and load it
*
*Purpose:
* Load the icons according to the resource ordinal.
*
*Entry:
* WORD wIconCode -- [in]the icon resource ordinal which will be displayed when button is in normal state.
* WORD wIconCodeDisable -- [in]the icon resource ordinal which will be displayed when button is in disabled state.
*
*Exit:
* if the function succeeds it return TRUE, else FALSE.
*
*Remarks:
* Set the parameters to zero, it will be a button without icon.
*
*******************************************************************************/
BOOL CNavButton::SetIcon(WORD wIconCode, WORD wIconCodeDisable)
{
// Delete the icons that are loaded before.
DestroyIcon(m_hIcon);
DestroyIcon(m_hIconDisable);
m_hIcon = m_hIconDisable = NULL;
if(wIconCode)
m_hIcon = (HICON)::LoadImage(NGetInstanceHandle(), MAKEINTRESOURCE(wIconCode), IMAGE_ICON, 0, 0, 0);
if(wIconCodeDisable)
m_hIconDisable = (HICON)::LoadImage(NGetInstanceHandle(), MAKEINTRESOURCE(wIconCodeDisable), IMAGE_ICON, 0, 0, 0);
if((wIconCode && !m_hIcon) || (wIconCodeDisable && !m_hIconDisable))
{
TRACE(_T("Load icon resource fail."));
ASSERT(FALSE);
return FALSE;
}
return TRUE;
}
void CNavButton::GetIconSize(DWORD &dwWidth, DWORD &dwHeight)
{
// it's not an icon button, set it's size to zero.
if(!m_hIcon)
{
dwWidth = dwHeight = 0;
return;
}
ICONINFO ii;
BOOL bRetValue;
RECT rc;
GetClientRect(&rc);
::ZeroMemory(&ii, sizeof(ICONINFO));
bRetValue = ::GetIconInfo(m_hIcon, &ii);
if (bRetValue == FALSE)
return ;
ii.xHotspot = ii.yHotspot = 16;
dwWidth = (DWORD)(ii.xHotspot * 2);
dwHeight = (DWORD)(ii.yHotspot * 2);
// not called in target version.
// this API's implementation in winCE may be different with
// that in windows. we have test this case in CE and it will
// not cause resource leak.
#ifdef PC_VERSION
::DeleteObject(ii.hbmMask);
::DeleteObject(ii.hbmColor);
#endif
// adjust the icon's height to appropriate height
if(dwHeight>(DWORD)((rc.bottom-rc.top)-2*(ICONMARGIN-2)))
dwWidth = dwHeight = (rc.bottom-rc.top)-2*(ICONMARGIN-2);
return;
}
void CNavButton::GetIconPos(int *px, int *py)
{
DWORD dwIconWidth = 0, dwIconHeight = 0; // windows icon size
// get client rect
int nWidth, nHeight; // button width and height
RECT rect;
GetClientRect(&rect);
nWidth = rect.right - rect.left;
nHeight = rect.bottom - rect.top;
// get window texxt
CNString strWindowText;
GetWindowText(strWindowText);
// Get icon dimension
GetIconSize(dwIconWidth,dwIconHeight);
if(_tcslen(strWindowText)==0) // caption is empty
{
// Centralize the icon if the button's caption is empty.
*px = rect.left + (nWidth-dwIconWidth)/2;
*py = rect.top + (nHeight-dwIconHeight)/2;
} else // caption is not empty
{
if(m_uIconFormat == 0) // draw icon on top
{
*px = rect.left + (nWidth-dwIconWidth)/2;
*py = rect.top + ICONMARGIN;
} else // draw icon on left
{
*px = rect.left + ICONMARGIN;
*py = rect.top + (nHeight-dwIconHeight)/2;
}
} // end if(_tcslen(strWindowText)==0)
}
void CNavButton::GetTextPos(RECT *prc)
{
DWORD dwIconWidth = 0, dwIconHeight = 0; // windows icon size
int nLines=1, pos=-1;
int nXOffset=0, nYOffset=0;
HDC hDC = NGetTempMemDC();
HFONT hOldFont;
TEXTMETRIC tm;
hOldFont = (HFONT)SelectObject(hDC, NGetNavFont());
GetTextMetrics(hDC, &tm);
// calaculate the total lines in the string
CNString strWindowText;
GetWindowText(strWindowText);
while((pos=strWindowText.Find('\n',pos+1)) != -1)
nLines++;
// Get icon dimension
if(IsIconButton())
{
if(0xFFFF != m_usIconCode) // If a KIWI icon on the button
{
// KWGetSymbolSize(&usIconWidth, &usIconHeight);
//nXOffset = 2*ICONMARGIN + usIconWidth;
}
else
{
GetIconSize(dwIconWidth, dwIconHeight);
if(m_uIconFormat == 0) // draw icon on top
{
//nXOffset = 2*ICONMARGIN + dwIconWidth;
DWORD h = (ICONMARGIN + dwIconHeight); // height occupied by icon
nYOffset = h+ ((prc->bottom - prc->top) - h - tm.tmHeight * nLines) / 2;
} else // draw icon on left
{
nXOffset = 2*ICONMARGIN + dwIconWidth;
nYOffset = ( (prc->bottom - prc->top) - tm.tmHeight * nLines) / 2;
}
}
}
else // button without icon
{
nYOffset = ( (prc->bottom-prc->top) - tm.tmHeight * nLines) / 2;
}
InflateRect(prc, -nXOffset/2, -nYOffset/2);
OffsetRect(prc, nXOffset/2, nYOffset/2);
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?