// TreeList.cpp : implementation file // #include "stdafx.h" #include "resource.h" #include "TreeList.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CTreeList CTreeList::CTreeList() { m_SelectionRect = CRect(0,0,0,0); m_SelectionFlag = FALSE; m_Point = CPoint(0, 0); m_PrevItem = -1; m_Rows = 0; m_Columns = 1; m_hBitmap = NULL; m_hMemDC = NULL; m_hOldBmp = NULL; m_bFocus = FALSE; } CTreeList::~CTreeList() { if (m_hBitmap) { if (m_hMemDC) { ::SelectObject(m_hMemDC, m_hOldBmp); ::DeleteDC(m_hMemDC); } ::DeleteObject (m_hBitmap); m_hBitmap = NULL; } } BEGIN_MESSAGE_MAP(CTreeList, CListCtrl) //{{AFX_MSG_MAP(CTreeList) ON_WM_LBUTTONDOWN() ON_WM_RBUTTONDOWN() ON_NOTIFY_REFLECT(NM_KILLFOCUS, OnKillfocus) ON_NOTIFY_REFLECT(NM_SETFOCUS, OnSetfocus) //}}AFX_MSG_MAP ON_MESSAGE(WM_SETFONT, OnSetFont) ON_WM_MEASUREITEM_REFLECT() END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CTreeList message handlers void CTreeList::OnLButtonDown(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default m_Point = point; m_SelectionFlag = FALSE; Invalidate(); CListCtrl::OnLButtonDown(nFlags, point); } BOOL CTreeList::PreCreateWindow(CREATESTRUCT& cs) { // TODO: Add your specialized code here and/or call the base class cs.style |= LVS_REPORT | LVS_OWNERDRAWFIXED| WS_BORDER; return CListCtrl::PreCreateWindow(cs); } LRESULT CTreeList::OnSetFont(WPARAM wParam, LPARAM) { LRESULT res = Default(); CRect rc; GetWindowRect( &rc ); WINDOWPOS wp; wp.hwnd = m_hWnd; wp.cx = rc.Width(); wp.cy = rc.Height(); wp.flags = SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOZORDER; SendMessage( WM_WINDOWPOSCHANGED, 0, (LPARAM)&wp ); return res; } void CTreeList::MeasureItem( LPMEASUREITEMSTRUCT lpMeasureItemStruct ) { lpMeasureItemStruct->itemHeight = 16; } void CTreeList::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) { PULONG pMagic = (PULONG) lpDrawItemStruct->itemData; TCHAR lpBuffer[256]; LV_ITEM lvi; LV_COLUMN lvc, lvcprev ; memset(lpBuffer, 0, 256); lvi.mask = LVIF_TEXT | LVIF_PARAM ; lvi.iItem = lpDrawItemStruct->itemID ; lvi.iSubItem = 0; lvi.pszText = lpBuffer ; lvi.cchTextMax = sizeof(lpBuffer); GetItem(&lvi); ::ZeroMemory(&lvc, sizeof(lvc)); ::ZeroMemory(&lvcprev, sizeof(lvcprev)); lvc.mask = LVCF_WIDTH |LVCF_FMT; lvcprev.mask = LVCF_WIDTH | LVCF_FMT; CDC* pDC; pDC = CDC::FromHandle(lpDrawItemStruct->hDC); int nCol; CRect rcText = lpDrawItemStruct->rcItem; CFont Fnt, *pOldFont = NULL; LOGFONT lf; int cyPixels = pDC->GetDeviceCaps(LOGPIXELSY); memset(&lf, 0, sizeof(LOGFONT)); if (pMagic == NULL) { return; } if (*pMagic == EXT2_CDROM_DEVICE_MAGIC || *pMagic == EXT2_DISK_MAGIC) { if (IsVista()) { lstrcpy(lf.lfFaceName, "MS Sans Serif"); /*Courier New*/ lf.lfHeight = -MulDiv(8, cyPixels, 72); lf.lfWeight = TRUE; } else { lstrcpy(lf.lfFaceName, "Arial Black"); /*Courier New*/ lf.lfHeight = -MulDiv(8, cyPixels, 72); lf.lfWeight = TRUE; } } else { lstrcpy(lf.lfFaceName, "MS Sans Serif"); lf.lfHeight = -MulDiv(8, cyPixels, 72); } Fnt.CreateFontIndirect(&lf); pOldFont = (CFont *) pDC->SelectObject(&Fnt); /* loading bitmap */ if (m_hBitmap == NULL) { m_hBitmap = (HBITMAP)::LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(IDB_LINE_SEP), IMAGE_BITMAP, 0, 0, 0); if (m_hBitmap) { m_hMemDC = ::CreateCompatibleDC(this->GetDC()->m_hDC); m_hOldBmp = (HBITMAP)::SelectObject(m_hMemDC, m_hBitmap); } } if (TRUE) { if (!m_SelectionFlag) { for (nCol=0; GetColumn(nCol, &lvc); nCol++) { if (nCol > 0) { GetSubItemRect(lpDrawItemStruct->itemID, nCol,LVIR_BOUNDS, m_SelectionRect); } else { GetItemRect(lpDrawItemStruct->itemID, m_SelectionRect,LVIR_BOUNDS); m_SelectionRect.right = GetColumnWidth(0); m_SelectionRect.left = 0; } if (m_SelectionRect.PtInRect(m_Point)) { m_SelectionFlag = TRUE; break; } else { m_SelectionFlag = FALSE; } } } if ((lpDrawItemStruct->itemState & ODS_SELECTED) && m_SelectionFlag ) { CRect rc = lpDrawItemStruct->rcItem; rc.left += 4; rc.right -= 4; rc.top += 1; rc.bottom -= 0; if (*pMagic == EXT2_CDROM_DEVICE_MAGIC || *pMagic == EXT2_DISK_MAGIC) { rc.bottom -= 3; rc.top -= 1; rc.right = (rc.Width() * 7 / 8) + rc.left; } pDC->FillSolidRect(&rc, GetSysColor(m_bFocus ? COLOR_HIGHLIGHT : COLOR_INACTIVEBORDER)); } else { CRect rc = lpDrawItemStruct->rcItem; pDC->FillSolidRect(&rc, GetSysColor(COLOR_WINDOW)) ; pDC->SetTextColor(GetSysColor(COLOR_WINDOWTEXT)) ; } } for (nCol=0; GetColumn(nCol, &lvc); nCol++) { UINT uFormat = DT_LEFT ; if (*pMagic == EXT2_CDROM_DEVICE_MAGIC || *pMagic == EXT2_DISK_MAGIC) { rcText = lpDrawItemStruct->rcItem; rcText.left += 4; rcText.bottom += 1; rcText.top = rcText.bottom - 6 + lf.lfHeight; ::DrawText(lpDrawItemStruct->hDC, lpBuffer, strlen(lpBuffer), &rcText, DT_LEFT) ; CRect rect = lpDrawItemStruct->rcItem; int rc = 0; BITMAP cs; rect.top = rcText.bottom - 4; rc = ::GetObject(m_hBitmap, sizeof(cs), &cs); if (rc == 0) { pDC->SelectObject(pOldFont); return; } ::StretchBlt(pDC->m_hDC, rect.left + 4, (rect.bottom + rect.top) / 2, rect.Width() * 7 / 8, cs.bmHeight, m_hMemDC, 0, 0, cs.bmWidth, cs.bmHeight, SRCCOPY); } else { if (nCol > 0) { GetColumn(nCol, &lvcprev) ; rcText.left = rcText.right; rcText.right += lvcprev.cx; rcText.left += 4; if (nCol == 3 || nCol == 4) { uFormat = DT_RIGHT; rcText.right -= 4; } } else { rcText = lpDrawItemStruct->rcItem; rcText.top += (16 + lf.lfHeight) / 2; rcText.right = rcText.left + GetColumnWidth(0); rcText.left += 20; } // Get and draw the text memset(lpBuffer, 0, 256); ::ZeroMemory(&lvi, sizeof(lvi)); lvi.iItem = lpDrawItemStruct->itemID; lvi.mask = LVIF_TEXT | LVIF_PARAM; lvi.iSubItem = nCol; lvi.pszText = lpBuffer; lvi.cchTextMax = sizeof(lpBuffer); GetItem(&lvi); ::DrawText(lpDrawItemStruct->hDC, lpBuffer, strlen(lpBuffer), &rcText, uFormat) ; if (nCol == 0) { rcText.left -= 20; } else { rcText.left -= 4; if (nCol == 3 || nCol == 4) { rcText.right += 4; } } } } pDC->SelectObject(pOldFont); return; } void CTreeList::OnRButtonDown(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default m_Point = point; m_SelectionFlag = FALSE; Invalidate(); CListCtrl::OnRButtonDown(nFlags, point); } void CTreeList::OnKillfocus(NMHDR* pNMHDR, LRESULT* pResult) { // TODO: Add your control notification handler code here m_bFocus = FALSE; Invalidate(); *pResult = 0; } void CTreeList::OnSetfocus(NMHDR* pNMHDR, LRESULT* pResult) { // TODO: Add your control notification handler code here m_bFocus = TRUE; Invalidate(); *pResult = 0; } int CTreeList::QuerySubItemText(int item, CHAR *Data, int length) { LV_COLUMN lvc; LV_ITEM lvi; int ncol; CRect rect; ::ZeroMemory(&lvc, sizeof(lvc)); lvc.mask = LVCF_WIDTH |LVCF_FMT; for (ncol=0; GetColumn(ncol, &lvc); ncol++) { if (ncol > 0) { GetSubItemRect(item, ncol,LVIR_BOUNDS, rect); } else { GetItemRect(item, rect, LVIR_BOUNDS); rect.right = GetColumnWidth(0); rect.left = 0; } if (rect.PtInRect(m_Point)) { ::ZeroMemory(Data, length); ::ZeroMemory(&lvi, sizeof(lvi)); lvi.iItem = item; lvi.mask = LVIF_TEXT; lvi.iSubItem = ncol; lvi.pszText = Data; lvi.cchTextMax = length; return GetItem(&lvi); break; } } return FALSE; } VOID CTreeList::Redraw() { m_bFocus = TRUE; m_SelectionFlag = TRUE; Invalidate(); }