ReportCtrl.cpp
资源名称:anywhere.zip [点击查看]
上传用户:zhenhuadz
上传日期:2007-01-07
资源大小:1511k
文件大小:58k
源码类别:
远程控制编程
开发平台:
Visual C++
- ////////////////////////////////////////////////////////////////////////////
- // File: CReportCtrl.cpp
- // Version: 1.0.1.0
- //
- // Author: Maarten Hoeben
- // E-mail: hoeben@nwn.com
- //
- // Implementation of the CReportCtrl and associated classes.
- //
- // You are free to use, distribute or modify this code
- // as long as the header is not removed or modified.
- //
- // Version history
- //
- // 1.0.1.0 - Initial release
- ////////////////////////////////////////////////////////////////////////////
- // ReportCtrl.cpp : implementation file
- //
- #include "stdafx.h"
- #include "ReportCtrl.h"
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- TCHAR* g_szSeparator = _T("|");
- /////////////////////////////////////////////////////////////////////////////
- // CReportData
- CReportData::CReportData()
- {
- }
- CReportData::~CReportData()
- {
- }
- BOOL CReportData::New(INT iSubItems)
- {
- for(INT i=0;i<iSubItems;i++)
- {
- CString str;
- str.Format(_T("(-1,-1,-1)%s"), g_szSeparator);
- *this += str;
- }
- return TRUE;
- }
- BOOL CReportData::GetSubItem(INT iSubItem, LPINT lpiImage, LPINT lpiCheck, LPINT lpiColor, LPTSTR lpszText, INT iTextMax)
- {
- INT i, iPos;
- for(i=0,iPos=0;i<iSubItem&&iPos>=0;i++,iPos++)
- iPos = Find(g_szSeparator, iPos);
- if(iPos<0)
- return FALSE;
- LPTSTR lpsz = GetBuffer(0);
- lpsz = &lpsz[iPos];
- VERIFY(_stscanf(lpsz, _T("(%d,%d,%d)"), lpiImage, lpiCheck, lpiColor));
- lpsz = _tcspbrk(lpsz, _T(")"))+1;
- if(lpsz && lpszText)
- {
- for(INT iTextSize=0;iTextSize<iTextMax-1 && *lpsz!=g_szSeparator[0];iTextSize++)
- lpszText[iTextSize] = *lpsz++;
- lpszText[iTextSize] = 0;
- }
- return TRUE;
- }
- BOOL CReportData::SetSubItem(INT iSubItem, INT iImage, INT iCheck, INT iColor, LPCTSTR lpszText)
- {
- if(!InsertSubItem(iSubItem, iImage, iCheck, iColor, lpszText))
- return FALSE;
- if(!DeleteSubItem(iSubItem+1))
- return FALSE;
- return TRUE;
- }
- BOOL CReportData::InsertSubItem(INT iSubItem, INT iImage, INT iCheck, INT iColor, LPCTSTR lpszText)
- {
- INT i, iPos;
- for(i=0,iPos=0;i<iSubItem&&iPos>=0;i++,iPos++)
- iPos = Find(g_szSeparator, iPos);
- if(iPos<0)
- return FALSE;
- lpszText = lpszText ? lpszText:_T("");
- CString str;
- str.Format("(%d,%d,%d)%s%s", iImage, iCheck, iColor, lpszText, g_szSeparator);
- Insert(iPos, str);
- return TRUE;
- }
- BOOL CReportData::DeleteSubItem(INT iSubItem)
- {
- INT i, iPos1, iPos2;
- for(i=0,iPos1=0;i<iSubItem&&iPos1>=0;i++,iPos1++)
- iPos1 = Find(g_szSeparator, iPos1);
- if(iPos1<0)
- return FALSE;
- iPos2 = Find(g_szSeparator, iPos1);
- if(iPos2++<0)
- return FALSE;
- Delete(iPos1, iPos2-iPos1);
- return TRUE;
- }
- /////////////////////////////////////////////////////////////////////////////
- // CReportView
- IMPLEMENT_DYNCREATE(CReportView, CView)
- CReportView::CReportView()
- {
- m_bCreated = FALSE;
- }
- CReportView::~CReportView()
- {
- }
- void CReportView::OnInitialUpdate()
- {
- CView::OnInitialUpdate();
- if(!m_bCreated)
- {
- CRect rect;
- GetClientRect(rect);
- if(m_wndReportCtrl.Create(WS_CHILD|WS_TABSTOP|WS_VISIBLE, rect, this, IDC_REPORTCTRL) == NULL)
- AfxThrowMemoryException();
- m_bCreated = TRUE;
- }
- }
- BEGIN_MESSAGE_MAP(CReportView, CView)
- //{{AFX_MSG_MAP(CReportView)
- ON_WM_SIZE()
- ON_WM_SETFOCUS()
- ON_WM_ERASEBKGND()
- //}}AFX_MSG_MAP
- END_MESSAGE_MAP()
- /////////////////////////////////////////////////////////////////////////////
- // CReportView drawing
- void CReportView::OnDraw(CDC* pDC)
- {
- ;
- }
- /////////////////////////////////////////////////////////////////////////////
- // CReportView diagnostics
- #ifdef _DEBUG
- void CReportView::AssertValid() const
- {
- CView::AssertValid();
- }
- void CReportView::Dump(CDumpContext& dc) const
- {
- CView::Dump(dc);
- }
- #endif //_DEBUG
- /////////////////////////////////////////////////////////////////////////////
- // CReportView implementation
- CReportCtrl& CReportView::GetReportCtrl()
- {
- return m_wndReportCtrl;
- }
- BOOL CReportView::OnEraseBkgnd(CDC* pDC)
- {
- return TRUE;
- }
- void CReportView::OnSize(UINT nType, int cx, int cy)
- {
- CView::OnSize(nType, cx, cy);
- if(m_wndReportCtrl.GetSafeHwnd())
- {
- CRect rect;
- GetClientRect(rect);
- m_wndReportCtrl.MoveWindow(rect);
- }
- }
- void CReportView::OnSetFocus(CWnd* pOldWnd)
- {
- m_wndReportCtrl.SetFocus();
- }
- /////////////////////////////////////////////////////////////////////////////
- // CReportCtrl
- IMPLEMENT_DYNCREATE(CReportCtrl, CWnd)
- CReportCtrl::CReportCtrl()
- {
- // Register the window class if it has not already been registered.
- WNDCLASS wndclass;
- HINSTANCE hInst = AfxGetInstanceHandle();
- if(!(::GetClassInfo(hInst, REPORTCTRL_CLASSNAME, &wndclass)))
- {
- // Otherwise we need to register a new class
- wndclass.style = CS_DBLCLKS|CS_HREDRAW|CS_VREDRAW;
- wndclass.lpfnWndProc = ::DefWindowProc;
- wndclass.cbClsExtra = wndclass.cbWndExtra = 0;
- wndclass.hInstance = hInst;
- wndclass.hIcon = NULL;
- wndclass.hCursor = LoadCursor(hInst, IDC_ARROW);
- wndclass.hbrBackground = (HBRUSH)COLOR_WINDOW;
- wndclass.lpszMenuName = NULL;
- wndclass.lpszClassName = REPORTCTRL_CLASSNAME;
- if (!AfxRegisterClass(&wndclass))
- AfxThrowResourceException();
- }
- m_bSubclassFromCreate = FALSE;
- m_bDoubleBuffer = TRUE;
- m_iSpacing = 6;
- // Initially use the system message font for the ReportCtrl font
- NONCLIENTMETRICS ncm;
- ncm.cbSize = sizeof(NONCLIENTMETRICS);
- VERIFY(SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, 0));
- m_font.CreateFontIndirect(&(ncm.lfMessageFont));
- m_pImageList = NULL;
- m_sizeImage.cx = 0;
- m_sizeImage.cy = 0;
- m_sizeCheck.cx = 8;
- m_sizeCheck.cy = 8;
- GetSysColors();
- m_arrayColors.SetSize(0, 8);
- m_iGridStyle = PS_SOLID;
- m_strNoItems = _T("There are no items to show in this view.");
- m_iDefaultWidth = 200;
- m_iDefaultHeight = 10;
- m_iVirtualWidth = 0;
- m_iVirtualHeight = 0;
- m_arraySubItems.SetSize(0, 8);
- m_arrayItems.SetSize(0, 128);
- m_bColumnsReordered = FALSE;
- m_arrayColumns.SetSize(0, 8);
- m_bFocus = FALSE;
- m_iFocusRow = -1;
- m_iSelectRow = 0;
- m_arrayRows.SetSize(0, 128);
- m_lprclc = NULL;
- m_lpfnrvc = NULL;
- }
- CReportCtrl::~CReportCtrl()
- {
- if(m_palette.m_hObject)
- m_palette.DeleteObject();
- if(m_font.m_hObject)
- m_font.DeleteObject();
- if(m_fontBold.m_hObject)
- m_fontBold.DeleteObject();
- }
- BOOL CReportCtrl::Create()
- {
- CRect rect(0, 0, 0, 0);
- DWORD dwStyle = HDS_HORZ|HDS_BUTTONS|HDS_FULLDRAG|HDS_DRAGDROP|CCS_TOP;
- if(!m_wndHeader.Create(dwStyle, rect, this, IDC_HEADERCTRL))
- return FALSE;
- CWnd* pWnd = GetParent();
- if(pWnd)
- {
- CFont* pFont = pWnd->GetFont();
- if(pFont)
- {
- LOGFONT lf;
- pFont->GetLogFont(&lf);
- m_font.DeleteObject();
- m_font.CreateFontIndirect(&lf);
- }
- }
- OnSetFont((WPARAM)((HFONT)m_font), FALSE);
- m_wndHeader.SetFont(&m_font, FALSE);
- GetClientRect(rect);
- Layout(rect.Width(), rect.Height());
- return TRUE;
- }
- BOOL CReportCtrl::Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext)
- {
- m_bSubclassFromCreate = TRUE;
- if(!CWnd::Create(REPORTCTRL_CLASSNAME, NULL, dwStyle, rect, pParentWnd, nID, pContext))
- return FALSE;
- return Create();
- }
- void CReportCtrl::PreSubclassWindow()
- {
- CWnd::PreSubclassWindow();
- if(!m_bSubclassFromCreate)
- if(!Create())
- AfxThrowMemoryException();
- }
- BEGIN_MESSAGE_MAP(CReportCtrl, CWnd)
- //{{AFX_MSG_MAP(CReportCtrl)
- ON_WM_SIZE()
- ON_WM_ERASEBKGND()
- ON_WM_PAINT()
- ON_WM_SYSCOLORCHANGE()
- ON_NOTIFY(HDN_ITEMCHANGED, IDC_HEADERCTRL, OnHdnItemChanged)
- ON_NOTIFY(HDN_ITEMCLICK, IDC_HEADERCTRL, OnHdnItemClick)
- ON_NOTIFY(HDN_ENDDRAG, IDC_HEADERCTRL, OnHdnEndDrag)
- ON_WM_HSCROLL()
- ON_WM_VSCROLL()
- ON_WM_LBUTTONDOWN()
- ON_WM_SETCURSOR()
- ON_WM_KEYDOWN()
- ON_WM_GETDLGCODE()
- ON_WM_LBUTTONDBLCLK()
- ON_WM_QUERYNEWPALETTE()
- ON_WM_PALETTECHANGED()
- ON_WM_SETFOCUS()
- ON_WM_KILLFOCUS()
- //}}AFX_MSG_MAP
- ON_MESSAGE(WM_SETFONT, OnSetFont)
- ON_MESSAGE(WM_GETFONT, OnGetFont)
- END_MESSAGE_MAP()
- /////////////////////////////////////////////////////////////////////////////
- // CReportCtrl attributes
- BOOL CReportCtrl::ModifyProperty(WPARAM wParam, LPARAM lParam)
- {
- switch(wParam)
- {
- case RVP_SPACING:
- m_iSpacing = (INT)lParam;
- break;
- case RVP_CHECK:
- m_sizeCheck.cx = LOWORD(lParam);
- m_sizeCheck.cy = HIWORD(lParam);
- break;
- case RVP_NOITEMTEXT:
- m_strNoItems = (LPCTSTR)lParam;
- break;
- case RVP_GRIDSTYLE:
- switch(wParam)
- {
- case RVP_GRIDSTYLE_DOT: m_iGridStyle = PS_DOT; break;
- case RVP_GRIDSTYLE_DASH: m_iGridStyle = PS_DASH; break;
- case RVP_GRIDSTYLE_SOLID: m_iGridStyle = PS_SOLID; break;
- default:
- return FALSE;
- }
- break;
- default:
- return FALSE;
- }
- CRect rect;
- GetClientRect(rect);
- Layout(rect.Width(), rect.Height());
- return TRUE;
- }
- INT CReportCtrl::ActivateColumn(INT iColumn, INT iOrder)
- {
- ASSERT(iColumn<m_arraySubItems.GetSize());
- SUBITEM& subitem = m_arraySubItems[iColumn];
- INT iResult = -1;
- INT iHeaderItems = m_arrayColumns.GetSize();
- HDITEM hdi;
- hdi.mask = HDI_LPARAM;
- for(INT iItem=0;iItem<iHeaderItems;iItem++)
- if(m_wndHeader.GetItem(iItem, &hdi))
- if(hdi.lParam == iColumn)
- break;
- if(iItem == iHeaderItems)
- {
- try
- {
- hdi.mask = HDI_FORMAT|HDI_WIDTH|HDI_LPARAM|HDI_ORDER;
- hdi.fmt = subitem.nFormat&RVCF_MASK;
- hdi.cxy = subitem.iWidth;
- hdi.iOrder = iOrder;
- hdi.lParam = (LPARAM)iColumn;
- if(subitem.nFormat&RVCF_IMAGE)
- {
- hdi.mask |= HDI_IMAGE;
- hdi.iImage = subitem.iImage;
- }
- if(subitem.nFormat&RVCF_TEXT)
- {
- hdi.mask |= HDI_TEXT;
- hdi.pszText = subitem.strText.GetBuffer(0);
- }
- iResult = m_wndHeader.InsertItem(iHeaderItems, &hdi);
- if(iResult >= 0)
- {
- m_iVirtualWidth += subitem.iWidth;
- HDITEMEX hditemex;
- hditemex.nStyle = (subitem.nFormat&RVCF_EX_MASK)>>16;
- hditemex.iMinWidth = subitem.iMinWidth;
- hditemex.iMaxWidth = subitem.iMaxWidth;
- m_wndHeader.SetItemEx(iResult, &hditemex);
- hdi.mask = HDI_WIDTH;
- m_wndHeader.GetItem(iResult, &hdi);
- subitem.iWidth = hdi.cxy;
- m_bColumnsReordered = TRUE;
- ScrollWindow(SB_HORZ, GetScrollPos32(SB_HORZ));
- }
- }
- catch(CMemoryException* e)
- {
- e->Delete();
- if(iResult >= 0)
- m_wndHeader.DeleteItem(iResult);
- }
- }
- return iResult;
- }
- BOOL CReportCtrl::DeactivateColumn(INT iColumn)
- {
- ASSERT(iColumn<m_arraySubItems.GetSize());
- HDITEM hdi;
- hdi.mask = HDI_WIDTH|HDI_LPARAM;
- INT iHeaderItems = m_arrayColumns.GetSize();
- for(INT iItem=0;iItem<iHeaderItems;iItem++)
- if(m_wndHeader.GetItem(iItem, &hdi))
- if(hdi.lParam == iColumn)
- break;
- if(iItem == iHeaderItems)
- return FALSE;
- ASSERT(iHeaderItems > 1); // At least one column must be active
- BOOL bResult = m_wndHeader.DeleteItem(iItem);
- m_iVirtualWidth -= hdi.cxy;
- m_bColumnsReordered = TRUE;
- ScrollWindow(SB_HORZ, GetScrollPos32(SB_HORZ));
- return bResult;
- }
- BOOL CReportCtrl::IsActiveColumn(INT iColumn)
- {
- INT iHeaderItems = m_arrayColumns.GetSize();
- HDITEM hdi;
- hdi.mask = HDI_LPARAM;
- for(INT iItem=0;iItem<iHeaderItems;iItem++)
- if(m_wndHeader.GetItem(iItem, &hdi))
- if(hdi.lParam == iColumn)
- break;
- if(iItem == iHeaderItems)
- return FALSE;
- return TRUE;
- }
- BOOL CReportCtrl::GetItem(LPRVITEM lprvi)
- {
- ASSERT(lprvi->iItem < m_arrayItems.GetSize()); // Specify item
- ASSERT(lprvi->iSubItem < m_arraySubItems.GetSize()); // Specify subitem
- UINT nMask = lprvi->nMask;
- ITEM item = m_arrayItems[lprvi->iItem];
- lprvi->nMask = 0;
- lprvi->nPreview = item.nPreview;
- if(lprvi->nPreview > 0)
- lprvi->nMask |= RVIM_PREVIEW;
- lprvi->iBkColor = item.iBkColor;
- if(lprvi->iBkColor >= 0)
- lprvi->nMask |= RVIM_BKCOLOR;
- lprvi->lpszText = nMask&RVIM_TEXT ? lprvi->lpszText:NULL;
- item.rdData.GetSubItem(lprvi->iSubItem, &lprvi->iImage, &lprvi->iCheck, &lprvi->iTextColor, lprvi->lpszText, lprvi->iTextMax);
- if(lprvi->lpszText && _tcslen(lprvi->lpszText))
- lprvi->nMask |= RVIM_TEXT;
- if(lprvi->iImage >= 0)
- lprvi->nMask |= RVIM_IMAGE;
- if(lprvi->iCheck >= 0)
- lprvi->nMask |= RVIM_CHECK;
- if(lprvi->iTextColor >= 0)
- lprvi->nMask |= RVIM_TEXTCOLOR;
- lprvi->nMask |= RVIM_STATE|RVIM_LPARAM;
- lprvi->nState = item.nState;
- lprvi->lParam = item.lParam;
- return TRUE;
- }
- BOOL CReportCtrl::SetItem(LPRVITEM lprvi)
- {
- TCHAR szText[REPORTCTRL_MAX_TEXT];
- RVITEM rvi;
- rvi.iItem = lprvi->iItem;
- rvi.iSubItem = lprvi->iSubItem;
- rvi.lpszText = szText;
- rvi.iTextMax = REPORTCTRL_MAX_TEXT;
- rvi.nMask = RVIM_TEXT;
- VERIFY(GetItem(&rvi));
- if(lprvi->nMask&RVIM_TEXT)
- {
- _tcsncpy(rvi.lpszText, lprvi->lpszText, REPORTCTRL_MAX_TEXT-1);
- rvi.lpszText[REPORTCTRL_MAX_TEXT-1] = 0;
- }
- if(lprvi->nMask&RVIM_TEXTCOLOR)
- rvi.iTextColor = lprvi->iTextColor;
- if(lprvi->nMask&RVIM_IMAGE)
- rvi.iImage = lprvi->iImage;
- if(lprvi->nMask&RVIM_CHECK)
- rvi.iCheck = lprvi->iCheck;
- if(lprvi->nMask&RVIM_BKCOLOR)
- rvi.iBkColor = lprvi->iBkColor;
- if(lprvi->nMask&RVIM_PREVIEW)
- rvi.nPreview = lprvi->nPreview;
- if(lprvi->nMask&RVIM_STATE)
- rvi.nState = lprvi->nState;
- if(lprvi->nMask&RVIM_LPARAM)
- rvi.lParam = lprvi->lParam;
- ITEM item = m_arrayItems[rvi.iItem];
- VERIFY(item.rdData.InsertSubItem(rvi.iSubItem, rvi.iImage, rvi.iCheck, rvi.iTextColor, rvi.lpszText));
- VERIFY(item.rdData.DeleteSubItem(rvi.iSubItem+1));
- item.iBkColor = rvi.iBkColor;
- item.nPreview = rvi.nPreview;
- item.nState = rvi.nState;
- item.lParam = rvi.lParam;
- m_arrayItems.SetAt(rvi.iItem, item);
- ScrollWindow(SB_VERT, GetScrollPos32(SB_VERT));
- RedrawItems(rvi.iItem);
- return TRUE;
- }
- INT CReportCtrl::GetItemText(INT iItem, INT iSubItem, LPTSTR lpszText, INT iLen)
- {
- RVITEM rvi;
- rvi.nMask = RVIM_TEXT;
- rvi.iItem = iItem;
- rvi.iSubItem = iSubItem;
- rvi.lpszText = lpszText;
- rvi.iTextMax = iLen;
- return GetItem(&rvi) ? _tcslen(rvi.lpszText):0;
- }
- CString CReportCtrl::GetItemText(INT iItem, INT iSubItem)
- {
- CString str;
- TCHAR szText[REPORTCTRL_MAX_TEXT];
- if(GetItemText(iItem, iSubItem, szText, REPORTCTRL_MAX_TEXT))
- str = szText;
- return str;
- }
- BOOL CReportCtrl::SetItemText(INT iItem, INT iSubItem, LPTSTR lpszText)
- {
- RVITEM rvi;
- rvi.nMask = RVIM_TEXT;
- rvi.iItem = iItem;
- rvi.iSubItem = iSubItem;
- rvi.lpszText = lpszText;
- return SetItem(&rvi);
- }
- INT CReportCtrl::GetItemImage(INT iItem, INT iSubItem)
- {
- RVITEM rvi;
- rvi.nMask = RVIM_IMAGE;
- rvi.iItem = iItem;
- rvi.iSubItem = iSubItem;
- return GetItem(&rvi) ? rvi.iImage:-1;
- }
- BOOL CReportCtrl::SetItemImage(INT iItem, INT iSubItem, INT iImage)
- {
- RVITEM rvi;
- rvi.nMask = RVIM_IMAGE;
- rvi.iItem = iItem;
- rvi.iSubItem = iSubItem;
- rvi.iImage = iImage;
- return SetItem(&rvi);
- }
- INT CReportCtrl::GetItemCheck(INT iItem, INT iSubItem)
- {
- RVITEM rvi;
- rvi.nMask = RVIM_CHECK;
- rvi.iItem = iItem;
- rvi.iSubItem = iSubItem;
- return GetItem(&rvi) ? rvi.iCheck:-1;
- }
- BOOL CReportCtrl::SetItemCheck(INT iItem, INT iSubItem, INT iCheck)
- {
- RVITEM rvi;
- rvi.nMask = RVIM_CHECK;
- rvi.iItem = iItem;
- rvi.iSubItem = iSubItem;
- rvi.iCheck = iCheck;
- return SetItem(&rvi);
- }
- DWORD CReportCtrl::GetItemData(INT iItem)
- {
- RVITEM rvi;
- rvi.nMask = RVIM_LPARAM;
- rvi.iItem = iItem;
- return GetItem(&rvi) ? rvi.lParam:0;
- }
- BOOL CReportCtrl::SetItemData(INT iItem, DWORD dwData)
- {
- RVITEM rvi;
- rvi.nMask = RVIM_LPARAM;
- rvi.iItem = iItem;
- rvi.lParam = dwData;
- return SetItem(&rvi);
- }
- INT CReportCtrl::GetVisibleCount(BOOL bUnobstructed)
- {
- return GetVisibleRows(bUnobstructed);
- }
- INT CReportCtrl::GetItemCount()
- {
- return m_arrayItems.GetSize();
- }
- INT CReportCtrl::GetFirstSelectedItem()
- {
- return GetNextSelectedItem(-1);
- }
- INT CReportCtrl::GetNextSelectedItem(INT iItem)
- {
- RVITEM rvi;
- rvi.nMask = RVIM_STATE;
- INT iItems = m_arrayItems.GetSize();
- for(iItem++;rvi.iItem<iItems;rvi.iItem++)
- if(GetItem(&rvi) && rvi.nState&RVIS_SELECTED)
- return rvi.iItem;
- return -1;
- }
- BOOL CReportCtrl::SetImageList(CImageList* pImageList)
- {
- m_pImageList = pImageList;
- m_wndHeader.SetImageList(pImageList);
- IMAGEINFO info;
- if(pImageList->GetImageInfo(0, &info))
- {
- m_sizeImage.cx = info.rcImage.right - info.rcImage.left;
- m_sizeImage.cy = info.rcImage.bottom - info.rcImage.top;
- m_iDefaultHeight = m_sizeImage.cy>m_iDefaultHeight ? m_sizeImage.cy:m_iDefaultHeight;
- Invalidate();
- return TRUE;
- }
- else
- return FALSE;
- }
- CImageList* CReportCtrl::GetImageList(void)
- {
- return m_pImageList;
- }
- CFlatHeaderCtrl* CReportCtrl::GetHeaderCtrl()
- {
- return &m_wndHeader;
- }
- BOOL CReportCtrl::SetReportColumnListCtrl(CReportColumnListCtrl* lprclc)
- {
- if(m_lprclc != NULL)
- {
- m_wndHeader.ModifyProperty(FH_PROPERTY_DROPTARGET, NULL);
- m_lprclc->SetReportCtrl(NULL);
- }
- m_lprclc = lprclc;
- if(m_lprclc != NULL)
- {
- m_wndHeader.ModifyProperty(FH_PROPERTY_DROPTARGET, (LPARAM)m_lprclc->m_hWnd);
- m_lprclc->SetReportCtrl(this);
- }
- return TRUE;
- }
- CReportColumnListCtrl* CReportCtrl::GetReportColumnListCtrl()
- {
- return m_lprclc;
- }
- BOOL CReportCtrl::SetSortCallback(LPFNRVCOMPARE lpfnrvc)
- {
- m_lpfnrvc = lpfnrvc;
- return TRUE;
- }
- LPFNRVCOMPARE CReportCtrl::GetSortCallback()
- {
- return m_lpfnrvc;
- }
- BOOL CReportCtrl::WriteProfile(LPCTSTR lpszSection, LPCTSTR lpszEntry)
- {
- CString str, strProfile;
- INT i;
- INT iSubItems = m_arraySubItems.GetSize();
- INT iColumns = m_arrayColumns.GetSize();
- strProfile.Format(_T("(%d,%d)"), iSubItems, iColumns);
- for(i=0;i<iSubItems;i++)
- {
- str.Format(" %d", m_arraySubItems[i].iWidth);
- strProfile += str;
- }
- for(i=0;i<iColumns;i++)
- {
- HDITEM hdi;
- hdi.mask = HDI_LPARAM;
- m_wndHeader.GetItem(m_arrayColumns[i], &hdi);
- str.Format(" %d", hdi.lParam);
- strProfile += str;
- }
- CWinApp* pApp = AfxGetApp();
- return pApp->WriteProfileString(lpszSection, lpszEntry, strProfile);
- }
- BOOL CReportCtrl::GetProfile(LPCTSTR lpszSection, LPCTSTR lpszEntry)
- {
- CString str, strProfile;
- CWinApp* pApp = AfxGetApp();
- strProfile = pApp->GetProfileString(lpszSection, lpszEntry);
- if(strProfile.IsEmpty())
- return FALSE;
- LPTSTR lpsz = strProfile.GetBuffer(0);
- INT i;
- INT iSubItems;
- INT iColumns;
- iSubItems = _tcstol(++lpsz, &lpsz, 10);
- iColumns = _tcstol(++lpsz, &lpsz, 10);
- if(iSubItems != m_arraySubItems.GetSize())
- return FALSE;
- for(i=0;i<iSubItems;i++)
- m_arraySubItems[i].iWidth = _tcstol(++lpsz, &lpsz, 10);
- for(i=0;i<iColumns;i++)
- ActivateColumn(_tcstol(++lpsz, &lpsz, 10), i);
- return TRUE;
- }
- /////////////////////////////////////////////////////////////////////////////
- // CReportCtrl operations
- BOOL CReportCtrl::ModifyStyle(DWORD dwRemove, DWORD dwAdd, UINT nFlags)
- {
- DWORD dwStyle = GetStyle();
- if(CWnd::ModifyStyle(dwRemove, dwAdd, nFlags))
- {
- if(!(dwStyle&RVS_SHOWHGRID) && dwAdd&RVS_SHOWHGRID)
- m_iDefaultHeight++;
- if(dwStyle&RVS_SHOWHGRID && dwRemove&RVS_SHOWHGRID)
- m_iDefaultHeight--;
- CRect rect;
- GetClientRect(rect);
- Layout(rect.Width(), rect.Height());
- return TRUE;
- }
- return FALSE;
- }
- INT CReportCtrl::DefineColumn(INT iColumn, LPRVCOLUMN lprvc, BOOL bUpdateList)
- {
- INT i;
- INT iColumns = m_arraySubItems.GetSize();
- ASSERT(iColumn <= iColumns);
- ASSERT(lprvc->lpszText != NULL); // Must supply (descriptive) text for subitem selector
- ASSERT(_tcslen(lprvc->lpszText) < FLATHEADER_TEXT_MAX);
- try
- {
- SUBITEM subitem;
- subitem.nFormat = lprvc->nFormat;
- subitem.iWidth = lprvc->iWidth<0 ? m_iDefaultWidth:lprvc->iWidth;
- subitem.iMinWidth = lprvc->iMinWidth;
- subitem.iMaxWidth = lprvc->iMaxWidth;
- subitem.iImage = lprvc->nFormat&RVCF_IMAGE ? lprvc->iImage:0;
- subitem.strText = lprvc->lpszText;
- m_arraySubItems.InsertAt(iColumn, subitem);
- HDITEM hdi;
- hdi.mask = HDI_LPARAM;
- INT iHeaderItems = m_arrayColumns.GetSize();
- for(i=0;i<iHeaderItems;i++)
- if(m_wndHeader.GetItem(i, &hdi))
- if(hdi.lParam >= iColumn)
- {
- hdi.lParam++;
- m_wndHeader.SetItem(i, &hdi);
- }
- INT iItems = m_arrayItems.GetSize();
- for(i=0;i<iItems;i++)
- VERIFY(m_arrayItems[i].rdData.InsertSubItem(iColumn, -1, -1, -1, NULL));
- if(bUpdateList && m_lprclc != NULL)
- m_lprclc->UpdateList();
- return iColumn;
- }
- catch(CMemoryException* e)
- {
- e->Delete();
- return -1;
- }
- }
- BOOL CReportCtrl::UndefineColumn(INT iColumn)
- {
- ASSERT(iColumn<m_arraySubItems.GetSize());
- VERIFY(!DeactivateColumn(iColumn));
- m_arraySubItems.RemoveAt(iColumn);
- HDITEM hdi;
- hdi.mask = HDI_LPARAM;
- INT i;
- INT iHeaderItems = m_arrayColumns.GetSize();
- for(i=0;i<iHeaderItems;i++)
- if(m_wndHeader.GetItem(i, &hdi))
- if(hdi.lParam > iColumn)
- {
- hdi.lParam--;
- m_wndHeader.SetItem(i, &hdi);
- }
- INT iItems = m_arrayItems.GetSize();
- for(i=0;i<iItems;i++)
- VERIFY(m_arrayItems[i].rdData.DeleteSubItem(iColumn));
- if(m_lprclc != NULL)
- m_lprclc->UpdateList();
- return TRUE;
- }
- INT CReportCtrl::InsertItem(INT iItem, LPTSTR lpszText, INT iImage, INT iCheck, INT iTextColor)
- {
- RVITEM rvi;
- rvi.nMask = RVIM_TEXT;
- rvi.iItem = iItem;
- rvi.iSubItem = 0;
- rvi.lpszText = lpszText;
- rvi.iTextColor = iTextColor;
- rvi.iImage = iImage;
- rvi.iCheck = iCheck;
- if(iTextColor >= 0)
- rvi.nMask |= RVIM_TEXTCOLOR;
- if(iImage >= 0)
- rvi.nMask |= RVIM_IMAGE;
- if(iCheck >= 0)
- rvi.nMask |= RVIM_CHECK;
- return InsertItem(&rvi);
- }
- INT CReportCtrl::InsertItem(LPRVITEM lprvi)
- {
- ASSERT(lprvi->iItem <= m_arrayItems.GetSize());
- ASSERT(lprvi->iSubItem < m_arraySubItems.GetSize());
- BOOL bInserted = FALSE;
- try
- {
- ITEM item;
- item.rdData.New(m_arraySubItems.GetSize());
- m_arrayItems.InsertAt(lprvi->iItem, item); bInserted = TRUE;
- m_arrayRows.InsertAt(lprvi->iItem, INT_MIN);
- INT iItems = m_arrayRows.GetSize();
- for(INT i=0;i<iItems;i++)
- if(m_arrayRows[i]>=lprvi->iItem)
- m_arrayRows[i]++;
- m_arrayRows[lprvi->iItem] = lprvi->iItem;
- m_iVirtualHeight++;
- VERIFY(SetItem(lprvi));
- ScrollWindow(SB_VERT, GetScrollPos32(SB_VERT));
- return lprvi->iItem;
- }
- catch(CMemoryException* e)
- {
- if(bInserted)
- m_arrayItems.RemoveAt(lprvi->iItem);
- e->Delete();
- return -1;
- }
- }
- BOOL CReportCtrl::DeleteItem(INT iItem)
- {
- m_arrayItems.RemoveAt(iItem);
- INT iItems = m_arrayRows.GetSize();
- for(INT i=0;i<iItems;i++)
- if(m_arrayRows[i]>iItem)
- m_arrayRows[i]--;
- m_iVirtualHeight--;
- iItems = m_arrayItems.GetSize();
- INT iFirst = GetScrollPos32(SB_VERT), iLast;
- GetVisibleRows(TRUE, &iFirst, &iLast);
- if(iItem<=iFirst || iLast>=iItems-1)
- GetVisibleRows(TRUE, &iFirst, &iLast, TRUE);
- ScrollWindow(SB_VERT, iFirst);
- return TRUE;
- }
- BOOL CReportCtrl::DeleteAllItems()
- {
- m_arrayItems.RemoveAll();
- m_iVirtualHeight = 0;
- ScrollWindow(SB_VERT, 0);
- return TRUE;
- }
- void CReportCtrl::RedrawItems(INT iFirst, INT iLast)
- {
- // TODO: Optimize to redraw indivual rows
- // taking into account that the row height
- // may have changed. Redrawing everything
- // will work as well :)
- Invalidate();
- }
- BOOL CReportCtrl::EnsureVisible(INT iItem, BOOL bUnobstructed)
- {
- INT iFirst = GetScrollPos32(SB_VERT), iLast;
- INT iRow = FindItem(iItem);
- if(iRow < 0)
- return FALSE;
- GetVisibleRows(bUnobstructed, &iFirst, &iLast);
- if(iRow<iFirst)
- ScrollWindow(SB_VERT, iRow);
- if(iRow>iLast)
- {
- iLast = iRow;
- GetVisibleRows(bUnobstructed, &iFirst, &iLast, TRUE);
- ScrollWindow(SB_VERT, iFirst);
- }
- return TRUE;
- }
- INT CReportCtrl::InsertColor(INT iIndex, COLORREF crColor)
- {
- if(m_arrayColors.GetSize() == REPORTCTRL_MAX_COLORS)
- return -1;
- try
- {
- m_arrayColors.InsertAt(iIndex, crColor);
- if(CreatePalette())
- return iIndex;
- return -1;
- }
- catch(CMemoryException* e)
- {
- e->Delete();
- return -1;
- }
- }
- BOOL CReportCtrl::DeleteColor(INT iIndex)
- {
- if(iIndex >= m_arrayColors.GetSize())
- return FALSE;
- m_arrayColors.RemoveAt(iIndex);
- CreatePalette();
- return TRUE;
- }
- INT CReportCtrl::HitTest(LPRVHITTESTINFO lprvhti)
- {
- ASSERT(lprvhti);
- lprvhti->nFlags = 0;
- lprvhti->iItem = -1;
- lprvhti->iSubItem = -1;
- if(m_rectReport.PtInRect(lprvhti->point))
- {
- INT iHPos = GetScrollPos32(SB_HORZ);
- INT iFirst = GetScrollPos32(SB_VERT), iLast;
- if(GetVisibleRows(FALSE, &iFirst, &iLast))
- {
- ITEM item;
- CRect rectItem(
- m_rectReport.left-iHPos, m_rectReport.top,
- m_rectReport.left-iHPos+m_iVirtualWidth, m_rectReport.top
- );
- for(;iFirst<=iLast;iFirst++)
- {
- item = m_arrayItems[m_arrayRows[iFirst]];
- rectItem.bottom += m_iDefaultHeight+item.nPreview;
- if(rectItem.PtInRect(lprvhti->point))
- break;
- rectItem.top = rectItem.bottom;
- }
- if(iFirst<=iLast)
- {
- if(item.nPreview)
- {
- CRect rectPreview(rectItem);
- rectPreview.top += m_iDefaultHeight;
- if(rectPreview.PtInRect(lprvhti->point))
- {
- lprvhti->iItem = m_arrayRows[iFirst];
- lprvhti->nFlags |= RVHT_ONITEMPREVIEW;
- return lprvhti->iItem;
- }
- }
- INT iHeaderItems = m_arrayColumns.GetSize();
- HDITEM hdi;
- hdi.mask = HDI_WIDTH|HDI_LPARAM;
- rectItem.right = rectItem.left;
- for(INT iHeaderItem=0;iHeaderItem<iHeaderItems;iHeaderItem++)
- {
- m_wndHeader.GetItem(m_arrayColumns[iHeaderItem], &hdi);
- rectItem.right += hdi.cxy;
- if(rectItem.PtInRect(lprvhti->point))
- break;
- rectItem.left = rectItem.right;
- }
- lprvhti->iSubItem = hdi.lParam;
- if(iHeaderItem<iHeaderItems)
- {
- RVITEM rvi;
- rvi.iItem = iFirst;
- rvi.iSubItem = lprvhti->iSubItem;
- GetItem(&rvi);
- lprvhti->iItem = m_arrayRows[iFirst];
- rectItem.right = rectItem.left+m_iSpacing;
- if(rvi.nMask&RVIM_IMAGE)
- {
- rectItem.right += m_sizeImage.cx+m_iSpacing;
- if(lprvhti->point.x < rectItem.right)
- {
- lprvhti->nFlags |= RVHT_ONITEMIMAGE;
- return lprvhti->iItem;
- }
- }
- if(rvi.nMask&RVIM_CHECK)
- {
- rectItem.right += m_sizeCheck.cx+m_iSpacing;
- if(lprvhti->point.x < rectItem.right)
- {
- lprvhti->nFlags |= RVHT_ONITEMCHECK;
- return lprvhti->iItem;
- }
- }
- lprvhti->nFlags |= RVHT_ONITEMTEXT;
- }
- else
- lprvhti->nFlags = RVHT_NOWHERE;
- }
- else
- lprvhti->nFlags = RVHT_NOWHERE;
- }
- else
- lprvhti->nFlags = RVHT_NOWHERE;
- }
- else
- {
- lprvhti->nFlags |= lprvhti->point.y<m_rectReport.top ? RVHT_ABOVE:0;
- lprvhti->nFlags |= lprvhti->point.y>m_rectReport.bottom ? RVHT_BELOW:0;
- lprvhti->nFlags |= lprvhti->point.x<m_rectReport.left ? RVHT_TOLEFT:0;
- lprvhti->nFlags |= lprvhti->point.x>m_rectReport.right ? RVHT_TORIGHT:0;
- }
- return lprvhti->iItem;
- }
- BOOL CReportCtrl::SortItems(INT iColumn, BOOL bAscending)
- {
- INT iHeaderColumn = FindColumnInHeader(iColumn);
- if(iHeaderColumn < 0)
- return FALSE; // Can't sort on columns that are not active
- INT iFocusItem = m_iFocusRow>=0 ? m_arrayRows[m_iFocusRow]:-1;
- INT iRows = m_arrayRows.GetSize();
- if(iRows>1)
- {
- for(INT i=0;i<iRows-1;i++)
- {
- for(INT j=i+1;j<iRows;j++)
- {
- INT iSort = CompareItems(iColumn, m_arrayRows[i], m_arrayRows[j]);
- if((bAscending && iSort>0) ||
- (!bAscending && iSort<0))
- {
- INT iItem = m_arrayRows[i];
- m_arrayRows[i] = m_arrayRows[j];
- m_arrayRows[j] = iItem;
- }
- }
- }
- }
- m_wndHeader.SetSortColumn(m_arrayColumns[iHeaderColumn], bAscending);
- if(iFocusItem>=0)
- {
- m_iFocusRow = FindItem(iFocusItem);
- INT iFirst = m_iFocusRow, iLast;
- GetVisibleRows(TRUE, &iFirst, &iLast);
- GetVisibleRows(TRUE, &iFirst, &iLast, TRUE);
- ScrollWindow(SB_VERT, iFirst);
- }
- Invalidate();
- return TRUE;
- }
- INT CReportCtrl::CompareItems(INT iColumn, INT iItem1, INT iItem2)
- {
- if(m_lpfnrvc == NULL)
- {
- RVITEM rvi1, rvi2;
- TCHAR szText1[REPORTCTRL_MAX_TEXT], szText2[REPORTCTRL_MAX_TEXT];
- rvi1.nMask = RVIM_TEXT;
- rvi1.iItem = iItem1;
- rvi1.iSubItem = iColumn;
- rvi1.lpszText = szText1;
- rvi1.iTextMax = REPORTCTRL_MAX_TEXT;
- VERIFY(GetItem(&rvi1));
- rvi2.nMask = RVIM_TEXT;
- rvi2.iItem = iItem2;
- rvi2.iSubItem = iColumn;
- rvi2.lpszText = szText2;
- rvi2.iTextMax = REPORTCTRL_MAX_TEXT;
- VERIFY(GetItem(&rvi2));
- return _tcscmp(szText1, szText2);
- }
- else
- return m_lpfnrvc(iColumn, iItem1, iItem2);
- }
- /////////////////////////////////////////////////////////////////////////////
- // CReportCtrl implementation
- void CReportCtrl::GetSysColors()
- {
- m_crBackground = GetSysColor(COLOR_WINDOW);
- m_crBkSelected = GetSysColor(COLOR_HIGHLIGHT);
- m_crBkSelectedNoFocus = GetSysColor(COLOR_BTNFACE);
- m_crText = GetSysColor(COLOR_WINDOWTEXT);
- m_crTextSelected = GetSysColor(COLOR_HIGHLIGHTTEXT);
- m_crTextSelectedNoFocus = GetSysColor(COLOR_WINDOWTEXT);
- m_crGrid = GetSysColor(COLOR_BTNFACE);
- }
- BOOL CReportCtrl::CreatePalette()
- {
- if(m_palette.m_hObject)
- m_palette.DeleteObject();
- INT iColors = m_arrayColors.GetSize();
- if(iColors)
- {
- struct
- {
- LOGPALETTE LogPalette;
- PALETTEENTRY PalEntry[REPORTCTRL_MAX_COLORS];
- } pal;
- LPLOGPALETTE lpLogPalette = (LOGPALETTE*) &pal;
- lpLogPalette->palVersion = 0x300;
- lpLogPalette->palNumEntries = (WORD)iColors;
- for(INT i=0;i<iColors;i++)
- {
- lpLogPalette->palPalEntry[i].peRed = GetRValue(m_arrayColors[i]);
- lpLogPalette->palPalEntry[i].peGreen = GetGValue(m_arrayColors[i]);
- lpLogPalette->palPalEntry[i].peBlue = GetBValue(m_arrayColors[i]);
- lpLogPalette->palPalEntry[i].peFlags = 0;
- }
- m_palette.CreatePalette(lpLogPalette);
- return TRUE;
- }
- return FALSE;
- }
- BOOL CReportCtrl::Notify(UINT nCode, INT iItem, INT iSubItem, LPARAM lParam)
- {
- NMREPORTVIEW nmrv;
- nmrv.hdr.hwndFrom = m_hWnd;
- nmrv.hdr.idFrom = GetDlgCtrlID();
- nmrv.hdr.code = nCode;
- nmrv.iItem = iItem;
- nmrv.iSubItem = iSubItem;
- nmrv.lParam = lParam;
- CWnd* pWnd = GetParent();
- if(pWnd)
- return pWnd->SendMessage(WM_NOTIFY, 0, (LPARAM)&nmrv);
- return FALSE;
- }
- BOOL CReportCtrl::Notify(UINT nCode, UINT nKeys, LPRVHITTESTINFO lprvhti)
- {
- NMREPORTVIEW nmrv;
- nmrv.hdr.hwndFrom = m_hWnd;
- nmrv.hdr.idFrom = GetDlgCtrlID();
- nmrv.hdr.code = nCode;
- nmrv.nKeys = nKeys;
- nmrv.point = lprvhti->point;
- nmrv.nFlags = lprvhti->nFlags;
- nmrv.iItem = lprvhti->iItem;
- nmrv.iSubItem = lprvhti->iSubItem;
- if(lprvhti->iItem >= 0)
- nmrv.lParam = m_arrayItems[lprvhti->iItem].lParam;
- CWnd* pWnd = GetParent();
- if(pWnd)
- return pWnd->SendMessage(WM_NOTIFY, 0, (LPARAM)&nmrv);
- return FALSE;
- }
- void CReportCtrl::Layout(INT cx, INT cy)
- {
- HDLAYOUT hdl;
- WINDOWPOS wpos;
- hdl.prc = &m_rectReport;
- hdl.pwpos = &wpos;
- m_rectReport.SetRect(0, 0, cx, cy);
- if(IsWindow(m_wndHeader.m_hWnd))
- {
- if(!(GetStyle()&RVS_NOHEADER))
- {
- VERIFY(m_wndHeader.SendMessage(HDM_LAYOUT, 0, (LPARAM)&hdl));
- m_rectHeader.SetRect(wpos.x, wpos.y, wpos.x+wpos.cx, wpos.y+wpos.cy);
- }
- else
- m_rectHeader.SetRect(0, 0, cx, 0);
- ScrollWindow(SB_HORZ, GetScrollPos32(SB_HORZ));
- ScrollWindow(SB_VERT, GetScrollPos32(SB_VERT));
- }
- }
- INT CReportCtrl::FindItem(INT iItem)
- {
- INT iRows = m_arrayRows.GetSize();
- for(INT iRow=0;iRow<iRows;iRow++)
- if(m_arrayRows[iRow] == iItem)
- return iRow;
- return -1;
- }
- INT CReportCtrl::FindColumnInHeader(INT iColumn)
- {
- INT iColumns = m_arrayColumns.GetSize();
- for(INT i=0;i<iColumns;i++)
- {
- HDITEM hdi;
- hdi.mask = HDI_WIDTH|HDI_LPARAM;
- m_wndHeader.GetItem(m_arrayColumns[i], &hdi);
- if(hdi.lParam == iColumn)
- return i;
- }
- return -1;
- }
- INT CReportCtrl::GetVisibleRows(BOOL bUnobstructed, LPINT lpiFirst, LPINT lpiLast, BOOL bReverse)
- {
- INT iHeight = m_rectReport.Height();
- INT iRows = 0;
- if(!bReverse)
- {
- INT iRow;
- INT iMaxRows = m_arrayRows.GetSize();
- if(lpiFirst)
- iRow = *lpiFirst;
- else
- iRow = GetScrollPos32(SB_VERT);
- for(;iRow<iMaxRows&&iHeight>0;iRow++,iRows++)
- {
- iHeight -= m_iDefaultHeight+m_arrayItems[m_arrayRows[iRow]].nPreview;
- if(bUnobstructed && iHeight<=0)
- break;
- }
- if(lpiLast)
- *lpiLast = iRow-1;
- }
- else
- {
- ASSERT(lpiFirst);
- ASSERT(lpiLast);
- for(*lpiFirst=*lpiLast;*lpiFirst>=0&&iHeight>0;*lpiFirst-=1,iRows++)
- {
- iHeight -= m_iDefaultHeight+m_arrayItems[m_arrayRows[*lpiFirst]].nPreview;
- if(bUnobstructed && iHeight<=0)
- break;
- }
- *lpiFirst += 1;
- }
- return iRows;
- }
- void CReportCtrl::SelectRows(INT iFirst, INT iLast, BOOL bSelect, BOOL bKeepSelection, BOOL bInvert)
- {
- INT i;
- if(GetStyle()&RVS_SINGLESELECT)
- {
- iLast = iFirst;
- bKeepSelection = FALSE;
- }
- if(m_iFocusRow>=0 && iFirst!=m_iFocusRow)
- {
- m_arrayItems[m_arrayRows[m_iFocusRow]].nState &= ~RVIS_FOCUSED;
- RedrawItems(m_iFocusRow);
- }
- m_iFocusRow = iFirst;
- m_arrayItems[m_arrayRows[iFirst]].nState |= RVIS_FOCUSED;
- if(iFirst > iLast)
- {
- iLast += iFirst;
- iFirst = iLast - iFirst;
- iLast -= iFirst;
- }
- if(bSelect)
- {
- for(i=iFirst;i<=iLast;i++)
- {
- INT iItem = m_arrayRows[i];
- UINT nOldState, nNewState;
- nOldState = nNewState = m_arrayItems[iItem].nState;
- if(bInvert)
- nNewState ^= RVIS_SELECTED;
- else
- nNewState |= RVIS_SELECTED;
- if(nNewState != nOldState)
- {
- if(Notify(RVN_SELECTIONCHANGING, iItem))
- continue;
- m_arrayItems[iItem].nState = nNewState;
- Notify(RVN_SELECTIONCHANGED, iItem);
- }
- }
- RedrawItems(iFirst, iLast);
- }
- else
- RedrawItems(iFirst);
- if(!bKeepSelection && bSelect)
- {
- INT iRows = m_arrayRows.GetSize();
- for(i=0;i<iRows;i++)
- {
- INT iItem = m_arrayRows[i];
- UINT nOldState, nNewState;
- nOldState = nNewState = m_arrayItems[iItem].nState;
- if((i<iFirst || i>iLast) && nOldState&RVIS_SELECTED)
- {
- nNewState &= ~RVIS_SELECTED;
- if(nNewState != nOldState)
- {
- if(Notify(RVN_SELECTIONCHANGING, iItem))
- continue;
- m_arrayItems[iItem].nState = nNewState;
- Notify(RVN_SELECTIONCHANGED, iItem);
- RedrawItems(i);
- }
- }
- }
- }
- }
- INT CReportCtrl::GetScrollPos32(INT iBar, BOOL bGetTrackPos)
- {
- SCROLLINFO si;
- si.cbSize = sizeof(SCROLLINFO);
- if(bGetTrackPos)
- {
- if(GetScrollInfo(iBar, &si, SIF_TRACKPOS))
- return si.nTrackPos;
- }
- else
- {
- if(GetScrollInfo(iBar, &si, SIF_POS))
- return si.nPos;
- }
- return 0;
- }
- BOOL CReportCtrl::SetScrollPos32(INT iBar, INT iPos, BOOL bRedraw)
- {
- SCROLLINFO si;
- si.cbSize = sizeof(SCROLLINFO);
- si.fMask = SIF_POS;
- si.nPos = iPos;
- return SetScrollInfo(iBar, &si, bRedraw);
- }
- void CReportCtrl::ScrollWindow(INT iBar, INT iPos)
- {
- if(m_rectReport.Width()<=0 || m_rectReport.Height()<=0)
- return;
- if(iBar == SB_HORZ)
- {
- SCROLLINFO si;
- INT iWidth = m_rectReport.Width();
- si.cbSize = sizeof(SCROLLINFO);
- si.fMask = SIF_PAGE|SIF_RANGE|SIF_POS;
- si.nPage = iWidth;
- si.nMin = 0;
- si.nMax = iWidth<m_iVirtualWidth ? m_iVirtualWidth-1:0;
- si.nPos = iPos;
- SetScrollInfo(SB_HORZ, &si, TRUE);
- INT x = GetScrollPos32(SB_HORZ);
- INT cx = iWidth<m_iVirtualWidth ? m_iVirtualWidth:iWidth;
- VERIFY(m_wndHeader.SetWindowPos(&wndTop, -x, m_rectHeader.top, cx, m_rectHeader.Height(), GetStyle()&RVS_NOHEADER ? SWP_HIDEWINDOW:SWP_SHOWWINDOW));
- }
- if(iBar == SB_VERT)
- {
- INT iItems = m_arrayItems.GetSize();
- ASSERT(iPos >= 0 && iPos<=iItems);
- INT iFirst = iPos, iLast;
- GetVisibleRows(TRUE, &iFirst, &iLast);
- SCROLLINFO si;
- si.cbSize = sizeof(SCROLLINFO);
- si.fMask = SIF_PAGE|SIF_RANGE|SIF_POS;
- si.nPage = (iLast - iFirst + 1);
- si.nMin = 0;
- si.nMax = (iLast - iFirst + 1)<iItems ? iItems-1:0;
- si.nPos = iFirst;
- SetScrollInfo(SB_VERT, &si, TRUE);
- }
- Invalidate();
- }
- void CReportCtrl::DrawCtrl(CDC* pDC)
- {
- CRect rectClip;
- if (pDC->GetClipBox(&rectClip) == ERROR)
- return;
- DWORD dwStyle = GetStyle();
- INT iHPos = GetScrollPos32(SB_HORZ);
- INT iVPos = GetScrollPos32(SB_VERT);
- pDC->FillSolidRect(rectClip, m_crBackground);
- CPen pen(m_iGridStyle, 1, m_crGrid);
- CPen* pPen = pDC->SelectObject(&pen);
- CFont* pFont = pDC->SelectObject(GetFont());
- pDC->SetBkMode(TRANSPARENT);
- CRect rectRow(m_rectReport.left-iHPos, m_rectReport.top, m_rectReport.left-iHPos+m_iVirtualWidth, m_rectReport.top);
- CRect rectItem(rectRow);
- TCHAR szText[REPORTCTRL_MAX_TEXT];
- RVITEM rvi;
- rvi.lpszText = szText;
- rvi.iTextMax = REPORTCTRL_MAX_TEXT;
- NMRVDRAWPREVIEW nmrvdp;
- nmrvdp.hdr.hwndFrom = m_hWnd;
- nmrvdp.hdr.idFrom = GetDlgCtrlID();
- nmrvdp.hdr.code = RVN_ITEMDRAWPREVIEW;
- nmrvdp.hDC = pDC->m_hDC;
- CWnd* pwndParent = GetParent();
- INT iRows = m_arrayRows.GetSize();
- INT iColumns = m_wndHeader.GetItemCount();
- ASSERT(iColumns>0); // Make sure that always one column is active
- if(m_bColumnsReordered)
- {
- LPINT lpi;
- m_arrayColumns.SetSize(iColumns, 8);
- lpi = m_arrayColumns.GetData();
- if(!m_wndHeader.GetOrderArray(lpi, iColumns))
- return;
- if(m_lprclc != NULL)
- m_lprclc->UpdateList();
- m_bColumnsReordered = FALSE;
- }
- if(!iRows)
- {
- rectRow.top += 2;
- rectRow.bottom = rectRow.top + m_iDefaultHeight;
- pDC->SetTextColor(m_crText);
- pDC->DrawText(m_strNoItems, rectRow, DT_CENTER|DT_END_ELLIPSIS);
- return;
- }
- INT iRow = iVPos;
- while(iRow<iRows && rectRow.top<rectClip.bottom)
- {
- rvi.iItem = m_arrayRows[iRow];
- ITEM& item = m_arrayItems[rvi.iItem];
- rectRow.bottom = rectRow.top + m_iDefaultHeight+item.nPreview;
- if(rectRow.bottom >= rectClip.top)
- {
- // You have to insert at least 1 color to use color alternate style.
- ASSERT(!(dwStyle&RVS_SHOWCOLORALTERNATE && !m_arrayColors.GetSize()));
- COLORREF crItem;
- crItem = (dwStyle&RVS_SHOWCOLORALTERNATE && iRow&1) ? m_arrayColors[0]:m_crBackground;
- crItem = item.iBkColor>=0 ? m_arrayColors[item.iBkColor]:crItem;
- if(item.nState&RVIS_SELECTED)
- {
- if(m_bFocus)
- crItem = m_crBkSelected;
- else
- if(dwStyle&RVS_SHOWSELALWAYS)
- crItem = m_crBkSelectedNoFocus;
- }
- pDC->FillSolidRect(rectRow, crItem);
- pDC->SetBkColor(crItem);
- if(item.nState&RVIS_BOLD)
- pDC->SelectObject(&m_fontBold);
- rectItem.SetRect(rectRow.left, rectRow.top, rectRow.left, rectRow.top+m_iDefaultHeight);
- for(INT iColumn=0;iColumn<iColumns&&rectItem.left<rectClip.right;iColumn++)
- {
- HDITEM hdi;
- hdi.mask = HDI_WIDTH|HDI_LPARAM;
- m_wndHeader.GetItem(m_arrayColumns[iColumn], &hdi);
- rvi.iSubItem = hdi.lParam;
- rectItem.right = rectItem.left + hdi.cxy;
- if(rectItem.right > rectClip.left)
- {
- rvi.nMask = RVIM_TEXT;
- VERIFY(GetItem(&rvi));
- COLORREF crText = rvi.nMask&RVIM_TEXTCOLOR ? m_arrayColors[rvi.iTextColor]:m_crText;
- if(item.nState&RVIS_SELECTED)
- {
- if(m_bFocus)
- crText = (dwStyle&RVS_SHOWCOLORALWAYS && rvi.nMask&RVIM_TEXTCOLOR) ? crText:m_crTextSelected;
- else
- if(dwStyle&RVS_SHOWSELALWAYS)
- crText = rvi.nMask&RVIM_TEXTCOLOR && dwStyle&RVS_SHOWCOLORALWAYS ? crText:m_crTextSelectedNoFocus;
- }
- pDC->SetTextColor(crText);
- rectItem.DeflateRect(m_iSpacing, 0);
- DrawItem(pDC, rectItem, &rvi);
- rectItem.InflateRect(m_iSpacing, 0);
- }
- rectItem.left = rectItem.right;
- }
- if(item.nState&RVIS_BOLD)
- pDC->SelectObject(GetFont());
- if(rvi.nMask&RVIM_PREVIEW && item.nPreview && pwndParent)
- {
- nmrvdp.iItem = rvi.iItem;
- nmrvdp.nState = item.nState;
- nmrvdp.rect = rectRow;
- nmrvdp.rect.top += m_iDefaultHeight;
- nmrvdp.lParam = item.lParam;
- pwndParent->SendMessage(WM_NOTIFY, 0, (LPARAM)&nmrvdp);
- }
- if(dwStyle&RVS_SHOWHGRID)
- {
- pDC->MoveTo(rectRow.left, rectRow.bottom-1);
- pDC->LineTo(rectRow.right, rectRow.bottom-1);
- }
- if(m_bFocus && item.nState&RVIS_FOCUSED)
- {
- if(dwStyle&(RVS_SHOWHGRID|RVS_SHOWVGRID))
- rectRow.DeflateRect(1, 0, 1, 1);
- pDC->SetBkColor(m_crBackground);
- pDC->SetTextColor(m_crText);
- pDC->DrawFocusRect(rectRow);
- if(dwStyle&(RVS_SHOWHGRID|RVS_SHOWVGRID))
- rectRow.InflateRect(1, 0, 1, 1);
- }
- }
- rectRow.top = rectRow.bottom;
- iRow++;
- }
- if(dwStyle&(RVS_SHOWHGRID|RVS_SHOWVGRID))
- {
- pDC->MoveTo(rectRow.left, m_rectReport.top);
- pDC->LineTo(rectRow.left, m_rectReport.bottom);
- pDC->MoveTo(rectRow.right-1, m_rectReport.top);
- pDC->LineTo(rectRow.right-1, m_rectReport.bottom);
- }
- if(dwStyle&RVS_SHOWHGRID && iRow>=iRows)
- {
- while(rectRow.bottom<rectClip.bottom)
- {
- pDC->MoveTo(rectRow.left, rectRow.bottom-1);
- pDC->LineTo(rectRow.right, rectRow.bottom-1);
- rectRow.bottom += m_iDefaultHeight;
- }
- }
- if(dwStyle&RVS_SHOWVGRID)
- {
- for(INT iColumn=0;iColumn<iColumns&&rectItem.left<rectClip.right;iColumn++)
- {
- HDITEM hdi;
- hdi.mask = HDI_WIDTH;
- m_wndHeader.GetItem(m_arrayColumns[iColumn], &hdi);
- rectRow.left += hdi.cxy;
- pDC->MoveTo(rectRow.left-1, m_rectReport.top);
- pDC->LineTo(rectRow.left-1, m_rectReport.bottom);
- }
- }
- pDC->SelectObject(pFont);
- pDC->SelectObject(pPen);
- pen.DeleteObject();
- }
- void CReportCtrl::DrawItem(CDC* pDC, CRect rect, LPRVITEM lprvi)
- {
- INT iWidth = 0;
- rect.left += (iWidth = DrawImage(pDC, rect, lprvi)) ? iWidth+m_iSpacing : 0;
- if(lprvi->nMask&RVIM_IMAGE && !iWidth)
- return;
- rect.left += (iWidth = DrawCheck(pDC, rect, lprvi)) ? iWidth+m_iSpacing : 0;
- if(lprvi->nMask&RVIM_CHECK && !iWidth)
- return;
- DrawText(pDC, rect, lprvi);
- }
- INT CReportCtrl::DrawImage(CDC* pDC, CRect rect, LPRVITEM lprvi)
- {
- CImageList* pImageList = GetImageList();
- INT iWidth = 0;
- if(lprvi->nMask&RVIM_IMAGE)
- {
- ASSERT(pImageList);
- ASSERT(lprvi->iImage>=0 && lprvi->iImage<pImageList->GetImageCount());
- if(rect.Width()>0)
- {
- POINT point;
- point.y = rect.CenterPoint().y - (m_sizeImage.cy>>1);
- point.x = rect.left;
- SIZE size;
- size.cx = rect.Width()<m_sizeImage.cx ? rect.Width():m_sizeImage.cx;
- size.cy = m_sizeImage.cy;
- pImageList->DrawIndirect(pDC, lprvi->iImage, point, size, CPoint(0, 0));
- iWidth = m_sizeImage.cx;
- }
- }
- else
- iWidth = m_arraySubItems[lprvi->iSubItem].nFormat&RVCF_SUBITEM_IMAGE ? m_sizeImage.cx:0;
- return iWidth;
- }
- INT CReportCtrl::DrawCheck(CDC* pDC, CRect rect, LPRVITEM lprvi)
- {
- INT iWidth = 0;
- if(lprvi->nMask&RVIM_CHECK)
- {
- if(rect.Width()>m_sizeCheck.cx)
- {
- rect.top = rect.CenterPoint().y - (m_sizeCheck.cy>>1);
- rect.left = rect.left;
- rect.bottom = rect.top + m_sizeCheck.cx;
- rect.right = rect.left + m_sizeCheck.cy;
- pDC->FillSolidRect(rect, m_crBackground); // Fixes visual problem with bigger fonts
- pDC->DrawFrameControl(
- rect,
- DFC_BUTTON,
- DFCS_BUTTONCHECK|DFCS_FLAT|(lprvi->iCheck?DFCS_CHECKED:0)
- );
- iWidth = m_sizeCheck.cx;
- }
- }
- else
- iWidth = m_arraySubItems[lprvi->iSubItem].nFormat&RVCF_SUBITEM_CHECK ? m_sizeCheck.cx:0;
- return iWidth;
- }
- INT CReportCtrl::DrawText(CDC* pDC, CRect rect, LPRVITEM lprvi)
- {
- CSize size;
- if(rect.Width()>0 && lprvi->nMask&RVIM_TEXT)
- {
- size = pDC->GetTextExtent(lprvi->lpszText);
- switch(m_arraySubItems[lprvi->iSubItem].nFormat&HDF_JUSTIFYMASK)
- {
- case HDF_LEFT:
- case HDF_LEFT|HDF_RTLREADING:
- pDC->DrawText(lprvi->lpszText, -1, rect, DT_LEFT|DT_END_ELLIPSIS|DT_SINGLELINE|DT_VCENTER);
- break;
- case HDF_CENTER:
- case HDF_CENTER|HDF_RTLREADING:
- pDC->DrawText(lprvi->lpszText, -1, rect, DT_CENTER|DT_END_ELLIPSIS|DT_SINGLELINE|DT_VCENTER);
- break;
- case HDF_RIGHT:
- case HDF_RIGHT|HDF_RTLREADING:
- pDC->DrawText(lprvi->lpszText, -1, rect, DT_RIGHT|DT_END_ELLIPSIS|DT_SINGLELINE|DT_VCENTER);
- break;
- }
- }
- size.cx = rect.Width()>size.cx ? size.cx:rect.Width();
- return size.cx>0 ? size.cx:0;
- }
- /////////////////////////////////////////////////////////////////////////////
- // CReportCtrl message handlers
- BOOL CReportCtrl::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
- {
- SetCursor(::LoadCursor(NULL, IDC_ARROW));
- return CWnd::OnSetCursor(pWnd, nHitTest, message);
- }
- void CReportCtrl::OnSetFocus(CWnd* pOldWnd)
- {
- CWnd::OnSetFocus(pOldWnd);
- m_bFocus = TRUE;
- Invalidate();
- }
- void CReportCtrl::OnKillFocus(CWnd* pNewWnd)
- {
- CWnd::OnKillFocus(pNewWnd);
- m_bFocus = FALSE;
- Invalidate();
- }
- void CReportCtrl::OnSysColorChange()
- {
- CWnd::OnSysColorChange();
- GetSysColors();
- }
- BOOL CReportCtrl::OnQueryNewPalette()
- {
- Invalidate();
- return CWnd::OnQueryNewPalette();
- }
- void CReportCtrl::OnPaletteChanged(CWnd* pFocusWnd)
- {
- CWnd::OnPaletteChanged(pFocusWnd);
- if(pFocusWnd->GetSafeHwnd() != GetSafeHwnd())
- Invalidate();
- }
- void CReportCtrl::OnSize(UINT nType, int cx, int cy)
- {
- CWnd::OnSize(nType, cx, cy);
- CRect rect;
- GetClientRect(rect);
- Layout(rect.Width(), rect.Height());
- }
- LRESULT CReportCtrl::OnGetFont(WPARAM wParam, LPARAM lParam)
- {
- return (LRESULT)m_font.m_hObject;
- }
- LRESULT CReportCtrl::OnSetFont(WPARAM wParam, LPARAM lParam)
- {
- LRESULT lResult = Default();
- CFont *pFont = CFont::FromHandle((HFONT)wParam);
- if(pFont)
- {
- LOGFONT lf;
- pFont->GetLogFont(&lf);
- m_font.DeleteObject();
- m_font.CreateFontIndirect(&lf);
- lf.lfWeight = FW_BOLD;
- m_fontBold.DeleteObject();
- m_fontBold.CreateFontIndirect(&lf);
- }
- CDC* pDC = GetDC();
- if (pDC)
- {
- CFont* pFont = pDC->SelectObject(&m_font);
- TEXTMETRIC tm;
- pDC->GetTextMetrics(&tm);
- pDC->SelectObject(pFont);
- ReleaseDC(pDC);
- m_iDefaultHeight = tm.tmHeight + tm.tmExternalLeading + 2;
- m_iDefaultHeight += GetStyle()&RVS_SHOWHGRID ? 1:0;
- m_sizeCheck.cx = m_iDefaultHeight-2;
- m_sizeCheck.cy = m_iDefaultHeight-2;
- }
- if(::IsWindow(GetSafeHwnd()) && lParam)
- {
- CRect rect;
- GetClientRect(rect);
- Layout(rect.Width(), rect.Height());
- }
- return lResult;
- }
- BOOL CReportCtrl::OnEraseBkgnd(CDC* pDC)
- {
- return TRUE;
- }
- void CReportCtrl::OnPaint()
- {
- CPaintDC dc(this);
- CPalette* pPalette = NULL;
- if(dc.GetDeviceCaps(RASTERCAPS) & RC_PALETTE)
- {
- pPalette = dc.SelectPalette(&m_palette, FALSE);
- dc.RealizePalette();
- }
- dc.ExcludeClipRect(m_rectHeader);
- if(m_bDoubleBuffer)
- {
- CMemDC MemDC(&dc);
- DrawCtrl(&MemDC);
- }
- else
- DrawCtrl(&dc);
- if(pPalette && dc.GetDeviceCaps(RASTERCAPS) & RC_PALETTE)
- dc.SelectPalette(pPalette, FALSE);
- }
- void CReportCtrl::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
- {
- INT iScrollPos = GetScrollPos32(SB_HORZ);
- INT iScroll;
- switch (nSBCode)
- {
- case SB_LINERIGHT:
- iScroll = min(m_iVirtualWidth-(m_rectReport.Width()+iScrollPos), m_rectReport.Width()>>3);
- ScrollWindow(SB_HORZ, iScrollPos + iScroll);
- break;
- case SB_LINELEFT:
- iScroll = min(iScrollPos, m_rectReport.Width()>>3);
- ScrollWindow(SB_HORZ, iScrollPos - iScroll);
- break;
- case SB_PAGERIGHT:
- iScrollPos = min(m_iVirtualWidth, iScrollPos + m_rectReport.Width());
- ScrollWindow(SB_HORZ, iScrollPos);
- break;
- case SB_PAGELEFT:
- iScrollPos = max(0, iScrollPos - m_rectReport.Width());
- ScrollWindow(SB_HORZ, iScrollPos);
- break;
- case SB_THUMBPOSITION:
- case SB_THUMBTRACK:
- iScrollPos = GetScrollPos32(SB_HORZ, TRUE);
- ScrollWindow(SB_HORZ, iScrollPos);
- break;
- case SB_RIGHT:
- ScrollWindow(SB_HORZ, m_iVirtualWidth);
- break;
- case SB_LEFT:
- ScrollWindow(SB_HORZ, 0);
- break;
- default:
- break;
- }
- }
- void CReportCtrl::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
- {
- INT iFirst = GetScrollPos32(SB_VERT), iLast;
- INT iItems = GetVisibleRows(TRUE, &iFirst, &iLast);
- switch(nSBCode)
- {
- case SB_LINEUP:
- if(iFirst>0)
- iFirst--;
- break;
- case SB_LINEDOWN:
- if(iFirst+iItems < m_iVirtualHeight)
- iFirst++;
- break;
- case SB_PAGEUP:
- GetVisibleRows(TRUE, &iLast, &iFirst, TRUE);
- iFirst = iLast-1;
- iFirst = iFirst<0 ? 0:iFirst;
- break;
- case SB_PAGEDOWN:
- iFirst += iItems;
- GetVisibleRows(TRUE, &iFirst, &iLast);
- GetVisibleRows(TRUE, &iFirst, &iLast, TRUE);
- break;
- case SB_THUMBPOSITION:
- case SB_THUMBTRACK:
- iFirst = GetScrollPos32(SB_VERT, TRUE);
- GetVisibleRows(TRUE, &iFirst, &iLast);
- GetVisibleRows(TRUE, &iFirst, &iLast, TRUE);
- break;
- case SB_TOP:
- iFirst = 0;
- break;
- case SB_BOTTOM:
- iLast = m_arrayRows.GetSize()-1;
- GetVisibleRows(TRUE, &iFirst, &iLast, TRUE);
- break;
- default:
- return;
- }
- ScrollWindow(SB_VERT, iFirst);
- }
- void CReportCtrl::OnLButtonDown(UINT nFlags, CPoint point)
- {
- SetFocus();
- RVHITTESTINFO rvhti;
- rvhti.point = point;
- HitTest(&rvhti);
- if(Notify(RVN_ITEMCLICK, nFlags, &rvhti))
- {
- CWnd::OnLButtonDown(nFlags, point);
- return;
- }
- if(rvhti.iItem>=0)
- {
- INT iRow = FindItem(rvhti.iItem);
- ASSERT(iRow >= 0);
- switch(nFlags&(MK_CONTROL|MK_SHIFT))
- {
- case MK_CONTROL:
- SelectRows(iRow, iRow, TRUE, TRUE, TRUE);
- m_iSelectRow = iRow;
- break;
- case MK_SHIFT:
- SelectRows(m_iSelectRow, iRow, TRUE);
- break;
- case MK_CONTROL|MK_SHIFT:
- SelectRows(m_iSelectRow, iRow, TRUE, TRUE);
- m_iSelectRow = iRow;
- break;
- default:
- SelectRows(iRow, iRow, TRUE);
- m_iSelectRow = iRow;
- break;
- }
- }
- }
- void CReportCtrl::OnLButtonDblClk(UINT nFlags, CPoint point)
- {
- RVHITTESTINFO rvhti;
- rvhti.point = point;
- HitTest(&rvhti);
- if(Notify(RVN_ITEMDBCLICK, nFlags, &rvhti))
- {
- CWnd::OnLButtonDblClk(nFlags, point);
- return;
- }
- }
- UINT CReportCtrl::OnGetDlgCode()
- {
- return DLGC_WANTARROWS;
- }
- #define IsShiftDown() ( (GetKeyState(VK_SHIFT) & (1 << (sizeof(SHORT)*8-1))) != 0 )
- #define IsCtrlDown() ( (GetKeyState(VK_CONTROL) & (1 << (sizeof(SHORT)*8-1))) != 0 )
- void CReportCtrl::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
- {
- INT iFirst = GetScrollPos32(SB_VERT), iLast;
- GetVisibleRows(TRUE, &iFirst, &iLast);
- switch (nChar)
- {
- case VK_SPACE:
- SelectRows(m_iFocusRow, m_iFocusRow, TRUE, TRUE);
- return;
- case VK_LEFT:
- SendMessage(WM_HSCROLL, LOWORD(SB_LINELEFT), NULL);
- return;
- case VK_RIGHT:
- SendMessage(WM_HSCROLL, LOWORD(SB_LINERIGHT), NULL);
- return;
- case VK_DOWN:
- if(m_iFocusRow<m_iVirtualHeight-1)
- {
- if(IsCtrlDown())
- {
- SelectRows(m_iFocusRow+1, m_iFocusRow+1, FALSE);
- m_iSelectRow = m_iFocusRow;
- }
- else if(!IsShiftDown())
- {
- SelectRows(m_iFocusRow+1, m_iFocusRow+1, TRUE);
- m_iSelectRow = m_iFocusRow;
- }
- else
- SelectRows(m_iFocusRow+1, m_iSelectRow, TRUE);
- EnsureVisible(m_arrayRows[m_iFocusRow]);
- }
- return;
- case VK_UP:
- if(m_iFocusRow>0)
- {
- if(IsCtrlDown())
- {
- SelectRows(m_iFocusRow-1, m_iFocusRow-1, FALSE);
- m_iSelectRow = m_iFocusRow;
- }
- else if(!IsShiftDown())
- {
- SelectRows(m_iFocusRow-1, m_iFocusRow-1, TRUE);
- m_iSelectRow = m_iFocusRow;
- }
- else
- SelectRows(m_iFocusRow-1, m_iSelectRow, TRUE);
- EnsureVisible(m_arrayRows[m_iFocusRow]);
- }
- return;
- case VK_NEXT:
- if(m_iFocusRow == iLast)
- {
- SendMessage(WM_VSCROLL, SB_PAGEDOWN, 0);
- iFirst = GetScrollPos32(SB_VERT);
- GetVisibleRows(TRUE, &iFirst, &iLast);
- }
- if(!IsShiftDown())
- {
- iFirst = iLast;
- m_iSelectRow = iLast;
- }
- else
- iFirst = m_iSelectRow;
- SelectRows(iLast, iFirst, TRUE);
- return;
- case VK_PRIOR:
- if(m_iFocusRow == iFirst)
- {
- SendMessage(WM_VSCROLL, SB_PAGEUP, 0);
- iFirst = GetScrollPos32(SB_VERT);
- }
- if(!IsShiftDown())
- {
- iLast = iFirst;
- m_iSelectRow = iFirst;
- }
- else
- iLast = m_iSelectRow;
- SelectRows(iFirst, iLast, TRUE);
- return;
- case VK_HOME:
- if(m_iFocusRow>0)
- {
- SendMessage(WM_VSCROLL, SB_TOP, 0);
- if(!IsShiftDown())
- m_iSelectRow = 0;
- SelectRows(0, m_iSelectRow, TRUE);
- }
- break;
- case VK_END:
- if(m_iFocusRow<m_iVirtualHeight)
- {
- SendMessage(WM_VSCROLL, SB_BOTTOM, 0);
- if(!IsShiftDown())
- m_iSelectRow = m_iVirtualHeight-1;
- SelectRows(m_iSelectRow, m_iVirtualHeight-1, TRUE);
- }
- break;
- }
- CWnd::OnKeyDown(nChar, nRepCnt, nFlags);
- }
- void CReportCtrl::OnHdnItemChanged(NMHDR* pNMHDR, LRESULT* pResult)
- {
- LPHDITEM lphdi = (LPHDITEM)((LPNMHEADER)pNMHDR)->pitem;
- HDITEM hdi;
- hdi.mask = HDI_WIDTH|HDI_LPARAM;
- m_wndHeader.GetItem(((LPNMHEADER)pNMHDR)->iItem, &hdi);
- if(lphdi->mask&HDI_FORMAT)
- m_arraySubItems[hdi.lParam].nFormat = lphdi->fmt&HDF_JUSTIFYMASK;
- if(lphdi->mask&HDI_WIDTH)
- {
- m_iVirtualWidth += lphdi->cxy - m_arraySubItems[hdi.lParam].iWidth;
- ASSERT(m_iVirtualWidth >= 0);
- m_arraySubItems[hdi.lParam].iWidth = lphdi->cxy;
- }
- ScrollWindow(SB_HORZ, GetScrollPos32(SB_HORZ));
- *pResult = FALSE;
- }
- void CReportCtrl::OnHdnItemClick(NMHDR* pNMHDR, LRESULT* pResult)
- {
- LPHDITEM lphdi = (LPHDITEM)((LPNMHEADER)pNMHDR)->pitem;
- HDITEM hdi;
- hdi.mask = HDI_ORDER|HDI_LPARAM;
- m_wndHeader.GetItem(((LPNMHEADER)pNMHDR)->iItem, &hdi);
- if(!Notify(RVN_COLUMNCLICK, -1, (INT)hdi.lParam))
- {
- if(!(GetStyle()&RVS_NOSORT))
- {
- BOOL bAscending;
- if(((LPNMHEADER)pNMHDR)->iItem == m_wndHeader.GetSortColumn(&bAscending))
- bAscending = !bAscending;
- else
- bAscending = TRUE;
- VERIFY(SortItems((INT)hdi.lParam, bAscending));
- }
- }
- pResult = FALSE;
- }
- void CReportCtrl::OnHdnEndDrag(NMHDR* pNMHDR, LRESULT* pResult)
- {
- LPNMHEADER lpnmhdr = (LPNMHEADER)pNMHDR;
- if(m_wndHeader.GetDropResult())
- {
- if(GetStyle()&RVS_ALLOWCOLUMNREMOVAL && m_arrayColumns.GetSize()>1)
- DeactivateColumn(lpnmhdr->pitem->lParam);
- *pResult = TRUE;
- }
- else
- {
- m_bColumnsReordered = TRUE;
- Invalidate();
- *pResult = FALSE;
- }
- }
- /////////////////////////////////////////////////////////////////////////////
- // CReportColumnListCtrl
- CReportColumnListCtrl::CReportColumnListCtrl()
- {
- m_pReportCtrl = NULL;
- m_iColumn = -1;
- m_pDragWnd = NULL;
- }
- CReportColumnListCtrl::~CReportColumnListCtrl()
- {
- }
- BEGIN_MESSAGE_MAP(CReportColumnListCtrl, CDragListBox)
- //{{AFX_MSG_MAP(CReportColumnListCtrl)
- //}}AFX_MSG_MAP
- END_MESSAGE_MAP()
- /////////////////////////////////////////////////////////////////////////////
- // CReportColumnListCtrl attributes
- BOOL CReportColumnListCtrl::SetReportCtrl(CReportCtrl* pReportCtrl)
- {
- m_pReportCtrl = pReportCtrl;
- ResetContent();
- return TRUE;
- }
- CReportCtrl* CReportColumnListCtrl::GetReportCtrl()
- {
- return m_pReportCtrl;
- }
- /////////////////////////////////////////////////////////////////////////////
- // CReportColumnListCtrl operations
- BOOL CReportColumnListCtrl::UpdateList()
- {
- INT iColumn, iColumns = m_pReportCtrl->m_arraySubItems.GetSize();
- ResetContent();
- for(iColumn=0;iColumn<iColumns;iColumn++)
- {
- if(!m_pReportCtrl->IsActiveColumn(iColumn) && Include(iColumn))
- {
- INT iItem = AddString(m_pReportCtrl->m_arraySubItems[iColumn].strText);
- SetItemData(iItem, iColumn);
- }
- }
- return TRUE;
- }
- BOOL CReportColumnListCtrl::Include(INT iColumn)
- {
- return TRUE;
- }
- /////////////////////////////////////////////////////////////////////////////
- // CReportColumnListCtrl message handlers
- void CReportColumnListCtrl::PreSubclassWindow()
- {
- CDragListBox::PreSubclassWindow();
- SetItemHeight(0, GetItemHeight(0)+2);
- }
- void CReportColumnListCtrl::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
- {
- CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
- CRect rcItem(lpDrawItemStruct->rcItem);
- if(GetCount() > 0)
- {
- pDC->DrawFrameControl(rcItem, DFC_BUTTON, DFCS_BUTTONPUSH);
- rcItem.DeflateRect(2, 2);
- if(lpDrawItemStruct->itemState&ODS_SELECTED)
- {
- pDC->FillRect(rcItem, &CBrush(::GetSysColor(COLOR_3DSHADOW)));
- pDC->SetTextColor(::GetSysColor(COLOR_3DHILIGHT));
- }
- else
- pDC->SetTextColor(::GetSysColor(COLOR_BTNTEXT));
- pDC->SetBkMode(TRANSPARENT);
- pDC->DrawText(
- m_pReportCtrl->m_arraySubItems[lpDrawItemStruct->itemData].strText,
- -1,
- rcItem,
- DT_SINGLELINE|DT_NOPREFIX|DT_NOCLIP|DT_VCENTER|DT_END_ELLIPSIS|DT_LEFT);
- }
- else
- pDC->FillSolidRect(rcItem, ::GetSysColor(COLOR_WINDOW));
- }
- BOOL CReportColumnListCtrl::BeginDrag(CPoint pt)
- {
- if(GetCount() <= 0)
- return FALSE;
- BOOL bAutoScroll = FALSE;
- INT iItem = ItemFromPt(pt);
- if(iItem >= 0)
- {
- GetClientRect(m_rcDragWnd);
- m_rcDragWnd.bottom = m_rcDragWnd.top + GetItemHeight(0);
- m_iColumn = GetItemData(iItem);
- _tcscpy(m_szColumnText, m_pReportCtrl->m_arraySubItems[m_iColumn].strText);
- m_hdiColumn.mask = HDI_WIDTH|HDI_TEXT|HDI_FORMAT;
- m_hdiColumn.cxy = m_rcDragWnd.Width();
- m_hdiColumn.pszText = m_szColumnText;
- m_hdiColumn.cchTextMax = sizeof(m_szColumnText);
- m_hdiColumn.fmt = HDF_STRING|HDF_LEFT;
- m_pDragWnd = new CFHDragWnd;
- if(m_pDragWnd)
- m_pDragWnd->Create(m_rcDragWnd, &m_pReportCtrl->m_wndHeader, -2, &m_hdiColumn);
- GetWindowRect(m_rcDropTarget1);
- m_pReportCtrl->m_wndHeader.GetWindowRect(m_rcDropTarget2);
- }
- m_iDropIndex = -1;
- return TRUE;
- }
- UINT CReportColumnListCtrl::Dragging(CPoint pt)
- {
- CPoint point = pt;
- point.Offset(-(m_rcDragWnd.Width()>>1), -(m_rcDragWnd.Height()>>1));
- if(m_pDragWnd != NULL)
- m_pDragWnd->SetWindowPos(
- &wndTop,
- point.x, point.y,
- 0, 0, SWP_NOSIZE|SWP_SHOWWINDOW|SWP_NOACTIVATE
- );
- if(m_rcDropTarget1.PtInRect(pt))
- return DL_MOVECURSOR;
- m_iDropIndex = m_pReportCtrl->m_wndHeader.SendMessage(HDM_SETHOTDIVIDER, TRUE, MAKELONG(pt.x, pt.y));
- if(m_rcDropTarget2.PtInRect(pt))
- return DL_MOVECURSOR;
- return DL_STOPCURSOR;
- }
- void CReportColumnListCtrl::CancelDrag(CPoint pt)
- {
- m_pReportCtrl->m_wndHeader.SendMessage(HDM_SETHOTDIVIDER, FALSE, -1);
- if(m_pDragWnd != NULL)
- {
- m_pDragWnd->DestroyWindow();
- m_pDragWnd = NULL;
- }
- }
- void CReportColumnListCtrl::Dropped(INT iSrcIndex, CPoint pt)
- {
- m_pReportCtrl->m_wndHeader.SendMessage(HDM_SETHOTDIVIDER, FALSE, -1);
- if(m_pDragWnd != NULL)
- {
- m_pDragWnd->DestroyWindow();
- m_pDragWnd = NULL;
- }
- if(m_iDropIndex >= 0)
- m_pReportCtrl->ActivateColumn(m_iColumn, m_iDropIndex);
- }