⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 filetreectrl.cpp

📁 版本更新了一下
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/*
Module : FileTreeCtrl.cpp
Purpose: Implementation for an MFC class which provides a tree control similiar 
         to the left hand side of explorer
Created: PJN / 25-12-1999
History: PJN / 11-01-2000 1. Added some asserts to HasGotSubEntries
                          2. Fixed a problem with calling OnDblclk when no tree item is selected
                          3. Removed an unused variable from SetSelectedPath
         PJN / 25-01-2000 1. Minor update to the code in CTreeFileCtrl::OnDblclk to only allow 
                          selected items to be opened.
         PJN / 31-01-2000 1. Fixed a problem when you right mouse click over a non - selected item.
                          The control now implements the same behavior as Explorer for this.
                          2. Removed check for keyboard invocation of the context menu in OnContextMenu
                          3. Now displays the context menu over the selected item when invoked via
                          the keyboard. Again this is the same bahavior as Explorer has.
                          4. Optimized the code in PreTranslateMessage
                          5. Fixed a bug in CTreeFileCtrl::OnEndlabeledit
         PJN / 02-04-2000 1. Fixed a small bug in CTreeFileCtrl::SetRootFolder
                          2. Fixed the problem with initialisation errors in the code. Client code must not 
                          explicitly call PopulateTree when the window is created. When used in a dialog
                          resource this is not necessary as it is called for you in the DDX functions.
         PJN / 13-05-2000 1. Fixed a problem where items on the context menu were being invoked for the 
                          wrong item when you right mouse click over an item that is not the selected item.
                          Behaviour now is that the item is selected prior to showing the context menu. 
                          Now, this is same behaviour as Explorer.
         PJN / 12-07-2000 1. Now uses ON_NOTIFY_REFLECT_EX instead of ON_NOTIFY_REFLECT for handling reflected
                          messages. This allows derived classes to handle these messages also. Thanks to 
                          Christian Dahl for this.
                          2. Sample app now allows drag drop behaviour to be toggled
                          3. Fixed a problem whereby two items were left selected after you did a drap /
                          drop operation. Thanks to Jonathon Ralston for this.
                          4. Removed function declaration for unused function "InsertDriveItem".
                          5. Removed an unreferenced variable in InsertFileItem.
                          6. Tidied up the UpOneLevel functions and made it public.
                          7. Removed all the message handlers in the sample code which reflect straight
                          down to the tree control. Instead the OnCmdMsg first routes the message to this
                          class.
                          8. Renamed all menu items which CTreeFileCtrl uses to include the prefix TREEFILECTRL
                          9. Renamed all the methods to more generic names
                          10. PreTranslateMessage now uses PostMessage instead of calling functions directly. 
                          This allows up to function correctly for derived classes in addition to correctly
                          disabling items through the OnUpdate mechanism
                          11. Removed an unreferrenced variable in OnRclick
                          12. Removed the unreferrenced variable m_hSelItem
                          13. Optimized a number of expressions by putting the boolean comparisons first
                          14. m_bAllowRename parameter is now observed for in place editing of an item
                          15. Now supports hiding of Drive types via the SetDriveHideFlags function. See the 
                          menu options on the Tools menu in the sample program for its usage.
                          16. Filename masks can now be specifed via the SetFileNameMask method. See the 
                          menu options on the Tools menu in the sample program for its usage.
                          17. File types can now be specified via the GetFileHideFlags function. See the 
                          menu options on the Tools menu in the sample program for its usage.
                          18. Fixed a small issue in one of my calls to ::GetKeyState
                          19. Fixed a bug where programs was crashing if an icon index for it could not
                          be found.
                          20. Made many of the methods of CTreeFileCtrl virtual, thus allowable better
                          use in end user derived classes.
                          21. Fixed problem where SetSelectedPath(_T("C:\\"), FALSE) was resulting 
                          in the drive being expanded even through FALSE was being sent in to specify
                          that the item should not be expanded.
                          22. A virtual "CanDisplayFile" has been added to allow you to decide at runtime
                          whether or not a certain file is to be displayed.
                          23. A virtual "CanDisplayFolder" has been added to allow you to decide at
                          runtime whether or not a certain folder is to be displayed
                          24. Now optionally displays compressed files in a different color, similiar to
                          explorer. The color is customizable through the class API.
                          25. Code has been made smarter so that it does not have to spin up the floppy
                          disk to determine if there are files on it. It now initially displays a "+"
                          and only when you try to expand it will it do the actual scan.
         PJN / 23-07-2000 1. Fixed a bug where the expansion state of the selected item was not being
                          preserved across refreshes.
                          2. Now includes full support for Next / Prev support similiar to Windows 
                          Explorer with the Desktop Update.
                          3. Updated sample app to have some useful toolbars.
                          4. Changing any tree settings which can affect its appearance now force
                          a refresh of its contents.
                          5. ItemToPath method has been made const.
                          6. Addition of PathToItem method
                          7. Auto refresh of items is now provided for by means of change notification
                          threads. This is configurable via the SetAutoRefresh method.
                          8. The root folder of the tree control can now be changed from the sample app
                          9. Fixed a bug in SetRootFolder when passed an empty folder
                          10. Fixed a bug where the system image list was not being initialized correctly
                          if the user did not have a "C:\\" drive. This could occur on NT/Windows2000
                          11. Fixed a bug in IsFile and IsFolder which was causing invalid files or folders
                          to appear valid.
                          12. Deleted items are now removed upon expansion. Also if the item being expanded was
                          deleted and it was the only child, then its parent has the "-" expansion button removed
                          13. Removable drive nodes are collapsed back to their root nodes if their media is 
                          changed in the intervening time when a node expansion occurs.
                          14. Wait cursor is now displayed while a refresh is taking place.
                          15. A "OnSelectionChanged" virtual function has now been provided
                          16. Sample app's icon has been made the same as Explorers.
                          17. Sample app now displays the path name of the currently selected item in the tree control.
                          18. Fixed a bug in IsCompressed
                          19. items are now deleted when selected if they do not exist.
         PJN / 05-09-2000 1. Fixed a bug in CTreeFileCtrl::IsFile and CTreeFileCtrl::IsFolder
         PJN / 20-09-2000 1. Control now includes DECLARE_DYNCREATE thereby allowing it to be used
                          in code which requires this such as Stingray's SEC3DTabWnd. Thanks to Petter Nilsen for
                          pointing out this omission
         PJN / 02-10-2000 1. Fixed a stack overwrite problem in CSystemImageList::CSystemImageList
                          2. Removed an unreferrenced variable in CTreeFileCtrl::OnSelChanged
                          3. Removed an unreferrenced variable in CTreeFileCtrl::OnItemExpanding
                          4. Changed the SendMessage in CTreeFileCtrl::OnDblClk to prevent a crash 
                          which was occurring when the open call sometimes caused a refresh call 
                          which changed the tree items at times. When the double click message handler
                          continued it then caused item expand notifications for items already deleted
                          and of course crashes.
                          5. Removed an unreferrenced variable in CTreeFileCtrl::EndDragging
                          6. Removed an unreferrenced variable in CTreeFileCtrl::KillNotificationThread
                          7. Sample app now remembers the selected path and its expansion state across
                          invocations.
         PJN / 05-05-2001 1. Updated copright message.
                          2. Fixed a resource leak where icon resources were not being released. Thanks to Jay Kohler for
                          spotting this problem
         PJN / 05-08-2001 1. You can now optionally display Network Neighborhood
                          2. You can now turn on / off display of file extensions.
                          3. You can now display shared items with a different icon
                          4. Friendly names can now be displayed for drives.
         PJN / 11-08-2001 1. Improved checking to see if action is allowed in Rename and Delete
                          2. Fixed a bug in OnBeginLabelEdit
                          3. Fixed a problem in OnEndLabelEdit which was causing renames to fail when filename extensions 
                          were not being shown.
         PJN / 11-08-2001 1. Fixed a bug in OnSelChanged which was causing a crash when you right click on an empty area of the control.
                          Thanks to Eli Fenton for spotting this one.
                          2. The control now by default shows drives as children of "My Computer" just like in Explorer.
                          3. When you display a rooted directory in the control, you now have the option of displaying the root
                          folder in the control as the root item.  Thanks to Eli Fenton for suggesting this.
         PJN / 26-10-2001 1. Fixed some stability problems with the code. This was due to adding items to the system image list.
                          This is normally a very bad thing. Instead now the code uses TreeView custom draw (just like the blue color
                          for compresed items) to draw the icons for the Network Neighborhood items. Thanks to Darken Screamer and
                          Timo Haberkern for spotting this problem.
         PJN / 24-12-2001 1. Fixed a copy and paste bug in GoForward. Thanks to Michael T. Luongo for this fix.
                          2. Now allows encrypted files to be displayed in a different color
                          3. Fixed memory leak which was occuring when control was being used in a dialog
                          4. Fixed a problem with the calculation of idents when the style "TVS_LINESATROOT" is used.
         PJN / 16-02-2002 1. Updated copyright message
                          2. Fixed a drag/drop problem which caused the tree state to be inconsistent after the file was dropped.
                          3. Fixed a bug in the refresh code which was causing it to not reselect the selected node
                          after the refresh occurs. Thanks to John No雔 for this fix.
                          4. Fixed a problem where the custom draw icons for network nodes were not being drawn in the correct
                          positions when scrollbars were present in the control. Again thanks to John No雔 for this fix.
                          5. Fixed a bug in SetSelectedPath which would not display the correct selection if the node we 
                          want to select has been deleted due to the node becoming deleted when it was previously collapsed.
                          Thanks to Franz Fackelmann and John No雔 for spotting this problem.
         PJN / 05-06-2002 1. Implemented function "SetUsingDifferentColorForEncrypted" which was declared but had no
                          implementation.
                          2. Fixed report of uninitialized member variable "m_nTimerID". Thanks to Emil Isberg for spoting this.
         PJN / 07-08-2002 1. Fixed a bug in the sample app which ships with the class which was occuring when you compiled
                          the code in Visual Studio.Net. This was due to MS changing the location oleimpl2.h header file. Thanks
                          to Darren Schroeder for spotting this problem.
         PJN / 22-09-2002 1. Removed a number of unreferrenced variables from the code, as highlighted by Visual Studio.Net. Thanks
                          to Bill Johnson for spotting this.




Copyright (c) 1999 - 2002 by PJ Naughter.  (Web: www.naughter.com, Email: pjna@naughter.com)

All rights reserved.

Copyright / Usage Details:

You are allowed to include the source code in any product (commercial, shareware, freeware or otherwise) 
when your product is released in binary form. You are allowed to modify the source code in any way you want 
except you cannot modify the copyright details at the top of each module. If you want to distribute source 
code with your application, then you are only allowed to distribute versions released by the author. This is 
to maintain a single distribution point for the source code. 

*/

