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 + -
显示快捷键?