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

📄 listview.cpp

📁 visual c++ 实例编程
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*
	JumpToIt - PC Magazine password utility

	Copyright (c) 1999 Ziff-Davis Publishing Company.  All rights reserved.
	First published in PC Magazine, US Edition.

	Written by Steven E. Sipe


	This file implements the link list view.
*/

#include "stdafx.h"

#include <intshcut.h>

#include "jumptoit.h"

#include "mainfrm.h"
#include "Doc.h"
#include "ListView.h"
#include "propdlg.h"

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

/////////////////////////////////////////////////////////////////////////////
// CJTIListView

IMPLEMENT_DYNCREATE(CJTIListView, CListView)

BEGIN_MESSAGE_MAP(CJTIListView, CListView)
	//{{AFX_MSG_MAP(CJTIListView)
	ON_WM_DESTROY()
	ON_COMMAND(ID_ADD_ITEM, OnAddItem)
	ON_COMMAND(ID_DELETE_ITEM, OnDeleteItem)
	ON_COMMAND(ID_ITEM_PROPERTIES, OnItemProperties)
	ON_UPDATE_COMMAND_UI(ID_ADD_ITEM, OnUpdateAddItem)
	ON_UPDATE_COMMAND_UI(ID_DELETE_ITEM, OnUpdateDeleteItem)
	ON_UPDATE_COMMAND_UI(ID_ITEM_PROPERTIES, OnUpdateItemProperties)
	ON_NOTIFY_REFLECT(NM_DBLCLK, OnDblClk)
	ON_NOTIFY_REFLECT(NM_RCLICK, OnRclick)
	ON_COMMAND(ID_OPEN_ITEM, OnOpenItem)
	ON_UPDATE_COMMAND_UI(ID_OPEN_ITEM, OnUpdateOpenItem)
	ON_COMMAND(ID_EDIT_COPY, OnEditCopy)
	ON_UPDATE_COMMAND_UI(ID_EDIT_COPY, OnUpdateEditCopy)
	ON_COMMAND(ID_EDIT_CUT, OnEditCut)
	ON_UPDATE_COMMAND_UI(ID_EDIT_CUT, OnUpdateEditCut)
	ON_COMMAND(ID_EDIT_PASTE, OnEditPaste)
	ON_UPDATE_COMMAND_UI(ID_EDIT_PASTE, OnUpdateEditPaste)
	ON_COMMAND(ID_SHORTCUT, OnShortcut)
	ON_UPDATE_COMMAND_UI(ID_SHORTCUT, OnUpdateShortcut)
	ON_WM_DROPFILES()
	ON_NOTIFY_REFLECT(LVN_BEGINDRAG, OnBeginDrag)
	ON_WM_MOUSEMOVE()
	ON_WM_LBUTTONUP()
	//}}AFX_MSG_MAP
	ON_MESSAGE(UM_GROUP_CHANGED,OnGroupChanged)
	ON_WM_CHANGECBCHAIN()
	ON_WM_DRAWCLIPBOARD()
	ON_COMMAND(ID_TOOL_ADD, OnAddItem)
	ON_COMMAND(ID_TOOL_DELETE, OnDeleteItem)
	ON_COMMAND(ID_TOOL_PROPERTIES, OnItemProperties)
	ON_UPDATE_COMMAND_UI(ID_TOOL_ADD, OnUpdateAddItem)
	ON_UPDATE_COMMAND_UI(ID_TOOL_DELETE, OnUpdateDeleteItem)
	ON_UPDATE_COMMAND_UI(ID_TOOL_PROPERTIES, OnUpdateItemProperties)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CJTIListView construction/destruction

// Constructor
CJTIListView::CJTIListView()
{
	CListCtrl& list = GetListCtrl();
	m_pList = &list;

	// Initialize the clipboard flags and drag/drop flags
	m_nActiveGroup = 0;
	m_nClipboardFormat = ::RegisterClipboardFormat("JumpToIt");
	m_hwndClipboard = NULL;
	m_bMonitoring = FALSE;
	m_bCanPaste = FALSE;
	m_bAutoPaste = FALSE;
	m_bDragging = FALSE;
	m_bCutMode = FALSE;
	m_bConfirm = TRUE;
}

// Destructor
CJTIListView::~CJTIListView()
{
}

// Called when window is created
BOOL CJTIListView::PreCreateWindow(CREATESTRUCT& cs)
{
	return CListView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CJTIListView drawing

// Called to draw window background
void CJTIListView::OnDraw(CDC* pDC)
{
	CJTIDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
}

// Called when window is initialized
void CJTIListView::OnInitialUpdate()
{
	static bFirstTime = TRUE;

	CListView::OnInitialUpdate();

	// Set up the list control the first time the view is created
	if(bFirstTime)
	{
		// Change the style; window will repaint automatically
		DWORD dwStyle = AfxGetApp()->GetProfileInt("List","Style",LVS_REPORT);
		ModifyStyle(LVS_TYPEMASK,dwStyle);

		// Is the list a report-style list?
		if(dwStyle & LVS_REPORT)
		{
			// Yes...make sure we don't have a column header
			ModifyStyle(0,LVS_NOCOLUMNHEADER);
		}

		// Create the image list
		m_ImageList.Create(IDB_LIST,16,1,RGB(255,0,255));

		// Make sure the list always shows a selection
		m_pList->ModifyStyle(0,LVS_SHOWSELALWAYS);

		// Setup one column
		m_pList->DeleteColumn(0);
		m_pList->InsertColumn(0,"",LVCFMT_LEFT,800);

		// Tell Windows that the list can accept dropped files
		DragAcceptFiles(TRUE);

		// Setup clipboard monitoring
		SetClipboardMonitor();

		// Reset flag so we won't execute this code again
		bFirstTime = FALSE;
	}

	// Set the normal and small image list
	m_pList->SetImageList(&m_ImageList,LVSIL_NORMAL);
	m_pList->SetImageList(&m_ImageList,LVSIL_SMALL);
}

/////////////////////////////////////////////////////////////////////////////
// CJTIListView diagnostics

#ifdef _DEBUG
void CJTIListView::AssertValid() const
{
	CListView::AssertValid();
}

void CJTIListView::Dump(CDumpContext& dc) const
{
	CListView::Dump(dc);
}

CJTIDoc* CJTIListView::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CJTIDoc)));
	return (CJTIDoc*)m_pDocument;
}
#endif //_DEBUG


// Comparsion function that's used to sort list items.  This routine receives
// the lParam value of each list item which it then uses to retrieve the 
// appropriate item and compare its description text.
static int CALLBACK CompareFunc(LPARAM lParam1, LPARAM lParam2, 
   LPARAM lParamSort)
{
	ITEMS *pItems= (ITEMS *) lParamSort;
	CItem& item1 = pItems->GetAt(lParam1);
	CItem& item2 = pItems->GetAt(lParam2);

	// Return the results of the description comparision
	return(stricmp(item1.strDescription,item2.strDescription));
}

// Performs the sort operation after getting the proper group pointer
void CJTIListView::DoSort()
{
	GROUPS& arrGroups = GetDocument()->GetGroups();

	m_pList->SortItems(CompareFunc,(LPARAM) &arrGroups[m_nActiveGroup].arrItems);
}

/////////////////////////////////////////////////////////////////////////////
// CJTIListView message handlers

// Called when the list style changes
void CJTIListView::OnStyleChanged(int nStyleType, LPSTYLESTRUCT lpStyleStruct)
{
}

// Called when the view is being destroyed
void CJTIListView::OnDestroy() 
{
	CRect rc;

	// Save the window location
	GetParentFrame()->GetWindowRect(&rc);
	AfxGetApp()->WriteProfileInt("Location","X",rc.left);
	AfxGetApp()->WriteProfileInt("Location","Y",rc.top);
	AfxGetApp()->WriteProfileInt("Location","CX",rc.Width());
	AfxGetApp()->WriteProfileInt("Location","CY",rc.Height());

	// Save the list style
	DWORD dwStyle = (GetStyle() & LVS_TYPEMASK);
	AfxGetApp()->WriteProfileInt("List","Style",dwStyle);

	CListView::OnDestroy();

	// Stop clipboard monitoring (do this last so the clipboard change method
	// won't get called in the process)
	if(m_hwndClipboard)
		ChangeClipboardChain(m_hwndClipboard);
}

// Called to add a link item to the group
void CJTIListView::OnAddItem() 
{
	CJTIPropDlg dlgProp;

	// Set proper title for the dialog
	dlgProp.SetTitle("Add");

	// Display the dialog
	if(dlgProp.DoModal() == IDOK)
	{
		GROUPS& arrGroups = GetDocument()->GetGroups();
		CItem item;

		// Retrieve the user's selections and add an item
		item.strDescription = dlgProp.GetDescription();
		item.strURL = dlgProp.GetURL();
		item.byType = dlgProp.GetType()+(dlgProp.GetMenuFlag()?2:0);
		arrGroups[m_nActiveGroup].arrItems.Add(item);

		// Redisplay the list with the new item added
		ShowList(m_nActiveGroup);
		GetDocument()->SetModifiedFlag(TRUE);
		GetDocument()->SaveModified();
	}
}

// Handles enabling of Add links menu item
void CJTIListView::OnUpdateAddItem(CCmdUI* pCmdUI) 
{
	// Can only add when a group is selected
	pCmdUI->Enable(m_nActiveGroup > 0);
}

// Called to delete the selected items
void CJTIListView::OnDeleteItem() 
{
	// Confirm the user's choice
	if(!m_bConfirm || AfxMessageBox(IDS_DELETE_ITEM,MB_ICONQUESTION|MB_YESNOCANCEL) == IDYES)
	{
		int nSelCount = m_pList->GetSelectedCount();

		// Iterate through the list items
		for(int i = m_pList->GetItemCount()-1; nSelCount && i >= 0 ; i--)
		{
			GROUPS& arrGroups = GetDocument()->GetGroups();

			// Is this item selected?
			if(m_pList->GetItemState(i,LVIS_SELECTED))
			{
				// Yep...zap it
				int nItem = m_pList->GetItemData(i);
				CItem& item = arrGroups[m_nActiveGroup].arrItems.GetAt(nItem);

				item.strDescription.Empty();
				arrGroups[m_nActiveGroup].arrItems.SetAt(nItem,item);

				m_pList->DeleteItem(i);
				nSelCount--;
			}
		}

		// Redisplay the list to show the changes
		ShowList(m_nActiveGroup);
		GetDocument()->SetModifiedFlag(TRUE);
		GetDocument()->SaveModified();
	}

	m_bConfirm = TRUE;
}

// Handles enabling delete menu item
void CJTIListView::OnUpdateDeleteItem(CCmdUI* pCmdUI) 
{
	// Must be at least one selected item
	pCmdUI->Enable(m_pList->GetSelectedCount() > 0);
}

// Returns the selected item from the list
int CJTIListView::GetSel()
{
	int nRow = -1;

	// Iterate through the list 
	for(int i = 0; i < m_pList->GetItemCount(); i++)
	{
		// Is the current item selected?
		if(m_pList->GetItemState(i,LVIS_SELECTED))
		{
			// Yep...get out
			nRow = i;
			break;
		}
	}

	return(nRow);
}