/////////////////////////////////  Includes  //////////////////////////////////
#include "stdafx.h"
#include "resource.h"
#include "FileTreeCtrl.h"
#include <afxpriv.h>
#include "SortedArray.h"




//////////////////////////////// Defines / Locals /////////////////////////////

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

#define WM_TREEUPDATE_CHANGE WM_USER

//To avoid having to have the latest Platform SDK installed to compile CTreeFileCtrl
#ifndef FILE_ATTRIBUTE_ENCRYPTED
#define FILE_ATTRIBUTE_ENCRYPTED            0x00004000  
#endif

int CSystemImageList::sm_nRefCount = 0; //Initialise the reference count
CSystemImageList theSystemImageList;    //The one and only system image list instance
CShareEnumerator theSharedEnumerator;   //The one and only share enumerator

//Pull in the WNet Lib automatically
#pragma comment(lib, "mpr.lib")



////////////////////////////// Implementation /////////////////////////////////

CTreeFileCtrlItemInfo::CTreeFileCtrlItemInfo()
{
  m_pNetResource = NULL;
  m_bNetworkNode = FALSE;
  m_bExtensionHidden = FALSE;
}

CTreeFileCtrlItemInfo::CTreeFileCtrlItemInfo(const CTreeFileCtrlItemInfo& ItemInfo)
{
  m_sFQPath       = ItemInfo.m_sFQPath;
  m_sRelativePath = ItemInfo.m_sRelativePath;
  m_bNetworkNode  = ItemInfo.m_bNetworkNode;
  m_pNetResource = new NETRESOURCE;
  if (ItemInfo.m_pNetResource)
  {
    //Copy the direct member variables of NETRESOURCE
    CopyMemory(m_pNetResource, ItemInfo.m_pNetResource, sizeof(NETRESOURCE)); 

    //Duplicate the strings which are stored in NETRESOURCE as pointers
    if (ItemInfo.m_pNetResource->lpLocalName)
		  m_pNetResource->lpLocalName	= _tcsdup(ItemInfo.m_pNetResource->lpLocalName);
    if (ItemInfo.m_pNetResource->lpRemoteName)
		  m_pNetResource->lpRemoteName = _tcsdup(ItemInfo.m_pNetResource->lpRemoteName);
    if (ItemInfo.m_pNetResource->lpComment)
		  m_pNetResource->lpComment	= _tcsdup(ItemInfo.m_pNetResource->lpComment);
    if (ItemInfo.m_pNetResource->lpProvider)
		  m_pNetResource->lpProvider	= _tcsdup(ItemInfo.m_pNetResource->lpProvider);
  }
  else
    ZeroMemory(m_pNetResource, sizeof(NETRESOURCE)); 
}

CTreeFileCtrlItemInfo::~CTreeFileCtrlItemInfo()
{
}


CSystemImageList::CSystemImageList()
{
  ASSERT(sm_nRefCount == 0); //Should only every be one instance of CSystemImageList declared
  ++sm_nRefCount;

  //Get the temp directory. This is used to then bring back the system image list
  TCHAR pszTempDir[_MAX_PATH];
  VERIFY(GetTempPath(_MAX_PATH, pszTempDir));
  TCHAR pszDrive[_MAX_DRIVE + 1];
  _tsplitpath(pszTempDir, pszDrive, NULL, NULL, NULL);
  int nLen = _tcslen(pszDrive);
  if (pszDrive[nLen-1] != _T('\\'))
    _tcscat(pszDrive, _T("\\"));

  //Attach to the system image list
  SHFILEINFO sfi;
  HIMAGELIST hSystemImageList = (HIMAGELIST) SHGetFileInfo(pszTempDir, 0, &sfi, sizeof(SHFILEINFO),
                                                           SHGFI_SYSICONINDEX | SHGFI_SMALLICON);
  VERIFY(m_ImageList.Attach(hSystemImageList));
}

CSystemImageList::~CSystemImageList()
{
  //Decrement the reference count
  --sm_nRefCount;

  //Detach from the image list to prevent problems on 95/98 where
  //the system image list is shared across processes
  m_ImageList.Detach();
}

