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

📄 booktreeview.cpp

📁 个人电子图书管理系统.提供电子书的书名和其他信息.检查电子书信息的合法性(E-1) .为这本电子书生成 id.使用分类id
💻 CPP
字号:
// GUI/BookTreeView.cpp : 实现文件
//

#include "stdafx.h"
#include "KingBook.h"
#include "BookTreeView.h"
#include "KingBookDoc.h"
using namespace Library;
using namespace std;


// CBookTreeView

IMPLEMENT_DYNCREATE(CBookTreeView, CTreeView)

CBookTreeView::CBookTreeView()
{

}

CBookTreeView::~CBookTreeView()
{
}

BEGIN_MESSAGE_MAP(CBookTreeView, CTreeView)
    ON_WM_CREATE()
    ON_NOTIFY_REFLECT(NM_RCLICK, &CBookTreeView::OnNMRclick)
    ON_NOTIFY_REFLECT(NM_CLICK, &CBookTreeView::OnNMClick)
    ON_NOTIFY_REFLECT(TVN_SELCHANGED, &CBookTreeView::OnTvnSelchanged)
END_MESSAGE_MAP()


// CBookTreeView 诊断

#ifdef _DEBUG
void CBookTreeView::AssertValid() const
{
	CTreeView::AssertValid();
}

#ifndef _WIN32_WCE
void CBookTreeView::Dump(CDumpContext& dc) const
{
	CTreeView::Dump(dc);
}
#endif
#endif //_DEBUG


// CBookTreeView 消息处理程序


/// <summary>创建窗口, 创建树状视图, 并添加几个根节点</summary>
/// <param name="lpCreateStruct">创建树状视图的样式</param>
/// <returns>成功返回 0.</returns>
/// <exception>NULL</exception>
/// <remarks>
///  修改视图的样式; 添加根节点:"我的电子书", "收藏夹", "最近浏览", "所有图书"
/// </remarks>
int CBookTreeView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    lpCreateStruct->style = lpCreateStruct->style | TVS_HASBUTTONS | TVS_LINESATROOT | TVS_LINESATROOT |TVS_HASLINES |TVS_NOHSCROLL  ;// |TVS_CHECKBOXES ;

    if (CTreeView::OnCreate(lpCreateStruct) == -1)
        return -1;

    CTreeCtrl* pTreeCtrl = &(this->GetTreeCtrl());

    TVINSERTSTRUCT  rootItem; 
    HTREEITEM       root; // 我的电子书节点
    rootItem.hInsertAfter = TVI_LAST;
    rootItem.hParent      = NULL;
    rootItem.item.mask    = TVIF_TEXT|TVIF_PARAM;

    rootItem.item.pszText = _T("我的电子书");
    bookClassID.push_back(IDS_BOOKCLASS_ROOT);
    rootItem.item.lParam  =  (LPARAM)bookClassID.size() - 1;
    root = pTreeCtrl->InsertItem(&rootItem);

    rootItem.item.pszText = _T("收藏夹");
    bookClassID.push_back(IDS_FAVORITE);
    rootItem.item.lParam  =  (LPARAM)bookClassID.size() - 1;
    pTreeCtrl->InsertItem(&rootItem);

    rootItem.item.pszText = _T("最近浏览");
    bookClassID.push_back(IDS_RECENT);
    rootItem.item.lParam  =  (LPARAM)bookClassID.size() - 1;
    pTreeCtrl->InsertItem(&rootItem);

    rootItem.item.pszText = _T("所有图书");
    bookClassID.push_back(IDS_ALL_BOOK);
    rootItem.item.lParam  =  (LPARAM)bookClassID.size() - 1;
    pTreeCtrl->InsertItem(&rootItem);

    //HTREEITEM bokClass = pTreeCtrl->InsertItem(_T("我的电子书")); 
    //HTREEITEM favo = pTreeCtrl->InsertItem(_T("收藏夹"));
    //HTREEITEM rece = pTreeCtrl->InsertItem(_T("最近浏览"));
    //HTREEITEM allBook = pTreeCtrl->InsertItem(_T("所有图书"));
return 0;
    TVINSERTSTRUCT  tvInsert; 
    std::vector<BookClass> roots;
    ((CKingBookDoc*)this->GetDocument())->bookLib.GetRootBookClass(roots);
    for(int i = 0; i < roots.size(); i ++)
    {
        tvInsert.hInsertAfter = TVI_LAST;
        tvInsert.hParent      = root;
        tvInsert.item.mask    = TVIF_TEXT|TVIF_PARAM;
//        MessageBox(roots[i].GetName().c_str());
        tvInsert.item.pszText = const_cast<LPSTR>(roots[i].GetName().c_str());
        
        // 将这个图书分类的ID保存到 结尾
        bookClassID.push_back(roots[i].GetID());
        tvInsert.item.lParam  = (LPARAM)bookClassID.size() - 1;//
        pTreeCtrl->InsertItem(&tvInsert);
//        MessageBox((LPTSTR)tvInsert.item.lParam);
       
    }

    return 0;
}


/// <summary>在视图里右击, 并视情况弹出菜单.</summary>
/// <param>忽略</param>
/// <returns>void</returns>
/// <exception>NULL</exception>
/// <remarks>
///  <b>步骤:</b>
///  <list type="number">
///  <item><description>得到鼠标位置, 并判断鼠标是否击中视图中的一个节点</description></item>
///  <item><description>选中鼠标击中的这个节点</description></item>
///  <item><description>得到选中节点对应的图书分类的ID</description></item>
///  <item><description>如果:分类是"收藏夹", "最近浏览", "所有图书", 没有操作</description></item>
///  <item><description>如果选中的是某个图书分类, 创建菜单.</description></item>
///  </list>
/// </remarks>
void CBookTreeView::OnNMRclick(NMHDR *pNMHDR, LRESULT *pResult)
{
    // TODO: 在树上右击
    CTreeCtrl* pTreeCtrl = &(this->GetTreeCtrl());
    CPoint pt;
    GetCursorPos(&pt);
    ScreenToClient(&pt); 
    HTREEITEM hitItem = pTreeCtrl->HitTest(pt);
    if(hitItem == NULL)
    {
        *pResult = 0;
        return ;
    }
    pTreeCtrl->Select(hitItem, TVGN_CARET);
    HTREEITEM sel =  pTreeCtrl->GetSelectedItem();
    int idIndex = (int)pTreeCtrl->GetItemData(sel);
    std::string clsID = this->bookClassID[idIndex];
    if(clsID == IDS_ALL_BOOK)
    {
    }
    else if( clsID == IDS_FAVORITE)
    {
    }
    else if( clsID == IDS_RECENT)
    {
    }
    else    // 击中普通的图书分类
    {
        // 弹出菜单
        CMenu mHitItem;
        mHitItem.LoadMenu(IDR_TV_HIT_ITEM);
        CMenu *subMenu;
        subMenu = mHitItem.GetSubMenu(0);
        ClientToScreen(&pt); 
        subMenu->TrackPopupMenu(0, pt.x, pt.y, this);
    }
    *pResult = 0;
}

BOOL CBookTreeView::PreCreateWindow(CREATESTRUCT& cs)
{    
    return CTreeView::PreCreateWindow(cs);
}


/// <summary>鼠标左键点击事件</summary>
/// <param>忽略</param>
/// <returns>void</returns>
/// <exception>NULL</exception>
/// <remarks>如果鼠标击中了一个节点(图书分类), 更新这个节点
/// </remarks>
void CBookTreeView::OnNMClick(NMHDR *pNMHDR, LRESULT *pResult)
{
    CTreeCtrl* pTreeCtrl = &(this->GetTreeCtrl());
    CPoint pt;
    GetCursorPos(&pt);
    ScreenToClient(&pt); 
    HTREEITEM hitItem = pTreeCtrl->HitTest(pt);
    //this->MessageBox(_T("鼠标左键"), _T("Tree View"));
    if(hitItem != NULL)  // 点在某个分支上, 判断是否有子节点, 是否需要加载
    {
        pTreeCtrl->Select(hitItem, TVGN_CARET);
        HTREEITEM selItem =  pTreeCtrl->GetSelectedItem();

        //更新树节点--图书分类,的子分类和包含的图书
        this->UpdateBookClassItem(selItem);
        
    }

    *pResult = 0;
}


/// <summary>更新树节点--图书分类,的子分类和包含的图书</summary>
/// <param name="bookClassItem">树状视图的节点, 应当是一个图书分类</param>
/// <returns>成功返回true, 失败返回false</returns>
/// <exception>调用的函数可能抛出异常</exception>
/// <remarks>加载这个分类的子分类, 加载包含的图书 , -- 如果存在的话</remarks>
bool CBookTreeView::UpdateBookClassItem(HTREEITEM bookClassItem)
{
    CTreeCtrl* pTreeCtrl = &(this->GetTreeCtrl());
    CKingBookDoc* pDoc = (CKingBookDoc*)this->GetDocument();
    // 得到选中节点图书分类的ID
    int idIndex = (int)pTreeCtrl->GetItemData(bookClassItem);
    // TODO:是"所有图书"节点?
    if(this->bookClassID[idIndex] == IDS_ALL_BOOK)
    {
        //return true;
    }
    else if(pTreeCtrl->GetChildItem(bookClassItem) == NULL)// 其他节点
    {  
        // 判断是否存在子节点
        // 没有子节点,加载
        std::vector<BookClass> subClass;
        pDoc->bookLib.GetSubsOfClass(BookObject(this->bookClassID[idIndex]), subClass);
        TVINSERTSTRUCT  tvInsert; 
        for(int i = 0; i < subClass.size(); i ++)
        {
            tvInsert.hInsertAfter = TVI_LAST;
            tvInsert.hParent      = bookClassItem;
            tvInsert.item.mask    = TVIF_TEXT|TVIF_PARAM;
            tvInsert.item.pszText = const_cast<LPSTR>(subClass[i].GetName().c_str());

            // 将这个图书分类的ID保存到 结尾
            bookClassID.push_back(subClass[i].GetID());
            tvInsert.item.lParam  = (LPARAM)bookClassID.size() - 1;//
            pTreeCtrl->InsertItem(&tvInsert);

        }
    }

    // TODO:  加载包含的图书, 通过Doc类通知ListView
    pDoc->SetShownBookClass( this->bookClassID[idIndex]);
    // 更新视图
    pDoc->UpdateAllViews(this, IDUP_TREEVIEW);
    return true;
}


/// <summary>视图中选定项发生了改变</summary>
/// <param>忽略</param>
/// <returns>void</returns>
/// <exception>NULL</exception>
/// <remarks>更新选定项的信息
/// </remarks>
void CBookTreeView::OnTvnSelchanged(NMHDR *pNMHDR, LRESULT *pResult)
{
    LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);

    CTreeCtrl* pTreeCtrl = &(this->GetTreeCtrl());
    selItem =  pTreeCtrl->GetSelectedItem();
    this->UpdateBookClassItem(selItem);
    *pResult = 0;
}


/// <summary>更新视图</summary>
/// <param name="lHint">[IN]更新原因代码</param>
/// <returns>void</returns>
/// <exception>NULL</exception>
/// <remarks>lHint 为IDUP_DOC_BOOKCLASS_ADD, IDUP_DOC_BOOKCLASS_EDIT, IDUP_DOC_BOOKCLASS_DEL 更新视图.<br/>
///  
/// </remarks>
void CBookTreeView::OnUpdate(CView* /*pSender*/, LPARAM lHint, CObject* /*pHint*/)
{
    CTreeCtrl* pTreeCtrl = &(this->GetTreeCtrl());
    CKingBookDoc* pDoc = (CKingBookDoc*)this->GetDocument();
    if(lHint == IDUP_DOC_BOOKCLASS_ADD)  // 刚才添加了分类
    {
        // 添加子节点
        Library::BookClass subClass;
        pDoc->bookLib.GetBookClassInfo(Library::BookObject(pDoc->GetShownBookClass()), subClass);
        TVINSERTSTRUCT  tvInsert; 
        tvInsert.hInsertAfter = TVI_LAST;
        tvInsert.hParent      = this->selItem;  // 添加到刚才选定的节点
        tvInsert.item.mask    = TVIF_TEXT|TVIF_PARAM;
        tvInsert.item.pszText = const_cast<LPSTR>(subClass.GetName().c_str());

        // 将这个图书分类的ID保存到 结尾
        bookClassID.push_back(subClass.GetID());
        tvInsert.item.lParam  = (LPARAM)bookClassID.size() - 1;//
        HTREEITEM newItem = pTreeCtrl->InsertItem(&tvInsert);

        // 展开selItem
        pTreeCtrl->Expand(selItem, TVE_TOGGLE);
        // 选中这个新的节点
        pTreeCtrl->Select(newItem, TVGN_CARET);

        return ;
    }
    else if(lHint == IDUP_DOC_BOOKCLASS_EDIT)// 刚才编辑了分类的信息
    {
        Library::BookClass bookClassInfo;
        pDoc->bookLib.GetBookClassInfo(Library::BookObject(pDoc->GetShownBookClass()), bookClassInfo);
        pTreeCtrl->SetItemText(this->selItem, bookClassInfo.GetName().c_str());
    }
    else if(lHint == IDUP_DOC_BOOKCLASS_DEL) // 刚才删除了分类
    {
        HTREEITEM parent = pTreeCtrl->GetParentItem(this->selItem);
        pTreeCtrl->DeleteItem(this->selItem);

        // 选中父节点, 没有父亲?天之骄子?
        pTreeCtrl->Select(parent, TVGN_CARET);
    }

}

⌨️ 快捷键说明

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