home *** CD-ROM | disk | FTP | other *** search
/ Xentax forum attachments archive / xentax.7z / 8090 / ModelEdit.7z / DragList.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2006-03-08  |  3.1 KB  |  146 lines

  1. // DragList.cpp : implementation file
  2. //
  3.  
  4. #include "precompile.h"
  5. #include "modeledit.h"
  6. #include "draglist.h"
  7.  
  8. /////////////////////////////////////////////////////////////////////////////
  9. // CDragList
  10.  
  11. CDragList::CDragList() :
  12.     m_bDragging(FALSE),
  13.     m_pDragImage(NULL),
  14.     m_fDropNotify(NULL),
  15.     m_pDropNotifyObject(NULL)
  16. {
  17. }
  18.  
  19. CDragList::~CDragList()
  20. {
  21.     if (m_pDragImage)
  22.         delete m_pDragImage;
  23. }
  24.  
  25.  
  26. BEGIN_MESSAGE_MAP(CDragList, CListCtrl)
  27.     //{{AFX_MSG_MAP(CDragList)
  28.     ON_NOTIFY_REFLECT(LVN_BEGINDRAG, OnBeginDrag)
  29.     ON_WM_MOUSEMOVE()
  30.     ON_WM_LBUTTONUP()
  31.     //}}AFX_MSG_MAP
  32. END_MESSAGE_MAP()
  33.  
  34. /////////////////////////////////////////////////////////////////////////////
  35. // CDragList message handlers
  36.  
  37. void CDragList::OnBeginDrag(NMHDR* pNMHDR, LRESULT* pResult) 
  38. {
  39.     NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
  40.     
  41.     *pResult = 0;
  42.  
  43.     // Create a drag image centered around the item
  44.     CPoint pt(8,8);
  45.     m_pDragImage = CreateDragImage(pNMListView->iItem, &pt);
  46.     m_pDragImage->BeginDrag(0, CPoint(8,8));
  47.     m_pDragImage->DragEnter(GetDesktopWindow(), pNMListView->ptAction);
  48.  
  49.     // Set the drag index
  50.     pt = pNMListView->ptAction;
  51.     m_iDragIndex = HitTest(pt);
  52.     m_iDropIndex = -1;
  53.  
  54.     // Go into drag mode
  55.     m_bDragging = TRUE;
  56.  
  57.     // Capture the mouse
  58.     SetCapture();
  59. }
  60.  
  61. void CDragList::OnMouseMove(UINT nFlags, CPoint point) 
  62. {
  63.     if (m_bDragging)
  64.     {
  65.         // Draw the drag image
  66.         CPoint scrPoint(point);
  67.  
  68.         ClientToScreen(&scrPoint);
  69.  
  70.         m_pDragImage->DragMove(scrPoint);
  71.  
  72.         m_pDragImage->DragShowNolock(FALSE);
  73.  
  74.         // Scroll the list if necessary
  75.         int iOverItem = HitTest(point);
  76.         int iTopItem = GetTopIndex();
  77.         int iBottomItem = iTopItem + GetCountPerPage() - 1;
  78.         if ((iOverItem == iTopItem) && (iTopItem != 0))
  79.         {
  80.             EnsureVisible(--iOverItem, FALSE);
  81.             UpdateWindow();
  82.         }
  83.         else if ((iOverItem == iBottomItem) && (iBottomItem < (GetItemCount() - 1)))
  84.         {
  85.             EnsureVisible(++iOverItem, FALSE);
  86.             UpdateWindow();
  87.         }
  88.  
  89.         // Show the drop target
  90.         ShowDropTarget(iOverItem);
  91.  
  92.         m_pDragImage->DragShowNolock(TRUE);
  93.     }
  94.     
  95.     CListCtrl::OnMouseMove(nFlags, point);
  96. }
  97.  
  98. void CDragList::OnLButtonUp(UINT nFlags, CPoint point) 
  99. {
  100.     CListCtrl::OnLButtonUp(nFlags, point);
  101.  
  102.     // Drop the item
  103.     if (m_bDragging)
  104.     {
  105.         // Let go of the mouse
  106.         ReleaseCapture();
  107.  
  108.         // Turn off drag mode
  109.         m_bDragging = FALSE;
  110.         m_pDragImage->DragLeave(GetDesktopWindow());
  111.         m_pDragImage->EndDrag();
  112.         delete m_pDragImage;
  113.         m_pDragImage = NULL;
  114.  
  115.         ClearDropTarget();
  116.  
  117.         m_iDropIndex = HitTest(point);
  118.         if (m_iDropIndex < 0)
  119.         {
  120.             CRect rect;
  121.             ClientToScreen(&point);
  122.             GetWindowRect(&rect);
  123.             if (point.y < rect.top)
  124.                 m_iDropIndex = GetTopIndex();
  125.             else
  126.                 m_iDropIndex = LTMIN(GetTopIndex() + GetCountPerPage(), GetItemCount());
  127.         }
  128.  
  129.         // Call the notification function
  130.         if (m_pDropNotifyObject && m_fDropNotify)
  131.             (m_pDropNotifyObject->*m_fDropNotify)(m_iDropIndex);
  132.     }
  133. }
  134.  
  135. void CDragList::ShowDropTarget(int iItem)
  136. {
  137.     // Draw an indication of the drop target
  138.     SetHotItem(LTMAX(iItem, 0));
  139.     UpdateWindow();
  140. }
  141.  
  142. void CDragList::ClearDropTarget()
  143. {
  144.     SetHotItem(-1);
  145.     UpdateWindow();
  146. }