CShareEnumerator::CShareEnumerator()
{
  //Set out member variables to defaults
  m_pNTShareEnum = NULL;
  m_pWin9xShareEnum = NULL;
  m_pNTBufferFree = NULL;
  m_pNTShareInfo = NULL;
  m_pWin9xShareInfo = NULL;
  m_pWin9xShareInfo = NULL;
  m_hNetApi = NULL;
  m_dwShares = 0;

  //Determine if we are running Windows NT or Win9x
  OSVERSIONINFO osvi;
  osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  m_bWinNT = (GetVersionEx(&osvi) && osvi.dwPlatformId == VER_PLATFORM_WIN32_NT);
  if (m_bWinNT)
  {
    //Load up the NETAPI dll
    m_hNetApi = LoadLibrary(_T("NETAPI32.dll"));
    if (m_hNetApi)
    {
      //Get the required function pointers
      m_pNTShareEnum = (NT_NETSHAREENUM*) GetProcAddress(m_hNetApi, "NetShareEnum");
      m_pNTBufferFree = (NT_NETAPIBUFFERFREE*) GetProcAddress(m_hNetApi, "NetApiBufferFree");
    }
  }
  else
  {
    //Load up the NETAPI dll
    m_hNetApi = LoadLibrary(_T("SVRAPI.dll"));
    if (m_hNetApi)
    {
      //Get the required function pointer
      m_pWin9xShareEnum = (WIN9X_NETSHAREENUM*) GetProcAddress(m_hNetApi, "NetShareEnum");
    }
  }

  //Update the array of shares we know about
  Refresh();
}

