程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Delphi >> 發掘ListBox的潛力(二):鼠標拖放插入點提示

發掘ListBox的潛力(二):鼠標拖放插入點提示

編輯:Delphi
  鼠標拖放是Windows常見的操作,比如拷貝文件就可用拖放方式進行。在我們編寫的應用程序中,有時為了方便用戶操作需要支持鼠標拖放。對於大部分的VCL控件只要鼠標將DragMode設為dmAutomatic,就可以在OnDragDrop、OnDragOver和OnEndDrag中處理拖放事件。與Drag類似的還有一個Dock方式用於支持控件懸浮,控件在懸浮時會顯示一個虛線框來表示懸浮位置,而Drag方式卻沒有這功能。現在讓我們嘗試在Listbox中顯示拖放插入點。
  上面提及的三個事件中OnDragOver是用來拖放鼠標經過控件上面時產生的,要顯示插入點提示當然是在這裡進行處理了。事件中先用Listbox.ItemAtPos(Point(X, Y) , true)取鼠標所有在的打目Index,再用Listbox.ItemRect(Index)取得作圖區域,最後在區域中畫出提示線框。下面給出代碼:
  
  
Unit1.pas內容 unit Unit1;

  

  interface

  uses
    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
    Dialogs, StdCtrls;

  type
    TForm1 = class(TForm)
      ListBox1: TListBox;
      ListBox2: TListBox;
      procedure ListBox1DragDrop(Sender, Source: TObject; X, Y: Integer);
      procedure ListBox1DragOver(Sender, Source: TObject; X, Y: Integer;
        State: TDragState; var Accept: Boolean);
    private
      FDragOverObject: TObject;    //ListBox1DragDrop、ListBox1DragOver由多個Listbox共享,這裡記錄當前那個Listbox接受鼠標拖放
  
    FDragOverItemIndex: Integer;  //記錄鼠標所在條目的Index
      procedure DrawInsertLine;
    public
      { Public declarations }
    end;

  var
    Form1: TForm1;

  implementation

  {$R *.dfm}
  

  {========================================================================
    DESIGN BY :  彭國輝
    DATE:        2004-12-24
    SITE:       
http://kacarton.yeah.Net/
    BLOG:        http://blog.csdn.Net/nhconch
    EMAIL:       kacarton#sohu.com

    文章為作者原創,轉載前請先與本人聯系,轉載請注明文章出處、保留作者信息,謝謝支持!
  =========================================================================}

  
  procedure TForm1.ListBox1DragDrop(Sender, Source: TObject; X, Y: Integer);
  var
      i: integer;
  begin
    //拖放完成,將內容從原來的Listbox讀到目標Listbox
    with TListBox(Source) do begin
  
    i := TListBox(Sender).ItemAtPos(Point(X, Y) , true);
      if i<>-1 then
        TListBox(Sender).Items.InsertObject(i, Items[ItemIndex], Items.Objects[ItemIndex])
      else
        i := TListBox(Sender).Items.AddObject(Items[ItemIndex], Items.Objects[ItemIndex]);
      if (Sender=Source) and (i>ItemIndex) then i := i-1;
      DeleteSelected;
      if (Sender=Source) then ItemIndex := i;
    end;
    FDragOverObject := nil;
    FDragOverItemIndex := -1;
  end;

  procedure TForm1.ListBox1DragOver(Sender, Source: TObject; X, Y: Integer;
    State: TDragState; var Accept: Boolean);
  var
    Index: Integer;
  begin
    Accept := (Source is TListBox) and (TListBox(Source).ItemIndex>-1);  //只接受來自Listbox的內容
  
  if not Accept then Exit;
    if (FDragOverObject<>nil) and (Sender<>FDragOverObject) then
      DrawInsertLine; //鼠標離開Listbox時,擦除插入位置提示線框
  
  Index := TListBox(Sender).ItemAtPos(Point(X, Y) , true);
    if (FDragOverObject = Sender) and (FDragOverItemIndex = Index) then Exit; //當鼠標在同一條目上移動時,只畫一次即可
    if (FDragOverObject = Sender) and (FDragOverItemIndex <> Index) then
      DrawInsertLine; //鼠標移到新位置,擦除舊的插入位置提示線框
  
  FDragOverObject := Sender;
    FDragOverItemIndex := Index;
    DrawInsertLine;   //畫出插入位置提示線框
  end;

  procedure TForm1.DrawInsertLine;
  var
    R: TRect;
  begin
    if FDragOverObject = nil then Exit;
    with TListBox(FDragOverObject) do begin
  
    if FDragOverItemIndex > -1 then begin
  
      R := ItemRect(FDragOverItemIndex);
        R.Bottom := R.Top + 4;
      end else if Items.Count>0 then begin
        R := ItemRect(Items.Count-1);
        R.Top := R.Bottom - 4;
      end else begin
  
      Windows.GetClIEntRect(Handle, R);
        R.Bottom := R.Top + 4;
      end;
  
    DrawFocusRect(Canvas.Handle, R);
      InflateRect(R, -1, -1);
      DrawFocusRect(Canvas.Handle, R);
    end;
  end;

  end.
  

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved