📄 listview.cpp
字号:
/*
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 + -