RadioListBox.cpp
#include "SF_RadioListBox.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define ID_EDIT_BOX 1000
CRadioListBox::CRadioListBox()
{
m_nEditId = -1;
}
CRadioListBox::~CRadioListBox()
{
}
BEGIN_MESSAGE_MAP( CRadioListBox, CListBox )
ON_WM_CTLCOLOR_REFLECT()
ON_WM_LBUTTONDBLCLK()
ON_WM_LBUTTONDOWN()
ON_WM_CREATE()
ON_EN_KILLFOCUS( ID_EDIT_BOX, OnEnKillfocusEdit )
END_MESSAGE_MAP()
void CRadioListBox::DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct )
{
CDC* pDC = CDC::FromHandle( lpDrawItemStruct->hDC );
if ( lpDrawItemStruct->itemID == (UINT)-1 )
{
if ( lpDrawItemStruct->itemAction & ODA_FOCUS )
pDC->DrawFocusRect( &lpDrawItemStruct->rcItem );
return;
}
else
{
int selChange = lpDrawItemStruct->itemAction & ODA_SELECT;
int focusChange = lpDrawItemStruct->itemAction & ODA_FOCUS;
int drawEntire = lpDrawItemStruct->itemAction & ODA_DRAWENTIRE;
if ( selChange || drawEntire )
{
BOOL sel = lpDrawItemStruct->itemState & ODS_SELECTED;
pDC->FillSolidRect( &lpDrawItemStruct->rcItem,
::GetSysColor( (GetExStyle()&WS_EX_TRANSPARENT) ? COLOR_BTNFACE : COLOR_WINDOW ) );
int h = lpDrawItemStruct->rcItem.bottom - lpDrawItemStruct->rcItem.top;
CRect rect( lpDrawItemStruct->rcItem.left + 2, lpDrawItemStruct->rcItem.top + 2,
lpDrawItemStruct->rcItem.left + h - 3, lpDrawItemStruct->rcItem.top + h - 3 );
pDC->DrawFrameControl( &rect, DFC_BUTTON, DFCS_BUTTONRADIO | (sel ? DFCS_CHECKED : 0) );
{
pDC->SetTextColor( COLOR_WINDOWTEXT );
pDC->SetBkMode( TRANSPARENT );
lpDrawItemStruct->rcItem.left += h;
CString str;
GetText( lpDrawItemStruct->itemID, str );
pDC->DrawText( str, &lpDrawItemStruct->rcItem, DT_LEFT | DT_VCENTER );
}
}
{
if ( focusChange || (drawEntire && (lpDrawItemStruct->itemState & ODS_FOCUS)) )
pDC->DrawFocusRect( &lpDrawItemStruct->rcItem );
}
}
}
HBRUSH CRadioListBox::CtlColor( CDC* pDC, UINT nCtlColor )
{
if ( (GetExStyle()&WS_EX_TRANSPARENT) && nCtlColor == CTLCOLOR_LISTBOX )
return (HBRUSH)::GetSysColorBrush( COLOR_BTNFACE );
return NULL;
}
void CRadioListBox::OnLButtonDblClk( UINT nFlags, CPoint point )
{
CListBox::OnLButtonDblClk( nFlags, point );
}
void CRadioListBox::OnLButtonDown( UINT nFlags, CPoint point )
{
CListBox::OnLButtonDown( nFlags, point );
int nCur = GetCurSel();
if ( nCur == LB_ERR )
return;
CRect rcItem;
GetItemRect( nCur, rcItem );
int h = rcItem.bottom - rcItem.top;
rcItem.left += h;
if( rcItem.PtInRect( point ) )
EditStarts( rcItem );
}
void CRadioListBox::EditStarts(const CRect& rc)
{
int nCur = GetCurSel();
if ( nCur == LB_ERR )
return;
m_edit.MoveWindow( CRect( rc.left, rc.top, rc.right, rc.bottom + 2 ) );
CString str;
GetText( nCur, str );
m_edit.SetWindowText( str );
m_edit.SetFocus();
m_edit.SetSel( 0, -1, TRUE );
m_edit.ShowWindow( TRUE );
m_nEditId = nCur;
}
int CRadioListBox::OnCreate( LPCREATESTRUCT lpCreateStruct )
{
if ( CListBox::OnCreate( lpCreateStruct ) == -1 )
return -1;
Init();
return 0;
}
void CRadioListBox::OnEnKillfocusEdit()
{
if ( m_edit.IsWindowVisible() == FALSE )
{
m_nEditId = -1;
return;
}
CString str;
m_edit.GetWindowText( str );
m_edit.ShowWindow( FALSE );
if ( str.GetLength() )
{
DeleteString( m_nEditId );
InsertString( m_nEditId, str );
SetCurSel( m_nEditId );
}
m_nEditId = -1;
}
BOOL CRadioListBox::SubclassDlgItem( UINT nID, CWnd* pParent )
{
BOOL bRet = CListBox::SubclassDlgItem( nID, pParent );
Init();
return bRet;
}
void CRadioListBox::Init(UINT nId , CWnd* pParentWnd )
{
if ( m_hWnd == NULL )
{
Create(
WS_CHILD | WS_VISIBLE | WS_BORDER | LBS_HASSTRINGS | WS_HSCROLL | WS_VSCROLL | LBS_OWNERDRAWVARIABLE | LBS_WANTKEYBOARDINPUT,
CRect(), pParentWnd, nId );
}
if ( m_edit.m_hWnd == NULL )
{
m_edit.Create( WS_VISIBLE | WS_CHILD | ES_LEFT | ES_AUTOHSCROLL, CRect(), this, 1000 );
m_edit.ModifyStyleEx( 0, WS_EX_CLIENTEDGE );
m_edit.ShowWindow( FALSE );
m_edit.SetFont( this->GetFont() );
}
}
int CRadioListBox::InsertString( int nIndex, LPCTSTR lpszItem )
{
int nRet = CListBox::InsertString( nIndex, lpszItem );
if ( nRet != LB_ERR )
{
SetItemHeight( nRet, (UINT)(GetItemHeight( nRet ) * 1.06) );
}
return nRet;
}
int CRadioListBox::AddString( LPCTSTR lpszItem )
{
int nRet = CListBox::AddString( lpszItem );
if ( nRet != LB_ERR )
{
SetItemHeight( nRet, (UINT)(GetItemHeight( nRet ) * 1.06) );
}
return nRet;
}
BOOL CRadioListBox::PreTranslateMessage( MSG* pMsg )
{
if ( pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RETURN )
{
if ( ::GetFocus() == m_edit.GetSafeHwnd() )
{
SetFocus();
return TRUE;
}
}
return CListBox::PreTranslateMessage( pMsg );
}
RadioListBox.h
#ifndef _RADIOLIST_BOX_H_
#define _RADIOLIST_BOX_H_
class CRadioListBox : public CListBox
{
public:
CRadioListBox();
virtual ~CRadioListBox();
void Init(UINT nId = -1, CWnd* pParentWnd = NULL);
public:
int InsertString( int nIndex, LPCTSTR lpszItem );
int AddString( LPCTSTR lpszItem );
public:
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
public:
void EditStarts( const CRect& rc );
BOOL SubclassDlgItem( UINT nID, CWnd* pParent );
protected:
//{{AFX_MSG(CRadioListBox)
afx_msg HBRUSH CtlColor(CDC* pDC, UINT nCtlColor);
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point);
afx_msg void OnLButtonDown( UINT nFlags, CPoint point );
afx_msg int OnCreate( LPCREATESTRUCT lpCreateStruct );
afx_msg void OnEnKillfocusEdit();
protected:
CEdit m_edit;
UINT m_nEditId;
public:
virtual BOOL PreTranslateMessage( MSG* pMsg );
};
#endif

