直接上代码:
void CReportRogueDlg::OnBegindragNewAPList(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
// TODO: Add your control notification handler code here
Save the index of the item being dragged in m_nDragIndex
This will be used later for retrieving the info dragged
m_nDragIndex = pNMListView->iItem;
Create a drag image
POINT pt;
int nOffset = -10; //offset in pixels for drag image (positive is up and to the left; neg is down and to the right)
if(m_lvNewAP.GetSelectedCount() > 1) //more than one item is selected
pt.x = nOffset;
pt.y = nOffset;
m_pDragImage = m_lvNewAP.CreateDragImage(m_nDragIndex, &pt);
ASSERT(m_pDragImage); //make sure it was created
//We will call delete later (in LButtonUp) to clean this up
CBitmap bitmap;
if(m_lvNewAP.GetSelectedCount() > 1) //more than 1 item in list is selected
//bitmap.LoadBitmap(IDB_BITMAP_MULTI);
bitmap.LoadBitmap(IDB_DRAGE_MULTI);
else
bitmap.LoadBitmap(IDB_DRAGE_SING);
m_pDragImage->Replace(0, &bitmap, &bitmap);
Change the cursor to the drag image
(still must perform DragMove() in OnMouseMove() to show it moving)
m_pDragImage->BeginDrag(0, CPoint(nOffset, nOffset - 4));
m_pDragImage->DragEnter(GetDesktopWindow(), pNMListView->ptAction);
Set dragging flag and others
m_bDragging = TRUE; //we are in a drag and drop operation
m_nDropIndex = -1; //we don't have a drop index yet
m_pDragList = &m_lvNewAP; //make note of which list we are dragging from
Capture all mouse messages
SetCapture ();
*pResult = 0;
}
void CReportRogueDlg::OnMouseMove(UINT nFlags, CPoint point)
{
//While the mouse is moving, this routine is called.
//This routine will redraw the drag image at the present
// mouse location to display the dragging.
//Also, while over a CListCtrl, this routine will highlight
// the item we are hovering over.
If we are in a drag/drop procedure (m_bDragging is true)
if (m_bDragging)
{
Move the drag image
CPoint pt(point); //get our current mouse coordinates
ClientToScreen(&pt); //convert to screen coordinates
m_pDragImage->DragMove(pt); //move the drag image to those coordinates
// Unlock window updates (this allows the dragging image to be shown smoothly)
m_pDragImage->DragShowNolock(false);
Get the CWnd pointer of the window that is under the mouse cursor
CWnd* pDropWnd = WindowFromPoint (pt);
ASSERT(pDropWnd); //make sure we have a window
If we drag outside current window we need to adjust the highlights displayed
if (pDropWnd != m_pDropWnd)
{
if (m_nDropIndex != -1) //If we drag over the CListCtrl header, turn off the hover highlight
{
TRACE("m_nDropIndex is -1\n");
CListCtrl* pList = (CListCtrl*)m_pDropWnd;
VERIFY (pList->SetItemState (m_nDropIndex, 0, LVIS_DROPHILITED));
// redraw item
VERIFY (pList->RedrawItems (m_nDropIndex, m_nDropIndex));
pList->UpdateWindow ();
m_nDropIndex = -1;
}
else //If we drag out of the CListCtrl altogether
{
TRACE("m_nDropIndex is not -1\n");
CListCtrl* pList = (CListCtrl*)m_pDropWnd;
int i = 0;
int nCount = pList->GetItemCount();
for(i = 0; i < nCount; i++)
{
pList->SetItemState(i, 0, LVIS_DROPHILITED);
}
pList->RedrawItems(0, nCount);
pList->UpdateWindow();
}
}
// Save current window pointer as the CListCtrl we are dropping onto
m_pDropWnd = pDropWnd;
// Convert from screen coordinates to drop target client coordinates
pDropWnd->ScreenToClient(&pt);
//If we are hovering over a CListCtrl we need to adjust the highlights
if(pDropWnd->IsKindOf(RUNTIME_CLASS (CListCtrl)))
{
//Note that we can drop here
SetCursor(LoadCursor(NULL, IDC_ARROW));
UINT uFlags;
CListCtrl* pList = (CListCtrl*)pDropWnd;
if( pList->GetDlgCtrlID() != IDC_LIST_NEWAP)
{
// Turn off hilight for previous drop target
pList->SetItemState (m_nDropIndex, 0, LVIS_DROPHILITED);
// Redraw previous item
pList->RedrawItems (m_nDropIndex, m_nDropIndex);
// Get the item that is below cursor
m_nDropIndex = ((CListCtrl*)pDropWnd)->HitTest(pt, &uFlags);
// Highlight it
pList->SetItemState(m_nDropIndex, LVIS_DROPHILITED, LVIS_DROPHILITED);
// Redraw item
pList->RedrawItems(m_nDropIndex, m_nDropIndex);
pList->UpdateWindow();
}
}
else
{
//If we are not hovering over a CListCtrl, change the cursor
// to note that we cannot drop here
SetCursor(LoadCursor(NULL, IDC_NO));
}
// Lock window updates
m_pDragImage->DragShowNolock(true);
}
CParentsDlg::OnMouseMove(nFlags, point);
}
void CReportRogueDlg::OnLButtonUp(UINT nFlags, CPoint point)
{
//This routine is the end of the drag/drop operation.
//When the button is released, we are to drop the item.
//There are a few things we need to do to clean up and
// finalize the drop:
// 1) Release the mouse capture
// 2) Set m_bDragging to false to signify we are not dragging
// 3) Actually drop the item (we call a separate function to do that)
//If we are in a drag and drop operation (otherwise we don't do anything)
if (m_bDragging)
{
// Release mouse capture, so that other controls can get control/messages
ReleaseCapture ();
// Note that we are NOT in a drag operation
m_bDragging = FALSE;
// End dragging image
m_pDragImage->DragLeave (GetDesktopWindow ());
m_pDragImage->EndDrag ();
delete m_pDragImage; //must delete it because it was created at the beginning of the drag
CPoint pt (point); //Get current mouse coordinates
ClientToScreen (&pt); //Convert to screen coordinates
// Get the CWnd pointer of the window that is under the mouse cursor
CWnd* pDropWnd = WindowFromPoint (pt);
ASSERT (pDropWnd); //make sure we have a window pointer
// If window is CListCtrl, we perform the drop
if (pDropWnd->IsKindOf (RUNTIME_CLASS (CListCtrl)))
{
m_pDropList = (CListCtrl*)pDropWnd; //Set pointer to the list we are dropping on
DropItemOnList(m_pDragList, m_pDropList); //Call routine to perform the actual drop
}
}
CParentsDlg::OnLButtonUp(nFlags, point);
}
void CReportRogueDlg::DropItemOnList(CListCtrl* pDragList, CListCtrl* pDropList)
{
//This routine performs the actual drop of the item dragged.
//It simply grabs the info from the Drag list (pDragList)
// and puts that info into the list dropped on (pDropList).
//Send: pDragList = pointer to CListCtrl we dragged from,
// pDropList = pointer to CListCtrl we are dropping on.
//Return: nothing.
Variables
if( pDropList->GetDlgCtrlID() == IDC_LIST_NEWAP)
return;
// Unhilight the drop target
pDropList->SetItemState (m_nDropIndex, 0, LVIS_DROPHILITED);
//Set up the LV_ITEM for retrieving item from pDragList and adding the new item to the pDropList
if(pDragList->GetSelectedCount() == 1)
{
// Get item that was dragged
CString szTextLabel = pDragList->GetItemText(m_nDragIndex, 0);
// CString szText = pDragList->GetItemText(m_nDragIndex, 1);
CString szBSSID = pDragList->GetItemText(m_nDragIndex, 1);
CString szSecurity = pDragList->GetItemText(m_nDragIndex, 2);
CString szBand = pDragList->GetItemText(m_nDragIndex, 3);
CString szSSID = pDragList->GetItemText(m_nDragIndex, 4);
CString szRSSI = pDragList->GetItemText(m_nDragIndex, 5);
if(IsExist(szBSSID,szBand))
{
AfxMessageBox(IDS_REPORT_ROGUEAP_EXIST);
return;
}
// Delete the original item (for Move operation)
// This is optional. If you want to implement a Copy operation, don't delete.
// This works very well though for re-arranging items within a CListCtrl.
// It is written at present such that when dragging from one list to the other
// the item is copied, but if dragging within one list, the item is moved.
// Insert item into pDropList
// if m_nDropIndex == -1, iItem = GetItemCount() (inserts at end of list), else iItem = m_nDropIndex
// lvi.plvi->iItem = (m_nDropIndex == -1) ? pDropList->GetItemCount () : m_nDropIndex;
pDragList->DeleteItem(m_nDragIndex);
int nItem = pDropList->InsertItem (0xffff,szTextLabel);
// pDropList->SetItemText(nItem, 1, szText);
pDropList->SetItemText(nItem, 1, szBSSID);
pDropList->SetItemText(nItem, 2, szSecurity);
pDropList->SetItemText(nItem, 3, szBand);
pDropList->SetItemText(nItem, 4, szSSID);
pDropList->SetItemText(nItem, 5, szRSSI);
// Select the new item we just inserted
pDropList->SetItemState (nItem, LVIS_SELECTED, LVIS_SELECTED);
}
else //more than 1 item is being dropped
{
//We have to parse through all of the selected items from the DragList
//1) Retrieve the info for the items and store them in memory
//2) If we are reordering, delete the items from the list
//3) Insert the items into the list (either same list or different list)
//Retrieve the selected items
POSITION pos = pDragList->GetFirstSelectedItemPosition(); //iterator for the CListCtrl
while(pos) //so long as we have a valid POSITION, we keep iterating
{
m_nDragIndex = pDragList->GetNextSelectedItem(pos);
CString szTextLabel = pDragList->GetItemText(m_nDragIndex, 0);
// CString szText = pDragList->GetItemText(m_nDragIndex, 1);
CString szBSSID = pDragList->GetItemText(m_nDragIndex, 1);
CString szSecurity = pDragList->GetItemText(m_nDragIndex, 2);
CString szBand = pDragList->GetItemText(m_nDragIndex, 3);
CString szSSID = pDragList->GetItemText(m_nDragIndex, 4);
CString szRSSI = pDragList->GetItemText(m_nDragIndex, 5);
if(IsExist(szBSSID,szBand))
{
AfxMessageBox(IDS_REPORT_ROGUEAP_EXIST);
continue;
}
pDragList->DeleteItem(m_nDragIndex);
pos = pDragList->GetFirstSelectedItemPosition(); //iterator for the CListCtrl
//Get the item
int nItem = pDropList->InsertItem (0xffff,szTextLabel);
// pDropList->SetItemText(nItem, 1, szText);
pDropList->SetItemText(nItem, 1, szBSSID);
pDropList->SetItemText(nItem, 2, szSecurity);
pDropList->SetItemText(nItem, 3, szBand);
pDropList->SetItemText(nItem, 4, szSSID);
pDropList->SetItemText(nItem, 5, szRSSI);
// Select the new item we just inserted
pDropList->SetItemState (nItem, LVIS_SELECTED, LVIS_SELECTED);
} //EO while(pos) -- at this point we have deleted the moving items and stored them in memory
//Iterate through the items stored in memory and add them back into the CListCtrl at the drop index
}
}