自画LISTCTRL

kmustty 2009-04-13 11:41:21
我写了个自画CLISTCTRL的代码,LIST列表可以更改背景颜色,可以更改高度,又可以实现高亮选择,但是我现在想在此基础上增LISTCTRL的编辑功能,该怎么弄呢?
代码如下:
// CXTListCtrlEx
IMPLEMENT_DYNAMIC(CXTListCtrlEx, CXTListCtrl)
BEGIN_MESSAGE_MAP(CXTListCtrlEx, CXTListCtrl)
ON_WM_MEASUREITEM_REFLECT()
ON_WM_PAINT()
ON_WM_LBUTTONDOWN()
ON_WM_CONTEXTMENU()
ON_MESSAGE(LVM_INSERTCOLUMN, OnInsertColumn)
ON_WM_LBUTTONDBLCLK()
END_MESSAGE_MAP()

void CXTListCtrlEx::DrawItem(LPDRAWITEMSTRUCT lpDIS)
{
TCHAR lpBuffer[256];
LV_ITEM lvi;
lvi.mask = LVIF_TEXT | LVIF_PARAM ;
lvi.iItem = lpDIS->itemID ;
lvi.iSubItem = 0;
lvi.pszText = lpBuffer ;
lvi.cchTextMax = sizeof(lpBuffer);
VERIFY(GetItem(&lvi));
LV_COLUMN lvc, lvcprev ;
::ZeroMemory(&lvc, sizeof(lvc));
::ZeroMemory(&lvcprev, sizeof(lvcprev));
lvc.mask = LVCF_WIDTH | LVCF_FMT;
lvcprev.mask = LVCF_WIDTH | LVCF_FMT;
CDC* pDC = CDC::FromHandle(lpDIS->hDC);
int nCol;
CRect m_SelectionRect = lpDIS->rcItem;
if(m_SelectionRect.PtInRect(m_Point))
{
m_SelectionFlag = TRUE;
}
else
{
m_SelectionFlag = FALSE;
}

if ( (lpDIS->itemState & ODS_SELECTED) && m_SelectionFlag )
{
CRect rc=lpDIS->rcItem;
pDC->FillSolidRect(&rc, m_Highlightcolor);
}
else
{
pDC->FillSolidRect(&lpDIS->rcItem, GetListBackColor());
pDC->SetTextColor(GetSysColor(COLOR_WINDOWTEXT));

}
for ( nCol=0; GetColumn(nCol, &lvc); nCol++)
{
if ( nCol > 0 )
{
// Get Previous Column Width in order to move the next display item
GetColumn(nCol-1, &lvcprev) ;
lpDIS->rcItem.left += lvcprev.cx ;
lpDIS->rcItem.right += lpDIS->rcItem.left ;
}

if(IsColumnVisible(nCol))
{
// Get the text
::ZeroMemory(&lvi, sizeof(lvi));
lvi.iItem = lpDIS->itemID;
lvi.mask = LVIF_TEXT | LVIF_PARAM;
lvi.iSubItem = nCol;
lvi.pszText = lpBuffer;
lvi.cchTextMax = sizeof(lpBuffer);
VERIFY(GetItem(&lvi));

pDC->SelectObject(GetStockObject(DEFAULT_GUI_FONT));

UINT uFormat = DT_LEFT ;
::DrawText(lpDIS->hDC, lpBuffer, strlen(lpBuffer),
&lpDIS->rcItem, uFormat) ;
pDC->SelectStockObject(SYSTEM_FONT) ;
}
}
}

void CXTListCtrlEx::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)
{
if( m_nItemHeight > 0 )
lpMeasureItemStruct->itemHeight = m_nItemHeight;

}

//设置行高
void CXTListCtrlEx::SetXTItemHeight(UINT nHeight)
{
m_nItemHeight = nHeight;
CRect rcWin;
GetWindowRect(&rcWin);
WINDOWPOS wp;
wp.hwnd = m_hWnd;
wp.cx = rcWin.Width();
wp.cy = rcWin.Height();
wp.flags = SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOZORDER;
SendMessage(WM_WINDOWPOSCHANGED, 0, (LPARAM)&wp);
}

void CXTListCtrlEx::OnPaint()
{
CXTListCtrl::OnPaint();
// Draw the lines only for LVS_REPORT mode
if( (GetStyle() & LVS_TYPEMASK) == LVS_REPORT )
{
// Get the number of columns
CPen penRed;
penRed.CreatePen(PS_SOLID,1,m_Linecolor);
CClientDC dc(this );
dc.SelectObject(&penRed);
CXTHeaderCtrl* pHeader = (CXTHeaderCtrl*)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 );
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 );
}
// First get the height
if( !GetItemRect( 0, &rect, LVIR_BOUNDS ))
return;

int height = rect.bottom - rect.top;

GetClientRect( &rect );
int width = rect.right;

for( int i = 1; i <= GetCountPerPage(); i++ )
{
dc.MoveTo( 0, top + height*i);
dc.LineTo( width, top + height*i );
}
}
}

CXTListCtrlEx::ColumnState& CXTListCtrlEx::GetColumnState(int nCol)
{
VERIFY( nCol >=0 && nCol < m_ColumnStates.GetSize() );
return m_ColumnStates[nCol];
}

BOOL CXTListCtrlEx::ShowColumn(int nCol, bool bShow)
{
SetRedraw(FALSE);
ColumnState& columnState = GetColumnState(nCol);
CXTHeaderCtrl* pHeader = (CXTHeaderCtrl*)GetDlgItem(0);
if (bShow)
{
// Restore the column width
columnState.m_Visible = true;
VERIFY( SetColumnWidth(nCol, columnState.m_OrgWidth) );
}
else
{
// Backup the column width
int orgWidth = GetColumnWidth(nCol);
VERIFY( SetColumnWidth(nCol, 0) );
columnState.m_Visible = false;
columnState.m_OrgWidth = orgWidth;
}
SetRedraw(TRUE);
Invalidate(FALSE);
return TRUE;
}

bool CXTListCtrlEx::IsColumnVisible(int nCol)
{
return GetColumnState(nCol).m_Visible;
}

int CXTListCtrlEx::GetColumnStateCount()
{
return m_ColumnStates.GetSize();
}

void CXTListCtrlEx::OnContextMenu(CWnd* pWnd, CPoint point)
{
if (point.x==-1 && point.y==-1)
{
}
else
{
CPoint pt = point;
ScreenToClient(&pt);

CRect headerRect;
GetHeaderCtrl()->GetClientRect(&headerRect);
if (headerRect.PtInRect(pt))
{
// Show context-menu with the option to show hide columns
CMenu Menu;
Menu.CreatePopupMenu();
Menu.AppendMenu(MF_STRING,ID_LISTGRIDSET, "设置");
CMenu funcMenu;
if(funcMenu.CreatePopupMenu())
{
funcMenu.InsertMenu(0, MF_STRING,ID_GRIDEXCELSET,"导出Excel设置");
funcMenu.InsertMenu(1, MF_STRING,ID_GRIDEXCEL,"另存为Excel");
}
Menu.AppendMenu(MF_STRING|MF_POPUP,(UINT_PTR)funcMenu.m_hMenu,"Excel操作");
CMenu popmenu;
if (popmenu.CreatePopupMenu())
{
for( int i = GetColumnStateCount()-1 ; i >= 0; --i)
{
UINT uFlags = MF_BYPOSITION | MF_STRING;

// Put check-box on context-menu
if (IsColumnVisible(i))
uFlags |= MF_CHECKED;
else
uFlags |= MF_UNCHECKED;

// Retrieve column-title
LVCOLUMN lvc = {0};
lvc.mask = LVCF_TEXT;
TCHAR sColText[256];
lvc.pszText = sColText;
lvc.cchTextMax = sizeof(sColText)-1;
VERIFY( GetColumn(i, &lvc) );
popmenu.InsertMenu(0, uFlags, i, lvc.pszText);
}
Menu.AppendMenu(MF_STRING|MF_POPUP,(UINT_PTR)popmenu.m_hMenu, "显示列");

Menu.TrackPopupMenu(TPM_LEFTALIGN, point.x, point.y, this, 0);
}
}
}
}

void CXTListCtrlEx::InsertColumnState(int nCol, bool bVisible, int nOrgWidth)
{
VERIFY( nCol >=0 && nCol <= m_ColumnStates.GetSize() );

ColumnState columnState;
columnState.m_OrgWidth = nOrgWidth;
columnState.m_Visible = bVisible;

if (nCol == m_ColumnStates.GetSize())
{
// Append column picker to the end of the array
m_ColumnStates.Add(columnState);
}
else
{
// Insert column in the middle of the array
CSimpleArray<ColumnState> newArray;
for(int i=0 ; i < m_ColumnStates.GetSize(); ++i)
{
if (i == nCol)
newArray.Add(columnState);
newArray.Add(m_ColumnStates[i]);
}
m_ColumnStates = newArray;
}
}

LRESULT CXTListCtrlEx::OnInsertColumn(WPARAM wParam, LPARAM lParam)
{
// Let the CListCtrl handle the event
LRESULT lRet = DefWindowProc(LVM_INSERTCOLUMN, wParam, lParam);
if (lRet == -1)
return -1;

int nCol = (int)lRet;

// Book keeping of columns
if (GetColumnStateCount() < GetHeaderCtrl()->GetItemCount())
InsertColumnState((int)nCol, true); // Insert as visible

return lRet;
}


...全文
158 2 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
liuzxchina 2009-04-13
  • 打赏
  • 举报
回复
LVS_EDITLABELS
Item text can be edited in place. The parent window must process the LVN_ENDLABELEDIT notification message.
kmustty 2009-04-13
  • 打赏
  • 举报
回复
已经实验了,问题是我的LISTCTRL的格子是自己绘制的,绘制出来的EDIT是可以,但是很小,不知道怎么解决

16,548

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • AIGC Browser
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