Solved

ListView LV_ITEM display & ImageList Icons

Posted on 1998-10-28
2
1,184 Views
Last Modified: 2008-03-06
I am writing a Windows Explorer type utility using VC++ 5.0 in Windows 98, to display disk folders & files with FileName, FileSize, ftCreationTime & ftLastWriteTime in LVS_REPORT mode.

I cannot persuade the LV_ITEM to insert the sub-items - I only get the FileName.  

Also, I have succeeded in displaying folder icons for folders, but how do I display the individual file icons?

Here is the View file:

// Lc6View.cpp : implementation of the CLc6View class

#include "stdafx.h"
#include "Lc6.h"
#include "Lc6Doc.h"
#include "Lc6View.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

HICON hIcon;
int firstclick;
/////////////////////////////////////////////////////////////////////////////
// CLc6View

IMPLEMENT_DYNCREATE(CLc6View, CListView)

BEGIN_MESSAGE_MAP(CLc6View, CListView)
      //{{AFX_MSG_MAP(CLc6View)
      ON_NOTIFY_REFLECT(LVN_COLUMNCLICK, OnColumnclick)
      ON_WM_DESTROY()
      //}}AFX_MSG_MAP
      // Standard printing commands
      ON_COMMAND(ID_FILE_PRINT, CListView::OnFilePrint)
      ON_COMMAND(ID_FILE_PRINT_DIRECT, CListView::OnFilePrint)
      ON_COMMAND(ID_FILE_PRINT_PREVIEW, CListView::OnFilePrintPreview)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CLc6View construction/destruction

CLc6View::CLc6View()
{
      // TODO: add construction code here

}

CLc6View::~CLc6View()
{
}

BOOL CLc6View::PreCreateWindow(CREATESTRUCT& cs)
{
      // TODO: Modify the Window class or styles here by modifying
      //  the CREATESTRUCT cs

      return CListView::PreCreateWindow(cs);
}

void CLc6View::OnInitialUpdate()
{
      CListView::OnInitialUpdate();

      // TODO: You may populate your ListView with items by directly accessing
      //  its list control through a call to GetListCtrl().

      ModifyStyle(LVS_TYPEMASK, LVS_REPORT);                                                // Report view;

      GetListCtrl().InsertColumn(0, "File Name", LVCFMT_LEFT, 192);            // insert column headers
      GetListCtrl().InsertColumn(1, "Size", LVCFMT_RIGHT, 125);                  //
      GetListCtrl().InsertColumn(2, "Created", LVCFMT_CENTER, 128);            //
      GetListCtrl().InsertColumn(3, "Last Modified", LVCFMT_CENTER, 128);      //

      m_smlImageList.Create(16, 16, ILC_COLOR4, 1, 0);                                          // Create ImageList controls
      hIcon = ::LoadIcon(AfxGetResourceHandle(), MAKEINTRESOURCE(IDI_FOLDER));      // add image to ImageList
      GetListCtrl().SetImageList(&m_smlImageList, LVSIL_SMALL);                              // Create ListView control

      FindFile();                                                                                          // find folders & files on disk
}
/////////////////////////////////////////////////////////////////////////////
// CLc6View message handlers

void CLc6View::FindFile()
{
      char szPath[MAX_PATH];                  // Get path to C:\*.* (all files)
      szPath[0] = 'C';                        //
      szPath[1] = ':';                        //
      szPath[2] = '\\';                        //
      szPath[3] = '*';                        //
      szPath[4] = '.';                        //
      szPath[5] = '*';                        //
      szPath[6] = 0;                              //

         WIN32_FIND_DATA fd;                        // Enumerate the files in the directory and add items to the list view

    HANDLE hFind = ::FindFirstFile(szPath, &fd);      // find 1st item
      if(hFind == INVALID_HANDLE_VALUE)
            return;
      else
            AddItem(fd);                                                // add 1st item

      while(::FindNextFile(hFind, &fd))                        // find remaining items
      {
            if(hFind == INVALID_HANDLE_VALUE)
                  return;
            else
                  AddItem(fd);                                          // add remaining items
      }
      ::FindClose (hFind);
}

BOOL CLc6View::AddItem(WIN32_FIND_DATA &fd)
{
      // Allocate an ITEMINFO structure to hold the item's data.
      ITEMINFO* pItem;
      try
      {
            pItem = new ITEMINFO;
      }
      catch(CMemoryException* e)
      {
            e->Delete();
            return FALSE;
      }

      CString s(fd.cFileName);                                                      // cjr - force Sentence case filenames
      s.MakeLower();                                                                        //
      strcpy(fd.cFileName, s);                                                      //
      if((fd.cFileName[0] >= 0x61) && (fd.cFileName[0] <= 0x7a))      // if 1st char: a-z convert to A-Z
            fd.cFileName[0] -= 0x20;                                                //

      // Initialize the ITEMINFO structure's fields.
      pItem->strFileName = fd.cFileName;    
      pItem->dwFileSize = fd.nFileSizeLow;
      pItem->ftCreationTime = fd.ftCreationTime;
      pItem->ftLastWriteTime = fd.ftLastWriteTime;

      // Add an item to the list view control, and set the item's lParam
      // equal to the address of the corresponding ITEMINFO structure.
      LV_ITEM lvi;
      lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
      if((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) // folder?
      {                                                                        
            m_smlImageList.Add(hIcon);                              // use folder icon
            lvi.iItem = 0;                                                //
            lvi.iSubItem = 0;                                          //
            lvi.state = 0;                                                //
            lvi.stateMask = 0;                                          //
            lvi.pszText = fd.cFileName;                              // display folder name
            lvi.cchTextMax = 0;                                          //
            lvi.iImage = 0;                                                // controls whether or not icon shows - wanted here
            lvi.lParam = (LPARAM)pItem;                              // this is needed for the sort
      }
      else                                                                  // must be file
      {
//            m_smlImageList.Add(hIcon2);                              // use file icon - not wanted here
            lvi.iItem = 0;                                                //
            lvi.iSubItem = 0;                                          //
            lvi.state = 0;                                                //
            lvi.stateMask = 0;                                          //
            lvi.pszText = fd.cFileName;                              // display filename
            lvi.cchTextMax = 0;                                          //
//            lvi.iImage = 0;                                                // controls whether or not icon shows - not wanted here
            lvi.lParam = (LPARAM)pItem;                              // this is needed for the sort
      }

      if(GetListCtrl().InsertItem(&lvi) == -1)
            return FALSE;
      return TRUE;
}

void CLc6View::OnColumnclick(NMHDR* pNMHDR, LRESULT* pResult)
{
      // TODO: Add your control notification handler code here
    // When a header button is clicked, call the list view's SortItems
    // function to sort the data in the column. The column number passed
    // in SortItem's second parameter becomes the lParamSort parameter
    // passed to the comparison function.
      NM_LISTVIEW* pNMListView = (NM_LISTVIEW*) pNMHDR;
      if(firstclick == 0)
      {
            firstclick = 1;
      }
      else
            firstclick = 0;
      GetListCtrl().SortItems(CompareFunc, pNMListView->iSubItem);
      *pResult = 0;
}

/////////////////////////////////////////////////////////////////////////////
// Callback function for sorting

int CALLBACK CLc6View::CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
{
      ITEMINFO* pItem1 = (ITEMINFO*) lParam1;
      ITEMINFO* pItem2 = (ITEMINFO*) lParam2;
    int nResult;

    switch (lParamSort)
      { // lParamSort == Column number (0-3)

    case 0: // File name
            if(firstclick == 1)
            {
                  nResult = pItem1->strFileName.CompareNoCase(pItem2->strFileName);
            }
            else
            {
                  nResult = pItem2->strFileName.CompareNoCase(pItem1->strFileName);
            }
        break;

    case 1: // File size
            if(firstclick == 1)
            {
              nResult = pItem1->dwFileSize - pItem2->dwFileSize;
            }
            else
            {
              nResult = pItem2->dwFileSize - pItem1->dwFileSize;
            }
        break;

    case 2: // Date and time created
            if(firstclick == 1)
            {
                  nResult = ::CompareFileTime(&pItem1->ftCreationTime, &pItem2->ftCreationTime);
            }
            else
            {
                  nResult = ::CompareFileTime(&pItem2->ftCreationTime, &pItem1->ftCreationTime);
            }
        break;

    case 3: // Date and time modified
            if(firstclick == 1)
            {
                  nResult = ::CompareFileTime (&pItem1->ftLastWriteTime, &pItem2->ftLastWriteTime);
            }
            else
            {
                  nResult = ::CompareFileTime (&pItem2->ftLastWriteTime, &pItem1->ftLastWriteTime);
            }
        break;
    }
      return nResult;
}

void CLc6View::OnDestroy()
{
      CListView::OnDestroy();
      
      // TODO: Add your message handler code here
      FreeItems();
}

void CLc6View::FreeItems()
{
    // Delete the ITEMINFO structures allocated when the control was created.
    int nCount = GetListCtrl().GetItemCount();
    if (nCount)
      {
        for(int i=0; i<nCount; i++)
            delete(ITEMINFO*)GetListCtrl().GetItemData(i);
    }
}

/////////////////////////////////////////////////////////////////////////////
// CLc6View diagnostics

#ifdef _DEBUG
void CLc6View::AssertValid() const
{
      CListView::AssertValid();
}

void CLc6View::Dump(CDumpContext& dc) const
{
      CListView::Dump(dc);
}

CLc6Doc* CLc6View::GetDocument() // non-debug version is inline
{
      ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CLc6Doc)));
      return (CLc6Doc*)m_pDocument;
}

#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CLc6View drawing

void CLc6View::OnDraw(CDC* pDC)
{
      CLc6Doc* pDoc = GetDocument();
      ASSERT_VALID(pDoc);

      // TODO: add draw code for native data here
}
0
Comment
Question by:chrisrobinson
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
2 Comments
 

Accepted Solution

by:
despote earned 100 total points
ID: 1176438
CLc6View::CLc6View()
{
//  Get System icon list for all files registred
    SHFILEINFO  sfi;
//  m_ImageList (CImageList) is global to the class
    m_ImageList.Attach((HIMAGELIST)SHGetFileInfo( "C:\\", 0, &sfi, sizeof(SHFILEINFO),SHGFI_SYSICONINDEX | SHGFI_SMALLICON));
}

CLc6View::~CLc6View()
{
//  dont forget to detach imagelist at the end of the program
    m_ImageList.Detach();
}


//  Now to use your iconlist
    SHFILEINFO sfi;
    LV_ITEM    lvi;
    lvi.mask    = LVIF_TEXT|LVIF_IMAGE;
    lvi.iItem      = 0;
//  Get File icon
    SHGetFileInfo( (char*)filename, 0, &sfi,
        sizeof(SHFILEINFO),
        SHGFI_SYSICONINDEX|SHGFI_SMALLICON);
    CString Tx ="test";
    lvi.iSubItem = 0;
    lvi.pszText = (LPSTR)(LPCSTR)Tx;
    lvi.cchTextMax = strlen( lvi.pszText);
    lvi.iImage = sfi.iIcon;
    int row = m_CtrlList.InsertItem(&lvi);
    m_CtrlList.SetItemText(lvi.iItem, 1, Tx);
    m_CtrlList.SetItemText(lvi.iItem, 2, "mytext"));

0
 

Author Comment

by:chrisrobinson
ID: 1176439
First class!  Thank you - it worked like a dream.

chrisrobinson
0

Featured Post

On Demand Webinar: Networking for the Cloud Era

Ready to improve network connectivity? Watch this webinar to learn how SD-WANs and a one-click instant connect tool can boost provisions, deployment, and management of your cloud connection.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Often, when implementing a feature, you won't know how certain events should be handled at the point where they occur and you'd rather defer to the user of your function or class. For example, a XML parser will extract a tag from the source code, wh…
Introduction This article is a continuation of the C/C++ Visual Studio Express debugger series. Part 1 provided a quick start guide in using the debugger. Part 2 focused on additional topics in breakpoints. As your assignments become a little more …
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

632 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question