// Called to modify the properties of the selected item
void CJTIListView::OnItemProperties() 
{
	GROUPS& arrGroups = GetDocument()->GetGroups();
	int nItem = m_pList->GetItemData(GetSel());
	CItem& item = arrGroups[m_nActiveGroup].arrItems.GetAt(nItem);
	CJTIPropDlg dlgProp;
	BYTE byType;
	BOOL bMenu;

	// Get the item's type -- 0 = Web, 1 = File, 2 = Web shortcut, 3 = File shortcut
	bMenu = (item.byType >= 2);
	byType = item.byType;
	if(byType >= 2)
		byType -= 2;

	// Set the property screen fields
	dlgProp.SetEntry(item.strDescription,item.strURL,bMenu,byType);

	// Display the dialog
	if(dlgProp.DoModal() == IDOK)
	{
		// Get the user's changes and save them to the link list
		item.strDescription = dlgProp.GetDescription();
		item.strURL = dlgProp.GetURL();
		item.byType = dlgProp.GetType()+(dlgProp.GetMenuFlag()?2:0);
		arrGroups[m_nActiveGroup].arrItems.SetAt(nItem,item);

		// Set the list item's data
		m_pList->SetItem(GetSel(),0,LVIF_TEXT|LVIF_IMAGE,
							item.strDescription,
							item.byType,0,0,0);

		// Redisplay the list to show the changes
		ShowList(m_nActiveGroup);
		GetDocument()->SetModifiedFlag(TRUE);
		GetDocument()->SaveModified();
	}
}

// Handles enabling the Item properties menu item
void CJTIListView::OnUpdateItemProperties(CCmdUI* pCmdUI) 
{
	// There can only be one item selected
	pCmdUI->Enable(m_pList->GetSelectedCount() == 1);
}

// Handles double-click -- treats it the same as opening (running) an item
void CJTIListView::OnDblClk(NMHDR* pNMHDR, LRESULT* pResult) 
{
	// There must be only one selected item
	if(m_pList->GetSelectedCount() == 1)
		OnOpenItem();

	*pResult = 0;
}

// Displays the link list context menu
void CJTIListView::ShowMenu(CPoint point) 
{
	CMenu menu;
	int nSel = GetSel();
	GROUPS& arrGroups = GetDocument()->GetGroups();

	// Load the menu
	menu.LoadMenu(IDR_LISTMENU);
	CMenu *pPopup = menu.GetSubMenu(0);

	// do we have a valid selection?
	if(nSel >= 0)
	{
		int nItem = m_pList->GetItemData(GetSel());
		CItem& item = arrGroups[m_nActiveGroup].arrItems.GetAt(nItem);

		if(item.byType >= 2)
			pPopup->CheckMenuItem(ID_SHORTCUT,MF_BYCOMMAND|MF_CHECKED);
	}

	// Display the menu
	SetFocus();
	pPopup->TrackPopupMenu(TPM_LEFTALIGN|TPM_LEFTBUTTON|TPM_RIGHTBUTTON,
							point.x,point.y,GetParentFrame(),NULL);
}

// Handles the right-click button -- displays the context menu
void CJTIListView::OnRclick(NMHDR* pNMHDR, LRESULT* pResult) 
{
	CPoint pt;

	GetCursorPos(&pt);
	ShowMenu(pt);
	
	*pResult = 0;
}

// Handles opening (running) an item
void CJTIListView::OnOpenItem() 
{
	GROUPS& arrGroups = GetDocument()->GetGroups();
	int nItem = m_pList->GetItemData(GetSel());
	CItem& item = arrGroups[m_nActiveGroup].arrItems.GetAt(nItem);

	// Run the selected item
	((CJTIApp *) AfxGetApp())->RunApp(item.strURL);
}

// Handles enabling the Open menu item
void CJTIListView::OnUpdateOpenItem(CCmdUI* pCmdUI) 
{
	pCmdUI->Enable(m_pList->GetSelectedCount() == 1);
}

// Loads the link list for the current group
void CJTIListView::LoadList(CArchive& ar)
{
	GROUPS& arrGroups = GetDocument()->GetGroups();

	// Load each group's items
	for(int i = 0; i < arrGroups.GetSize(); i++)
		arrGroups[i].Serialize(ar);
}

// Saves the list to the specified archive object.  Also takes into account
// that the order of groups could have changed in the group tree by using
// the pMap array provided.
void CJTIListView::SaveList(CArchive& ar, int *pMap)
{
	GROUPS& arrGroups = GetDocument()->GetGroups();

	// Save each group's items
	for(int i = 0; i < arrGroups.GetSize(); i++)
	{
		int nEntry = pMap[i];

		if(nEntry >= 0)
			arrGroups[nEntry].Serialize(ar);
	}
}

// Clears the link list and redisplays it
void CJTIListView::ShowList(int nList)
{
	GROUPS& arrGroups = GetDocument()->GetGroups();

	m_nActiveGroup = nList;

	// Clear the list
	m_pList->DeleteAllItems();

	// Iterate through the specified group's items
	for(int i = 0; i < arrGroups[nList].arrItems.GetSize(); i++)
	{
		CItem& item = arrGroups[nList].arrItems.GetAt(i);

		// Add the group item
		if(!item.strDescription.IsEmpty())
			m_pList->InsertItem(LVIF_TEXT|LVIF_IMAGE|LVIF_PARAM,
								i,item.strDescription,
								0,0,item.byType,i);
	}

	// Sort the data
	DoSort();
}

// Called when the group selection changes in the group tree
LRESULT CJTIListView::OnGroupChanged(WPARAM wParam, LPARAM)
{
	// Display the list
	ShowList(wParam);

	return(0);
}

// Handles the clipboard copy operation by copying data from the selected items
// to the clipboard in a custom format.
void CJTIListView::OnEditCopy() 
{
	GROUPS& arrGroups = GetDocument()->GetGroups();
	CSharedFile mf(GMEM_ZEROINIT|GMEM_MOVEABLE|GMEM_DDESHARE);
	CArchive ar(&mf,CArchive::store);
	int nOperation = (m_bCutMode?ID_EDIT_CUT:ID_EDIT_COPY);
	HGLOBAL hMem;
	int nSelCount = m_pList->GetSelectedCount();

	// Write the operation we're performing	so we'll know how to treat
	// pasted data
	ar.Write(&nOperation,sizeof(nOperation));

	// Write the total number of items
	ar.Write(&nSelCount,sizeof(nSelCount));

	// Iterate through the list of links
	for(int i = 0; nSelCount && i < m_pList->GetItemCount(); i++)
	{
		// Serialize each selected item
		if(m_pList->GetItemState(i,LVIS_SELECTED))
		{
			int nItem = m_pList->GetItemData(i);
			CItem& item = arrGroups[m_nActiveGroup].arrItems.GetAt(nItem);

			// Save the item's data
			item.Serialize(ar);

			nSelCount--;
		}
	}

	// Close the archive object
	ar.Close();

	// Get a memory handle to the archive object
	hMem = mf.Detach();

	// Place the data on the clipboard
	OpenClipboard();
	EmptyClipboard();
	SetClipboardData(m_nClipboardFormat,hMem);
	CloseClipboard();

	m_bCutMode = FALSE;
}

// Handles enabling the copy menu item
void CJTIListView::OnUpdateEditCopy(CCmdUI* pCmdUI) 
{
	// There must be at least one selected item
	pCmdUI->Enable(m_pList->GetSelectedCount() > 0);
}

// Handles the Cut clipboard operation
void CJTIListView::OnEditCut() 
{
	m_bCutMode = TRUE;

	// Copy the selected items to the clipboard
	OnEditCopy();

	// Remove the selected items from the list
	m_bConfirm = FALSE;
	OnDeleteItem();

	// Make sure document is updated
	GetDocument()->SetModifiedFlag(TRUE);
	GetDocument()->SaveModified();
}

// Handles enabling the Cut menu item
void CJTIListView::OnUpdateEditCut(CCmdUI* pCmdUI) 
{
	// There must be at least one selected item
	pCmdUI->Enable(m_pList->GetSelectedCount() > 0);
}

// Handles the paste clipboard operation.  Allows pasting of both text URLS and
// custom data placed on the clipboard by JumpToIt.
void CJTIListView::OnEditPaste() 
{
	HGLOBAL hMem;
	GROUPS& arrGroups = GetDocument()->GetGroups();

	int nDefGroup = 0;

	// Is this an auto-paste operation?  If so get the default paste group

⌨️ 快捷键说明

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