//----------------------------------------------------------------------------------------------------------------- //WTLExplorer : WTLized version of the explorer sample from MSDN. // Use this code at your own risk. We wrote it just for fun :-) // Tested *only* on Win2k. Requires Platform SDK headers. // // //----------------------------------------------------------------------------------------------------------------- #include "stdafx.H" #include "MainFrm.H" #include "atlctrlx.H" //---------------------------------------------------------------------------------------------------- void CMainFrame::InitTreeView() { CComPtr spFolder; HRESULT hr = SHGetDesktopFolder(&spFolder); if(FAILED(hr)) return ; SHFILEINFO sfi; memset(&sfi, 0, sizeof(SHFILEINFO)); HIMAGELIST hImageList = (HIMAGELIST)SHGetFileInfo((LPCSTR)_T("C:\\"), 0, &sfi, sizeof(SHFILEINFO), SHGFI_SYSICONINDEX | SHGFI_SMALLICON); // Attach ImageList to TreeView if (hImageList && m_wndFolderTree.m_wndContained.IsWindow()) m_wndFolderTree.m_wndContained.SetImageList(hImageList,0); CWaitCursor wait; FillTreeView(spFolder,NULL,TVI_ROOT); m_wndFolderTree.m_wndContained.Expand(m_wndFolderTree.m_wndContained.GetRootItem()); m_wndFolderTree.m_wndContained.SelectItem(m_wndFolderTree.m_wndContained.GetRootItem()); return ; } //---------------------------------------------------------------------------------------------------- void CMainFrame::InitListView() { // Insert columns m_wndListView.InsertColumn(0, _T("Name"), LVCFMT_LEFT, 200, 0); m_wndListView.InsertColumn(1, _T("Size"), LVCFMT_RIGHT, 100, 1); m_wndListView.InsertColumn(2, _T("Type"), LVCFMT_LEFT, 100, 2); m_wndListView.InsertColumn(3, _T("Modified"), LVCFMT_LEFT, 100, 3); m_wndListView.InsertColumn(4, _T("Attributes"), LVCFMT_RIGHT, 100, 4); // Get system image lists SHFILEINFO sfi; memset(&sfi, 0, sizeof(SHFILEINFO)); HIMAGELIST hImageList = (HIMAGELIST)::SHGetFileInfo( _T("c:\\"), 0, &sfi, sizeof(sfi), SHGFI_SYSICONINDEX | SHGFI_SMALLICON); ATLASSERT(hImageList != NULL); if(hImageList != NULL) m_wndListView.SetImageList(hImageList, LVSIL_SMALL); memset(&sfi, 0, sizeof(SHFILEINFO)); hImageList = (HIMAGELIST)::SHGetFileInfo(_T("c:\\"), 0, &sfi, sizeof(sfi),SHGFI_SYSICONINDEX | SHGFI_ICON); ATLASSERT(hImageList != NULL); if(hImageList != NULL) m_wndListView.SetImageList(hImageList, LVSIL_NORMAL); } //-------------------------------------------------------------------------------------- BOOL CMainFrame::InitComboBox() { HIMAGELIST himlSmall = 0; SHFILEINFO sfi; memset(&sfi, 0, sizeof(SHFILEINFO)); himlSmall = (HIMAGELIST)SHGetFileInfo((LPCSTR)_T("C:\\"), 0, &sfi, sizeof(SHFILEINFO), SHGFI_SYSICONINDEX | SHGFI_SMALLICON); if (himlSmall) { m_wndCombo.SetImageList(himlSmall); return TRUE; } return FALSE; } //---------------------------------------------------------------------------------------------------------- BOOL CMainFrame::FillComboBox(LPNMTREEVIEW lpTV, IShellFolder* pShellFolder) { m_wndCombo.ResetContent(); CWaitCursor wait; HTREEITEM hItem = lpTV->itemNew.hItem; HRESULT hr = S_OK; int nLevel = 0; while(hItem) { nLevel++; hItem = m_wndFolderTree.m_wndContained.GetParentItem(hItem); } int nIndent = nLevel; int nIndex = nLevel; hItem = lpTV->itemNew.hItem; HTREEITEM hPrevItem1 = hItem; HTREEITEM hPrevItem2 = NULL; while(hItem) { FillComboItem(hItem, 0, nIndent--); hPrevItem2 = hPrevItem1; hPrevItem1 = hItem; hItem = m_wndFolderTree.m_wndContained.GetParentItem(hItem); } bool bInsertAfter = false; HTREEITEM hRootItem = m_wndFolderTree.m_wndContained.GetRootItem(); if(hRootItem != hPrevItem1) FillComboItem(hRootItem, 0, 1); hItem = m_wndFolderTree.m_wndContained.GetChildItem(hRootItem); nIndex = 1; while(hItem) { if(hItem != hPrevItem1 && hItem != hPrevItem2) FillComboItem(hItem, (bInsertAfter? -1 : nIndex++), 2); else bInsertAfter = true; hItem = m_wndFolderTree.m_wndContained.GetNextSiblingItem(hItem); } hItem = m_wndFolderTree.m_wndContained.GetNextSiblingItem(hRootItem); while(hItem) { if(hItem != hPrevItem1 && hItem != hPrevItem2) FillComboItem(hItem, (bInsertAfter? -1: nIndex++), 1); else bInsertAfter = true; hItem = m_wndFolderTree.m_wndContained.GetNextSiblingItem(hItem); } for(int n = 0; n < m_wndCombo.GetCount(); n++) { if(m_wndCombo.GetItemData(n) == (DWORD_PTR)lpTV->itemNew.hItem) { m_wndCombo.SetCurSel(n); /*LPTVITEMDATA lptvid=(LPTVITEMDATA)lpTV->itemNew.lParam; TCHAR psz[MAX_PATH]; GetName(lptvid->spParentFolder, lptvid->lpi, SHGDN_FORPARSING, psz); if( StrChr(psz,_T('{')) ) //special case GetName(lptvid->spParentFolder, lptvid->lpi, SHGDN_NORMAL, psz); int nImage = 0; int nSelectedImage = 0; m_wndFolderTree.m_wndContained.GetItemImage(lpTV->itemNew.hItem,nImage,nSelectedImage); COMBOBOXEXITEM cbei; cbei.mask = CBEIF_TEXT | CBEIF_INDENT |CBEIF_IMAGE| CBEIF_SELECTEDIMAGE; cbei.iItem = -1; //Editbox of the comboboxex cbei.pszText = psz; cbei.cchTextMax = MAX_PATH; if(m_wndFolderTree.m_wndContained.ItemHasChildren(lpTV->itemNew.hItem)) { cbei.iImage = nImage; cbei.iSelectedImage = nImage; } else { cbei.iImage = nSelectedImage; cbei.iSelectedImage = nSelectedImage; } cbei.iIndent = 1; m_wndCombo.SetItem(&cbei);*/ break; } } return TRUE; } //--------------------------------------------------------------------------------------------------------- BOOL CMainFrame::FillComboItem(HTREEITEM hItem, int nIndex, int nIndent) { TVITEM tvi; LPTVITEMDATA lptvid = NULL; LPITEMIDLIST lpifq = NULL; HTREEITEM hParent = m_wndFolderTree.m_wndContained.GetParentItem(hItem); if(hParent) { tvi.hItem = hParent; tvi.mask = TVIF_PARAM; m_wndFolderTree.m_wndContained.GetItem(&tvi); lptvid = (LPTVITEMDATA)tvi.lParam; lpifq = lptvid->lpifq; } tvi.hItem = hItem; tvi.mask = TVIF_PARAM; m_wndFolderTree.m_wndContained.GetItem(&tvi); lptvid = (LPTVITEMDATA)tvi.lParam; CComPtr spFolder; TCHAR szBuff[256]; HRESULT hr = GetName(lptvid->spParentFolder,lptvid->lpi,SHGDN_FORADDRESSBAR,szBuff); if(FAILED(hr)) return hr; COMBOBOXEXITEM cbei; cbei.mask = CBEIF_TEXT | CBEIF_INDENT |CBEIF_IMAGE| CBEIF_SELECTEDIMAGE | CBEIF_LPARAM; cbei.pszText = szBuff; cbei.cchTextMax = MAX_PATH; LPITEMIDLIST lpifqThisItem = ConcatPidls(lpifq, lptvid->lpi); //Now, make a copy of the ITEMIDLIST GetNormalAndSelectedIcons(lpifqThisItem, &tvi); cbei.iItem = nIndex; cbei.iImage = tvi.iImage; cbei.iSelectedImage = tvi.iSelectedImage; cbei.iIndent = nIndent; cbei.lParam = (LPARAM)hItem; m_wndCombo.SendMessage(CBEM_INSERTITEM, 0, (LPARAM)&cbei); return TRUE; } //---------------------------------------------------------------------------------------------------------- BOOL CMainFrame::FillListView(LPTVITEMDATA lptvid, IShellFolder* pShellFolder, SHCONTF shFlag) { if(!pShellFolder) return E_POINTER; CComPtr spMalloc; HRESULT hr = SHGetMalloc(&spMalloc); if (FAILED(hr)) return FALSE; CComPtr spEnumIDList; hr=pShellFolder->EnumObjects(m_wndListView.GetParent(),shFlag, &spEnumIDList); if (FAILED(hr)) return FALSE; LPITEMIDLIST lpifqThisItem = NULL; LPITEMIDLIST lpi = NULL; LPLVITEMDATA lplvid; ULONG ulFetched =0; LV_ITEM lvi; int nCounter = 0; lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM; while (S_OK==spEnumIDList->Next(1, &lpi, &ulFetched)) { // Get some memory for the ITEMDATA structure. lplvid = (LPLVITEMDATA)spMalloc->Alloc(sizeof(LVITEMDATA)); if (!lplvid) { if (lpi && spMalloc) spMalloc->Free(lpi); if (lpifqThisItem && spMalloc) spMalloc->Free(lpifqThisItem); return FALSE; } ULONG ulAttrs=SFGAO_DISPLAYATTRMASK; hr = pShellFolder->GetAttributesOf(1, (const struct _ITEMIDLIST **)&lpi, &ulAttrs); if(FAILED(hr)) { if (lpi && spMalloc) spMalloc->Free(lpi); if (lpifqThisItem && spMalloc) spMalloc->Free(lpifqThisItem); return FALSE; } lplvid->ulAttribs = ulAttrs; lpifqThisItem = ConcatPidls(lptvid->lpifq, lpi); lvi.iItem = nCounter; lvi.iSubItem = 0; lvi.pszText = LPSTR_TEXTCALLBACK; lvi.cchTextMax = MAX_PATH; lvi.iImage = I_IMAGECALLBACK; lplvid->spParentFolder.p=pShellFolder; pShellFolder->AddRef(); // Now make a copy of the ITEMIDLIST. lplvid->lpi= CopyITEMID(spMalloc, lpi); lvi.lParam = (LPARAM)lplvid; // Add the item to the list view control. int n = m_wndListView.InsertItem(&lvi); m_wndListView.AddItem(n,1,LPSTR_TEXTCALLBACK,I_IMAGECALLBACK); m_wndListView.AddItem(n,2,LPSTR_TEXTCALLBACK,I_IMAGECALLBACK); m_wndListView.AddItem(n,3,LPSTR_TEXTCALLBACK,I_IMAGECALLBACK); m_wndListView.AddItem(n,4,LPSTR_TEXTCALLBACK,I_IMAGECALLBACK); nCounter++; spMalloc->Free(lpifqThisItem); lpifqThisItem=NULL; spMalloc->Free(lpi); lpi=NULL; } return TRUE; } //---------------------------------------------------------------------------------------------------- int CALLBACK CMainFrame::ListViewCompareProc(LPARAM lparam1, LPARAM lparam2,LPARAM lparamSort) { LPLVITEMDATA lplvid1=(LPLVITEMDATA)lparam1; LPLVITEMDATA lplvid2=(LPLVITEMDATA)lparam2; SortData* pData = (SortData*)lparamSort; if(!pData) return 0L; HRESULT hr = S_OK; if(pData->nSort == 0) { if(!pData->bReverseSort) { hr = lplvid1->spParentFolder->CompareIDs(0,lplvid1->lpi,lplvid2->lpi); if (FAILED(hr)) return 0; } else { hr = lplvid1->spParentFolder->CompareIDs(0,lplvid2->lpi,lplvid1->lpi); if (FAILED(hr)) return 0; } return (short)SCODE_CODE(GetScode(hr)); } TCHAR psz1[1024]; TCHAR psz2[1024]; hr = GetItemName(lplvid1,pData->nSort, psz1); if(FAILED(hr)) return hr; hr = GetItemName(lplvid2,pData->nSort, psz2); if(FAILED(hr)) return hr; if(!pData->bReverseSort) //$$Need to special case the date/size columns return lstrcmpi(psz1,psz2); else return lstrcmpi(psz2,psz1); return hr; } //------------------------------------------------------------------------------------------------------------------ HRESULT CMainFrame::GetItemName(LPLVITEMDATA lplvid, UINT nColumnID, LPTSTR psz) { if(!lplvid) return E_POINTER; CComPtr spFolder2; HRESULT hr = lplvid->spParentFolder->QueryInterface(IID_IShellFolder2,(void**)&spFolder2); if(FAILED(hr)) return hr; SHELLDETAILS sd; memset(&sd, 0, sizeof(SHELLDETAILS)); sd.fmt = LVCFMT_CENTER; sd.cxChar = 15; hr = spFolder2->GetDetailsOf(lplvid->lpi,nColumnID, &sd); if(FAILED(hr)) return hr; if(sd.str.uType == STRRET_WSTR) { USES_CONVERSION; lstrcpy(psz, OLE2T(sd.str.pOleStr)); } else if(sd.str.uType == STRRET_OFFSET) { lstrcpy(psz, (LPTSTR)lplvid->lpi+sd.str.uOffset); } else if(sd.str.uType == STRRET_CSTR) { lstrcpy(psz, sd.str.cStr); } return hr; } //----------------------------------------------------------------------------------------------------------------- HRESULT CMainFrame::FillTreeView(IShellFolder * pShellFolder,LPITEMIDLIST lpifq,HTREEITEM hParent) { if(!pShellFolder) return E_POINTER; CComPtr spMalloc; HRESULT hr=SHGetMalloc(&spMalloc); if (FAILED(hr)) return hr; CComPtr spIDList; hr= pShellFolder->EnumObjects( m_wndFolderTree.m_wndContained.GetParent(), SHCONTF_FOLDERS | SHCONTF_NONFOLDERS,&spIDList); if (FAILED(hr)) return hr; LPITEMIDLIST lpi=NULL, lpifqThisItem = NULL; LPTVITEMDATA lptvid = NULL; ULONG nCounter = 0; ULONG ulFetched = 0; HTREEITEM hPrev = NULL; // Hourglass on! CWaitCursor wait; while (S_OK==spIDList->Next(1,&lpi,&ulFetched)) { TV_ITEM tvi; TV_INSERTSTRUCT tvins; ULONG ulAttrs = SFGAO_HASSUBFOLDER | SFGAO_FOLDER; hr = pShellFolder->GetAttributesOf(1, (LPCITEMIDLIST*)&lpi, &ulAttrs); if( SUCCEEDED(hr) && ( ulAttrs & (SFGAO_HASSUBFOLDER | SFGAO_FOLDER) ) ) { nCounter++; if (ulAttrs & SFGAO_FOLDER) { tvi.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE |TVIF_PARAM; if (ulAttrs & SFGAO_HASSUBFOLDER) { tvi.cChildren=1; tvi.mask |= TVIF_CHILDREN; } lptvid = (LPTVITEMDATA)spMalloc->Alloc(sizeof(TVITEMDATA)); if (!lptvid) { if (lpi && spMalloc) spMalloc->Free(lpi); if (lpifqThisItem && spMalloc) spMalloc->Free(lpifqThisItem); return E_FAIL; } TCHAR szBuff[256]; if (!GetName(pShellFolder, lpi, SHGDN_NORMAL, szBuff)) { if (lpi && spMalloc) spMalloc->Free(lpi); if (lpifqThisItem && spMalloc) spMalloc->Free(lpifqThisItem); return E_FAIL; } tvi.pszText = szBuff; tvi.cchTextMax = MAX_PATH; lpifqThisItem=ConcatPidls(lpifq, lpi); lptvid->lpi=CopyITEMID(spMalloc, lpi); GetNormalAndSelectedIcons(lpifqThisItem, &tvi); lptvid->spParentFolder.p=pShellFolder; //Store the parent folders SF pShellFolder->AddRef(); lptvid->lpifq=ConcatPidls(lpifq, lpi); tvi.lParam = (LPARAM)lptvid; tvins.item = tvi; tvins.hInsertAfter = hPrev; tvins.hParent = hParent; // Add the item to the tree and combo hPrev = m_wndFolderTree.m_wndContained.InsertItem(&tvins); } spMalloc->Free(lpifqThisItem); lpifqThisItem=NULL; } spMalloc->Free(lpi); //Finally, free the pidl that the shell gave us... lpi=NULL; } if(!nCounter) { TVITEM tvi; tvi.hItem = hParent; tvi.cChildren = 0; tvi.mask = TVIF_CHILDREN; m_wndFolderTree.m_wndContained.SetItem(&tvi); } return hr; } //-------------------------------------------------------------------------------------- int CALLBACK CMainFrame::TreeViewCompareProc(LPARAM lparam1,LPARAM lparam2,LPARAM lparamSort) { LPTVITEMDATA lptvid1 =(LPTVITEMDATA)lparam1; if(!lptvid1 || !lptvid1->spParentFolder) return -1; LPTVITEMDATA lptvid2 =(LPTVITEMDATA)lparam2; if(!lptvid2 || !lptvid2->spParentFolder) return -1; HRESULT hr = lptvid1->spParentFolder->CompareIDs(0,lptvid1->lpi,lptvid2->lpi); if (FAILED(hr)) return 0; return (short)SCODE_CODE(GetScode(hr)); } //-------------------------------------------------------------------------------------------------------------------- HWND CMainFrame::CreateAnotherToolBarCtrl(HWND hWndParent, DWORD dwStyle, UINT nID) { RECT rc = { 50, 0, 300, 100 }; m_wndCombo.Create(hWndParent, rc, NULL, WS_CHILD | WS_VISIBLE | CBS_AUTOHSCROLL|CBS_DROPDOWNLIST|WS_VSCROLL | WS_TABSTOP); m_wndCombo.SetFont((HFONT)::GetStockObject(DEFAULT_GUI_FONT)); InitComboBox(); return m_wndCombo; } //---------------------------------------------------------------------------------------------------------------- LRESULT CMainFrame::OnCreate(UINT, WPARAM , LPARAM , BOOL& ) { // create command bar window RECT rcCmdBar = { 0, 0, 100, 100 }; HWND hWndCmdBar = m_wndCmdBar.Create(m_hWnd, rcCmdBar, NULL, ATL_SIMPLE_CMDBAR_PANE_STYLE); // atach menu m_wndCmdBar.AttachMenu(GetMenu()); // load command bar images m_wndCmdBar.LoadImages(IDR_MAINFRAME); // remove old menu SetMenu(NULL); HWND hWndToolBar = CreateSimpleToolBarCtrl(m_hWnd, IDR_MAINFRAME, FALSE, ATL_SIMPLE_TOOLBAR_PANE_STYLE); /**/ HWND hWndToolBar2 = CreateAnotherToolBarCtrl(m_hWnd, ATL_SIMPLE_TOOLBAR_PANE_STYLE); CreateSimpleReBar(ATL_SIMPLE_REBAR_NOBORDER_STYLE); AddSimpleReBarBand(hWndCmdBar); AddSimpleReBarBand(hWndToolBar, NULL, TRUE); /**/ AddSimpleReBarBand(hWndToolBar2, _T("Address"), TRUE); CreateSimpleStatusBar(); RECT rect = { 0, 0, 1, 1 }; m_hWndClient = m_wndSplitter.Create(m_hWnd, rect, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN); m_wndFolderTree.Create(m_wndSplitter, rect, NULL, WS_CHILD | WS_VISIBLE); m_nSort = 0; m_bReverseSort = false; m_wndListView.Create(m_wndSplitter, rect, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | LVS_SINGLESEL|LVS_REPORT | LVS_AUTOARRANGE | LVS_SHOWSELALWAYS | LVS_SHAREIMAGELISTS, WS_EX_CLIENTEDGE); //m_wndListView.SetExtendedListViewStyle(LVS_EX_TRACKSELECT | LVS_EX_ONECLICKACTIVATE | LVS_EX_UNDERLINEHOT); InitTreeView(); InitListView(); UpdateLayout(); m_wndSplitter.SetSplitterPanes(m_wndFolderTree, m_wndListView); GetClientRect(&rect); m_wndSplitter.SetSplitterPos((rect.right - rect.left) / 4); UIAddToolBar(hWndToolBar); UISetCheck(ID_VIEW_TOOLBAR, 1); UISetCheck(ID_VIEW_STATUS_BAR, 1); UISetCheck(ID_VIEW_DETAILS, 1); UISetCheck(ID_VIEW_SORT_NAME, 1); CMessageLoop* pLoop = _Module.GetMessageLoop(); pLoop->AddMessageFilter(this); pLoop->AddIdleHandler(this); return 0; } //---------------------------------------------------------------------------------------------------------------- LRESULT CMainFrame::OnViewChange(WORD, WORD wID, HWND, BOOL& ) { UISetCheck(ID_VIEW_ICONS, FALSE); UISetCheck(ID_VIEW_SMALL_ICONS, FALSE); UISetCheck(ID_VIEW_LIST, FALSE); UISetCheck(ID_VIEW_DETAILS, FALSE); UISetCheck(wID, TRUE); DWORD dwNewStyle = (int)wID - ID_VIEW_ICONS; m_wndListView.SetViewType(dwNewStyle); return 0; } //---------------------------------------------------------------------------------------------------------------- LRESULT CMainFrame::OnViewRefresh(WORD, WORD , HWND , BOOL& ) { ::MessageBox(0, _T("Left as a future enhancement"), _T("Not Implemented Yet"), MB_OK); return 0; } //---------------------------------------------------------------------------------------------------------------- LRESULT CMainFrame::OnViewSort(WORD, WORD wID, HWND, BOOL&) { UISetCheck(ID_VIEW_SORT_NAME, FALSE); UISetCheck(ID_VIEW_SORT_SIZE, FALSE); UISetCheck(ID_VIEW_SORT_TYPE, FALSE); UISetCheck(ID_VIEW_SORT_TIME, FALSE); UISetCheck(ID_VIEW_SORT_ATTR, FALSE); UISetCheck(wID, TRUE); m_bReverseSort = false; m_nSort = (int)wID - ID_VIEW_SORT_NAME; ATLASSERT(m_nSort >= 0 && m_nSort <= 4); SortData sd(m_nSort, m_bReverseSort); m_wndListView.SortItems(CMainFrame::ListViewCompareProc, (DWORD)&sd); return 0; } //---------------------------------------------------------------------------------------------------------------- LRESULT CMainFrame::OnTVSelChanged(int , LPNMHDR pnmh, BOOL& ) { LPNMTREEVIEW lpTV = (LPNMTREEVIEW)pnmh; LPTVITEMDATA lptvid=(LPTVITEMDATA)lpTV->itemNew.lParam; if (lptvid) { CComPtr spFolder; HRESULT hr=lptvid->spParentFolder->BindToObject(lptvid->lpi,0,IID_IShellFolder,(LPVOID *)&spFolder); if(FAILED(hr)) return hr; if(m_wndListView.GetItemCount() > 0) m_wndListView.DeleteAllItems(); if(!FillListView(lptvid,spFolder,SHCONTF_NONFOLDERS)) return 0L; if(!FillListView(lptvid,spFolder,SHCONTF_FOLDERS)) return 0L; if(!FillComboBox(lpTV,spFolder)) return 0L; } return 0L; } //---------------------------------------------------------------------------------------------------------------- LRESULT CMainFrame::OnTVItemExpanding(int , LPNMHDR pnmh, BOOL& ) { CWaitCursor wait; LPNMTREEVIEW pnmtv = (LPNMTREEVIEW)pnmh; if ((pnmtv->itemNew.state & TVIS_EXPANDEDONCE)) return 0L; LPTVITEMDATA lptvid=(LPTVITEMDATA)pnmtv->itemNew.lParam; CComPtr spFolder; HRESULT hr=lptvid->spParentFolder->BindToObject(lptvid->lpi,0,IID_IShellFolder,(LPVOID *)&spFolder); if(FAILED(hr)) return hr; FillTreeView(spFolder,lptvid->lpifq,pnmtv->itemNew.hItem); TV_SORTCB tvscb; tvscb.hParent = pnmtv->itemNew.hItem; tvscb.lpfnCompare = CMainFrame::TreeViewCompareProc; tvscb.lParam = 0; m_wndFolderTree.m_wndContained.SortChildrenCB(&tvscb); return 0L; } //---------------------------------------------------------------------------------------------------------------- LRESULT CMainFrame::OnTVDeleteItem(int , LPNMHDR pnmh, BOOL& ) { LPNMTREEVIEW pnmtv = (LPNMTREEVIEW)pnmh; CComPtr spMalloc; HRESULT hr=SHGetMalloc(&spMalloc); if (FAILED(hr)) return 0; LPTVITEMDATA lptvid = (LPTVITEMDATA)pnmtv->itemOld.lParam; lptvid->spParentFolder.Release(); lptvid->spParentFolder = 0; spMalloc->Free(lptvid->lpi); spMalloc->Free(lptvid->lpifq); spMalloc->Free(lptvid); return 0; } //---------------------------------------------------------------------------------------------------------------- LRESULT CMainFrame::OnLVGetDispInfo(int , LPNMHDR pnmh, BOOL& ) { NMLVDISPINFO* plvdi = (NMLVDISPINFO*)pnmh; if(!plvdi) return 0L; LPLVITEMDATA lplvid= (LPLVITEMDATA)plvdi->item.lParam; TV_ITEM tvi; HTREEITEM hti; hti = m_wndFolderTree.m_wndContained.GetSelectedItem(); tvi.mask = TVIF_PARAM; tvi.hItem = hti; m_wndFolderTree.m_wndContained.GetItem(&tvi); if(tvi.lParam<=0) return 0L; LPTVITEMDATA lptvid = (LPTVITEMDATA)tvi.lParam; if (!lptvid) return 0L; plvdi->item.iImage = GetIcon( ConcatPidls(lptvid->lpifq, lplvid->lpi), SHGFI_PIDL | SHGFI_SYSICONINDEX | SHGFI_SMALLICON); if (plvdi->item.iSubItem == 0 && (plvdi->item.mask & LVIF_TEXT) ) //File Name { GetName(lplvid->spParentFolder, lplvid->lpi, SHGDN_NORMAL, plvdi->item.pszText); return 0L; } else { CComPtr spFolder2; HRESULT hr = lptvid->spParentFolder->QueryInterface(IID_IShellFolder2,(void**)&spFolder2); if(FAILED(hr)) return hr; SHELLDETAILS sd; memset(&sd, 0, sizeof(SHELLDETAILS)); sd.fmt = LVCFMT_CENTER; sd.cxChar = 15; hr = spFolder2->GetDetailsOf(lplvid->lpi,plvdi->item.iSubItem, &sd); if(FAILED(hr)) return hr; if(sd.str.uType == STRRET_WSTR) { USES_CONVERSION; plvdi->item.pszText = OLE2T(sd.str.pOleStr); } else if(sd.str.uType == STRRET_OFFSET) { plvdi->item.pszText = (LPSTR)lptvid->lpi+sd.str.uOffset; } else if(sd.str.uType == STRRET_CSTR) { plvdi->item.pszText = (LPSTR)sd.str.cStr; } } return 0L; } //---------------------------------------------------------------------------------------------------------------- LRESULT CMainFrame::OnLVColumnClick(int, LPNMHDR pnmh, BOOL&) { LPNMLISTVIEW lpLV = (LPNMLISTVIEW)pnmh; if(m_nSort == lpLV->iSubItem) m_bReverseSort = !m_bReverseSort; else m_nSort = lpLV->iSubItem; ATLASSERT(m_nSort >= 0 && m_nSort <= 4); SortData sd(m_nSort, m_bReverseSort); m_wndListView.SortItems(CMainFrame::ListViewCompareProc, (DWORD)&sd); return 0; } //---------------------------------------------------------------------------------------------------------------- LRESULT CMainFrame::OnContextMenu(int , LPNMHDR pnmh, BOOL& ) { DWORD dwPos = ::GetMessagePos(); POINT pt = {LOWORD(dwPos), HIWORD(dwPos)}; //TreeView if(pnmh->hwndFrom == m_wndFolderTree.m_wndContained.m_hWnd) { TV_HITTESTINFO tvhti; TV_ITEM tvi; m_wndFolderTree.m_wndContained.ScreenToClient(&pt); tvhti.pt=pt; m_wndFolderTree.m_wndContained.HitTest(&tvhti); m_wndFolderTree.m_wndContained.SelectItem(tvhti.hItem); if (tvhti.flags & TVHT_ONITEMLABEL) { m_wndFolderTree.m_wndContained.ClientToScreen(&pt); tvi.mask=TVIF_PARAM; tvi.hItem=tvhti.hItem; if (!m_wndFolderTree.m_wndContained.GetItem(&tvi)) return 0; LPTVITEMDATA lptvid=(LPTVITEMDATA)tvi.lParam; if (lptvid) PopContextMenu(::GetParent(m_wndFolderTree.m_wndContained.m_hWnd),lptvid->spParentFolder, lptvid->lpi, &pt); } } //ListView else if(pnmh->hwndFrom == m_wndListView.m_hWnd) { LV_HITTESTINFO lvhti; LV_ITEM lvi; m_wndListView.ScreenToClient(&pt); lvhti.pt=pt; m_wndListView.HitTest(&lvhti); if (lvhti.flags & LVHT_ONITEMLABEL) { m_wndListView.ClientToScreen(&pt); lvi.mask=LVIF_PARAM; lvi.iItem=lvhti.iItem; if (!m_wndListView.GetItem(&lvi)) return 0; LPLVITEMDATA lptvid=(LPLVITEMDATA)lvi.lParam; if (lptvid) PopContextMenu(::GetParent(m_wndListView.m_hWnd),lptvid->spParentFolder, lptvid->lpi, &pt); } } return 0L; } //---------------------------------------------------------------------------------------------------------------- LRESULT CMainFrame::OnLVItemKeyDown(int , LPNMHDR pnmh, BOOL& bHandled) { LPNMLVKEYDOWN pkbd = (LPNMLVKEYDOWN)pnmh; if(pkbd->wVKey == VK_RETURN) { return OnLVItemClick(0, pnmh, bHandled); } return 0L; } //---------------------------------------------------------------------------------------------------------------- LRESULT CMainFrame::OnLVItemClick(int , LPNMHDR pnmh, BOOL& ) { if(pnmh->hwndFrom != m_wndListView.m_hWnd) return 0L; LV_ITEM lvi; lvi.mask = LVIF_PARAM; lvi.iItem = m_wndListView.GetSelectedIndex(); lvi.iSubItem = 0; if (!m_wndListView.GetItem(&lvi)) return 0; LPLVITEMDATA lplvid=(LPLVITEMDATA)lvi.lParam; if(!lplvid) return 0L; //else if (!(lplvid->ulAttribs & SFGAO_FOLDER)){ SHELLEXECUTEINFO sei = { sizeof(SHELLEXECUTEINFO), SEE_MASK_INVOKEIDLIST, // fMask ::GetParent(m_wndListView.m_hWnd), // hwnd of parent _T("Open"), // lpVerb NULL, // lpFile _T(""), _T(""), // lpDirectory SW_SHOWNORMAL, // nShow _Module.GetModuleInstance(), // hInstApp (LPVOID)NULL, // lpIDList...will set below NULL, // lpClass 0, // hkeyClass 0, // dwHotKey NULL // hIcon }; sei.lpIDList=GetFullyQualPidl(lplvid->spParentFolder, lplvid->lpi); ShellExecuteEx(&sei); return 0L; } //---------------------------------------------------------------------------------------------------------------- LRESULT CMainFrame::OnLVDeleteItem(int, LPNMHDR pnmh, BOOL&) { LPNMLISTVIEW pnmlv = (LPNMLISTVIEW)pnmh; CComPtr spMalloc ; HRESULT hr= SHGetMalloc(&spMalloc); if (FAILED(hr)) return 0; LV_ITEM lvi; lvi.mask = LVIF_PARAM; lvi.iItem = pnmlv->iItem; lvi.iSubItem = 0; if (!m_wndListView.GetItem(&lvi)) return 0; LPLVITEMDATA lplvid= (LPLVITEMDATA)lvi.lParam; lplvid->spParentFolder.Release(); lplvid->spParentFolder = 0; spMalloc->Free(lplvid->lpi); spMalloc->Free(lplvid); return 0; } //---------------------------------------------------------------------------------------------------------------- LRESULT CMainFrame::OnFileExit(WORD, WORD, HWND, BOOL&) { PostMessage(WM_CLOSE); return 0; } //---------------------------------------------------------------------------------------------------------------- LRESULT CMainFrame::OnFileNew(WORD, WORD, HWND, BOOL&) { CWaitCursor wait; ::PostThreadMessage(_Module.m_dwMainThreadID, WM_USER, 0, 0L); return 0; } //---------------------------------------------------------------------------------------------------------------- LRESULT CMainFrame::OnViewToolBar(WORD, WORD, HWND, BOOL&) { static BOOL bNew = TRUE; // initially visible bNew = !bNew; ::SendMessage(m_hWndToolBar, RB_SHOWBAND, 1, bNew); // toolbar is band #1 UISetCheck(ID_VIEW_TOOLBAR, bNew); UpdateLayout(); return 0; } //---------------------------------------------------------------------------------------------------------------- LRESULT CMainFrame::OnViewStatusBar(WORD, WORD, HWND, BOOL&) { BOOL bNew = !::IsWindowVisible(m_hWndStatusBar); ::ShowWindow(m_hWndStatusBar, bNew ? SW_SHOWNOACTIVATE : SW_HIDE); UISetCheck(ID_VIEW_STATUS_BAR, bNew); UpdateLayout(); return 0; } //---------------------------------------------------------------------------------------------------------------- LRESULT CMainFrame::OnAppAbout(WORD, WORD, HWND, BOOL&) { ::ShellAbout( m_hWnd, _T("WTL Explorer"), _T("WTL Rules!"), ::LoadIcon(_Module.GetResourceInstance(), MAKEINTRESOURCE(IDR_MAINFRAME)) ); return 0; } //Private methods // // //-------------------------------------------------------------------------------------- int CMainFrame::GetIcon(LPITEMIDLIST lpi, UINT uFlags) { SHFILEINFO sfi; memset(&sfi, 0, sizeof(SHFILEINFO)); SHGetFileInfo((LPCSTR)lpi, 0, &sfi, sizeof(SHFILEINFO), uFlags); return sfi.iIcon; } //-------------------------------------------------------------------------------------- void CMainFrame::GetNormalAndSelectedIcons(LPITEMIDLIST lpifq,LPTV_ITEM lptvitem) { lptvitem->iImage = GetIcon(lpifq, SHGFI_PIDL | SHGFI_SYSICONINDEX | SHGFI_SMALLICON); lptvitem->iSelectedImage = GetIcon(lpifq, SHGFI_PIDL | SHGFI_SYSICONINDEX | SHGFI_SMALLICON | SHGFI_OPENICON); return; } //-------------------------------------------------------------------------------------- LPITEMIDLIST CMainFrame::ConcatPidls(LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2) { LPITEMIDLIST pidlNew; UINT cb1 = 0; UINT cb2 = 0; if (pidl1) //May be NULL cb1 = GetSize(pidl1) - sizeof(pidl1->mkid.cb); else cb1 = 0; cb2 = GetSize(pidl2); pidlNew = InitializeItems(cb1 + cb2); if (pidlNew) { if (pidl1) memcpy(pidlNew, pidl1, cb1); memcpy(((LPSTR)pidlNew) + cb1, pidl2, cb2); } return pidlNew; } //-------------------------------------------------------------------------------------- BOOL CMainFrame::GetName (LPSHELLFOLDER lpsf, LPITEMIDLIST lpi, DWORD dwFlags, LPSTR lpFriendlyName) { BOOL bSuccess=TRUE; STRRET str; if (NOERROR==lpsf->GetDisplayNameOf(lpi,dwFlags, &str)) { switch (str.uType) { case STRRET_WSTR: { WideCharToMultiByte( CP_ACP, // code page 0, // dwFlags str.pOleStr, // lpWideCharStr -1, // cchWideCharStr lpFriendlyName, // lpMultiByteStr lstrlenW(str.pOleStr) + sizeof(WCHAR), // cchMultiByte NULL, // lpDefaultChar NULL); // lpUsedDefaultChar } break; case STRRET_OFFSET: lstrcpy(lpFriendlyName, (LPSTR)lpi+str.uOffset); break; case STRRET_CSTR: lstrcpy(lpFriendlyName, (LPSTR)str.cStr); break; default: bSuccess = FALSE; break; } } else bSuccess = FALSE; return bSuccess; } //-------------------------------------------------------------------------------------- LPITEMIDLIST CMainFrame::InitializeItems(UINT cbSize) { CComPtr spMalloc; LPITEMIDLIST pidl=0; HRESULT hr=SHGetMalloc(&spMalloc); if (FAILED(hr)) return 0; pidl=(LPITEMIDLIST)spMalloc->Alloc(cbSize); if (pidl) memset(pidl, 0, cbSize); // zero-init for external task alloc return pidl; } //-------------------------------------------------------------------------------------- LPITEMIDLIST CMainFrame::Next(LPCITEMIDLIST pidl) { LPSTR lpMem=(LPSTR)pidl; lpMem+=pidl->mkid.cb; return (LPITEMIDLIST)lpMem; } //-------------------------------------------------------------------------------------- UINT CMainFrame::GetSize(LPCITEMIDLIST pidl) { UINT cbTotal = 0; if (pidl) { cbTotal += sizeof(pidl->mkid.cb); // Null terminator while (pidl->mkid.cb) { cbTotal += pidl->mkid.cb; pidl = Next(pidl); } } return cbTotal; } //-------------------------------------------------------------------------------------- LPITEMIDLIST CMainFrame::CopyITEMID(IMalloc* lpMalloc, LPITEMIDLIST lpi) { LPITEMIDLIST lpiTemp = 0; lpiTemp=(LPITEMIDLIST)lpMalloc->Alloc(lpi->mkid.cb+sizeof(lpi->mkid.cb)); CopyMemory((PVOID)lpiTemp, (CONST VOID *)lpi, lpi->mkid.cb+sizeof(lpi->mkid.cb)); return lpiTemp; } //---------------------------------------------------------------------------------------------------------- LPITEMIDLIST CMainFrame::GetFullyQualPidl(LPSHELLFOLDER lpsf, LPITEMIDLIST lpi) { TCHAR szBuff[MAX_PATH]; OLECHAR szOleChar[MAX_PATH]; CComPtr spDeskTop; LPITEMIDLIST lpifq; ULONG ulEaten, ulAttribs; HRESULT hr; if (!GetName(lpsf, lpi, SHGDN_FORPARSING, szBuff)) return NULL; hr=SHGetDesktopFolder(&spDeskTop); if (FAILED(hr)) return NULL; MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szBuff, -1, (USHORT *)szOleChar, sizeof(szOleChar)); hr=spDeskTop->ParseDisplayName(NULL, NULL, szOleChar, &ulEaten, &lpifq, &ulAttribs); if (FAILED(hr)) return NULL; return lpifq; } //---------------------------------------------------------------------------------------------------- BOOL CMainFrame::PopContextMenu(HWND hwnd, LPSHELLFOLDER lpsfParent,LPITEMIDLIST lpi, LPPOINT lppt) { CComPtr spContextMenu; CMINVOKECOMMANDINFO cmi; DWORD dwAttribs=0; int idCmd = 0; HMENU hMenu = NULL; HRESULT hr=lpsfParent->GetUIObjectOf(hwnd,1, (const struct _ITEMIDLIST **)&lpi,IID_IContextMenu, 0,(LPVOID *)&spContextMenu); if(FAILED(hr)) return FALSE; hMenu = CreatePopupMenu(); if(!hMenu) return FALSE; // Get the context menu for the item. hr=spContextMenu->QueryContextMenu(hMenu, 0, 1, 0x7fff, CMF_EXPLORE); if(FAILED(hr)) return FALSE; idCmd=TrackPopupMenu(hMenu, TPM_LEFTALIGN | TPM_RETURNCMD | TPM_RIGHTBUTTON, lppt->x, lppt->y, 0, hwnd, NULL); if (idCmd) { // Execute the command that was selected. cmi.cbSize = sizeof(CMINVOKECOMMANDINFO); cmi.fMask = 0; cmi.hwnd = hwnd; cmi.lpVerb = MAKEINTRESOURCE(idCmd-1); cmi.lpParameters = NULL; cmi.lpDirectory = NULL; cmi.nShow = SW_SHOWNORMAL; cmi.dwHotKey = 0; cmi.hIcon = NULL; hr= spContextMenu->InvokeCommand(&cmi); } DestroyMenu(hMenu); return TRUE; } //----------------------------------------------------------------------------------------------------------------- LRESULT CMainFrame::OnComboChange(WORD, WORD, HWND, BOOL& ) { COMBOBOXEXITEM cbei; cbei.mask = CBEIF_LPARAM; cbei.iItem = m_wndCombo.GetCurSel() ; m_wndCombo.GetItem(&cbei); HTREEITEM hItem = (HTREEITEM)cbei.lParam; m_wndFolderTree.m_wndContained.SelectItem(hItem); return 0L; } //-----------------------------------------------------------------------------------------------------------------