CShareEnumerator::~CShareEnumerator()
{
  if (m_bWinNT)
  {
    //Free the buffer if valid
    if (m_pNTShareInfo)
      m_pNTBufferFree(m_pNTShareInfo);
  }
  else
    //Free up the heap memory we have used
		delete [] m_pWin9xShareInfo;      

  //Free the dll now that we are finished with it
  if (m_hNetApi)
  {
    FreeLibrary(m_hNetApi);
    m_hNetApi = NULL;
  }
}

void CShareEnumerator::Refresh()
{
  m_dwShares = 0;
  if (m_bWinNT)
  {
    //Free the buffer if valid
    if (m_pNTShareInfo)
      m_pNTBufferFree(m_pNTShareInfo);

    //Call the function to enumerate the shares
    if (m_pNTShareEnum)
    {
      DWORD dwEntriesRead = 0;
      m_pNTShareEnum(NULL, 502, (LPBYTE*) &m_pNTShareInfo, MAX_PREFERRED_LENGTH, &dwEntriesRead, &m_dwShares, NULL);
    }
  }
  else
  {
    //Free the buffer if valid
    if (m_pWin9xShareInfo)
      delete [] m_pWin9xShareInfo;

    //Call the function to enumerate the shares
    if (m_pWin9xShareEnum)
    {
      //Start with a reasonably sized buffer
      unsigned short cbBuffer = 1024;
      BOOL bNeedMoreMemory = TRUE;
      BOOL bSuccess = FALSE;
      while (bNeedMoreMemory && !bSuccess)
      {
        unsigned short nTotalRead = 0;
        m_pWin9xShareInfo = (CTreeFile_share_info_50*) new BYTE[cbBuffer];
        ZeroMemory(m_pWin9xShareInfo, cbBuffer);
        unsigned short nShares = 0;
        NET_API_STATUS nStatus = m_pWin9xShareEnum(NULL, 50, (char FAR *)m_pWin9xShareInfo, cbBuffer, (unsigned short FAR *)&nShares, (unsigned short FAR *)&nTotalRead);
        if (nStatus == ERROR_MORE_DATA)
		    {            
          //Free up the heap memory we have used
		      delete [] m_pWin9xShareInfo;      

          //And double the size, ready for the next loop around
          cbBuffer *= 2;
		    }
        else if (nStatus == NERR_Success)
        {
          m_dwShares = nShares;
          bSuccess = TRUE;
        }
        else
          bNeedMoreMemory = FALSE;
      }
    }
  }
}

BOOL CShareEnumerator::IsShared(const CString& sPath)
{
  //Assume the item is not shared
  BOOL bShared = FALSE;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -