2026-10-04 00:04:20 +08:00
|
|
|
// Author: SFr frydaysoft@gmx.de
|
2026-09-28 15:28:50 +08:00
|
|
|
|
|
|
|
|
#include "stdafx.h"
|
|
|
|
|
#include "HListCtrl.h"
|
|
|
|
|
|
|
|
|
|
#ifdef _DEBUG
|
|
|
|
|
#define new DEBUG_NEW
|
|
|
|
|
#undef THIS_FILE
|
|
|
|
|
static char THIS_FILE[] = __FILE__;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
CHListCtrl::CHListCtrl(int colSize)
|
|
|
|
|
{
|
|
|
|
|
m_columnSize=colSize; // number of columns
|
|
|
|
|
m_fullColumnLines=TRUE; // paint vert. lines | | |
|
|
|
|
|
m_withSingleRect=FALSE; // paint single rect for all sub-items
|
|
|
|
|
#ifdef _DEBUG
|
|
|
|
|
m_BigFocusRect=TRUE; // focus-rect with small/big dots
|
|
|
|
|
#endif
|
|
|
|
|
#ifndef _DEBUG
|
|
|
|
|
m_BigFocusRect=FALSE; // focus-rect with small/big dots
|
|
|
|
|
#endif
|
|
|
|
|
IsCreated=FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//***************************************************************
|
|
|
|
|
CHListCtrl::~CHListCtrl()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//***************************************************************
|
|
|
|
|
BEGIN_MESSAGE_MAP(CHListCtrl, CListCtrl)
|
|
|
|
|
//{{AFX_MSG_MAP(CHListCtrl)
|
|
|
|
|
ON_WM_PAINT()
|
|
|
|
|
ON_WM_DESTROY()
|
|
|
|
|
ON_WM_KILLFOCUS()
|
|
|
|
|
ON_WM_SETFOCUS()
|
|
|
|
|
ON_WM_SIZE()
|
|
|
|
|
//}}AFX_MSG_MAP
|
|
|
|
|
END_MESSAGE_MAP()
|
|
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
2026-10-04 00:04:20 +08:00
|
|
|
// Behandlungsroutinen f黵 Nachrichten CHListCtrl
|
2026-09-28 15:28:50 +08:00
|
|
|
void CHListCtrl::OnDestroy()
|
|
|
|
|
{
|
|
|
|
|
DeleteAllItems();
|
|
|
|
|
CListCtrl::OnDestroy();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//***************************************************************
|
|
|
|
|
void CHListCtrl::SetColumnType(BOOL bNew)
|
|
|
|
|
{
|
|
|
|
|
m_fullColumnLines=bNew; // paint no/vert. lines | | |
|
|
|
|
|
if (IsCreated)
|
|
|
|
|
{
|
|
|
|
|
RedrawWindow();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
void CHListCtrl::SetRectType(BOOL bNew)
|
|
|
|
|
{
|
|
|
|
|
m_withSingleRect=bNew; // paint no/single rect for all sub-items
|
|
|
|
|
if (IsCreated)
|
|
|
|
|
{
|
|
|
|
|
RedrawWindow();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
void CHListCtrl::SetFocusType(BOOL bNew)
|
|
|
|
|
{
|
|
|
|
|
m_BigFocusRect=bNew; // focus-rect with small/big dots
|
|
|
|
|
if (IsCreated)
|
|
|
|
|
{
|
|
|
|
|
RedrawWindow();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//***************************************************************
|
|
|
|
|
CMyLParam* CHListCtrl::GetMyLParam(int Index)
|
|
|
|
|
{
|
|
|
|
|
LVITEM Item;
|
|
|
|
|
Item.mask = LVIF_PARAM;
|
|
|
|
|
Item.iItem = Index;
|
|
|
|
|
Item.iSubItem = 0;
|
|
|
|
|
CListCtrl::GetItem(&Item);
|
|
|
|
|
return (CMyLParam*)Item.lParam;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//***************************************************************
|
|
|
|
|
CRect CHListCtrl::GetFullCellRect(int nItem, BOOL outside)
|
|
|
|
|
{
|
|
|
|
|
static CRect rectCell;
|
|
|
|
|
CListCtrl::GetItemRect(nItem, rectCell, LVIR_BOUNDS);
|
|
|
|
|
if (!outside)
|
|
|
|
|
{ //decrease 1 pixel
|
|
|
|
|
rectCell.left++; rectCell.right--;
|
|
|
|
|
rectCell.top++; rectCell.bottom--;
|
|
|
|
|
}
|
|
|
|
|
return rectCell;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//***************************************************************
|
|
|
|
|
CRect CHListCtrl::GetCellRect(int nItem, int nColumn, BOOL outside)
|
|
|
|
|
{
|
|
|
|
|
static CRect rectCell;
|
|
|
|
|
|
|
|
|
|
// Get the height
|
|
|
|
|
CListCtrl::GetItemRect(nItem, rectCell, LVIR_BOUNDS);
|
|
|
|
|
LV_COLUMN column;
|
|
|
|
|
column.mask = LVCF_WIDTH; // Set the mask to only return the width
|
|
|
|
|
|
|
|
|
|
for (int x=0; x<nColumn; x++)
|
|
|
|
|
{
|
|
|
|
|
column.iSubItem=1;
|
|
|
|
|
CListCtrl::GetColumn(x, &column); // Get rect-edge (left/top)
|
|
|
|
|
rectCell.left+=column.cx;
|
|
|
|
|
}
|
|
|
|
|
column.iSubItem=1;
|
|
|
|
|
CListCtrl::GetColumn(nColumn, &column); // Get rect-edge (right/bottom)
|
|
|
|
|
rectCell.right = rectCell.left + column.cx;
|
|
|
|
|
|
|
|
|
|
if (!outside)
|
|
|
|
|
{ //decrease 1 pixel
|
|
|
|
|
rectCell.left++; rectCell.right--;
|
|
|
|
|
rectCell.top++; rectCell.bottom--;
|
|
|
|
|
}
|
|
|
|
|
return rectCell;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//***************************************************************
|
|
|
|
|
void CHListCtrl::InvalidateFullItem(int nItem, BOOL bErase)
|
|
|
|
|
{
|
|
|
|
|
CRect rcBounds=GetFullCellRect(nItem, TRUE);
|
|
|
|
|
InvalidateRect(rcBounds, bErase);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//***************************************************************
|
|
|
|
|
// create ListCtrl-head
|
|
|
|
|
int CHListCtrl::InitCtrl(CStringArray *phead, CByteArray *pProcent)
|
|
|
|
|
{
|
|
|
|
|
if ( (!phead)||(!pProcent)) return 1;
|
|
|
|
|
LV_COLUMN lvc;
|
|
|
|
|
int cx=0;
|
|
|
|
|
INT_PTR count = phead->GetSize();
|
|
|
|
|
if (count!=m_columnSize) return 2;
|
|
|
|
|
if (pProcent->GetSize() != count) return 3;
|
|
|
|
|
for (int x=0; x<count; x++) cx+=pProcent->GetAt(x);
|
|
|
|
|
if (cx!=100) return 4;
|
|
|
|
|
|
|
|
|
|
CRect rect_listbox;
|
|
|
|
|
|
|
|
|
|
lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
|
|
|
|
|
GetWindowRect( rect_listbox );
|
|
|
|
|
cx=int((rect_listbox.right-rect_listbox.left)-20); //some Pixel for Scrollbar
|
|
|
|
|
|
|
|
|
|
//set head-columns in ListBox
|
|
|
|
|
lvc.iSubItem = 0;
|
|
|
|
|
lvc.fmt = LVCFMT_LEFT ;
|
|
|
|
|
|
|
|
|
|
for (x=0; x<count; x++)
|
|
|
|
|
{
|
|
|
|
|
lvc.cx = int(cx*pProcent->GetAt(x)/100);
|
|
|
|
|
lvc.pszText = (LPTSTR)(LPCTSTR)(phead->GetAt(x));
|
|
|
|
|
CListCtrl::InsertColumn(x,&lvc);
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//***************************************************************
|
|
|
|
|
// add an item
|
|
|
|
|
int CHListCtrl::AddItem(CStringArray *line, int pos)
|
|
|
|
|
{
|
|
|
|
|
int ret_index=LISTCTRL_ERROR;
|
|
|
|
|
if (!line) return ret_index;
|
|
|
|
|
|
|
|
|
|
LV_ITEM lvi;
|
|
|
|
|
|
|
|
|
|
//set List-properties
|
|
|
|
|
lvi.mask = LVIF_TEXT ;
|
|
|
|
|
lvi.iSubItem = 0;
|
|
|
|
|
lvi.pszText = const_cast<LPTSTR>(_T(""));
|
|
|
|
|
|
|
|
|
|
int count=GetItemCount();
|
|
|
|
|
INT_PTR columns=line->GetSize();
|
|
|
|
|
|
|
|
|
|
if (m_columnSize!=columns) return ret_index;
|
|
|
|
|
|
|
|
|
|
if (DWORD(pos)<=DWORD(count)) count=pos;
|
|
|
|
|
|
|
|
|
|
lvi.iItem = count;
|
|
|
|
|
//lvi.lParam= count;
|
|
|
|
|
lvi.mask = LVIF_TEXT ;
|
|
|
|
|
lvi.iSubItem = 0; //refer to no Item
|
|
|
|
|
// insert an new line
|
|
|
|
|
ret_index=InsertItem(&lvi);
|
|
|
|
|
// set item text for additional columns
|
|
|
|
|
for (int x=0; x<columns; x++)
|
|
|
|
|
{
|
|
|
|
|
CListCtrl::SetItemText(count,x,(LPCTSTR)(line->GetAt(x)) );
|
|
|
|
|
}
|
|
|
|
|
lvi.mask = LVIF_STATE;
|
|
|
|
|
lvi.iSubItem = 1;
|
|
|
|
|
lvi.stateMask = 0xFFFFFFFF ;
|
|
|
|
|
lvi.state = 0;
|
|
|
|
|
|
|
|
|
|
if (CListCtrl::SetItem(&lvi))
|
|
|
|
|
{
|
|
|
|
|
CMyLParam *p=new CMyLParam(m_columnSize); //init with: DEF_BACKGROUND, def_text
|
|
|
|
|
|
|
|
|
|
#ifdef TESTCOLOR
|
|
|
|
|
// only for TEST
|
|
|
|
|
if (ret_index<3)
|
|
|
|
|
{
|
|
|
|
|
p->SetBackColor(ITEM_COLOR(ret_index+BLUE),0);
|
|
|
|
|
p->SetTextColor(ITEM_COLOR(ret_index+RED ),0);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
if (ret_index<=6)
|
|
|
|
|
{
|
|
|
|
|
p->SetBackColor(ITEM_COLOR(ret_index+BLUE),1);
|
|
|
|
|
p->SetTextColor(ITEM_COLOR(ret_index+RED ),1);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
p->SetBackColor(ITEM_COLOR((ret_index+BLUE)&0xF),2);
|
|
|
|
|
p->SetTextColor(ITEM_COLOR((ret_index+RED )&0xF),2);
|
|
|
|
|
}
|
|
|
|
|
// end: only for TEST
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
CListCtrl::SetItemData( ret_index, DWORD_PTR(p) );
|
|
|
|
|
return ret_index;
|
|
|
|
|
}
|
|
|
|
|
return LISTCTRL_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//***************************************************************
|
|
|
|
|
BOOL CHListCtrl::DeleteAllItems()
|
|
|
|
|
{
|
|
|
|
|
while (CListCtrl::GetItemCount())
|
|
|
|
|
CHListCtrl::DeleteItem(0);
|
|
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//***************************************************************
|
|
|
|
|
BOOL CHListCtrl::DeleteItem(int nItem )
|
|
|
|
|
{
|
|
|
|
|
if (CListCtrl::GetItemCount()<=nItem) return FALSE;
|
|
|
|
|
CMyLParam *p=(CMyLParam*)CListCtrl::GetItemData(nItem);
|
|
|
|
|
if (p)
|
|
|
|
|
{
|
|
|
|
|
CListCtrl::SetItemData( nItem, p->GetData() );
|
|
|
|
|
delete p;
|
|
|
|
|
return CListCtrl::DeleteItem( nItem );
|
|
|
|
|
}
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//***************************************************************
|
|
|
|
|
DWORD CHListCtrl::GetItemData( int nItem ) const
|
|
|
|
|
{
|
|
|
|
|
CMyLParam *p=(CMyLParam*)CListCtrl::GetItemData(nItem);
|
|
|
|
|
if (p)
|
|
|
|
|
{
|
|
|
|
|
return p->GetData();
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//***************************************************************
|
|
|
|
|
BOOL CHListCtrl::SetItemData( int nItem, DWORD dwData )
|
|
|
|
|
{
|
|
|
|
|
CMyLParam *p=(CMyLParam*)CListCtrl::GetItemData(nItem);
|
|
|
|
|
if (p)
|
|
|
|
|
{
|
|
|
|
|
p->SetData(dwData);
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//***************************************************************
|
|
|
|
|
BOOL CHListCtrl::SetItemBackgndColor(ITEM_COLOR color, int Index, int iSub)
|
|
|
|
|
{
|
|
|
|
|
CMyLParam *p=GetMyLParam(Index);
|
|
|
|
|
if (!p) return FALSE;
|
|
|
|
|
if ( p->SetBackColor(color, iSub) )
|
|
|
|
|
{
|
|
|
|
|
RedrawItems( Index, Index );
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//***************************************************************
|
|
|
|
|
BOOL CHListCtrl::SetItemTextColor(ITEM_COLOR color, int Index, int iSub)
|
|
|
|
|
{
|
|
|
|
|
CMyLParam *p=GetMyLParam(Index);
|
|
|
|
|
if (!p) return FALSE;
|
|
|
|
|
if ( p->SetTextColor(color, iSub) )
|
|
|
|
|
{
|
|
|
|
|
RedrawItems( Index, Index );
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//***************************************************************
|
|
|
|
|
COLORREF CHListCtrl::GetItemBackgndColor(int Index, int iSub)
|
|
|
|
|
{
|
|
|
|
|
CMyLParam *p=GetMyLParam(Index);
|
|
|
|
|
if (!p) return 0;
|
|
|
|
|
return p->GetBackColor(iSub);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//***************************************************************
|
|
|
|
|
COLORREF CHListCtrl::GetItemTextColor(int Index, int iSub)
|
|
|
|
|
{
|
|
|
|
|
CMyLParam *p=GetMyLParam(Index);
|
|
|
|
|
if (!p) return 0;
|
|
|
|
|
return p->GetTextColor(iSub);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//***************************************************************
|
|
|
|
|
void CHListCtrl::OnPaint()
|
|
|
|
|
{
|
|
|
|
|
// First let the control do its default drawing.
|
|
|
|
|
const MSG *msg = GetCurrentMessage();
|
|
|
|
|
DefWindowProc( msg->message, msg->wParam, msg->lParam );
|
|
|
|
|
|
|
|
|
|
if (!m_fullColumnLines) return;
|
|
|
|
|
|
|
|
|
|
// Draw the lines only for LVS_REPORT mode
|
|
|
|
|
if( (GetStyle() & LVS_TYPEMASK) == LVS_REPORT )
|
|
|
|
|
{
|
|
|
|
|
// Get the number of columns
|
|
|
|
|
CClientDC dc(this );
|
|
|
|
|
CHeaderCtrl* pHeader = (CHeaderCtrl*)GetDlgItem(0);
|
|
|
|
|
int nColumnCount = pHeader->GetItemCount();
|
|
|
|
|
|
|
|
|
|
// The bottom of the header corresponds to the top of the line
|
|
|
|
|
RECT rect;
|
|
|
|
|
pHeader->GetClientRect( &rect );
|
|
|
|
|
int top = rect.bottom;
|
|
|
|
|
|
|
|
|
|
// Now get the client rect so we know the line length and
|
|
|
|
|
// when to stop
|
|
|
|
|
GetClientRect( &rect );
|
|
|
|
|
|
|
|
|
|
// The border of the column is offset by the horz scroll
|
|
|
|
|
int borderx = 0 - GetScrollPos( SB_HORZ );
|
|
|
|
|
|
|
|
|
|
CPen *pOldPen;
|
|
|
|
|
CPen pen;
|
|
|
|
|
CGdiObject *pOldBrush;
|
|
|
|
|
pen.CreatePen( PS_SOLID, 0, GetColorRef(DEF_DESELTEXT) );
|
|
|
|
|
pOldPen =dc.SelectObject(&pen);
|
|
|
|
|
pOldBrush=dc.SelectStockObject(NULL_BRUSH);
|
|
|
|
|
|
|
|
|
|
for( int i = 0; i < nColumnCount; i++ )
|
|
|
|
|
{
|
|
|
|
|
// Get the next border
|
|
|
|
|
borderx += GetColumnWidth( i );
|
|
|
|
|
|
|
|
|
|
// if next border is outside client area, break out
|
|
|
|
|
if( borderx >= rect.right ) break;
|
|
|
|
|
|
|
|
|
|
// Draw the line.
|
|
|
|
|
dc.MoveTo( borderx-1, top);
|
|
|
|
|
dc.LineTo( borderx-1, rect.bottom );
|
|
|
|
|
}
|
|
|
|
|
dc.SelectObject(pOldPen);
|
|
|
|
|
dc.SelectObject(pOldBrush);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
// Do not call CListCtrl::OnPaint() for painting messages
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//***************************************************************
|
|
|
|
|
void CHListCtrl::RepaintSelectedItems()
|
|
|
|
|
{
|
|
|
|
|
// Invalidate focused item so it can repaint
|
|
|
|
|
int nItem = GetNextItem(-1, LVNI_FOCUSED);
|
|
|
|
|
|
|
|
|
|
if(nItem != -1)
|
|
|
|
|
{
|
|
|
|
|
InvalidateFullItem(nItem, FALSE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Invalidate selected items depending on LVS_SHOWSELALWAYS
|
|
|
|
|
if((GetStyle() & LVS_SHOWSELALWAYS))
|
|
|
|
|
{
|
|
|
|
|
for(nItem = GetNextItem(-1, LVNI_SELECTED);
|
|
|
|
|
nItem != -1; nItem = GetNextItem(nItem, LVNI_SELECTED))
|
|
|
|
|
{
|
|
|
|
|
InvalidateFullItem(nItem, FALSE);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
UpdateWindow();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//***************************************************************
|
|
|
|
|
BOOL CHListCtrl::SetSel(int pos, BOOL bSelect)
|
|
|
|
|
{
|
|
|
|
|
// LVS_ES_FULLROWSELECT only works with newer version of Comctl32
|
|
|
|
|
// This style and some of the other new extended styles
|
|
|
|
|
// only work with version 4.72 (or higer) of COMCTL32.DLL
|
|
|
|
|
|
|
|
|
|
UINT nState=0;
|
|
|
|
|
if (bSelect) nState=LVIS_SELECTED|LVS_EX_FULLROWSELECT; else nState=0;
|
|
|
|
|
if (SetItemState(pos, nState, LVIS_SELECTED|LVS_EX_FULLROWSELECT))
|
|
|
|
|
{
|
|
|
|
|
if((GetStyle() & LVS_SHOWSELALWAYS))
|
|
|
|
|
{
|
|
|
|
|
InvalidateFullItem(pos, TRUE);
|
|
|
|
|
}
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
//***************************************************************
|
|
|
|
|
void CHListCtrl::OnKillFocus(CWnd* pNewWnd)
|
|
|
|
|
{
|
|
|
|
|
SendMessage(WM_PAINT);
|
|
|
|
|
CListCtrl::OnKillFocus(pNewWnd);
|
|
|
|
|
// check if we are losing focus
|
|
|
|
|
if(pNewWnd != NULL && pNewWnd->GetParent() == this)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
// repaint items that should change appearance
|
|
|
|
|
if((GetStyle() & LVS_TYPEMASK) == LVS_REPORT)
|
|
|
|
|
RepaintSelectedItems();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//***************************************************************
|
|
|
|
|
void CHListCtrl::OnSetFocus(CWnd* pOldWnd)
|
|
|
|
|
{
|
|
|
|
|
CListCtrl::OnSetFocus(pOldWnd);
|
|
|
|
|
|
|
|
|
|
// check if we are getting focus
|
|
|
|
|
if(pOldWnd!=NULL && pOldWnd->GetParent()==this)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
// repaint items that should change appearance
|
|
|
|
|
if((GetStyle() & LVS_TYPEMASK)==LVS_REPORT)
|
|
|
|
|
RepaintSelectedItems();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//***************************************************************
|
|
|
|
|
void CHListCtrl::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
|
|
|
|
|
{
|
|
|
|
|
if (!lpDrawItemStruct) return;
|
|
|
|
|
IsCreated=TRUE;
|
|
|
|
|
CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
|
|
|
|
|
CMyLParam* pMyLParam = GetMyLParam(lpDrawItemStruct->itemID);
|
|
|
|
|
CRect rcItem;
|
|
|
|
|
|
|
|
|
|
if (!pMyLParam) return;
|
|
|
|
|
int x=0;
|
|
|
|
|
typedef enum {R_NOTHINGS=0, R_FOCUS, R_SELECT, R_NORMAL, R_SEL_NOFOCUS} redrawmode;
|
|
|
|
|
redrawmode redraw=R_NORMAL;
|
|
|
|
|
|
|
|
|
|
// Get item image and state info
|
|
|
|
|
LV_ITEM lvi;
|
|
|
|
|
lvi.mask = LVIF_IMAGE | LVIF_STATE;
|
|
|
|
|
lvi.iItem = lpDrawItemStruct->itemID;
|
|
|
|
|
lvi.iSubItem = 0;
|
|
|
|
|
lvi.stateMask = 0xFFFF; // get all state flags
|
|
|
|
|
GetItem(&lvi);
|
|
|
|
|
|
|
|
|
|
BOOL bHighlight = ( (lvi.state & LVIS_DROPHILITED)
|
|
|
|
|
||
|
|
|
|
|
(
|
|
|
|
|
(lvi.state & LVIS_SELECTED)
|
|
|
|
|
&&
|
|
|
|
|
( ( GetFocus() == this ) || ( GetStyle() & LVS_SHOWSELALWAYS ) )
|
|
|
|
|
)
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
BOOL bLostFocus=(GetFocus()!=this);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ( (lpDrawItemStruct->itemAction&ODA_FOCUS)==ODA_FOCUS)
|
|
|
|
|
{ //the control gains or loses input focus
|
|
|
|
|
if (bLostFocus) redraw=R_SEL_NOFOCUS;
|
|
|
|
|
else
|
|
|
|
|
if ((lvi.state&LVIS_FOCUSED)==LVIS_FOCUSED) redraw=R_FOCUS;
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (bHighlight) redraw=R_SELECT;
|
|
|
|
|
else redraw=R_NORMAL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
if ((lpDrawItemStruct->itemAction&ODA_SELECT)==ODA_SELECT)
|
|
|
|
|
{ //the selection status has changed
|
|
|
|
|
if (bHighlight)
|
|
|
|
|
{
|
|
|
|
|
if (bLostFocus) redraw=R_SEL_NOFOCUS;
|
|
|
|
|
else redraw=R_SELECT;
|
|
|
|
|
}
|
|
|
|
|
else redraw=R_NORMAL;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{ //redraw the item
|
|
|
|
|
if (bLostFocus)
|
|
|
|
|
{
|
|
|
|
|
if (bHighlight) redraw=R_SEL_NOFOCUS;
|
|
|
|
|
else
|
|
|
|
|
redraw=R_NORMAL;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if ((lvi.state&LVIS_FOCUSED)==LVIS_FOCUSED) redraw=R_FOCUS;
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (bHighlight) redraw=R_SELECT;
|
|
|
|
|
else redraw=R_NORMAL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CPen *pOldPen;
|
|
|
|
|
CPen pen;
|
|
|
|
|
CGdiObject *pOldBrush;
|
|
|
|
|
|
|
|
|
|
switch(redraw)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
case R_FOCUS:
|
|
|
|
|
rcItem=GetFullCellRect(lpDrawItemStruct->itemID, TRUE);
|
|
|
|
|
pDC->FillSolidRect(rcItem, GetColorRef(DEF_SELBACKGROUND));
|
|
|
|
|
pDC->SetTextColor(GetColorRef(DEF_SELTEXT));
|
|
|
|
|
if (m_BigFocusRect)
|
|
|
|
|
{
|
|
|
|
|
pen.CreatePen( PS_SOLID, 0, GetColorRef(DEF_SELTEXT) );
|
|
|
|
|
pOldPen =pDC->SelectObject(&pen);
|
|
|
|
|
pOldBrush=pDC->SelectStockObject(NULL_BRUSH);
|
|
|
|
|
pDC->Rectangle(rcItem);
|
|
|
|
|
pDC->SelectObject(pOldPen);
|
|
|
|
|
pDC->SelectObject(pOldBrush);
|
|
|
|
|
}
|
|
|
|
|
else pDC->DrawFocusRect(rcItem);
|
|
|
|
|
for (x=0; x<m_columnSize; x++)
|
|
|
|
|
{
|
|
|
|
|
rcItem = GetCellRect(lpDrawItemStruct->itemID, x, FALSE);
|
|
|
|
|
pDC->DrawText(CListCtrl::GetItemText(lpDrawItemStruct->itemID,x), rcItem, DT_SINGLELINE | DT_LEFT | DT_VCENTER );
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case R_SELECT:
|
|
|
|
|
rcItem=GetFullCellRect(lpDrawItemStruct->itemID, TRUE);
|
|
|
|
|
pDC->FillSolidRect(rcItem, GetColorRef(DEF_SELBACKGROUND));
|
|
|
|
|
pDC->SetTextColor(GetColorRef(DEF_SELTEXT));
|
|
|
|
|
for (x=0; x<m_columnSize; x++)
|
|
|
|
|
{
|
|
|
|
|
rcItem = GetCellRect(lpDrawItemStruct->itemID, x, FALSE);
|
|
|
|
|
pDC->DrawText(CListCtrl::GetItemText(lpDrawItemStruct->itemID,x), rcItem, DT_SINGLELINE | DT_LEFT | DT_VCENTER);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case R_SEL_NOFOCUS:
|
|
|
|
|
rcItem=GetFullCellRect(lpDrawItemStruct->itemID, TRUE);
|
|
|
|
|
pDC->FillSolidRect(rcItem, GetColorRef(DEF_DESELBACKGROUND));
|
|
|
|
|
pDC->SetTextColor(pMyLParam->GetTextColor(DEF_DESELTEXT));
|
|
|
|
|
pen.CreatePen( PS_SOLID, 0, GetColorRef(DEF_DESELBACKGROUND) );
|
|
|
|
|
pOldPen =pDC->SelectObject(&pen);
|
|
|
|
|
pOldBrush=pDC->SelectStockObject(NULL_BRUSH);
|
|
|
|
|
if (!m_withSingleRect)
|
|
|
|
|
pDC->Rectangle(rcItem);
|
|
|
|
|
for (x=0; x<m_columnSize; x++)
|
|
|
|
|
{
|
|
|
|
|
rcItem = GetCellRect(lpDrawItemStruct->itemID, x, FALSE);
|
|
|
|
|
pDC->DrawText(CListCtrl::GetItemText(lpDrawItemStruct->itemID,x), rcItem, DT_SINGLELINE | DT_LEFT | DT_VCENTER);
|
|
|
|
|
}
|
|
|
|
|
pDC->SelectObject(pOldPen);
|
|
|
|
|
pDC->SelectObject(pOldBrush);
|
|
|
|
|
break;
|
|
|
|
|
case R_NORMAL:
|
|
|
|
|
for (x=0; x<m_columnSize; x++)
|
|
|
|
|
{
|
|
|
|
|
rcItem = GetCellRect(lpDrawItemStruct->itemID, x, TRUE);
|
|
|
|
|
pDC->FillSolidRect(rcItem, pMyLParam->GetBackColor(x));
|
|
|
|
|
pDC->SetTextColor(pMyLParam->GetTextColor(x));
|
|
|
|
|
if (m_withSingleRect)
|
|
|
|
|
{
|
|
|
|
|
pOldBrush=pDC->SelectStockObject(NULL_BRUSH);
|
|
|
|
|
pDC->Rectangle(rcItem);
|
|
|
|
|
pDC->SelectObject(pOldBrush);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
rcItem = GetCellRect(lpDrawItemStruct->itemID, x, FALSE);
|
|
|
|
|
pDC->DrawText(CListCtrl::GetItemText(lpDrawItemStruct->itemID,x), rcItem, DT_SINGLELINE | DT_LEFT | DT_VCENTER);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CHListCtrl::OnSize(UINT nType, int cx, int cy)
|
|
|
|
|
{
|
|
|
|
|
CListCtrl::OnSize(nType, cx, cy);
|
|
|
|
|
if (IsCreated)
|
|
|
|
|
{
|
|
|
|
|
RedrawWindow();
|
|
|
|
|
}
|
|
|
|
|
}
|