📄 sortheaderctrl.cpp
字号:
#include "stdafx.h"
#include "SortHeaderCtrl.h"
#include "SortListCtrl.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
int GetListCtrlImageIndex ( CListCtrl *pListCtrl, int nItem )
{
ASSERT ( pListCtrl );
LVITEM Item;
memset ( &Item, 0, sizeof(LVITEM) );
Item.mask = LVIF_IMAGE;
Item.iItem = nItem;
if ( !pListCtrl->GetItem ( &Item ) )
return -1;
return Item.iImage;
}
void TellListCtrl_ItemChange (
CWnd *pWnd,
CSortListCtrl *pListCtrl,
int nItem,
int nSubItem
)
{
CString csNewText;
pWnd->GetWindowText(csNewText);
CString csOldText = pListCtrl->GetItemText ( nItem, nSubItem );
if ( csOldText != csNewText )
{
CSortHeaderCtrl::t_MessageParameter MessageParameter;
memset ( &MessageParameter, 0, sizeof(CSortHeaderCtrl::t_MessageParameter) );
MessageParameter.nItem = nItem;
MessageParameter.nSubItem = nSubItem;
MessageParameter.lpszOldText = csOldText;
MessageParameter.lpszNewText = csNewText;
MessageParameter.nImageIndex = GetListCtrlImageIndex ( pListCtrl, nItem );
MessageParameter.dwItemData = pListCtrl->GetItemData ( nItem );
pListCtrl->GetParent()->SendMessage ( WM_SortCtrl_ItemChange,
(WPARAM)&MessageParameter, NULL );
pListCtrl->SetItemText ( nItem, nSubItem, csNewText );
}
}
CSortHeaderCtrl::CSortHeaderCtrl()
: m_iSortColumn( -1 )
, m_bSortAscending( TRUE )
{
}
CSortHeaderCtrl::~CSortHeaderCtrl()
{
}
BEGIN_MESSAGE_MAP(CSortHeaderCtrl, CHeaderCtrl)
//{{AFX_MSG_MAP(CSortHeaderCtrl)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CSortHeaderCtrl message handlers
void CSortHeaderCtrl::SetSortArrow( const int iSortColumn, const BOOL bSortAscending )
{
m_iSortColumn = iSortColumn;
m_bSortAscending = bSortAscending;
// change the item to owner drawn.
HD_ITEM hditem;
hditem.mask = HDI_FORMAT;
VERIFY( GetItem( iSortColumn, &hditem ) );
hditem.fmt |= HDF_OWNERDRAW;
VERIFY( SetItem( iSortColumn, &hditem ) );
// invalidate the header control so it gets redrawn
Invalidate();
}
void CSortHeaderCtrl::DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct )
{
// attath to the device context.
CDC dc;
VERIFY( dc.Attach( lpDrawItemStruct->hDC ) );
// save the device context.
const int iSavedDC = dc.SaveDC();
// get the column rect.
CRect rc( lpDrawItemStruct->rcItem );
// set the clipping region to limit drawing within the column.
CRgn rgn;
VERIFY( rgn.CreateRectRgnIndirect( &rc ) );
(void)dc.SelectObject( &rgn );
VERIFY( rgn.DeleteObject() );
// draw the background,
CBrush brush( GetSysColor( COLOR_3DFACE ) );
dc.FillRect( rc, &brush );
// get the column text and format.
TCHAR szText[ 256 ];
HD_ITEM hditem;
hditem.mask = HDI_TEXT | HDI_FORMAT;
hditem.pszText = szText;
hditem.cchTextMax = 255;
VERIFY( GetItem( lpDrawItemStruct->itemID, &hditem ) );
// determine the format for drawing the column label.
UINT uFormat = DT_SINGLELINE | DT_NOPREFIX | DT_NOCLIP | DT_VCENTER | DT_END_ELLIPSIS ;
if( hditem.fmt & HDF_CENTER)
uFormat |= DT_CENTER;
else if( hditem.fmt & HDF_RIGHT)
uFormat |= DT_RIGHT;
else
uFormat |= DT_LEFT;
// adjust the rect if the mouse button is pressed on it.
if( lpDrawItemStruct->itemState == ODS_SELECTED )
{
rc.left++;
rc.top += 2;
rc.right++;
}
CRect rcIcon( lpDrawItemStruct->rcItem );
const int iOffset = ( rcIcon.bottom - rcIcon.top ) / 4;
// adjust the rect further if the sort arrow is to be displayed.
if( lpDrawItemStruct->itemID == (UINT)m_iSortColumn )
rc.right -= 3 * iOffset;
rc.left += iOffset;
rc.right -= iOffset;
// draw the column label.
if( rc.left < rc.right )
(void)dc.DrawText( szText, -1, rc, uFormat );
// draw the sort arrow.
if( lpDrawItemStruct->itemID == (UINT)m_iSortColumn )
{
// set up the pens to use for drawing the arrow.
CPen penLight( PS_SOLID, 1, GetSysColor( COLOR_3DHILIGHT ) );
CPen penShadow( PS_SOLID, 1, GetSysColor( COLOR_3DSHADOW ) );
CPen* pOldPen = dc.SelectObject( &penLight );
if( m_bSortAscending )
{
// draw the arrow pointing upwards.
dc.MoveTo( rcIcon.right - 2 * iOffset, iOffset);
dc.LineTo( rcIcon.right - iOffset, rcIcon.bottom - iOffset - 1 );
dc.LineTo( rcIcon.right - 3 * iOffset - 2, rcIcon.bottom - iOffset - 1 );
(void)dc.SelectObject( &penShadow );
dc.MoveTo( rcIcon.right - 3 * iOffset - 1, rcIcon.bottom - iOffset - 1 );
dc.LineTo( rcIcon.right - 2 * iOffset, iOffset - 1);
}
else
{
// draw the arrow pointing downwards.
dc.MoveTo( rcIcon.right - iOffset - 1, iOffset );
dc.LineTo( rcIcon.right - 2 * iOffset - 1, rcIcon.bottom - iOffset );
(void)dc.SelectObject( &penShadow );
dc.MoveTo( rcIcon.right - 2 * iOffset - 2, rcIcon.bottom - iOffset );
dc.LineTo( rcIcon.right - 3 * iOffset - 1, iOffset );
dc.LineTo( rcIcon.right - iOffset - 1, iOffset );
}
// restore the pen.
(void)dc.SelectObject( pOldPen );
}
// restore the previous device context.
VERIFY( dc.RestoreDC( iSavedDC ) );
// detach the device context before returning.
(void)dc.Detach();
}
void CSortHeaderCtrl::Serialize( CArchive& ar )
{
if( ar.IsStoring() )
{
const int iItemCount = GetItemCount();
if( iItemCount != -1 )
{
ar << iItemCount;
HD_ITEM hdItem = { 0 };
hdItem.mask = HDI_WIDTH;
for( int i = 0; i < iItemCount; i++ )
{
VERIFY( GetItem( i, &hdItem ) );
ar << hdItem.cxy;
}
}
}
else
{
#ifndef _DEBUG
int iItemCount;
ar >> iItemCount;
if( GetItemCount() != iItemCount )
TRACE0( _T("Different number of columns in registry.") );
else
{
HD_ITEM hdItem = { 0 };
hdItem.mask = HDI_WIDTH;
for( int i = 0; i < iItemCount; i++ )
{
ar >> hdItem.cxy;
VERIFY( SetItem( i, &hdItem ) );
}
}
#endif
}
}
/////////////////////////////////////////////////////////////////////////////
// CComboBoxForListCtrl
CComboBoxForListCtrl::CComboBoxForListCtrl(int nItem, int nSubItem, CStringArray *pStrAry, CComboBoxForListCtrl **ppCombo)
{
if ( pStrAry ) m_StrAry.Append ( *pStrAry );
m_nItem = nItem;
m_nSubItem = nSubItem;
m_bVK_ESCAPE = FALSE;
m_ppCombo = ppCombo;
}
CComboBoxForListCtrl::~CComboBoxForListCtrl()
{
m_StrAry.RemoveAll();
}
BEGIN_MESSAGE_MAP(CComboBoxForListCtrl, CComboBox)
//{{AFX_MSG_MAP(CComboBoxForListCtrl)
ON_WM_CREATE()
ON_WM_NCDESTROY()
ON_WM_KILLFOCUS()
ON_CONTROL_REFLECT(CBN_CLOSEUP, OnCloseup)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CComboBoxForListCtrl message handlers
int CComboBoxForListCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CComboBox::OnCreate(lpCreateStruct) == -1)
return -1;
CFont* font = GetParent()->GetFont();
SetFont(font);
for ( int i=0; i<m_StrAry.GetSize(); i++ )
{
AddString ( m_StrAry.GetAt(i) );
}
SetFocus();
return 0;
}
BOOL CComboBoxForListCtrl::PreTranslateMessage(MSG* pMsg)
{
if ( pMsg->message == WM_KEYDOWN )
{
if ( pMsg->wParam == VK_RETURN || pMsg->wParam == VK_ESCAPE )
{
if( pMsg->wParam == VK_ESCAPE )
m_bVK_ESCAPE = TRUE;
::TranslateMessage(pMsg);
::DispatchMessage(pMsg);
return TRUE;
}
}
return CComboBox::PreTranslateMessage(pMsg);
}
void CComboBoxForListCtrl::OnNcDestroy()
{
CComboBox::OnNcDestroy();
if ( m_ppCombo && *m_ppCombo ) *m_ppCombo = NULL;
delete this;
}
void CComboBoxForListCtrl::OnKillFocus(CWnd* pNewWnd)
{
CComboBox::OnKillFocus(pNewWnd);
if ( GetCurSel() >= 0 )
{
CSortListCtrl *pListCtrl = (CSortListCtrl*)GetParent();
if ( !m_bVK_ESCAPE )
{
TellListCtrl_ItemChange ( this, pListCtrl, m_nItem, m_nSubItem );
}
PostMessage(WM_CLOSE);
if ( m_ppCombo && *m_ppCombo ) *m_ppCombo = NULL;
}
delete this;
}
void CComboBoxForListCtrl::OnCloseup()
{
CListCtrl *pListCtrl = (CListCtrl*)GetParent();
pListCtrl->SetFocus();
pListCtrl->Invalidate();
}
/////////////////////////////////////////////////////////////////////////////
// CEditForListCtrl
CEditForListCtrl::CEditForListCtrl(int nItem, int nSubItem, CString &sContent, CEditForListCtrl **ppEdit)
{
m_nItem = nItem;
m_nSubItem = nSubItem;
m_sContent = sContent;
m_bVK_ESCAPE = FALSE;
m_ppEdit = ppEdit;
}
CEditForListCtrl::~CEditForListCtrl()
{
}
BEGIN_MESSAGE_MAP(CEditForListCtrl, CEdit)
//{{AFX_MSG_MAP(CEditForListCtrl)
ON_WM_CREATE()
ON_WM_KILLFOCUS()
ON_WM_NCDESTROY()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CEditForListCtrl message handlers
int CEditForListCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CEdit::OnCreate(lpCreateStruct) == -1)
return -1;
CFont* font = GetParent()->GetFont();
SetFont(font);
SetWindowText(m_sContent);
SetFocus();
SetSel(0, -1);
return 0;
}
void CEditForListCtrl::OnKillFocus(CWnd* pNewWnd)
{
CEdit::OnKillFocus(pNewWnd);
CSortListCtrl *pListCtrl = (CSortListCtrl*)GetParent();
if ( !m_bVK_ESCAPE )
{
TellListCtrl_ItemChange ( this, pListCtrl, m_nItem, m_nSubItem );
}
PostMessage(WM_CLOSE);
if ( m_ppEdit && *m_ppEdit ) *m_ppEdit = NULL;
delete this;
}
BOOL CEditForListCtrl::PreTranslateMessage(MSG* pMsg)
{
if( pMsg->message == WM_KEYDOWN )
{
if( pMsg->wParam == VK_RETURN ||
pMsg->wParam == VK_DELETE ||
pMsg->wParam == VK_ESCAPE ||
GetKeyState( VK_CONTROL))
{
if( pMsg->wParam == VK_ESCAPE )
m_bVK_ESCAPE = TRUE;
::TranslateMessage(pMsg);
::DispatchMessage(pMsg);
return 1;
}
}
return CEdit::PreTranslateMessage(pMsg);
}
void CEditForListCtrl::OnNcDestroy()
{
CEdit::OnNcDestroy();
if ( m_ppEdit && *m_ppEdit ) *m_ppEdit = NULL;
delete this;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -