📄 tabtreectrl.cpp
字号:
// TabTreeCtrl.cpp : implementation file
//
#include "stdafx.h"
#include "BeeReader.h"
#include "TabTreeCtrl.h"
#include "MainFrm.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CTabTreeCtrl
CTabTreeCtrl::CTabTreeCtrl()
{
pGroupData = NULL;
pManager = NULL;
uTimer = 0;
}
CTabTreeCtrl::~CTabTreeCtrl()
{
}
BEGIN_MESSAGE_MAP(CTabTreeCtrl, CXTTreeCtrl)
//{{AFX_MSG_MAP(CTabTreeCtrl)
ON_WM_CREATE()
ON_NOTIFY_REFLECT(TVN_SELCHANGED, OnSelchanged)
ON_NOTIFY_REFLECT(TVN_ENDLABELEDIT, OnEndlabeledit)
ON_NOTIFY_REFLECT(TVN_BEGINLABELEDIT,OnBeginlabeledit)
ON_WM_TIMER()
ON_WM_RBUTTONDOWN()
//}}AFX_MSG_MAP
ON_MESSAGE( WM_UPDATE_CHANNEL,OnUpdateChannel)
ON_MESSAGE( WM_UPDATE_ITEMCOUNT,OnUpdateItemCount)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CTabTreeCtrl message handlers
BOOL CTabTreeCtrl::PreCreateWindow(CREATESTRUCT& cs)
{
if ( !CXTTreeCtrl::PreCreateWindow( cs ) )
return FALSE;
// Set the style for the tree control.
cs.style |= TVS_HASBUTTONS|TVS_HASLINES|TVS_EDITLABELS|TVS_SHOWSELALWAYS;
// If non-xp mode, add a client edge border to the tree.
if (!xtAfxData.bXPMode)
{
cs.dwExStyle |= WS_EX_CLIENTEDGE;
}
// TODO: Add your specialized code here and/or call the base class
return TRUE;
}
int CTabTreeCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CXTTreeCtrl::OnCreate(lpCreateStruct) == -1)
return -1;
// Create the image list used by the tree control.
if ( !m_imageList.Create( 16, 16, ILC_COLOR24 | ILC_MASK, 1, 1 ) )
{
TRACE0("Failed to create image list.\n");
return -1;
}
// load the tree images bitmap and add it to the image list.
m_bitmap.LoadBitmap( IDB_LIST_VIEW_ALL );
m_imageList.Add( &m_bitmap, RGB( 0x00,0xff,0x00 ) );
// Set the image list for the tree control.
SetImageList( &m_imageList, TVSIL_NORMAL );
CBeeReaderApp* pApp = (CBeeReaderApp*)AfxGetApp();
ASSERT(pApp);
uTimer = SetTimer(1, 500, 0);
pGroupData = pApp->GetNewsGroup();
// Add the parent item
CString szItem;
szItem = pGroupData->GetRootNode()->szNodeName;
HTREEITEM htItem = InsertItem( szItem );
SetItemData( htItem,(DWORD)pGroupData->GetRootNode() );
SetItemState( htItem, TVIS_BOLD, TVIS_BOLD );
InitGroup( pGroupData->GetRootNode()->pFirstChild,htItem);
Expand( htItem, TVE_EXPAND );
m_coolMenu.HookWindow(m_hWnd);
return 0;
}
void CTabTreeCtrl::InitGroup(PGROUPNODE pNode,HTREEITEM hParentItem)
{
PGROUPNODE pg = NULL;
HTREEITEM htItem;
if( !pNode ) return;
if( pNode->dwData == 0 )
htItem = InsertItem( pNode->szNodeName,2,2,hParentItem);
else
{
htItem = InsertItem( pNode->szNodeName,1,1,hParentItem);
PCHANNELDATA pData = (PCHANNELDATA)pNode->dwData;
pData->htItem = htItem;
}
SetItemData(htItem,(DWORD)pNode);
if( pNode->pFirstChild )
{
InitGroup( pNode->pFirstChild,htItem);
}
if( pNode->pNextSibling != pNode->pParentNode->pFirstChild )
InitGroup( pNode->pNextSibling,hParentItem);
}
void CTabTreeCtrl::InsertGroup(PGROUPNODE pParentNode, PGROUPNODE pNode)
{
if( !pParentNode || !pNode ) return;
HTREEITEM htItem;
htItem = FindItem(GetRootItem(),(DWORD)pParentNode);
if( htItem )
{
htItem = InsertItem( pNode->szNodeName,2,2,htItem);
SetItemData( htItem,(DWORD)pNode);
Expand( GetParentItem(htItem), TVE_EXPAND );
pGroupData->Save();
}
UpdateWindow();
}
void CTabTreeCtrl::InsertChannel(PGROUPNODE pParentNode, PGROUPNODE pNode)
{
if( !pParentNode || !pNode ) return;
HTREEITEM htItem;
htItem = FindItem(GetRootItem(),(DWORD)pParentNode);
if( htItem )
{
PCHANNELDATA pData = (PCHANNELDATA)pNode->dwData;
CRSSChannel* pChannel = pData->pChannel;
ASSERT(pChannel);
htItem = InsertItem( pChannel->GetTitle() ,1,1,htItem);
pData->htItem = htItem;
SetItemData( htItem,(DWORD)pNode);
SendMessage(WM_UPDATE_ITEMCOUNT,0,(LPARAM)pChannel);
Expand( GetParentItem(htItem), TVE_EXPAND );
pGroupData->Save();
}
}
HTREEITEM CTabTreeCtrl::FindItem(HTREEITEM htParent, DWORD dwData)
{
if( htParent == NULL ) return NULL;
if( GetItemData( htParent ) == dwData ) return htParent;
if( ItemHasChildren(htParent) )
{
HTREEITEM hItem = GetChildItem(htParent);
HTREEITEM hItem1 = FindItem( hItem,dwData );
if( hItem1 == NULL )
{
while (hItem != NULL)
{
hItem = GetNextSiblingItem(hItem);
hItem1 = FindItem( hItem,dwData );
if( hItem1 ) return hItem1;
}
}
else return hItem1;
}
return NULL;
}
void CTabTreeCtrl::OnSelchanged(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
// TODO: Add your control notification handler code here
HTREEITEM hOldItem = pNMTreeView->itemOld.hItem;
AfxGetMainWnd()->SendMessage( WM_NEWSTREEITEMCHANGE,(WPARAM)hOldItem,0 );
*pResult = 0;
}
LRESULT CTabTreeCtrl::OnUpdateChannel(WPARAM wParam, LPARAM lParam)
{
CRSSChannel* pChannel = (CRSSChannel*)lParam;
if( !pChannel ) return 0;
HTREEITEM htItem = FindItem(pChannel);
if( htItem )
{
PGROUPNODE pNode = (PGROUPNODE)GetItemData( htItem );
PCHANNELDATA pData = (PCHANNELDATA)pNode->dwData;
if( wParam == 1 ) //开始更新。
pData->iUpdateing = 4;
else if( wParam == 2 )//结束更新。
{
SetItemImage( htItem,1,1);
pData->iUpdateing = 0;
}
else if( wParam == 0 ) //更新出错。
{
SetItemImage( htItem,3,3);
pData->iUpdateing = -3;
}
}
return 1;
}
HTREEITEM CTabTreeCtrl::FindItem(CRSSChannel *pChannel)
{
if( !pChannel ) return NULL;
PGROUPNODE pNode;
PCHANNELDATA pData;
pNode = pGroupData->GetRootNode()->pNextSibling;
while( pNode )
{
pData = (PCHANNELDATA)pNode->dwData;
if( pData )
{
if( pData->pChannel == pChannel )
return pData->htItem;
}
pNode = pNode->pNextNode;
}
return NULL;
}
void CTabTreeCtrl::OnTimer(UINT nIDEvent)
{
PGROUPNODE pNode = pGroupData->GetRootNode()->pNextSibling;
PCHANNELDATA pData;
while(pNode)
{
pData = (PCHANNELDATA)pNode->dwData;
if( pData )
{
if(pData->iUpdateing > 3 )
{
Expand( GetParentItem(pData->htItem),TVE_EXPAND);
SetItemImage( pData->htItem,pData->iUpdateing,pData->iUpdateing);
if( pData->iUpdateing >= 7 ) pData->iUpdateing = 4;
else pData->iUpdateing ++;
}
}
pNode = pNode->pNextNode;
}
CXTTreeCtrl::OnTimer(nIDEvent);
}
void CTabTreeCtrl::OnRButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
HTREEITEM hItem = GetSelectedItem();
if( hItem != NULL )
{
CXTMenu menu;
VERIFY(menu.LoadMenu(IDR_MENU_POPUP_TREE));
CXTMenu* pPopup = menu.GetSubMenu(0);
ASSERT(pPopup != NULL);
::SetMenuDefaultItem(pPopup->m_hMenu, IDM_CHANNEL_UPDATE, FALSE);
if( hItem == GetRootItem() )
{
menu.EnableMenuItem( IDM_REMOVE_CHANNEL,MF_BYCOMMAND|MF_GRAYED );
menu.EnableMenuItem( IDM_REMOVE_GROUP,MF_BYCOMMAND|MF_GRAYED );
menu.EnableMenuItem( IDM_RENAME,MF_BYCOMMAND|MF_GRAYED );
menu.EnableMenuItem( IDM_CHANNEL_PROP,MF_BYCOMMAND|MF_GRAYED );
menu.EnableMenuItem( IDM_TREE_VIEWRSSFEED,MF_BYCOMMAND|MF_GRAYED );
menu.EnableMenuItem( IDM_CHANNEL_UPDATE,MF_BYCOMMAND|MF_GRAYED );
}
else
{
PGROUPNODE pNode = (PGROUPNODE)GetItemData(hItem);
ASSERT(pNode);
if( pNode->dwData == 0 )
{
menu.EnableMenuItem( IDM_CHANNEL_PROP,MF_BYCOMMAND|MF_GRAYED );
menu.EnableMenuItem( IDM_TREE_VIEWRSSFEED,MF_BYCOMMAND|MF_GRAYED );
menu.EnableMenuItem( IDM_CHANNEL_UPDATE,MF_BYCOMMAND|MF_GRAYED );
}
else
{
menu.EnableMenuItem( IDM_CHANNEL_UPDATEALL,MF_BYCOMMAND|MF_GRAYED );
}
}
ClientToScreen(&point);
pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON,
point.x, point.y, this);
return;
}
CXTTreeCtrl::OnRButtonDown(nFlags, point);
}
BOOL CTabTreeCtrl::OnCommand(WPARAM wParam, LPARAM lParam)
{
// TODO: Add your specialized code here and/or call the base class
if( HIWORD(wParam) == 0 && LOWORD(wParam) > 0 )
{
CMainFrame* pMainWnd = (CMainFrame*)AfxGetMainWnd();
pMainWnd->SendMessage(WM_COMMAND,wParam,lParam);
}
return CXTTreeCtrl::OnCommand(wParam, lParam);
}
void CTabTreeCtrl::OnEndlabeledit(NMHDR* pNMHDR, LRESULT* pResult)
{
TV_DISPINFO* pTVDispInfo = (TV_DISPINFO*)pNMHDR;
// TODO: Add your control notification handler code here
TVITEM tvItem = pTVDispInfo->item;
PGROUPNODE pNode;
pNode = (PGROUPNODE)GetItemData( tvItem.hItem );
if( tvItem.pszText )
{
CString szText = (LPCTSTR)tvItem.pszText;
if( szText == _T("") )
{
*pResult = 0;
}
else
{
pGroupData->ReName(pNode, tvItem.pszText );
*pResult = 1;
}
if( pNode->dwData != 0 )
{
PCHANNELDATA pData = (PCHANNELDATA)pNode->dwData;
PostMessage(WM_UPDATE_ITEMCOUNT,0,(LPARAM)pData->pChannel);
}
}
else
*pResult = 0;
}
void CTabTreeCtrl::OnBeginlabeledit(NMHDR* pNMHDR, LRESULT* pResult)
{
TV_DISPINFO* pTVDispInfo = (TV_DISPINFO*)pNMHDR;
// TODO: Add your control notification handler code here
TVITEM tvItem = pTVDispInfo->item;
PGROUPNODE pNode;
pNode = (PGROUPNODE)GetItemData( tvItem.hItem );
if( pNode->dwData != 0 )
{
GetEditControl()->SetWindowText(pNode->szNodeName);
}
}
LRESULT CTabTreeCtrl::OnUpdateItemCount(WPARAM wParam, LPARAM lParam)
{
CRSSChannel* pChannel = (CRSSChannel*)lParam;
if( !pChannel ) return 0;
HTREEITEM htItem = FindItem(pChannel);
if( htItem )
{
PGROUPNODE pNode = (PGROUPNODE)GetItemData( htItem );
PCHANNELDATA pData = (PCHANNELDATA)pNode->dwData;
CString szViewTitle;
szViewTitle.Format( _T(" (%d/%d)"),pChannel->GetReadedItems(),pChannel->GetItemCount());
szViewTitle = pNode->szNodeName +szViewTitle;
SetItemText( htItem,szViewTitle );
if( pChannel->GetReadedItems() < pChannel->GetItemCount() )
SetItemState( htItem, TVIS_BOLD, TVIS_BOLD );
else
SetItemState( htItem, 0,TVIS_BOLD );
}
return 1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -