📄 listview.cpp
字号:
if(m_bAutoPaste && !m_bDragging)
nDefGroup = GetDocument()->GetDefGroup();
// No group specified so use the active group
if(nDefGroup == 0)
nDefGroup = m_nActiveGroup;
// Open the clipboard
OpenClipboard();
// Try to get data in JumpToIt's custom format first
hMem = ::GetClipboardData(m_nClipboardFormat);
// Was there some available?
if(hMem)
{
CSharedFile mf;
mf.SetHandle(hMem);
CArchive ar(&mf,CArchive::load);
int nSelCount, nOperation;
// Get the operation
ar.Read(&nOperation,sizeof(nOperation));
// Get the total item count
ar.Read(&nSelCount,sizeof(nSelCount));
// Iterate through each item
for(int i = 0; i < nSelCount; i++)
{
CItem item;
item.Serialize(ar);
// Don't allow menu shortcuts to be copied. This prevents us
// from having more than the maximum allowed
if(nOperation == ID_EDIT_COPY && item.byType >= 2)
item.byType -= 2;
// Add the item to the specified group
arrGroups[nDefGroup].arrItems.Add(item);
arrGroups[nDefGroup].byCount++;
}
// Close the archive object and release the data
ar.Close();
mf.Detach();
}
else if(hMem = ::GetClipboardData(CF_TEXT))
{
LPTSTR lpszText = (LPTSTR) GlobalLock(hMem);
CString strURL = lpszText;
// Look for text URLs
strURL = strURL.SpanExcluding("\r\n");
// Make sure this is a valid URL
if(strURL.Left(7).CompareNoCase("http://") == 0 ||
strURL.Left(6).CompareNoCase("ftp://") == 0 ||
strURL.Left(7).CompareNoCase("file://") == 0)
{
CItem item;
// Get the description/URL
item.strDescription = strURL;
item.strURL = strURL;
item.byType = (strURL.Left(7).CompareNoCase("http://")?1:0);
// Add the new item to the specified group
arrGroups[nDefGroup].arrItems.Add(item);
arrGroups[nDefGroup].byCount++;
}
GlobalUnlock(hMem);
}
else if(hMem = ::GetClipboardData(::RegisterClipboardFormat("Filename")))
{
LPTSTR lpszText = (LPTSTR) GlobalLock(hMem);
CString strURL = lpszText, strDescription;
// Determine if this is a URL
strURL = ResolveURL(lpszText);
if(!strURL.IsEmpty())
{
char szTemp[_MAX_PATH+1];
WIN32_FIND_DATA ff;
// Try to get the long filename for the shortcut
HANDLE hFile = FindFirstFile(lpszText,&ff);
if(hFile)
{
// It worked...copy the filename
strcpy(szTemp,ff.cFileName);
FindClose(hFile);
}
else strcpy(szTemp,lpszText);
strDescription = ((CJTIApp *) AfxGetApp())->SplitFileName(szTemp,FNAME);
// Add the new item to the list
GROUPS& arrGroups = GetDocument()->GetGroups();
CItem item;
item.strDescription = strDescription;
item.strURL = strURL;
item.byType = 0;
arrGroups[m_nActiveGroup].arrItems.Add(item);
ShowList(m_nActiveGroup);
}
GlobalUnlock(hMem);
}
// Close the clipboard
CloseClipboard();
// Show the updated list
if(!m_bAutoPaste)
ShowList(m_nActiveGroup);
// Make sure document is updated
GetDocument()->SetModifiedFlag(TRUE);
GetDocument()->SaveModified();
m_bAutoPaste = FALSE;
}
// Handles enabling the Paste menu item
void CJTIListView::OnUpdateEditPaste(CCmdUI* pCmdUI)
{
pCmdUI->Enable(m_bCanPaste && m_nActiveGroup > 0);
}
// Handles the Menu Shortcut menu item on JumpToIt's context menu
void CJTIListView::OnShortcut()
{
GROUPS& arrGroups = GetDocument()->GetGroups();
int nItem = m_pList->GetItemData(GetSel());
CItem& item = arrGroups[m_nActiveGroup].arrItems.GetAt(nItem);
// Was this item not previously a shortcut?
if(item.byType < 2)
{
// That's correct, so make sure that adding it doesn't result
// in too many shortcuts
if(!((CMainFrame *) GetParentFrame())->CanAddShortcut())
{
AfxMessageBox(IDS_TOO_MANY_SHORTCUTS,MB_ICONWARNING|MB_OK);
return;
}
// Make it a shortcut item
item.byType += 2;
}
else item.byType -= 2;
// Set the item's data
arrGroups[m_nActiveGroup].arrItems.SetAt(nItem,item);
m_pList->SetItem(GetSel(),0,LVIF_IMAGE,NULL,item.byType,0,0,0);
// Make sure the document gets saved
GetDocument()->SetModifiedFlag(TRUE);
GetDocument()->SaveModified();
}
// Handles enabling the Menu Shortcut menu item
void CJTIListView::OnUpdateShortcut(CCmdUI* pCmdUI)
{
pCmdUI->Enable(m_pList->GetSelectedCount() == 1);
}
// Resolves a dropped URL shortcut
CString CJTIListView::ResolveURL(LPCTSTR lpszItem)
{
CString strURL;
IUniformResourceLocator *pIURL = NULL;
IPersistFile *pIPF = NULL;
WORD szWide[MAX_PATH];
HRESULT hResult;
LPSTR pszURL = NULL;
// Instantiate a URL object
hResult = ::CoCreateInstance(CLSID_InternetShortcut,
NULL,CLSCTX_INPROC_SERVER,IID_IUniformResourceLocator,
(void **) &pIURL);
if(SUCCEEDED(hResult))
{
// Get pointer to the object's IPersistFile interface.
hResult = pIURL->QueryInterface(IID_IPersistFile,(void **) &pIPF);
if(!SUCCEEDED(hResult))
pIURL->Release();
}
// Are both items valid?
if(pIPF && pIURL)
{
MultiByteToWideChar(CP_ACP,0,lpszItem,-1,szWide,_MAX_PATH);
if(pIPF->Load(szWide,STGM_READ) == S_OK)
{
if(pIURL->GetURL(&pszURL) == S_OK)
{
// Save the URL for return
strURL = pszURL;
// Free the URL's work buffer
IMalloc* pMalloc;
hResult = SHGetMalloc(&pMalloc);
if(SUCCEEDED(hResult))
{
pMalloc->Free(pszURL);
pMalloc->Release();
}
}
}
}
if(pIPF)
pIPF->Release();
if(pIURL)
pIURL->Release();
return(strURL);
}
// Resolves a dropped shortcut link
CString CJTIListView::ResolveLnk(LPCTSTR lpszItem, CString& strDescription)
{
CString strURL;
IShellLink *pISL = NULL;
IPersistFile *pIPF = NULL;
WORD szWide[MAX_PATH];
HRESULT hResult;
// Instantiate a shortcut object
hResult = CoCreateInstance (CLSID_ShellLink,NULL,CLSCTX_INPROC_SERVER,
IID_IShellLink,(void **)&pISL);
if(SUCCEEDED(hResult))
{
// Get pointer to the object's IPersistFile interface.
hResult = pISL->QueryInterface(IID_IPersistFile,(void **)&pIPF);
if(!SUCCEEDED(hResult))
pISL->Release();
}
// Are both items valid?
if(pIPF && SUCCEEDED(hResult))
{
if(SUCCEEDED(hResult))
{
MultiByteToWideChar(CP_ACP,0,lpszItem,-1,szWide,_MAX_PATH);
// Load the shortcut.
if(pIPF->Load(szWide,STGM_READ) == S_OK)
{
// Get the shortcut information
hResult = pISL->Resolve(AfxGetMainWnd()->GetSafeHwnd(),SLR_ANY_MATCH);
if(SUCCEEDED (hResult))
{
WIN32_FIND_DATA wfd;
char szTemp[MAX_PATH];
// Get the path
hResult = pISL->GetPath(szTemp,MAX_PATH,(WIN32_FIND_DATA *)&wfd,SLGP_SHORTPATH);
strURL = lpszItem;
if(SUCCEEDED(hResult))
strURL = szTemp;
// Get the arguments
hResult = pISL->GetArguments(szTemp,MAX_PATH);
if(SUCCEEDED(hResult))
strURL += CString(" ")+szTemp;
// Get the description
hResult = pISL->GetDescription(szTemp,MAX_PATH);
if(SUCCEEDED(hResult))
strDescription = szTemp;
}
}
}
}
if(pIPF)
pIPF->Release();
if(pISL)
pISL->Release();
return(strURL);
}
// Handles files dropped by another window
void CJTIListView::OnDropFiles(HDROP hDropInfo)
{
int nEntries = DragQueryFile(hDropInfo,-1,NULL,0);
CString strURL;
CString strFileList;
CString strDescription;
// Can't drop into group title
if(m_nActiveGroup <= 0)
{
::MessageBeep(0);
return;
}
for(int i = 0 ; i < nEntries; i++)
{
// Get the size of the item
int nSize = DragQueryFile(hDropInfo,i,NULL,0);
BYTE byType = 0;
// Allocate memory to contain the item
LPTSTR lpszItem = (LPTSTR) LocalAlloc(LPTR,nSize+1);
// Is this a valid item?
if(lpszItem)
{
// Get the item's information
DragQueryFile(hDropInfo,i,lpszItem,nSize+1);
// Determine if this is a URL
strURL = ResolveURL(lpszItem);
if(!strURL.IsEmpty())
strDescription = ((CJTIApp *) AfxGetApp())->SplitFileName(lpszItem,FNAME);
else
{
strURL = ResolveLnk(lpszItem,strDescription);
if(strDescription.IsEmpty())
strDescription = ((CJTIApp *) AfxGetApp())->SplitFileName(strURL,FNAME);
byType = 1;
}
// Is it valid?
if(!strURL.IsEmpty())
{
// Add the new item to the list
GROUPS& arrGroups = GetDocument()->GetGroups();
CItem item;
item.strDescription = strDescription;
item.strURL = strURL;
item.byType = byType;
arrGroups[m_nActiveGroup].arrItems.Add(item);
ShowList(m_nActiveGroup);
}
// Free the local buffer now
LocalFree(lpszItem);
}
}
// Free the memory block containing the dropped-file information
DragFinish(hDropInfo);
}
// Called when clipboard contents change
void CJTIListView::OnDrawClipboard()
{
CListView::OnDrawClipboard();
static BOOL bFirstTime = TRUE;
if(bFirstTime == TRUE)
{
bFirstTime = FALSE;
return;
}
// Check the types of clipboard data available
unsigned int nExplorer = ::RegisterClipboardFormat("Filename");
unsigned int anFormats[] = {m_nClipboardFormat,CF_TEXT,nExplorer};
unsigned int nFormat = GetPriorityClipboardFormat(anFormats,sizeof(anFormats));
m_bCanPaste = FALSE;
// Text data?
if(nFormat == CF_TEXT)
{
HGLOBAL hMem;
OpenClipboard();
// Yes...check to see if the data is a valid URL
if(hMem = ::GetClipboardData(CF_TEXT))
{
LPTSTR lpszText = (LPTSTR) GlobalLock(hMem);
CString strURL = lpszText;
strURL = strURL.SpanExcluding("\r\n");
// Valid URL?
if(strURL.Left(7).CompareNoCase("http://") == 0 ||
strURL.Left(6).CompareNoCase("ftp://") == 0 ||
strURL.Left(7).CompareNoCase("file://") == 0)
{
// Yes...set the paste enable flag
m_bCanPaste = TRUE;
}
GlobalUnlock(hMem);
}
CloseClipboard();
}
else if(nFormat == (unsigned int) m_nClipboardFormat)
m_bCanPaste = TRUE;
else if(nFormat == nExplorer)
m_bCanPaste = TRUE;
CWnd *pOwner = GetClipboardOwner();
DWORD dwCurrPID, dwOwnerPID;
// Make sure that JumpToIt's edit control didn't place this
// item on the clipboard. This prevents auto-pasting of something that
// the user manually copied
if(pOwner)
{
// Get process ids of this task and clipboard task
GetWindowThreadProcessId(GetSafeHwnd(),&dwCurrPID);
GetWindowThreadProcessId(pOwner->GetSafeHwnd(),&dwOwnerPID);
// Came from this task so get out
if(dwCurrPID == dwOwnerPID)
return;
}
// Are we monitoring the clipboard?
if(GetDocument()->GetMonitorMode())
{
m_bAutoPaste = TRUE;
OnEditPaste();
// Add the data an refresh the list
ShowList(m_nActiveGroup);
}
}
// Clipboard contents changed...
void CJTIListView::OnChangeCbChain(HWND hWndRemove, HWND hWndAfter)
{
CView::OnChangeCbChain(hWndRemove,hWndAfter);
if(hWndRemove == m_hwndClipboard)
m_hwndClipboard = hWndAfter;
}
// Install a monitor for the clipboard
void CJTIListView::SetClipboardMonitor()
{
// Make sure we get notified when the clipboard contents
if(!m_bMonitoring)
{
m_hwndClipboard = SetClipboardViewer();
m_bMonitoring = TRUE;
}
else
{
if(m_hwndClipboard && m_bMonitoring)
ChangeClipboardChain(m_hwndClipboard);
m_hwndClipboard = NULL;
m_bMonitoring = FALSE;
}
}
// Handles keyboard support first list -- delete key to remove entries,
// insert key to add entries.
BOOL CJTIListView::PreTranslateMessage(MSG* pMsg)
{
if(pMsg->message == WM_KEYUP)
{
switch(pMsg->wParam)
{
// Add an entry
case VK_INSERT:
OnAddItem();
return(TRUE);
// Delete an entry
case VK_DELETE:
// Anything selected?
if(m_pList->GetSelectedCount() > 0)
OnDeleteItem();
return(TRUE);
}
}
return CListView::PreTranslateMessage(pMsg);
}
// Handles drag operation initialization
void CJTIListView::OnBeginDrag(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
m_htreeDropItem = NULL;
// Get the selected item's information
if(m_pList->GetSelectedCount())
{
POSITION pos = m_pList->GetFirstSelectedItemPosition();
int nItem = m_pList->GetNextSelectedItem(pos);
if(nItem >= 0)
{
// Create drag image and begin dragging
SetCapture();
m_bDragging = TRUE;
}
}
*pResult = 0;
}
// Handles mouse moves during dragging
void CJTIListView::OnMouseMove(UINT nFlags, CPoint point)
{
if(m_bDragging)
{
CMainFrame *pFrame = (CMainFrame *) GetParentFrame();
CTreeCtrl *pTree = pFrame->GetTreeCtrl();
UINT nFlags;
CPoint ptScreen(point);
CPoint ptTree;
// Find the item that we're currently dragging over
ClientToScreen(&ptScreen);
ptTree = ptScreen;
pTree->ScreenToClient(&ptTree);
m_htreeDropItem = pTree->HitTest(ptTree,&nFlags);
// Set the cursor to drop or no-drop based on whether it's
// over a valid drop item
if(m_htreeDropItem && m_htreeDropItem != pTree->GetRootItem())
::SetCursor(AfxGetApp()->LoadCursor(IDC_DRAG));
else
{
m_htreeDropItem = NULL;
::SetCursor(::LoadCursor(NULL,IDC_NO));
}
}
CListView::OnMouseMove(nFlags, point);
}
// Handles dropping of a dragged item
void CJTIListView::OnLButtonUp(UINT nFlags, CPoint point)
{
if(m_bDragging)
{
ReleaseCapture();
// Valid drop item?
if(m_htreeDropItem)
{
CMainFrame *pFrame = (CMainFrame *) GetParentFrame();
CTreeCtrl *pTree = pFrame->GetTreeCtrl();
// Get drop group
int nNewGroup = pTree->GetItemData(m_htreeDropItem);
// Is it different from the dragged group?
if(nNewGroup != m_nActiveGroup)
{
int nOldGroup = m_nActiveGroup;
// Cut the selected entries
OnEditCut();
// Paste the entries to the new group
m_bAutoPaste = TRUE;
m_nActiveGroup = nNewGroup;
OnEditPaste();
m_nActiveGroup = nOldGroup;
}
}
m_bDragging = FALSE;
}
CListView::OnLButtonUp(nFlags, point);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -