拖放列表框项目

介绍 这个listbox类演示了如何在不使用OLE的情况下使用拖放重新排列listbox项。这种方法的优点是,您不必创建庞大的全局内存句柄来简单地在同一个应用程序的同一个窗口内移动数据。概念非常简单:跟踪被拖放的项,当用户拖动项时指示拖放的位置,最后,在用户释放鼠标按钮时将项插入到它的新位置。 要完成这个任务,你需要为你的listbox窗口捕捉三条消息:WM_LBUTTONDOWN, WM_MOUSEMOVE,和WM_LBUTTONUP。 WM_LBUTTONDOWN处理程序方法通过查找用户单击的项目来初始化拖放过程。隐藏,复制Code

void CDragAndDropListBox::OnLButtonDown(UINT nFlags, CPoint point)
{
   CListBox::OnLButtonDown(nFlags, point);

   //clear all the flags
   m_MovingIndex = LB_ERR;
   m_MoveToIndex = LB_ERR;
   m_Captured = FALSE;
   m_Interval = 0;
   
   BOOL Outside;
   //find the item that they want to drag
   //and keep track of it. Later in the mouse move
   //we will capture the mouse if this value is set
   int Index = ItemFromPoint(point,Outside);
   if (Index != LB_ERR && !Outside)
   {
      m_MovingIndex = Index;
      SetCurSel(Index);
   }
}

WM_WMMOUSEMOVE处理程序方法做三件事。一种方法是,如果鼠标没有这样做,就捕获它。第二种方法是,如果用户将鼠标拖动到列表框窗口的上方或下方,则滚动列表框(这是通过计时器的帮助实现的)。最后,为了在被拖放的项上面画一条线,它还跟踪项的索引值,这样WM_LBUTTONUP就不必再查找信息了。隐藏,收缩,复制Code

void CDragAndDropListBox::OnMouseMove(UINT nFlags, CPoint point)
{
   CListBox::OnMouseMove(nFlags, point);
   if (nFlags & MK_LBUTTON)
   {
      if (m_MovingIndex != LB_ERR && !m_Captured)
      {
         SetCapture();
         m_Captured = TRUE;
      }
      BOOL Outside;
      int Index = ItemFromPoint(point,Outside);
      //if they our not on a particular item
      if (Outside)
      {
         CRect ClientRect;
         GetClientRect(&ClientRect);

         //if they are still within the listbox window, then
         //simply select the last item as the drop point
         //else if they are outside the window then scroll the items
         if (ClientRect.PtInRect(point))
         {
            KillTimer(TID_SCROLLDOWN);
            KillTimer(TID_SCROLLUP);
            m_Interval = 0;
            //indicates that the user wants to drop the item
            //at the end of the list
            Index = LB_ERR;
            Outside = FALSE;
         }
         else
         {
            DoTheScrolling(point,ClientRect);
         }
      }
      else
      {
         KillTimer(TID_SCROLLDOWN);
         KillTimer(TID_SCROLLUP);
         m_Interval = 0;
      }
      
      if (Index != m_MoveToIndex && !Outside)
      {
         DrawTheLines(Index);
      }
   }
}

接下来,WM_LBUTTONUP消息处理程序将执行实际的删除操作。它首先检查以确保在开始时有一个被拖动的项目。接下来,它检查以确保按钮在listbox窗口中被释放。如果不是,那就没什么可做的了。另一方面,如果它是在窗口中释放的,那么只需将该项插入到WM_MOUSEMOVE处理程序所指示的索引处的列表框中。隐藏,收缩,复制Code

void CDragAndDropListBox::OnLButtonUp(UINT nFlags, CPoint point)
{
   if (m_MovingIndex != LB_ERR && m_Captured)
   {
      KillTimer(TID_SCROLLDOWN);
      KillTimer(TID_SCROLLUP);
      m_Interval = 0;
      m_Captured = FALSE;
      ReleaseCapture();

      CRect Rect;
      GetClientRect(&Rect);
      //if they are still within the listbox window
      if (Rect.PtInRect(point))
      {
         InsertDraggedItem();
      }
      else
      {
         Invalidate();
         UpdateWindow();
      }
      m_MovingIndex = LB_ERR;
      m_MoveToIndex = LB_ERR;
   }

   CListBox::OnLButtonUp(nFlags, point);
}

使用的代码 要使用这个类,只需将一个变量(子类)附加到窗口上的listbox控件上,然后将这个变量从CListBox更改为CDragAndDropListBox。这是所有。隐藏,复制Code

// CDragDropListBoxSampleDlg dialog
class CDragDropListBoxSampleDlg : public CDialog
{
......

// Implementation
protected:
   CDragAndDropListBox  m_ListBox;
   
......
};

本文转载于:http://www.diyabc.com/frontweb/news171.html

posted @ 2020-08-04 01:50  Dincat  阅读(103)  评论(0编辑  收藏  举报