ttreeview.cpp

来自「mpq文件的格式就是一种压缩格式」· C++ 代码 · 共 315 行

CPP
315
字号
/*****************************************************************************/
/* TTreeView.cpp                          Copyright (c) Ladislav Zezula 2003 */
/*---------------------------------------------------------------------------*/
/* Implementation of the TTreeView class                                     */
/*---------------------------------------------------------------------------*/
/*   Date    Ver   Who  Comment                                              */
/* --------  ----  ---  -------                                              */
/* 03.04.03  1.00  Lad  The first version of TTreeView.cpp                   */
/*****************************************************************************/

#include "stdafx.h"
#include "TMainFrm.h"
#include "TTreeView.h"
#include "TListView.h"

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

//-----------------------------------------------------------------------------
// TTreeView

IMPLEMENT_DYNCREATE(TTreeView, CTreeView);

BEGIN_MESSAGE_MAP(TTreeView, CTreeView)
	//{{AFX_MSG_MAP(TTreeView)
	ON_NOTIFY_REFLECT(TVN_DELETEITEM, OnDeleteItem)
	ON_NOTIFY_REFLECT(TVN_SELCHANGED, OnSelChanged)
	ON_WM_CREATE()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

//-----------------------------------------------------------------------------
// TTreeView construction/destruction

TTreeView::TTreeView()
{
    // Create the image list
    m_pIml = new CImageList();           // Create the image list
    m_pIml->Create(16, 16, ILC_MASK | ILC_COLOR32, 4, 4);  // Initialize the image list
}

TTreeView::~TTreeView()
{
    if(m_pIml != NULL)
        delete m_pIml;
}

BOOL TTreeView::PreCreateWindow(CREATESTRUCT& cs)
{
    cs.style |= (TVS_HASLINES | TVS_LINESATROOT | TVS_HASBUTTONS);
	return CTreeView::PreCreateWindow(cs);
}

int TTreeView::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
    CTreeCtrl & TreeCtrl = GetTreeCtrl();
    HINSTANCE hModule = AfxGetResourceHandle();
    UINT nIDIcons[] = {IDR_MAINFRAME, IDI_FOLDER, IDI_OPENFOLDER, 0};

    if (CTreeView::OnCreate(lpCreateStruct) == -1)
		return -1;
	
    // Remember the window handle
    m_hTreeView = TreeCtrl.m_hWnd;

    // Initialize our image list
    for(int i = 0; nIDIcons[i] != 0; i++)
    {
        HICON hIcon = LoadIcon(hModule, MAKEINTRESOURCE(nIDIcons[i]));
        m_pIml->Add(hIcon);
    }
    GetTreeCtrl().SetImageList(m_pIml, TVSIL_NORMAL);
	return 0;
}

//-----------------------------------------------------------------------------
// Public functions

void TTreeView::SetLinkPointers(TMainFrame * pMainFrame, TListView * pListView)
{
    m_pMainFrame = pMainFrame;
    m_pListView  = pListView;
}


HTREEITEM TTreeView::GetRootTreeItem(CPtrList ** ppFileList)
{
    HTREEITEM hRootItem = TreeView_GetRoot(m_hTreeView);
    CPtrList * pFileList = NULL;
    TVITEM    tvitem;

    if(hRootItem != NULL)
    {
        tvitem.mask  = TVIF_HANDLE | TVIF_PARAM;
        tvitem.hItem = hRootItem;
        TreeView_GetItem(m_hTreeView, &tvitem);
        pFileList = (CPtrList *)tvitem.lParam;
    }

    if(ppFileList != NULL)
        *ppFileList = pFileList;
    return hRootItem;
}


HTREEITEM TTreeView::InsertTreeItem(HTREEITEM hParent, const char * szText, CPtrList ** ppFileList)
{
    TVINSERTSTRUCT tvInsert;
    CPtrList * pFileList = new CPtrList(50);
    HTREEITEM hItem;

    // Initialize structure for tree item
    ZeroMemory(&tvInsert, sizeof(TVINSERTSTRUCT));
    tvInsert.hParent = hParent;
    tvInsert.hInsertAfter = TVI_LAST;
    tvInsert.hInsertAfter = NULL;
    tvInsert.item.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_TEXT | TVIF_PARAM;
    tvInsert.item.pszText = (char *)szText;
    tvInsert.item.iImage         = (hParent == NULL) ? 0 : 1;
    tvInsert.item.iSelectedImage = (hParent == NULL) ? 0 : 2;
    tvInsert.item.lParam  = (LPARAM)pFileList;
    hItem = TreeView_InsertItem(m_hTreeView, &tvInsert);

    if(ppFileList != NULL)
        *ppFileList = pFileList;
    return hItem;
}


HTREEITEM TTreeView::FindTreeItem(HTREEITEM hRootItem, const char * szFindText, CPtrList ** ppFileList)
{
    HTREEITEM hChildItem;
    TV_ITEM item;
    char szText[MAX_PATH];

    // Get root tree item, if necessary
    if(ppFileList != NULL)
        *ppFileList = NULL;
    if(hRootItem == NULL)
    {
        if((hRootItem = TreeView_GetRoot(m_hTreeView)) == NULL)
            return NULL;
    }

    // Prepare the tree view item
    ZeroMemory(&item, sizeof(TV_ITEM));
    item.mask  = TVIF_HANDLE | TVIF_TEXT | TVIF_PARAM;
    item.pszText = szText;
    item.cchTextMax = sizeof(szText);

    // If the item has no children, do nothing
    hChildItem = TreeView_GetNextItem(m_hTreeView, hRootItem, TVGN_CHILD);
    while(hChildItem != NULL)
    {
        item.hItem = hChildItem;
        TreeView_GetItem(m_hTreeView, &item);

        // If the text agress, return the item
        if(!stricmp(szText, szFindText))
        {
            if(ppFileList != NULL)
                *ppFileList = (CPtrList *)item.lParam;
            break;
        }
        
        // Move to the next child item
        hChildItem = TreeView_GetNextItem(m_hTreeView, hChildItem, TVGN_NEXT);
    } 

    return hChildItem;
}

// Retrieves the tree item lParam and text (if szText != NULL).
CPtrList * TTreeView::GetItemData(HTREEITEM hItem, char * szText, int nMaxChars)
{
    CPtrList * pFileList = NULL;
    TV_ITEM tvitem;
    
    ZeroMemory(&tvitem, sizeof(TV_ITEM));
    tvitem.hItem   = hItem;
    tvitem.mask    = TVIF_HANDLE | TVIF_PARAM;
    if(szText != NULL)
    {
        tvitem.mask |= TVIF_TEXT;
        tvitem.pszText = szText;
        tvitem.cchTextMax = nMaxChars - 1;
    }

    // Retrieve the item and get the file list
    if(TreeView_GetItem(m_hTreeView, &tvitem))
        pFileList = (CPtrList *)tvitem.lParam;

    return pFileList;
}

// Removes all deleted items from the tree view.
void TTreeView::FreeRemovedFiles(HTREEITEM hItem)
{
    HTREEITEM hNextItem;
    HTREEITEM hSubItem = TreeView_GetChild(m_hTreeView, hItem);
    TFileInfo * pInfo;
    CPtrList * pFileList;

    // Walk through all subitems
    while(hSubItem != NULL)
    {
        DWORD dwFiles = 0;

        // Walk through all subitems
        FreeRemovedFiles(hSubItem);

        // Free the deleted files for the entry
        if((pFileList = GetItemData(hSubItem)) != NULL)
        {
            POSITION pos = pFileList->GetHeadPosition();

            while(pos != NULL)
            {
                POSITION savePos = pos;

                pInfo = (TFileInfo *)pFileList->GetNext(pos);
                if(pInfo->bDeleted)
                {
                    delete pInfo;
                    pFileList->RemoveAt(savePos);
                }
                else
                    dwFiles++;
            }
        }

        // If no items left, remove the tree item itself
        hNextItem = TreeView_GetNextSibling(m_hTreeView, hSubItem);
        if(dwFiles == 0)
            TreeView_DeleteItem(m_hTreeView, hSubItem);
        hSubItem = hNextItem;
    }
}

// Returns the current "folder" within the MPQ archive.
// If not root directory, the returned folder contains
// also the ending backslash
CPtrList * TTreeView::GetCurrentMpqDir(char * szDir)
{
    CPtrList * pFileList = NULL;
    HTREEITEM hRoot = TreeView_GetRoot(m_hTreeView);
    HTREEITEM hItem = TreeView_GetSelection(m_hTreeView);
    char szPath[MAX_PATH] = "";
    char szTemp[MAX_PATH];

    pFileList = GetItemData(hItem);
    while(hItem != hRoot)
    {
        strcpy(szTemp, szPath);
        GetItemData(hItem, szPath, sizeof(szPath));
        strcat(szPath, "\\");
        strcat(szPath, szTemp);

        hItem = TreeView_GetNextItem(m_hTreeView, hItem, TVGN_PARENT);
    }

    strcpy(szDir, szPath);
    return pFileList;
}

//-----------------------------------------------------------------------------
// Protected functions


void TTreeView::DestroyItem(TV_ITEM & item)
{
    // Free the information about the structure
    if(item.mask & TVIF_PARAM)
    {
        CPtrList * pPtrList = (CPtrList *)item.lParam;
        
        if(pPtrList != NULL)
        {
            POSITION pos = pPtrList->GetHeadPosition();

            while(pos != NULL)
            {
                TFileInfo * pFileInfo = (TFileInfo *)pPtrList->GetNext(pos);
                delete pFileInfo;
            }
            delete pPtrList;
        }
    }
}

//-----------------------------------------------------------------------------
// TTreeView message handlers

void TTreeView::OnDeleteItem(NMHDR* pNMHDR, LRESULT* pResult) 
{
	NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;

    DestroyItem(pNMTreeView->itemOld);
	*pResult = 0;
}

void TTreeView::OnSelChanged(NMHDR* pNMHDR, LRESULT* pResult) 
{
	NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
	
    // Force list view to reload the items
    if(m_pListView != NULL)
        m_pListView->LoadListView(pNMTreeView->itemNew.hItem);
	*pResult = 0;
}

⌨️ 快捷键说明

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