📄 uictrl.cpp
字号:
//*******************************************************************************
// COPYRIGHT NOTES
// ---------------
// You may use this source code, compile or redistribute it as part of your application
// for free. You cannot redistribute it as a part of a software development
// library without the agreement of the author. If the sources are
// distributed along with the application, you should leave the original
// copyright notes in the source code without any changes.
// This code can be used WITHOUT ANY WARRANTIES at your own risk.
//
// For the latest updates to this code, check this site:
// http://www.masmex.com
// after Sept 2000
//
// Copyright(C) 2000 Philip Oldaker <email: philip@masmex.com>
//*******************************************************************************
#include "stdafx.h"
#include "UICtrl.h"
#include "InPlaceEdit.h"
#include "TextProgressCtrl.h"
#include "UIres.h"
#include "ctype.h"
#include "cbformats.h"
#include <yvals.h>
//////////////////////////////////////////////////////
// Temporarily changes the view type
//////////////////////////////////////////////////////
CChangeViewType::CChangeViewType(CUIODListCtrl *pLC,DWORD dwType)
{
m_pLC = pLC;
m_dwType = m_pLC->GetViewType();
m_pLC->SetViewType(dwType);
}
CChangeViewType::~CChangeViewType()
{
m_pLC->SetViewType(m_dwType);
}
//////////////////////////////////////////////////////////
LPCTSTR CUIODListCtrl::szEntryHeadings = _T("Headings");
LPCTSTR CUIODListCtrl::szEntryStyle = _T("Style");
LPCTSTR CUIODListCtrl::szEntryRowSel = _T("RowSelection");
LPCTSTR CUIODListCtrl::szEntryViewType = _T("ViewType");
LPCTSTR CUIODListCtrl::szEntryColumnSizing = _T("ColumnSizing");
LPCTSTR CUIODListCtrl::szEntrySortColumn = _T("SortColumn");
LPCTSTR CUIODListCtrl::szEntrySubItems = _T("Columns");
LPCTSTR CUIODListCtrl::szEntryColOrder = _T("ColumnOrder");
LPCTSTR CUIODListCtrl::szEntryColWidths = _T("ColumnWidths");
IMPLEMENT_SERIAL(CUIODListCtrl, CListCtrl, 0)
#define COLUMN_DELIMITER '|'
#define COLUMN_DELIMITER_STR "|"
const int nMaxDigLen = _MAX_INT_DIG*4;
//////////////////////////////
//
// CUIODListCtrl
//
//////////////////////////////
BEGIN_MESSAGE_MAP(CUIODListCtrl, CListCtrl)
//{{AFX_MSG_MAP(CUIODListCtrl)
ON_MESSAGE(WM_APP_ON_PROPERTIES_KEY,OnAppPropertiesKey)
ON_MESSAGE(WM_APP_ON_DELETE_KEY,OnAppDeleteKey)
ON_MESSAGE(WM_APP_ON_CONTEXT_MENU_KEY,OnAppContextMenuKey)
ON_MESSAGE(WM_APP_ON_BACKSPACE_KEY,OnAppBackspaceKey)
ON_MESSAGE(WM_APP_ON_EDIT_KEY,OnAppEditKey)
ON_MESSAGE(WM_APP_ON_REFRESH_KEY,OnAppRefreshKey)
ON_NOTIFY_REFLECT_EX(LVN_BEGINDRAG, OnBegindrag)
ON_NOTIFY_REFLECT_EX(LVN_BEGINRDRAG, OnBeginRDrag)
ON_WM_CREATE()
ON_WM_DESTROY()
ON_MESSAGE(LVM_SETCOLUMNWIDTH,OnSetColumnWidth)
ON_MESSAGE(LVM_DELETEALLITEMS,OnDeleteAllItems)
ON_MESSAGE(LVM_DELETEITEM,OnDeleteItem)
ON_MESSAGE(LVM_DELETECOLUMN,OnDeleteColumn)
ON_MESSAGE(WM_UPDATEHEADERWIDTH,OnUpdateHeaderWidth)
ON_WM_SIZE()
ON_WM_PAINT()
ON_WM_SETFOCUS()
ON_WM_KILLFOCUS()
ON_WM_CONTEXTMENU()
ON_WM_INITMENUPOPUP()
ON_WM_LBUTTONDOWN()
ON_WM_HSCROLL()
ON_WM_VSCROLL()
ON_COMMAND(ID_UI_VIEW_LARGE_ICONS,OnViewLargeIcons)
ON_COMMAND(ID_UI_VIEW_SMALL_ICONS,OnViewSmallIcons)
ON_COMMAND(ID_UI_VIEW_DETAILS,OnViewDetails)
ON_COMMAND(ID_UI_VIEW_LIST,OnViewList)
ON_COMMAND(ID_UI_VIEW_FULL_ROW_SELECTION,OnViewFullRowSelection)
ON_COMMAND(ID_UI_VIEW_COLUMN_ORDERING,OnViewColumnOrdering)
ON_COMMAND(ID_UI_VIEW_COLUMN_SIZING,OnViewColumnSizing)
ON_COMMAND(ID_UI_VIEW_GRIDLINES,OnViewGridlines)
ON_COMMAND(ID_UI_VIEW_CHECKBOXES,OnViewCheckboxes)
ON_COMMAND(ID_UI_VIEW_TRACK_SELECT,OnViewTrackSelect)
ON_COMMAND(ID_UI_VIEW_EDIT_COLUMN,OnViewEditColumn)
ON_COMMAND(ID_HEADER_REMOVE_COL,OnHeaderRemoveColumn)
ON_COMMAND(ID_HEADER_EDIT_TEXT,OnHeaderEditText)
ON_COMMAND(ID_HEADER_RESET,OnHeaderReset)
ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTW, 0, 0xFFFF, OnToolTipText)
ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTA, 0, 0xFFFF, OnToolTipText)
ON_WM_DROPFILES()
ON_MESSAGE(LVM_SETIMAGELIST, OnSetImageList)
ON_MESSAGE(LVM_SETTEXTCOLOR, OnSetTextColor)
ON_MESSAGE(LVM_SETTEXTBKCOLOR, OnSetTextBkColor)
ON_MESSAGE(LVM_SETBKCOLOR, OnSetBkColor)
ON_MESSAGE(LVM_GETITEMTEXT, OnGetItemText)
//}}AFX_MSG_MAP
ON_MESSAGE(WM_APP_OLE_DD_DROP, OnDragDrop)
ON_MESSAGE(WM_APP_OLE_DD_DODRAGDROP, OnDDDoDragDrop)
ON_MESSAGE(WM_APP_OLE_DD_OVER, OnDragOver)
ON_MESSAGE(WM_APP_OLE_DD_ENTER, OnDragEnter)
ON_MESSAGE(WM_APP_OLE_DD_LEAVE, OnDragLeave)
END_MESSAGE_MAP()
CUIODListCtrl::CUIODListCtrl(bool bDragDrop)
{
m_PopupID = 0;
m_MultiPopupID = 0;
m_bDragDrop = bDragDrop;
m_bDropFiles = true;
m_pColWidths = NULL;
m_pColOrder = NULL;
m_pColTypes = NULL;
m_hOrigFont = NULL;
m_pPopupWnd = NULL;
m_nImageList = LVSIL_SMALL;
m_nColClicked = -1;
m_nSortColumn = 0;
m_nSubItems = 0;
m_nItems = 0;
m_nImage = 0;
m_dwExStyle = LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_INFOTIP;
m_dwViewType = LVS_REPORT;
m_bDelayPaint = false;
m_bColumnSizing=TRUE;
m_bRClickChangeIconSize = TRUE;
// this is toggled on in InitListCtrl
m_bFullRowSel=FALSE;
m_bClientWidthSel=TRUE;
m_bSortAscending=TRUE;
m_bToolTips=FALSE;
m_bEditSubItems = true;
m_cxClient=0;
m_cxStateImageOffset=0;
m_clrText=::GetSysColor(COLOR_WINDOWTEXT);
m_clrTextBk=::GetSysColor(COLOR_WINDOW);
m_clrBkgnd=::GetSysColor(COLOR_WINDOW);
m_strNoItemsMess.LoadString(IDS_NO_ITEMS_MESS);
}
CUIODListCtrl::~CUIODListCtrl()
{
Empty();
}
void CUIODListCtrl::AllItemsDeleted()
{
}
void CUIODListCtrl::Empty()
{
m_objList.DeleteAll();
delete []m_pColWidths;
delete []m_pColOrder;
delete []m_pColTypes;
m_pColWidths = NULL;
m_pColOrder = NULL;
m_pColTypes = NULL;
}
// should be overridden to do any initialization
void CUIODListCtrl::Init()
{
}
void CUIODListCtrl::UpdateEvent(LPARAM lHint,CObject *pHint)
{
GetParent()->SendMessage(WM_APP_UPDATE_ALL_VIEWS,(WPARAM)lHint,(LPARAM)pHint);
}
BOOL CUIODListCtrl::SetViewType(DWORD dwViewType,UINT nFlags)
{
BOOL bRet = ModifyStyle(LVS_TYPEMASK,dwViewType & LVS_TYPEMASK,nFlags);
if (bRet)
SaveProfile();
return bRet;
}
DWORD CUIODListCtrl::GetViewType() const
{
return(GetStyle() & LVS_TYPEMASK);
}
void CUIODListCtrl::ChangeStyle(UINT &dwStyle)
{
LoadProfile();
dwStyle |= LVS_SHOWSELALWAYS | m_dwViewType;
}
// offsets for first and other columns
#define OFFSET_FIRST 2
#define OFFSET_OTHER 6
void CUIODListCtrl::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
CDC* pDC=CDC::FromHandle(lpDrawItemStruct->hDC);
CRect rcItem(lpDrawItemStruct->rcItem);
UINT uiFlags=ILD_TRANSPARENT;
CImageList* pImageList;
int nItem=lpDrawItemStruct->itemID;
BOOL bFocus=(GetFocus()==this);
COLORREF clrTextSave, clrBkSave;
COLORREF clrImage=m_clrBkgnd;
static _TCHAR szBuff[MAX_PATH];
LPCTSTR pszText;
if (m_cxClient == 0)
{
CRect rcClient;
GetClientRect(rcClient);
m_cxClient = rcClient.Width();
}
// get item data
LV_ITEM lvi;
lvi.mask=LVIF_TEXT | LVIF_IMAGE | LVIF_STATE | LVIF_PARAM;
lvi.iItem=nItem;
lvi.iSubItem=0;
lvi.pszText=szBuff;
lvi.cchTextMax=sizeof(szBuff);
lvi.stateMask=0xFFFF; // get all state flags
GetItem(&lvi);
BOOL bSelected=(bFocus || (GetStyle() & LVS_SHOWSELALWAYS)) && lvi.state & LVIS_SELECTED;
bSelected=bSelected || (lvi.state & LVIS_DROPHILITED);
// set colors if item is selected
CRect rcAllLabels;
GetItemRect(nItem,rcAllLabels,LVIR_BOUNDS);
CRect rcLabel;
GetItemRect(nItem,rcLabel,LVIR_LABEL);
rcAllLabels.left=rcLabel.left;
// if(m_bClientWidthSel && rcAllLabels.right<m_cxClient)
// rcAllLabels.right=m_cxClient;
int BkMode = pDC->SetBkMode(TRANSPARENT);
CUIListCtrlData *pData = (CUIListCtrlData*)lvi.lParam;
ASSERT(pData->IsKindOf(RUNTIME_CLASS(CUIListCtrlData)));
CFont *pOldFont = NULL;
if (pData && pData->IsFontSet())
{
pOldFont = pDC->SelectObject((CFont*)pData->GetFont());
}
if(bSelected)
{
if (bFocus)
{
clrTextSave=pDC->SetTextColor(::GetSysColor(COLOR_HIGHLIGHTTEXT));
clrBkSave=pDC->SetBkColor(::GetSysColor(COLOR_HIGHLIGHT));
pDC->FillRect(rcAllLabels,&CBrush(::GetSysColor(COLOR_HIGHLIGHT)));
}
else
{
clrTextSave=pDC->GetTextColor();
clrBkSave=pDC->GetBkColor();
DWORD clrTextBk;
if (pData)
{
pDC->SetTextColor(pData->GetTextColor());
clrTextBk = pData->GetBkColor();
}
else
{
clrTextBk = m_clrTextBk;
pDC->SetTextColor(m_clrText);
}
CRect rc(rcAllLabels);
pDC->FillRect(rcAllLabels,&CBrush(clrTextBk));
pDC->FrameRect(rc,&CBrush(::GetSysColor(COLOR_HIGHLIGHT)));
}
}
else
{
CUIListCtrlData *pData = (CUIListCtrlData *)lvi.lParam;
if (pData)
{
ASSERT(pData->IsKindOf(RUNTIME_CLASS(CUIListCtrlData)));
pDC->SetTextColor(pData->GetTextColor());
pDC->SetBkColor(pData->GetBkColor());
pDC->FillRect(rcAllLabels,&CBrush(pData->GetBkColor()));
}
else
pDC->FillRect(rcAllLabels,&CBrush(m_clrTextBk));
}
// set color and mask for the icon
if(lvi.state & LVIS_CUT)
{
clrImage=m_clrBkgnd;
uiFlags|=ILD_BLEND50;
}
else if(bSelected)
{
clrImage=::GetSysColor(COLOR_HIGHLIGHT);
uiFlags|=ILD_BLEND50;
}
// draw state icon
UINT nStateImageMask=lvi.state & LVIS_STATEIMAGEMASK;
if(nStateImageMask)
{
int nImage=(nStateImageMask>>12)-1;
pImageList=GetImageList(LVSIL_STATE);
if(pImageList)
pImageList->Draw(pDC,nImage,CPoint(rcItem.left,rcItem.top),ILD_TRANSPARENT);
}
// draw normal and overlay icon
CRect rcIcon;
GetItemRect(nItem,rcIcon,LVIR_ICON);
pImageList=GetImageList(LVSIL_SMALL);
if(pImageList)
{
UINT nOvlImageMask=lvi.state & LVIS_OVERLAYMASK;
if(rcItem.left<rcItem.right-1)
ImageList_DrawEx(pImageList->m_hImageList,lvi.iImage,pDC->m_hDC,rcIcon.left,rcIcon.top,16,16,m_clrBkgnd,clrImage,uiFlags | nOvlImageMask);
}
// draw item label
GetItemRect(nItem,rcItem,LVIR_LABEL);
rcItem.right-=m_cxStateImageOffset;
pszText=MakeShortString(pDC,szBuff,rcItem.right-rcItem.left,2*OFFSET_FIRST);
rcLabel=rcItem;
rcLabel.left+=OFFSET_FIRST;
rcLabel.right-=OFFSET_FIRST;
pDC->DrawText(pszText,-1,rcLabel,DT_LEFT | DT_SINGLELINE | DT_NOPREFIX | DT_NOCLIP | DT_VCENTER);
// draw labels for extra columns
LV_COLUMN lvc;
lvc.mask=LVCF_FMT | LVCF_WIDTH;
for(int nColumn=1; GetColumn(nColumn,&lvc); nColumn++)
{
rcItem.left=rcItem.right;
rcItem.right+=lvc.cx;
int nRetLen=GetItemText(nItem,nColumn,szBuff,sizeof(szBuff));
if(nRetLen==0) continue;
pszText=MakeShortString(pDC,szBuff,rcItem.right-rcItem.left,2*OFFSET_OTHER);
UINT nJustify=DT_LEFT;
if(pszText==szBuff)
{
switch(lvc.fmt & LVCFMT_JUSTIFYMASK)
{
case LVCFMT_RIGHT:
nJustify=DT_RIGHT;
break;
case LVCFMT_CENTER:
nJustify=DT_CENTER;
break;
default:
break;
}
}
rcLabel=rcItem;
rcLabel.left+=OFFSET_OTHER;
rcLabel.right-=OFFSET_OTHER;
pDC->DrawText(pszText,-1,rcLabel,nJustify | DT_SINGLELINE | DT_NOPREFIX | DT_NOCLIP | DT_VCENTER);
}
if (pData->IsKindOf(RUNTIME_CLASS(CUIStrListCtrlData)))
{
CUIStrListCtrlData *pStrData = (CUIStrListCtrlData*)pData;
if (!pStrData->GetExtraString().IsEmpty())
{
rcLabel=rcAllLabels;
rcLabel.top += (m_cySmallIcon+1);
pDC->DrawText(pStrData->GetExtraString(),-1,rcLabel,DT_LEFT | DT_SINGLELINE | DT_NOPREFIX | DT_NOCLIP | DT_VCENTER);
}
}
// draw focus rectangle if item has focus
if(lvi.state & LVIS_FOCUSED && bFocus)
pDC->DrawFocusRect(rcAllLabels);
// set original colors if item was selected
if(bSelected)
{
pDC->SetTextColor(clrTextSave);
pDC->SetBkColor(clrBkSave);
}
if (pOldFont)
pDC->SelectObject(pOldFont);
pDC->SetBkMode(BkMode);
}
LPCTSTR CUIODListCtrl::MakeShortString(CDC* pDC, LPCTSTR lpszLong, int nColumnLen, int nOffset)
{
static const _TCHAR szThreeDots[]=_T("...");
int nStringLen=lstrlen(lpszLong);
if(nStringLen==0 || pDC->GetTextExtent(lpszLong,nStringLen).cx+nOffset<=nColumnLen)
return(lpszLong);
static _TCHAR szShort[MAX_PATH];
lstrcpy(szShort,lpszLong);
int nAddLen=pDC->GetTextExtent(szThreeDots,sizeof(szThreeDots)).cx;
for(int i=nStringLen-1; i>0; i--)
{
szShort[i]=0;
if(pDC->GetTextExtent(szShort,i).cx+nOffset+nAddLen<=nColumnLen)
break;
}
lstrcat(szShort,szThreeDots);
return(szShort);
}
void CUIODListCtrl::RepaintSelectedItems()
{
CRect rcItem, rcLabel;
// invalidate focused item so it can repaint properly
int nItem=GetNextItem(-1,LVNI_FOCUSED);
if(nItem!=-1)
{
GetItemRect(nItem,rcItem,LVIR_BOUNDS);
GetItemRect(nItem,rcLabel,LVIR_LABEL);
rcItem.left=rcLabel.left;
InvalidateRect(rcItem,FALSE);
}
// if selected items should not be preserved, invalidate them
// if(!(GetStyle() & LVS_SHOWSELALWAYS))
// {
for(nItem=GetNextItem(-1,LVNI_SELECTED);
nItem!=-1; nItem=GetNextItem(nItem,LVNI_SELECTED))
{
GetItemRect(nItem,rcItem,LVIR_BOUNDS);
GetItemRect(nItem,rcLabel,LVIR_LABEL);
rcItem.left=rcLabel.left;
InvalidateRect(rcItem,FALSE);
}
// }
// update changes
UpdateWindow();
}
void CUIODListCtrl::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItem)
{
lpMeasureItem->itemHeight = (m_cySmallIcon+1)*3;
}
BOOL CUIODListCtrl::OnChildNotify(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
LPNMHDR pnmh;
switch (message)
{
case WM_DRAWITEM:
ASSERT(pResult == NULL);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -