📄 xpcombobox.cpp
字号:
// XPComboBox.cpp : implementation file
//
#include "stdafx.h"
#include "XPComboBox.h"
#include "bcgbarres.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CXPComboBox
CXPComboBox::CXPComboBox()
{
m_clrBtnFace= ::GetSysColor(COLOR_3DFACE);
m_clrBtnLight=::GetSysColor(COLOR_3DHILIGHT);
m_clrBtnDark=::GetSysColor(COLOR_3DSHADOW);
m_iWidthDrowDown=GetSystemMetrics(SM_CXHTHUMB);
m_bOverCombo=FALSE;
m_Font.CreateStockObject (DEFAULT_GUI_FONT);
m_bPress=FALSE;
m_imgArrow.Create(IDB_DOCKBAR,9,11,RGB(255,0,255));
CBitmap cbmp;
BITMAP bmp;
cbmp.LoadBitmap(IDB_DOCKBAR);
cbmp.GetBitmap(&bmp);
mHeight=CPoint(bmp.bmWidth,bmp.bmHeight);
m_bFondoXp=FALSE;
m_IsCallMiniTool=FALSE;
bColor=TRUE;
bhistory=FALSE;
m_pImageList = NULL;
m_crfCBTextColor = GetSysColor(COLOR_BTNTEXT);
memset(&m_logCBFont, 0, sizeof(LOGFONT)); // zero out structure
m_logCBFont.lfHeight = 15; // request a 12-pixel-height font
///m_logCBFont.lfWeight = FW_BOLD;
strcpy((char*)m_logCBFont.lfFaceName, (const char*)"Courier");// request a face name "Arial"
}
CXPComboBox::~CXPComboBox()
{
}
void CXPComboBox::OnSysColorChange( )
{
CComboBox::OnSysColorChange( );
m_clrBtnLight=::GetSysColor(COLOR_3DHILIGHT);
m_clrBtnDark=::GetSysColor(COLOR_3DSHADOW);
if (bColor)
m_clrBtnFace= ::GetSysColor(COLOR_3DFACE);
}
void CXPComboBox::AutoColor(BOOL bAColor)
{
bColor=bAColor;
}
BEGIN_MESSAGE_MAP(CXPComboBox, CComboBox)
//{{AFX_MSG_MAP(CGuiComboFont)
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_PAINT()
ON_WM_SETCURSOR()
ON_WM_TIMER()
ON_CONTROL_REFLECT(CBN_KILLFOCUS, OnCbnKillfocus)
//ON_CONTROL_REFLECT(CBN_KILLFOCUS, OnKillFocus)
ON_WM_SETFOCUS()
ON_WM_CREATE()
ON_WM_SYSCOLORCHANGE()
ON_CONTROL_REFLECT(CBN_CLOSEUP, OnCloseup)
//}}AFX_MSG_MAP
ON_CONTROL_REFLECT(CBN_EDITUPDATE, OnCbnEditupdate)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CGuiComboFont message handlers
void CXPComboBox::PreSubclassWindow()
{
CComboBox::PreSubclassWindow();
}
void CXPComboBox::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
m_bOverCombo=TRUE;
m_bPress=TRUE;
CClientDC dc(this);
DrawCombo(CM_SELECCIONADO,&dc);
CComboBox::OnLButtonDown(nFlags, point);
}
void CXPComboBox::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
if (m_IsCallMiniTool==TRUE)
m_bPress=FALSE;
CComboBox::OnLButtonUp(nFlags, point);
}
void CXPComboBox::OnPaint()
{
CPaintDC dc(this); // device context for painting
/*
* Se hace un llamamdo a la funci髇 definida por defecto
* para el procesamiento de mensajes que la aplicaci髇 definitivamente
* no esta interesado en manejar
**/
CComboBox::DefWindowProc(WM_PAINT,(WPARAM)dc.m_hDC,0);
if (m_bPress != TRUE)
DrawCombo(CM_NORMAL,&dc);
else
DrawCombo(CM_SELECCIONADO,&dc);
// Do not call CComboBox::OnPaint() for painting messages
}
void CXPComboBox::OnSetFocus(CWnd* pOldWnd)
{
CComboBox::OnSetFocus(pOldWnd);
CClientDC dc(this);
DrawCombo(CM_SELECCIONADO,&dc);
}
BOOL CXPComboBox::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
// TODO: Add your message handler code here and/or call default
CPoint ptCurPos;
CRect m_rcCli;
GetCursorPos (&ptCurPos);
ScreenToClient (&ptCurPos);
GetClientRect(&m_rcCli);
if (m_rcCli.PtInRect (ptCurPos) && m_bOverCombo==FALSE && m_bPress==FALSE)
{
m_bOverCombo=TRUE;
CClientDC dc(this);
DrawCombo(CM_ONFOCUS,&dc);
SetTimer(1,10,NULL);
OnTimer(1);
return TRUE;
}
return CComboBox::OnSetCursor(pWnd, nHitTest, message);
}
void CXPComboBox::SetColor(COLORREF clrFace)
{
m_clrBtnFace=clrFace;
Invalidate();
UpdateWindow();
}
void CXPComboBox::DrawCombo(enTypeShow enShow,CDC* pDC)
{
CRect m_rcClient;
CRect m_rcDropDown;
GetClientRect(&m_rcClient);
m_rcClient.bottom-=2;
//primero eliminamos los bordes 3D del combobox
pDC->Draw3dRect(&m_rcClient,m_clrBtnFace,m_clrBtnFace);
m_rcClient.DeflateRect(1,1);
if (IsWindowEnabled())
{
if (enShow==CM_NORMAL)
pDC->Draw3dRect(&m_rcClient,GuiDrawLayer::GetRGBPressBXP(),GuiDrawLayer::GetRGBPressBXP());
}
else
pDC->Draw3dRect(&m_rcClient,m_clrBtnLight,m_clrBtnLight);
if (enShow==CM_NORMAL)
pDC->Draw3dRect(&m_rcClient,m_clrBtnFace,m_clrBtnFace);
else // && !XP
pDC->Draw3dRect(&m_rcClient,GuiDrawLayer::GetRGBCaptionXP(),GuiDrawLayer::GetRGBCaptionXP());
//debemos pintar el borde del boton drawDwon
m_rcClient.DeflateRect(1,1);
m_rcClient.left=m_rcClient.right-m_iWidthDrowDown;
pDC->Draw3dRect(&m_rcClient,m_clrBtnFace,m_clrBtnFace);
m_rcClient.DeflateRect(1,1);
pDC->Draw3dRect(&m_rcClient,GuiDrawLayer::GetRGBCaptionXP(),GuiDrawLayer::GetRGBCaptionXP());
m_rcClient.InflateRect(0,1);
if (enShow==CM_NORMAL)
{
//el boton no esta seleccionado
m_rcClient.right += 1;
m_rcClient.left -= 1;
pDC->Draw3dRect(&m_rcClient,m_clrBtnLight,m_clrBtnLight);
m_rcClient.DeflateRect(1,1);
CBrush cblu;
cblu.CreateSolidBrush( m_clrBtnFace);
pDC->FillRect(&m_rcClient,&cblu);
m_rcClient.left += 2;
m_rcClient.right+= 2;
DrawArrow(pDC,m_rcClient);
}
else
{
m_rcClient.InflateRect(1,1);
CBrush cblu;
cblu.CreateSolidBrush(enShow == CM_ONFOCUS? GuiDrawLayer::GetRGBFondoXP():GuiDrawLayer::GetRGBPressBXP());
pDC->FillRect(&m_rcClient,&cblu);
m_rcClient.right += 1;
pDC->Draw3dRect(&m_rcClient,GuiDrawLayer::GetRGBCaptionXP(),GuiDrawLayer::GetRGBCaptionXP());
DrawArrow(pDC,m_rcClient);
}
}
void CXPComboBox::DrawArrow(CDC* pDC,CRect m_rc)
{
int difh =m_rc.Height()-mHeight.y;
difh/=2;
m_rc.left=m_rc.right-m_iWidthDrowDown;
m_imgArrow.Draw(pDC,0,CPoint(m_rc.left+2,m_rc.top+difh),ILD_TRANSPARENT);
}
void CXPComboBox::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
if (nIDEvent== 1)
{
CPoint pt(GetMessagePos());
CRect m_rc;
ScreenToClient(&pt);
GetClientRect(m_rc);
if (!m_rc.PtInRect(pt) && m_bPress!=TRUE)
{
KillTimer(1);
m_bOverCombo=FALSE;
CClientDC dc(this);
if (m_bPress==FALSE)
DrawCombo(CM_NORMAL,&dc);
else
DrawCombo(CM_ONFOCUS,&dc);
m_bPress=FALSE;
}
}
CComboBox::OnTimer(nIDEvent);
}
void CXPComboBox::OnCloseup()
{
// TODO: Add your control notification handler code here
CClientDC dc(this);
m_bPress=FALSE;
OnTimer(1);
}
//void CGuiComboFont::OnKillFocus(CWnd* pNewWnd) //version 6
void CXPComboBox::OnCbnKillfocus() //version 7.0
{
CClientDC dc(this);
DrawCombo(CM_NORMAL,&dc);
if (!(GetStyle( ) & CBS_DROPDOWNLIST))
{
CString sCad;
GetWindowText(sCad);
AddString(sCad);
}
m_bPress=FALSE;
m_bOverCombo=FALSE;
// TODO: Add your message handler code here
}
int CXPComboBox::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CComboBox::OnCreate(lpCreateStruct) == -1)
return -1;
SetFont(&m_Font);
return 0;
}
void CXPComboBox::OnCbnEditupdate()
{
CString m_szCad;
GetWindowText(m_szCad);
DWORD m_dwCurRange=GetEditSel();
DWORD m_dwStart=LOWORD(m_dwCurRange);
DWORD m_dwEnd = HIWORD(m_dwCurRange);
//se busca la cadena aprox, si no existe se debe insertar
if (SelectString(-1,m_szCad) == CB_ERR)
{
SetCurSel( 0);
}
else
{
if (m_dwCurRange != CB_ERR)
{
if (m_dwEnd <(DWORD) m_szCad.GetLength())
SetEditSel(m_dwStart,m_dwEnd);
else
SetEditSel(m_szCad.GetLength(),-1);
}
}
}
void CXPComboBox::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)
{
ASSERT(lpMeasureItemStruct->CtlType == ODT_COMBOBOX);
if (lpMeasureItemStruct->itemID != (UINT) -1)
{
LPCTSTR lpszText = (LPCTSTR) lpMeasureItemStruct->itemData;
ASSERT(lpszText != NULL);
CSize sz;
CDC* pDC = GetDC();
sz = pDC->GetTextExtent(lpszText);
ReleaseDC(pDC);
lpMeasureItemStruct->itemHeight = 2*sz.cy;
}
}
void CXPComboBox::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
ASSERT(lpDrawItemStruct->CtlType == ODT_COMBOBOX);
int nIndex = lpDrawItemStruct->itemID;
CDC dc;
dc.Attach(lpDrawItemStruct->hDC);
int cx = 0, cy = 0;
int iImage = -1;
if(nIndex == -1)return;
CString strItem;
GetLBText(nIndex,strItem);
CRect rcText(lpDrawItemStruct->rcItem);
CFont font;
VERIFY(font.CreateFontIndirect(&m_logCBFont)); // create the font
CFont* pOldFont = dc.SelectObject(&font);
if(m_pImageList != NULL)
{
iImage = GetImage(strItem);
if(iImage != -1)
{
int iImageCount = m_pImageList->GetImageCount();
//TRACE1("%d Image :\n",iImage);
::ImageList_GetIconSize(*m_pImageList, &cx, &cy);
rcText.DeflateRect(cx,0,0,0);
}
}
// Save these value to restore them when done drawing.
COLORREF crOldTextColor = dc.GetTextColor();
COLORREF crOldBkColor = dc.GetBkColor();
int nMode = dc.SetBkColor(TRANSPARENT);
//not responsible for drawing selection
if ((lpDrawItemStruct->itemAction | ODA_SELECT) &&
(lpDrawItemStruct->itemState & ODS_SELECTED))
{
dc.SetTextColor(::GetSysColor(COLOR_HIGHLIGHTTEXT));
dc.SetBkColor(::GetSysColor(COLOR_HIGHLIGHT));
dc.FillSolidRect(&rcText, ::GetSysColor(COLOR_HIGHLIGHT));
}
else
{
//CBrush backgrndBrush(RGB(192,192,192));
//dc.Rectangle(&lpDrawItemStruct->rcItem);
//backgrndBrush.DeleteObject();
dc.FillSolidRect(&lpDrawItemStruct->rcItem, crOldBkColor);
dc.SetTextColor(m_crfCBTextColor);
}
dc.DrawText(strItem,strItem.GetLength(),&rcText,
DT_LEFT|DT_SINGLELINE/*|DT_VCENTER*/);
if(iImage != -1)
m_pImageList->Draw(&dc,iImage,CPoint(rcText.left-cx,rcText.top),ILD_TRANSPARENT);
// Reset the background color and the text color back to their
// original values.
dc.SetTextColor(crOldTextColor);
dc.SetBkColor(crOldBkColor);
dc.SetBkMode(nMode);
dc.SelectObject(pOldFont);
font.DeleteObject();
dc.Detach();
}
int CXPComboBox::AddString(LPCTSTR szpText,int iImage /*= -1*/)
{
int nResult = CComboBox::AddString(szpText);
if(nResult != CB_ERR && nResult != CB_ERRSPACE)
{
m_iImageStringMap.SetAt(szpText,iImage);
}
return nResult;
}
int CXPComboBox::GetImage(LPCTSTR lszpItem)
{
for(POSITION nPos = m_iImageStringMap.GetStartPosition(); nPos != NULL;)
{
int iImage;
LPCTSTR lszpString;
m_iImageStringMap.GetNextAssoc(nPos,(LPCTSTR)lszpString,iImage);
if(strcmp((const char *)lszpItem,(const char *)lszpString) == 0)
return iImage;
}
return -1;
}
void CXPComboBox::DeleteImage(LPCTSTR lszpItem)
{
m_iImageStringMap.RemoveKey(lszpItem);
}
int CXPComboBox::DeleteString(UINT nIndex)
{
ASSERT(nIndex<(UINT)GetCount());
CString strItem;
GetLBText(nIndex,strItem);
DeleteImage(strItem);
return CComboBox::DeleteString(nIndex);
}
void CXPComboBox::ResetContent()
{
m_iImageStringMap.RemoveAll();
CComboBox::ResetContent();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -