Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 604
  • Last Modified:

CImageList containing windows system icons

Hi,

I'm writing an app that involves the selection and manipulation of files using a CTreeCtrl.  I would very much like to have icons next to each item in the tree e.g. icons for folders and icons for the associated files eg. Icons that depict a text document etc - as in windows explorer.

Can anyone tell me how to do this?

Many Thanks

Stuart
0
csuog
Asked:
csuog
  • 2
1 Solution
 
RuskialtCommented:
First, draw the icons on a single bitmap, one by one next to each other. Make each icon same size, eg 16x16 pixels. Have the image saved as bmp. Add the image to the application resources. Then somewhere duing initialization (for example your treeviews OnInitialUpdate()) create the imagelist and give ot to the treectrl

like this:

m_pIconImageList = new CImageList;
m_pIconImageList->Create( IDB_ICONS  , 16 , 1 , RGB(255,0,255) );
m_tree.SetImageList( m_pIconImageList, TVSIL_NORMAL );

where IDB_ICONS is the resource id of you icon bitmap, and RGB(255,0,255) is the transparent color - in this case pink.

Then when inserting items in the tree control do:

m_tree.InsertItem( "SomeNode" , 0 , 1 );

The 0 is the unselected image, and the 1 is the selected image for the node.

A great way to draw good icons is to use a vector based graphics program. I used openoffice's draw. Then when done, I zoom in close to the icon (mabe around 300x300 pixels, not important as long as it is quite big) and take a screenshot. The icon is then resized to 16x16 in a graphics program, I use irfanview. The resizing gives you nice small smooth looking icons which are difficult to draw by hand.
0
 
nonubikCommented:
You need also to do some shell programming in order to get the proper icons.

Here's an excerpt from a class the does populate a checkboxed tree with folders and proper icons (starting from 'Desktop' item)

LPITEMIDLIST MakeCopy(LPCITEMIDLIST pidl)
{
      LPITEMIDLIST pidlTemp = (LPITEMIDLIST) pidl;

      // Calculate size of list.
      UINT cb = pidl->mkid.cb + sizeof(pidl->mkid.cb);


      LPITEMIDLIST pidlRet = (LPITEMIDLIST)g_pMalloc->Alloc(cb);
      if (pidlRet)
            CopyMemory(pidlRet, pidl, cb);
      return pidlRet;
}

// CTargetTree message handlers


void CTargetTree::Populate(HTREEITEM hItem /*= NULL*/)
{
      
      LPITEMIDLIST      pidlDesktop;
      HRESULT                  hr;
      STRRET                  strDispName;
      TCHAR                  szDisplayName[100];

      //LPSHELLVIEW            pShellView;
      // // Get a pointer to the Desktop's IShellFolder interface. //
      if(FAILED(SHGetDesktopFolder(&m_pSHDesktopFolder)))
      {
            return;
      }

      hr = SHGetSpecialFolderLocation(NULL, CSIDL_DESKTOP, &pidlDesktop);
      hr = m_pSHDesktopFolder->GetDisplayNameOf(pidlDesktop, SHGDN_INFOLDER, &strDispName);
      hr = StrRetToBuf(&strDispName, pidlDesktop, szDisplayName, sizeof(szDisplayName));

      
      SHFILEINFO      sfi;
      HIMAGELIST      hDesktop = (HIMAGELIST)SHGetFileInfo((LPCTSTR)pidlDesktop, 0, &sfi, sizeof(sfi), SHGFI_PIDL | SHGFI_SYSICONINDEX | SHGFI_SMALLICON);

      if(!hItem)
      {
            CImageList      *pIL = CImageList::FromHandle(hDesktop);

            SetImageList(pIL, TVSIL_NORMAL);
            hItem = InsertItem(szDisplayName, sfi.iIcon, sfi.iIcon);
      }

      CImageList      *pIl2 = GetImageList(TVSIL_STATE);
      ASSERT(pIl2!=0);
      IMAGEINFO      imgInfo;
      ZeroMemory(&imgInfo, sizeof(imgInfo));
      pIl2->GetImageInfo(0, &imgInfo);
      pIl2->Add(LoadIcon(AfxGetResourceHandle(), MAKEINTRESOURCE(IDI_CHECK_GRAY)));

      PopulateSubItem(m_pSHDesktopFolder, hItem);

      //m_pSHDesktopFolder->Release();

      Expand(hItem, TVE_EXPAND);
}


void CTargetTree::PopulateSubItem(LPSHELLFOLDER pSHFolder, HTREEITEM hParent, int iDepth)
{
      LPITEMIDLIST      pIdl;
      LPENUMIDLIST      pEnumFolders;
      //SHFILEINFO            sfi;
      //HIMAGELIST            hDesktop;
      HRESULT                  hr;
      CImageList            *pIL;
      STRRET                  strDispName;
      TCHAR                  szDisplayName[MAX_PATH],szFullName[MAX_PATH];
      HTREEITEM            hItem;
      SFGAOF                  rgf = SFGAO_HASSUBFOLDER;
      _FolderData            *pFolderData;


      hr = pSHFolder->EnumObjects(NULL, SHCONTF_FOLDERS | SHCONTF_INCLUDEHIDDEN, &pEnumFolders);
      if(FAILED(hr))
            return;

      m_iDepth++;

      hr = pEnumFolders->Next(1, &pIdl, NULL);

      while(SUCCEEDED(hr) && (hr != S_FALSE))
      {
            rgf = -1;
            hr = pSHFolder->GetAttributesOf(1, (LPCITEMIDLIST*)&pIdl, &rgf);

            //special case for Control Panel -> skip
            //
            if(rgf  == 0xa0000004)
            {
                  hr = pEnumFolders->Next(1, &pIdl, NULL);
                  continue;
            }

            //if we have a folder
            //
            if((rgf & SFGAO_FOLDER) && !(rgf & SFGAO_LINK))
            {
                  hr = pSHFolder->GetDisplayNameOf(pIdl, SHGDN_INFOLDER, &strDispName);
                  hr = StrRetToBuf(&strDispName, pIdl, szDisplayName, sizeof(szDisplayName));

                  hr = pSHFolder->GetDisplayNameOf(pIdl, SHGDN_NORMAL | SHGDN_FORPARSING, &strDispName);
                  hr = StrRetToBuf(&strDispName, pIdl, szFullName, sizeof(szFullName));
                  
//                  if((rgf & 0xf080014c) != 0xf080014c)
//                        hDesktop = (HIMAGELIST)SHGetFileInfo((LPCTSTR)pIdl, 0, &sfi, sizeof(sfi), SHGFI_PIDL | SHGFI_SYSICONINDEX | SHGFI_SMALLICON | SHGFI_ICON);
//                  else
//                        hDesktop = (HIMAGELIST)SHGetFileInfo(szFullName, 0, &sfi, sizeof(SHFILEINFO), SHGFI_SYSICONINDEX | SHGFI_SMALLICON);

                  LPEXTRACTICON      pIcon;
                  hr = pSHFolder->GetUIObjectOf(NULL, 1, (LPCITEMIDLIST*)&pIdl, IID_IExtractIcon, NULL, (void**)&pIcon);
                  if(SUCCEEDED(hr))
                  {
                        TCHAR      szIconLoc[300];
                        int            iIndex;
                        UINT      uFlags;
                        HICON      hSmall,hLarge;

                        hr = pIcon->GetIconLocation(GIL_FORSHELL, szIconLoc, 300, &iIndex, &uFlags);
                        hr = pIcon->Extract(szIconLoc, iIndex, &hLarge, &hSmall, 16);
                        pIcon->Release();

                        pIL = GetImageList(TVSIL_NORMAL);
                        if(!pIL)
                        {
                              pIL = new CImageList;
                              pIL->Create(16, 16, ILC_COLOR32, 0, 4);
                        }
                        
                        pIL->Add(hLarge);
                        int      iIdx = pIL->GetImageCount()-1;
                        SetImageList(pIL, TVSIL_NORMAL);
                        hItem = InsertItem(szDisplayName, iIdx, iIdx, hParent);
                        
                        //check children
                        //
                        int      iCheck = GetCheck(hParent);
                        if(iCheck == eChecked)
                              SetCheck(hItem, iCheck);

                        //if the item is on excluded, will be unchecked (MUST be done after the above check ;)
                        //if the item is on scan folders, will be checked
                        //
                        CheckItemOnPopulate(hItem, szFullName);
                  }

/*
                  pIL = CImageList::FromHandle(hDesktop);
                  SetImageList(pIL, TVSIL_NORMAL);
                  hItem = InsertItem(szDisplayName, sfi.iIcon, sfi.iIcon, hParent);
                  SetItemData(hItem, NULL);
*/
            
                  //SHGetPathFromIDList(pIdl, szDisplayName);

                  pFolderData = new _FolderData;
                  pFolderData->pIdl = MakeCopy(pIdl);
                  pFolderData->pSHF = pSHFolder;
                  SetItemData(hItem, (DWORD_PTR)pFolderData);

                  //if it has subfolders
                  //
                  if((m_iDepth <= iDepth) && (rgf & SFGAO_HASSUBFOLDER))
                  {
                        LPSHELLFOLDER      pSHSubFolder;
                        hr = pSHFolder->BindToObject(pIdl, NULL, IID_IShellFolder, (void**)&pSHSubFolder);
                        if(SUCCEEDED(hr))
                        {
                              if(m_iDepth < iDepth)
                                    PopulateSubItem(pSHSubFolder, hItem);
                              //pSHSubFolder->Release();

                              //for my computer (and others) do extra stuff
                              //
                              DoExtraStuff(szFullName, hItem);
                        }
                  }
            }
            hr = pEnumFolders->Next(1, &pIdl, NULL);
      }

      m_iDepth--;
}


void CTargetTree::OnTvnItemexpanding(NMHDR *pNMHDR, LRESULT *pResult)
{
      LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);
      HTREEITEM      hItem = pNMTreeView->itemNew.hItem;
      
      if(pNMTreeView->action == TVE_EXPAND)
      {
            if(ItemHasChildren(hItem))
            {
                  CWaitCursor      cw;            
                  HTREEITEM      hChild = GetChildItem(hItem);

                  do
                  {
                        if(!ItemHasChildren(hChild))
                        {
                              _FolderData      *pFD = (_FolderData*)GetItemData(hChild);

                              if(pFD)
                                    if(pFD->pSHF)
                                    {
                                          LPSHELLFOLDER      pSHSubFolder;
                                          HRESULT hr = pFD->pSHF->BindToObject(pFD->pIdl, NULL, IID_IShellFolder, (void**)&pSHSubFolder);
                                          if(SUCCEEDED(hr))
                                          {
                                                PopulateSubItem(pSHSubFolder, hChild, 1);
                                          }
                                    }
                                    //pSHFolder->Release();
                        }
                        hChild = GetNextSiblingItem(hChild);
                  }while(hChild);
            }
      }

      *pResult = 0;
}
0
 
nonubikCommented:
Was not my answer satisfactory?
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now