Solved

ListView LV_ITEM display & ImageList Icons

Posted on 1998-10-28
2
1,172 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

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
trigs fail! I thought I knew how to do trignometry 3 94
Error creating a new C++ project in ,net 20 60
learn programming 8 95
COM server issue 2 29
When writing generic code, using template meta-programming techniques, it is sometimes useful to know if a type is convertible to another type. A good example of when this might be is if you are writing diagnostic instrumentation for code to generat…
  Included as part of the C++ Standard Template Library (STL) is a collection of generic containers. Each of these containers serves a different purpose and has different pros and cons. It is often difficult to decide which container to use and …
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.

752 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