Tsyslistviewex.cpp
上传用户:maicowu
上传日期:2007-01-02
资源大小:87k
文件大小:32k
- /************************************
- REVISION LOG ENTRY
- Revision By: Mihai Filimon
- Revised on 5/22/98 9:23:23 AM
- Comments: Tsyslistviewex.cpp : implementation file
- ************************************/
- #include "stdafx.h"
- #include "Tsyslistviewex.h"
- #include "resource.h"
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- #define scanCodeS 0x13
- /////////////////////////////////////////////////////////////////////////////
- // CTsyslistviewex
- TCHAR CTsyslistviewex::m_cImageTextSeparator = TCHAR(':');
- // Function name : CTsyslistviewex::CTsyslistviewex
- // Description : constructor
- // In contructor u must set the height of item list. (MeasureItem is called before
- // PreSubclassWindow!). U can not modify item height at runtime, therefore.
- // Return type : void
- // Argument : int nHeightRel ; set item height
- CTsyslistviewex::CTsyslistviewex(int nHeightRel)
- {
- m_fctDrawItem = CTsyslistviewex::DrawItemNoGrid;
- m_nHeightRel = nHeightRel;
- m_bSorted = false;
- m_bSortWhenClickHeader = TRUE;
- m_nSortItems = 0;
- m_nIProgress = 0;
- m_bSaveHeader = false;
- ResetBoldLines();
- }
- // Function name : CTsyslistviewex::~CTsyslistviewex
- // Description : destructor
- // Return type : void
- CTsyslistviewex::~CTsyslistviewex()
- {
- // Remove the CTColumnBitmap from m_bmpColumns
- POSITION posBmp = m_bmpColumns.GetStartPosition( );
- while (posBmp)
- {
- CTColumnBitmap* pBitmap = NULL;
- int nColumn = 0;
- m_bmpColumns.GetNextAssoc( posBmp , nColumn, pBitmap );
- if (pBitmap)
- delete pBitmap;
- }
- m_bmpColumns.RemoveAll();
-
- // Remove the CTColumnBitmap from m_bmpCells
- posBmp = m_bmpCells.GetStartPosition( );
- while (posBmp)
- {
- CTColumnBitmap* pBitmap = NULL;
- DWORD nKey = 0;
- m_bmpCells.GetNextAssoc( posBmp , nKey, pBitmap );
- if (pBitmap)
- delete pBitmap;
- }
- m_bmpCells.RemoveAll();
- }
- // Function name : CTsyslistviewex::IsHeaderSaved
- // Description : accessor: header saved
- // Return type : BOOL ;Return TRUE if EnableSaveHeader was called
- BOOL CTsyslistviewex::IsHeaderSaved()
- {
- return m_bSaveHeader;
- }
- // Function name : CTsyslistviewex::GetRegisteredSort
- // Description : Read form registry in dest for Sort:ID.
- // Return type : BOOL ; Return TRUE if key exist.
- // Argument : CString & dest ; string to put value into
- BOOL CTsyslistviewex::GetRegisteredSort(CString & dest)
- {
- BOOL bResult = false;
- if (IsHeaderSaved())
- {
- CString secid; secid.Format(_T("Sort:%08X"), GetDlgCtrlID());
- CString result = AfxGetApp()->GetProfileString(LIST_SECTION, secid, _T("Default"));
- if (result != _T("Default"))
- {
- dest = result;
- bResult = true;
- }
- }
- return bResult;
- }
- // Function name : CTsyslistviewex::SaveHeader
- // Description : Save widths and sort columns in registry in fromat:
- // Header:ID = Column1:C:126, ...
- // Sort:ID = 1D,2,3 ...
- // Return type : void
- void CTsyslistviewex::SaveHeader()
- {
- if (IsHeaderSaved())
- {
- CString secid; secid.Format(_T("Header:%08X"), GetDlgCtrlID());
- AfxGetApp()->WriteProfileString(LIST_SECTION, secid, (LPCTSTR)GetHeaderString());
- secid.Format(_T("Sort:%08X"), GetDlgCtrlID());
- AfxGetApp()->WriteProfileString(LIST_SECTION, secid, (LPCTSTR)GetHeaderSortString());
- }
- }
- BEGIN_MESSAGE_MAP(CTsyslistviewex, CListCtrl)
- //{{AFX_MSG_MAP(CTsyslistviewex)
- ON_WM_LBUTTONDOWN()
- ON_NOTIFY_REFLECT(LVN_COLUMNCLICK, OnColumnclick)
- ON_WM_CHAR()
- //}}AFX_MSG_MAP
- ON_WM_MEASUREITEM_REFLECT()
- END_MESSAGE_MAP()
- /////////////////////////////////////////////////////////////////////////////
- // CTsyslistviewex message handlers
- // Function name : CTsyslistviewex::PreSubclassWindow
- // Description : Called when user subclass list control form resource
- // Return type : void
- void CTsyslistviewex::PreSubclassWindow( )
- {
- // Must be owner draw and report mode....
- ModifyStyle(LVS_SMALLICON | LVS_LIST | LVS_ICON , LVS_OWNERDRAWFIXED | LVS_REPORT);
- m_pOldHeaderCtrl = GetDlgItem(0);
- // Create different fonts..
- if (CFont* pFont = GetFont())
- {
- LOGFONT lf;
- pFont->GetLogFont(&lf);
- lf.lfWeight = FW_BOLD;
- m_boldFont.CreateFontIndirect(&lf);
- lf.lfWeight = FW_NORMAL;
- lf.lfItalic = TRUE;
- m_italicFont.CreateFontIndirect(&lf);
- lf.lfWeight = FW_BOLD;
- lf.lfItalic = TRUE;
- m_italicBoldFont.CreateFontIndirect(&lf);
- }
- SetWindowLong(m_hWnd, GWL_USERDATA , LIST_SUBCLASSED);
- }
- // Function name : CTsyslistviewex::OnLButtonDown
- // Description : If user click in list ctrl, test item, subItem
- // Return type : void
- // Argument : UINT nFlags
- // Argument : CPoint point
- void CTsyslistviewex::OnLButtonDown(UINT nFlags, CPoint point)
- {
- SetFocus();
- int item = -1, subItem = -1 ;
- item = HitTestEx(point, subItem);
- CListCtrl::OnLButtonDown(nFlags, point);
- }
- // Function name : CTsyslistviewex::MakeShortString
- // Description : Return shorted string lpszLong in device pDC
- // Return type : LPCTSTR
- // Argument : CDC* pDC
- // Argument : LPCTSTR lpszLong
- // Argument : int nColumnLen
- // Argument : int nOffset
- LPCTSTR CTsyslistviewex::MakeShortString(CDC* pDC, LPCTSTR lpszLong, int nColumnLen, int nOffset)
- {
- static const TCHAR szThreeDots[] = _T("... ");
- static TCHAR szShort[MAX_PATH];
- int nStringLen = strlen(lpszLong);
- if(nStringLen == 0 ||
- (pDC->GetTextExtent(lpszLong, nStringLen).cx + nOffset) <= nColumnLen)
- {
- return(lpszLong);
- }
- strcpy(szShort,lpszLong);
- int nAddLen = pDC->GetTextExtent(szThreeDots,strlen(szThreeDots)).cx;
- for(int i = nStringLen-1; i > 0; i--)
- {
- szShort[i] = ' ';
- if((pDC->GetTextExtent(szShort, i).cx + nOffset + nAddLen)
- <= nColumnLen)
- {
- break;
- }
- }
- strcat(szShort, szThreeDots);
- return(szShort);
- }
- // Function name : CTsyslistviewex::DrawCell
- // Description : Draw at pDC in drawRect cell(nItem,nColumn) with format
- // Return type : void
- // Argument : CDC* pDC
- // Argument : CRect& drawRect
- // Argument : int nItem
- // Argument : int nColumn
- void CTsyslistviewex::DrawCell(CDC* pDC, CRect& drawRect, DWORD format, int nItem, int nColumn)
- {
- static TCHAR szBuff[MAX_PATH];
- LPCTSTR pszText;
- GetItemText(nItem, nColumn, szBuff, sizeof(szBuff));
- {
- CTColumnBitmap* pBitmap = GetBitmapCell(GetItemData(nItem),nColumn);
- int dxBitmap = 0;
- CString sImageBitmap, sText(szBuff);
- if (pBitmap)
- {
- dxBitmap = min(pBitmap->GetWidth(),drawRect.Width());
- int p = sText.Find(m_cImageTextSeparator);
- sImageBitmap = sText.Left(max(0,p));
- sText = sText.Mid(p + 1);
- if (p < 0)
- {
- sImageBitmap = sText;
- sText.Empty();
- }
- }
- pszText = MakeShortString(pDC, (LPCTSTR)sText, (drawRect.right - (drawRect.left + dxBitmap + OFFSET)), OFFSET);
- if (*pszText != TCHAR(' '))
- {
- UINT nJustify = DT_LEFT;
- if(pszText == sText)
- {
- switch(format & LVCFMT_JUSTIFYMASK)
- {
- case LVCFMT_RIGHT:
- nJustify = DT_RIGHT;
- break;
- case LVCFMT_CENTER:
- nJustify = DT_CENTER;
- break;
- default:
- break;
- }
- }
- drawRect.left = drawRect.left + dxBitmap + OFFSET;
- pDC->DrawText(pszText, -1, drawRect, nJustify | DT_SINGLELINE | DT_NOPREFIX | DT_VCENTER);
- drawRect.left = drawRect.left -(dxBitmap + OFFSET);
- }
- if (dxBitmap)
- {
- int nImageColumn = atoi(sImageBitmap);
- int x = drawRect.left;
- CRect rectImage = pBitmap->GetRectImage(nImageColumn);
- pBitmap->Put(nImageColumn, pDC, x , drawRect.top + (drawRect.Height() - rectImage.Height())/2, dxBitmap);
- }
- }
- }
- // Function name : CTsyslistviewex::DrawItemGrid
- // Description : Draw item with grid lines
- // Return type : void
- // Argument : LPDRAWITEMSTRUCT lpDrawItemStruct
- void CTsyslistviewex::DrawItemGrid(LPDRAWITEMSTRUCT lpDrawItemStruct)
- {
- // device contextul itemului
- CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
-
- // dreptunghiul corespunzator itemului
- CRect rcItem(lpDrawItemStruct->rcItem);
- // identificatorul itemului
- int nItem = lpDrawItemStruct->itemID;
-
- BYTE value = 0;
- CFont* pOldFont = NULL;
- if (m_mapRowsBold.Lookup(lpDrawItemStruct->itemData, value))
- pOldFont = (CFont*)pDC->SelectObject(&m_boldFont);
- if (m_mapRowsItalic.Lookup(lpDrawItemStruct->itemData, value))
- {
- CFont* pF = (CFont*)pDC->SelectObject(&m_italicFont);
- if (pOldFont)
- pF = (CFont*)pDC->SelectObject(&m_italicBoldFont);
- else
- pOldFont = pF;
- }
-
- // culori
- COLORREF clrTextSave, clrBkSave;
- // get item data
- LV_ITEM lvi;
- lvi.mask = LVIF_STATE;
- lvi.iItem = nItem;
- lvi.iSubItem = 0;
- lvi.stateMask = 0xFFFF; // get all state flags
- GetItem(&lvi);
- BOOL bFocus = ((lvi.state & LVIS_FOCUSED) == LVIS_FOCUSED);
- BOOL bSelected = (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);
- if (bSelected)
- {
- clrTextSave = pDC->SetTextColor(::GetSysColor(COLOR_HIGHLIGHTTEXT));
- clrBkSave = pDC->SetBkColor(::GetSysColor(COLOR_HIGHLIGHT));
- }
- pDC->FillRect(rcAllLabels, &CBrush(::GetSysColor(bSelected ? COLOR_HIGHLIGHT : COLOR_WINDOW)));
- // draw item
- CBrush brush(RGB(128,128,128));
- GetItemRect(nItem, rcItem, LVIR_LABEL);
- LV_COLUMN lvc;
- lvc.mask = LVCF_FMT | LVCF_WIDTH;
- rcItem.OffsetRect(-OFFSET,0);
- for(int nColumn = 0; GetColumn(nColumn, &lvc); nColumn++)
- {
- rcItem.right = rcItem.left + lvc.cx;
- CRect drawRect(rcItem);
- drawRect.InflateRect(-1,-1);
- pDC->FrameRect(drawRect, &brush);
- drawRect.OffsetRect(1,0);
- drawRect.InflateRect(-2,0);
- DrawCell(pDC,drawRect,lvc.fmt, nItem,nColumn);
- rcItem.left = rcItem.right;
- }
- pDC->SelectObject(pOldFont);
- // draw focus rectangle if item has focus
- if (bFocus)
- pDC->DrawFocusRect(rcAllLabels);
- // set original colors if item was selected
- if (bSelected)
- {
- pDC->SetTextColor(clrTextSave);
- pDC->SetBkColor(clrBkSave);
- }
- }
- // Function name : CTsyslistviewex::DrawItemNoGrid
- // Description : Draw item without grid lines.
- // Return type : void
- // Argument : LPDRAWITEMSTRUCT lpDrawItemStruct
- void CTsyslistviewex::DrawItemNoGrid(LPDRAWITEMSTRUCT lpDrawItemStruct)
- {
- // device contextul itemului
- CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
-
- // dreptunghiul corespunzator itemului
- CRect rcItem(lpDrawItemStruct->rcItem);
- // identificatorul itemului
- int nItem = lpDrawItemStruct->itemID;
-
- BYTE value = 0;
- CFont* pOldFont = NULL;
- if (m_mapRowsBold.Lookup(lpDrawItemStruct->itemData, value))
- pOldFont = (CFont*)pDC->SelectObject(&m_boldFont);
- if (m_mapRowsItalic.Lookup(lpDrawItemStruct->itemData, value))
- {
- CFont* pF = (CFont*)pDC->SelectObject(&m_italicFont);
- if (pOldFont)
- pF = (CFont*)pDC->SelectObject(&m_italicBoldFont);
- else
- pOldFont = pF;
- }
- // culori
- COLORREF clrTextSave, clrBkSave;
-
- // get item data
- LV_ITEM lvi;
- lvi.mask = LVIF_STATE;
- lvi.iItem = nItem;
- lvi.iSubItem = 0;
- lvi.stateMask = 0xFFFF; // get all state flags
- GetItem(&lvi);
- BOOL bFocus = ((lvi.state & LVIS_FOCUSED) == LVIS_FOCUSED);
- BOOL bSelected = (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);
- if (bSelected)
- {
- clrTextSave = pDC->SetTextColor(::GetSysColor(COLOR_HIGHLIGHTTEXT));
- clrBkSave = pDC->SetBkColor(::GetSysColor(COLOR_HIGHLIGHT));
- }
- pDC->FillRect(rcAllLabels, &CBrush(::GetSysColor(bSelected ? COLOR_HIGHLIGHT : COLOR_WINDOW)));
- // draw item
- CBrush brush(RGB(0,0,0));
- GetItemRect(nItem, rcItem, LVIR_LABEL);
- LV_COLUMN lvc;
- lvc.mask = LVCF_FMT | LVCF_WIDTH;
- rcItem.OffsetRect(-OFFSET,0);
- for(int nColumn = 0; GetColumn(nColumn, &lvc); nColumn++)
- {
- rcItem.right = rcItem.left + lvc.cx;
- CRect drawRect(rcItem);
- drawRect.InflateRect(-1,-1);
- drawRect.OffsetRect(2,0);
- drawRect.InflateRect(-4,0);
- DrawCell(pDC,drawRect,lvc.fmt, nItem,nColumn);
- rcItem.left = rcItem.right;
- }
- pDC->SelectObject(pOldFont);
- // draw focus rectangle if item has focus
- if (bFocus)
- pDC->DrawFocusRect(rcAllLabels);
- // set original colors if item was selected
- if (bSelected)
- {
- pDC->SetTextColor(clrTextSave);
- pDC->SetBkColor(clrBkSave);
- }
- }
- // Function name : CTsyslistviewex::DrawItem
- // Description : Draw one item. m_fctDrawItem is set in ViewGridLines(BOOL bEnable ).
- // Return type : void
- // Argument : LPDRAWITEMSTRUCT lpDrawItemStruct
- void CTsyslistviewex::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
- {
- (this->*m_fctDrawItem)(lpDrawItemStruct);
- }
- // Function name : CTsyslistviewex::HitTestEx
- // Description : Check if point is in on of list's cell. Return row(return value) an column (subItem)
- // Return type : int
- // Argument : CPoint point
- // Argument : int& subItem
- int CTsyslistviewex::HitTestEx(CPoint point, int& subItem)
- {
- CRect rect; int item = -1;
- subItem = -1;
- if (GetItemRect(0, rect, LVIR_LABEL))
- {
- CRect hRect = rect;
- hRect.OffsetRect((abs(hRect.left) - hRect.left)/2,0);
- item = HitTest(CPoint(int((hRect.left + hRect.right)/2), point.y));
- }
- if (item>=0)
- {
- int ccx = rect.left;
- LV_COLUMN lvc;lvc.mask = LVCF_WIDTH;
- for(int nColumn = 0; GetColumn(nColumn, &lvc); nColumn++, ccx += lvc.cx)
- if ((point.x >= ccx) && (point.x < ccx + lvc.cx))
- {
- subItem = nColumn;
- break;
- }
- }
- item = subItem >= 0 ? item : -1;
- return item;
- }
- // Function name : CTsyslistviewex::GetSubItemRect
- // Description : Return the rect of subitem subItem
- // Return type : BOOL ; TRUE if succeeded
- // Argument : int item ; item - row position
- // Argument : int subItem ; subItem - column position
- // Argument : CRect & rect ; CRect to complete
- BOOL CTsyslistviewex::GetSubItemRect(int item, int subItem, CRect & rect)
- {
- if (subItem >= 0)
- if (GetItemRect(item, rect, LVIR_LABEL))
- {
- int ccx = rect.TopLeft().x;
- LV_COLUMN lvc;lvc.mask = LVCF_WIDTH;
- if (GetColumn(subItem, &lvc))
- {
- int dx = lvc.cx;
- for (int nColumn = 0; nColumn < subItem && GetColumn(nColumn, &lvc); nColumn++)
- ccx += lvc.cx;
- rect = CRect(CPoint(ccx,rect.TopLeft().y),CPoint(ccx + dx,rect.BottomRight().y));
- return TRUE;
- }
- }
- return FALSE;
- }
- // Function name : CTsyslistviewex::MeasureItem
- // Description : see contructor CTsyslistviewex(int nHeightRel)
- // Return type : void
- // Argument : LPMEASUREITEMSTRUCT lpMeasureItem ; finds StructHeight of item needed to set m_nHeightRel
- void CTsyslistviewex::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)
- {
- lpMeasureItemStruct->itemHeight += m_nHeightRel;
- }
- // Function name : CTsyslistviewex::ViewGridLines
- // Description : Enable or disable draw grid lines.
- // Return type : void
- // Argument : BOOL bEnable ; TRUE to enable
- void CTsyslistviewex::ViewGridLines(BOOL bEnable )
- {
- m_fctDrawItem = bEnable ? CTsyslistviewex::DrawItemGrid : CTsyslistviewex::DrawItemNoGrid;
- Invalidate();
- }
- // Function name : CTsyslistviewex::ExpandHeader
- // Description : Try to put all columns from list control in client rect.
- // Return type : void
- void CTsyslistviewex::ExpandHeader()
- {
- const offsetMarginHeader = 8;
- CHeaderCtrl* pHeader = (CHeaderCtrl*)GetDlgItem(0);
- CRect rect; GetClientRect(rect);
- int dxRect = rect.Width() - 2;
- int dxHeader = 0, i = 0; BOOL bColumn = true;
- int nLastColumn = pHeader->GetItemCount() - 1;
- if (nLastColumn >= 0)
- {
- HD_ITEM item; item.mask = HDI_WIDTH;
- for (i = 0; i < nLastColumn && (pHeader->GetItem(i, &item)); i++)
- dxHeader += item.cxy ;
- BOOL bStop = false;
- do
- {
- pHeader->GetItem(nLastColumn, &item);
- int icx = dxRect - dxHeader;
- bStop = icx >=0;
- if (!bStop)
- icx = offsetMarginHeader / 2;
- item.cxy = icx;
- pHeader->SetItem(nLastColumn, &item);
- if (bStop)
- return;
- ASSERT (icx >= 0);
- nLastColumn--;
- pHeader->GetItem(nLastColumn, &item);
- dxHeader = dxHeader - item.cxy + icx;
- }
- while (nLastColumn>=0);
- }
- }
- // Function name : CTsyslistviewex::AddSortCallBack
- // Description : Attach to an column nColumn
- // comparing function:
- // typedef int (*COLUMNCALLBACKCOMPARE) (const wchar_t *stringi, const wchar_t *stringj)
- // return values:
- // -1 for stringi < stringj
- // 0 for stringi == stringj
- // +1 for stringi > stringj
- // Return type : void
- // Argument : int nColumn
- // Argument : COLUMNCALLBACKCOMPARE pCallBack
- void CTsyslistviewex::AddSortCallBack(int nColumn, COLUMNCALLBACKCOMPARE pCallBack)
- {
- // Already u must call EnableSort...
- ASSERT (m_sortColumns.m_pListCtrl == this);
- // pCallBack must be nenul...
- ASSERT (pCallBack != NULL);
- m_sortColumns.Add(nColumn, pCallBack);
- }
- // Function name : CTsyslistviewex::EnableSaveHeader
- // Description : Enable or disable save widths of listctrl
- // Must call it before attach this list control attach to record set
- // (!)In InitInstance, u must call: SetRegistryKey(AfxGetAppName());
- // Return type : void
- // Argument : BOOL bEnable ; TRUE to enable
- void CTsyslistviewex::EnableSaveHeader(BOOL bEnable)
- {
- // The control must already subclassed....
- ASSERT ((GetWindowLong(m_hWnd, GWL_USERDATA) & LIST_MASKCLASS) == LIST_SUBCLASSED);
- m_bSaveHeader = bEnable;
- }
- // Function name : CTsyslistviewex::EnableSort
- // Description : Enable or disable sort procedure.
- // Return type : void
- // Argument : BOOL bEnable ; TRUE to enable
- void CTsyslistviewex::EnableSort(BOOL bEnable)
- {
- CWnd* pWnd = bEnable ? &m_wndSortHeaderEx : m_pOldHeaderCtrl;
- pWnd->SubclassDlgItem(0,this);
- m_bSorted = bEnable;
- m_sortColumns.AttachControl(bEnable ? this : NULL);
- }
- // Function name : CTsyslistviewex::OnColumnclick
- // Description : SortClick handler (if m_bSortWhenClickHeader is set)
- // Return type : void
- // Argument : NMHDR* pNMHDR
- // Argument : LRESULT* pResult
- void CTsyslistviewex::OnColumnclick(NMHDR* pNMHDR, LRESULT* pResult)
- {
- NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
- *pResult = 0;
- if (m_bSorted)
- {
- GetAsyncKeyState(VK_CONTROL);
- BOOL bControl = GetAsyncKeyState(VK_CONTROL);
- int iNewSortColumn = pNMListView->iSubItem;
- BOOL bAsc = true;
- int nPosition = 0;
- BOOL bSortedColumn = m_wndSortHeaderEx.GetColumnOrder(iNewSortColumn, bAsc, nPosition);
- if (!bControl && !bSortedColumn)
- m_wndSortHeaderEx.ResetSortColumns();
- if (bSortedColumn)
- if (!bAsc)
- {
- m_wndSortHeaderEx.DeleteColumnOrder(iNewSortColumn);
- iNewSortColumn = -1;
- }
- else
- bAsc = !bAsc;
- if (iNewSortColumn >= 0)
- m_wndSortHeaderEx.SetColumnOrder(iNewSortColumn, bAsc);
- if (m_bSortWhenClickHeader)
- SortAllItems();
- }
- }
- // Function name : CTsyslistviewex::AttachBitmap
- // Description : Attach a bitmap image to a column
- // Return type : BOOL
- // Argument : int nColumn ; column to put immage into
- // Argument : UINT nIDBitmap ; bitmap identifier
- // Argument : int nImageWidth ; bitmap width
- // Argument : int nImageHeight ; bitmap height
- // Argument : int nRowImage ; sub-bitmap index (for multi-icon bitmaps)
- BOOL CTsyslistviewex::AttachBitmap(int nColumn, UINT nIDBitmap, int nImageWidth, int nImageHeight, int nRowImage)
- {
- CTColumnBitmap* pBitmap = NULL;
- if (pBitmap = new CTColumnBitmap(nIDBitmap, nImageWidth, nImageHeight, nRowImage))
- {
- ASSERT(pBitmap->IsLoad());
- if (CTColumnBitmap* pOldBitmap = GetBitmapColumn(nColumn))
- delete pOldBitmap;
- m_bmpColumns[nColumn] = pBitmap;
- return TRUE;
- }
- return FALSE;
- }
- // Function name : CTHxgrid::ComposeKeyForCell
- // Description : Return a key identifier for search in maps.
- // Return type : DWORD
- // Argument : short nIDRow
- // Argument : short nColumn
- DWORD CTsyslistviewex::ComposeKeyForCell(USHORT nIDRow, USHORT nColumn)
- {
- return MAKELONG(nColumn,nIDRow);
- }
- // Function name : CTsyslistviewex::AttachBitmapCell
- // Description : Attach a bitmap to a cell.
- // Return type : BOOL
- // Argument : USHORT nIDRow - cell is on item witch contain in userdata nIDRow
- // Argument : USHORT nColumn - cell is on column nColumn
- // Argument : UINT nIDBitmap - Resource identifier of bitmap.
- // Argument : int nImageWidth - Width of bitmap cell.
- // Argument : int nImageHeight - Height of bitmap cell
- // Argument : int nRowImage - sub-bitmap index (for multi-icon bitmaps)
- BOOL CTsyslistviewex::AttachBitmapCell(USHORT nIDRow, USHORT nColumn, UINT nIDBitmap, int nImageWidth, int nImageHeight, int nRowImage)
- {
- CTColumnBitmap* pBitmap = NULL;
- if (pBitmap = new CTColumnBitmap(nIDBitmap, nImageWidth, nImageHeight, nRowImage))
- {
- ASSERT(pBitmap->IsLoad());
- if (CTColumnBitmap* pOldBitmap = GetBitmapCell(nIDRow,nColumn))
- delete pOldBitmap;
- m_bmpCells[ComposeKeyForCell(nIDRow, nColumn)] = pBitmap;
- return TRUE;
- }
- return FALSE;
- }
- // Function name : CTsyslistviewex::GetBitmapColumn
- // Description : Return pointer to CTColumnBitmap object if nColumn is registered
- // as column of bitmaps.
- // Return type : CTColumnBitmap*
- // Argument : int nColumn
- CTColumnBitmap* CTsyslistviewex::GetBitmapColumn(int nColumn)
- {
- CTColumnBitmap* pOldBitmap = NULL;
- m_bmpColumns.Lookup(nColumn, pOldBitmap);
- return pOldBitmap;
- }
- // Function name : CTsyslistviewex::GetBitmapCell
- // Description : Return pointer to CTColumnBitmap object if cell from (Item with nIDRow userdata,nColumn) is registered
- // as bitmap cell.
- // Return type : CTColumnBitmap*
- // Argument : DWORD nIDRow
- // Argument : int nColumn
- CTColumnBitmap* CTsyslistviewex::GetBitmapCell(DWORD nIDRow, int nColumn)
- {
- CTColumnBitmap* pOldBitmap = GetBitmapColumn(nColumn);
- if (pOldBitmap == NULL)
- m_bmpCells.Lookup(ComposeKeyForCell((USHORT)nIDRow,(USHORT)nColumn), pOldBitmap);
- return pOldBitmap;
- }
- // Function name : CTsyslistviewex::SortAllItems
- // Description : Call sort items specified by lpszColumnsSort. lpszColumnsSort can be: _T("0,2D,1A"),
- // and this means that order of sort is column 0 ascending, the next, 2 descending
- // This procedure take all column for order from lpszColumnsSort, and reset old
- // columns sort.
- // (!) Stop relay event in all recordsets in SortAllItems().
- // Return type : void
- // Argument : LPCTSTR lpszColumnsSort
- void CTsyslistviewex::SortAllItems(LPCTSTR lpszColumnsSort)
- {
- // Already call EnableSort...
- ASSERT ( m_bSorted );
- LPCTSTR lpszCurrentColumnsSort = lpszColumnsSort;
- CString sRegisterColumnsSort; sRegisterColumnsSort.Empty();
- if (GetRegisteredSort(sRegisterColumnsSort))
- lpszCurrentColumnsSort = (LPCTSTR)sRegisterColumnsSort;
- CString column; int i = 0;
- m_wndSortHeaderEx.ResetSortColumns();
- do
- {
- AfxExtractSubString(column, lpszCurrentColumnsSort, i++, ',');
- if (!column.IsEmpty())
- {
- TCHAR cAsc = column[column.GetLength()-1];
- BOOL bAsc = true;
- if (!iswdigit(cAsc))
- {
- ASSERT (cAsc == 'A' || cAsc == 'D');
- if (cAsc == 'D')
- bAsc = !bAsc;
- column = column.Left(column.GetLength()-1);
- }
- int nColumn = atoi((LPCTSTR)column);
- m_wndSortHeaderEx.SetColumnOrder(nColumn, bAsc);
- }
- }
- while (!column.IsEmpty());
- SortAllItems();
- }
- // Function name : CTsyslistviewex::SortAllItems
- // Description : sort all items according to header flags
- // (!) Stop relay event in all recordsets.
- // Return type : void
- void CTsyslistviewex::SortAllItems()
- {
- ASSERT ( m_bSorted );
- m_sortColumns.ResetOrderColumn();
- int column = 0;
- BOOL bAsc = true;
- for (int iPosition = 1; m_wndSortHeaderEx.GetPositionColumn(iPosition, bAsc, column); iPosition++ )
- m_sortColumns.AddOrderColumn(column,bAsc ? 1 : -1);
- if (m_sortColumns.GetCountOrderColumn())
- {
- AfxGetApp()->DoWaitCursor(1);
- m_sortColumns.Sort();
- AfxGetApp()->DoWaitCursor(-1);
- }
- SaveHeader();
- }
- // Function name : CTsyslistviewex::GetCountColumn
- // Description : Return number of columns from control.
- // Return type : int ; columns count
- int CTsyslistviewex::GetCountColumn()
- {
- return ((CHeaderCtrl*)GetDlgItem(0))->GetItemCount();
- }
- // Function name : CTsyslistviewex::Progress
- // Description : displays the progress bar
- // Return type : void
- // Argument : int nPercent ; 0 - progress bar set top middle, 100 progress bar is off
- void CTsyslistviewex::Progress(int nPercent)
- {
- if (!m_wndProgress.GetSafeHwnd())
- {
- const int dyProgress = 20;
- CRect rect; GetWindowRect(rect);
- ScreenToClient(rect);
- int dxProgress = rect.Width() * 3 / 4;
- rect.top += (rect.Height() - dyProgress) / 2;
- rect.bottom = rect.top + dyProgress ;
- rect.left += (rect.Width() - dxProgress) / 2;
- rect.right = rect.left + dxProgress;
- m_wndProgress.Create(WS_CHILD | WS_BORDER | WS_VISIBLE, rect, this, GetDlgCtrlID());
- }
- m_wndProgress.SetPos(nPercent);
- if (nPercent == 100)
- m_wndProgress.DestroyWindow();
- }
- // Function name : CTsyslistviewex::ResetBoldLines
- // Description : reset all bold lines
- // Return type : void
- void CTsyslistviewex::ResetBoldLines()
- {
- m_mapRowsBold.RemoveAll();
- }
- // Function name : CTsyslistviewex::SetBoldRow
- // Description : If lParam == NULL then set bold for focused line.
- // Return type : void
- // Argument : LPARAM lParam
- // Argument : BOOL bBold
- // Argument : BOOL bInvalidate
- void CTsyslistviewex::SetBoldRow(LPARAM lParam, BOOL bBold, BOOL bInvalidate)
- {
- if (m_boldFont.GetSafeHandle())
- {
- if (!lParam)
- lParam = GetItemData(GetNextItem(-1, LVNI_FOCUSED));
- if (bBold)
- m_mapRowsBold[lParam] = 1;
- else
- m_mapRowsBold.RemoveKey(lParam);
-
- if (bInvalidate)
- Invalidate(false);
- }
- }
- // Function name : CTsyslistviewex::SetItalicRow
- // Description : If lParam == NULL then set italic for focused line.
- // Return type : void
- // Argument : LPARAM lParam
- // Argument : BOOL bItalic
- // Argument : BOOL bInvalidate
- void CTsyslistviewex::SetItalicRow(LPARAM lParam, BOOL bItalic, BOOL bInvalidate)
- {
- if (m_italicFont.GetSafeHandle())
- {
- if (!lParam)
- lParam = GetItemData(GetNextItem(-1, LVNI_FOCUSED));
- if (bItalic)
- m_mapRowsItalic[lParam] = 1;
- else
- m_mapRowsItalic.RemoveKey(lParam);
-
- if (bInvalidate)
- Invalidate(false);
- }
- }
- // Function name : CTsyslistviewex::DeselectAll
- // Description : Deselect all items from control
- // Return type : void
- void CTsyslistviewex::DeselectAll()
- {
- int iCurrent = GetNextItem(-1, LVIS_SELECTED);
- while (iCurrent >= 0)
- {
- SetItemState(iCurrent, ~LVIS_SELECTED, LVIS_SELECTED);
- iCurrent = GetNextItem(iCurrent, LVIS_SELECTED);
- }
- }
- // Function name : CTsyslistviewex::SelectItem
- // Description : Deselect all items, and select one item.
- // Return type : void
- // Argument : int i ; item index
- void CTsyslistviewex::SelectItem(int i)
- {
- DeselectAll();
- SetItemState(i, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
- EnsureVisible(i,false);
- }
- // Function name : CTsyslistviewex::GetHeaderSortString
- // Description : Called in SaveAllItems(), returns header format string
- // Return type : CString ; sort header as string, for save it in the registry
- CString CTsyslistviewex::GetHeaderSortString()
- {
- CString result; result.Empty();
- if (m_bSorted)
- {
- int nPosition = 1;
- int nColumn = NULL;
- BOOL bAsc = true;
- while (m_wndSortHeaderEx.GetPositionColumn(nPosition++, bAsc, nColumn))
- {
- CString sColumn; sColumn.Format(_T("%i%s,"),nColumn, (bAsc ? _T("") : _T("D")));
- result += sColumn;
- }
- if (!result.IsEmpty())
- result = result.Left(result.GetLength() - 1);
- }
- return result;
- }
- // Function name : CTsyslistviewex::GetHeaderString
- // Description : Return the header format string
- // Return type : CString ; header formated as: ColumnName1:FormatColumn1:WidthColumn1,...
- CString CTsyslistviewex::GetHeaderString()
- {
- CString result; result.Empty();
- LV_COLUMN column;
- TCHAR pszText[MAX_PATH];
- column.mask = LVCF_TEXT | LVCF_FMT | LVCF_WIDTH;
- column.pszText = pszText;
- column.cchTextMax = MAX_PATH;
- for (int i = 0; GetColumn(i, &column); i++)
- {
- TCHAR f = TCHAR('L');
- switch (column.fmt & LVCFMT_JUSTIFYMASK)
- {
- case LVCFMT_RIGHT:
- f = TCHAR('R');
- break;
- case LVCFMT_CENTER:
- f = TCHAR('C');
- break;
- }
- CString w; w.Format(_T("%i"), column.cx);
- result = result + column.pszText + TCHAR(':') + w + TCHAR(':') + f + TCHAR(',');
- column.mask = LVCF_TEXT | LVCF_FMT | LVCF_WIDTH;
- }
- return result.Left(result.GetLength() - (result.IsEmpty() ? 0 : 1)); // last ,
- }
- // Function name : CTsyslistviewex::OnNotify
- // Description : Called when item width changed. If necessarly the widths are saved in registry.
- // Return type : BOOL
- // Argument : WPARAM wParam
- // Argument : LPARAM lParam
- // Argument : LRESULT* pResult
- BOOL CTsyslistviewex::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
- {
- if ((int)wParam == 0)
- if (GetDlgItem(0)->IsWindowVisible())
- {
- switch (((HD_NOTIFY*)lParam)->hdr.code)
- {
- case HDN_ITEMCHANGEDA:
- case HDN_ITEMCHANGEDW:
- SaveHeader();
- break;
- }
- }
-
- return CListCtrl::OnNotify(wParam, lParam, pResult);
- }
- // Function name : CTsyslistviewex::NeedCX
- // Description : Calc total width of listctrl
- // Return type : int ; listctrl width
- int CTsyslistviewex::NeedCX()
- {
- int result = 0;
- LV_COLUMN lvc; lvc.mask = LVCF_WIDTH;
- for (int i = 0; GetColumn(i, &lvc); i++)
- result += lvc.cx;
- return result;
- }
- // Function name : CTsyslistviewex::NeedCY
- // Description : Calc partial visible height of listctrl
- // Return type : int ; visible height of listctrl
- int CTsyslistviewex::NeedCY()
- {
- CRect rect; GetClientRect(rect); int hRect = rect.Height();
- CRect rcItem;
- int result = 0;
- for (int i = GetTopIndex(); GetItemRect(i, rcItem,LVIR_LABEL) && result + rcItem.Height() < hRect; i++ )
- result += rcItem.Height();
- return result;
- }
- // Function name : CTsyslistviewex::OnChar
- // Description : Treat specialy CTRL+S for sorting, if m_bSortWhenClickHeader is FALSE
- // Return type : void
- // Argument : UINT nChar
- // Argument : UINT nRepCnt
- // Argument : UINT nFlags
- void CTsyslistviewex::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
- {
- if (!m_bSortWhenClickHeader)
- if (GetKeyState(VK_CONTROL) < 0)
- if (nChar == scanCodeS)
- SortAllItems();
-
- CListCtrl::OnChar(nChar, nRepCnt, nFlags);
- }
- // Function name : CTsyslistviewex::GetCountRowsBold
- // Description : Return count of bold rows
- // Return type : int
- int CTsyslistviewex::GetCountRowsBold()
- {
- return m_mapRowsBold.GetCount();
- }
- // Function name : CTsyslistviewex::GetCountRowsItalic
- // Description : Return count of italic rows
- // Return type : int
- int CTsyslistviewex::GetCountRowsItalic()
- {
- return m_mapRowsItalic.GetCount();
- }
- // Function name : CTsyslistview32::SetHeader
- // Description :
- // Return type : BOOL
- // Argument : CListCtrl * pList
- // Argument : CString newHeader
- BOOL CTsyslistviewex::SetHeader(CListCtrl * pList, CString newHeader)
- {
- CHeaderCtrl* pHeader = (CHeaderCtrl*)pList->GetDlgItem(0);
- if (pHeader)
- {
- while (pHeader->GetItemCount()) pHeader->DeleteItem(0);
- int i = 0; CString rString; rString.Empty();
- CMap<TCHAR,TCHAR,int,int> justifyMap;
- justifyMap['L'] = LVCFMT_LEFT;
- justifyMap['C'] = LVCFMT_CENTER;
- justifyMap['R'] = LVCFMT_RIGHT;
- do
- {
- AfxExtractSubString(rString, newHeader, i, ',');
- if (!rString.IsEmpty())
- {
- CString columnName;
- AfxExtractSubString(columnName, rString, 0, ':');
- CString columnWidth;
- AfxExtractSubString(columnWidth, rString, 1, ':');
- if (columnWidth.IsEmpty()) columnWidth = _T("128"); // default value
- CString columnJustify;
- AfxExtractSubString(columnJustify, rString, 2, ':');
- int justify = LVCFMT_LEFT;
- if (!columnJustify.IsEmpty())
- justifyMap.Lookup(columnJustify[0], justify);
- pList->InsertColumn(i,columnName, justify, _wtoi((const wchar_t*)columnWidth.GetBuffer(0)));
- i++;
- }
- } while (!rString.IsEmpty());
- }
- return (pHeader != NULL);
- }