程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> C++ Builder中實現拖放功能

C++ Builder中實現拖放功能

編輯:關於C++

Windows中的拖放功能大家一定很熟悉了,如文件的轉移,拷貝等操作用鼠標輕輕一拖即可,在編寫程序中有時也用到拖放,那麼如何實現呢?現以C++ Builder5(簡稱CB5)為例,分析拖放功能的具體實現。

一.工具條的拖放

---- 要實現拖放功能,首先必須了解幾個與拖放有關的屬性和方法, 對於TControl控件,CB5提供了三個屬性,DockSite,DragKind和DragMode。靈活運用這三個屬性會得到意想不到的效果。這三個屬性的意義是:

---- DockSite:指定當前控件是否接受Drag-and-Dock類型的操作

---- DragKind:拖放種類,分為dkDrag和dkDock兩種

---- DragMode:拖放模式,分為自動和手動模式兩種

---- 其中Dock操作是指某控件脫離它的Parent,轉而成為另一個控件的Child,也就是兩個控件合並。若某一控件的DockSite為True,表明它接受執行Dock操作的某控件,並成為它的Parent。

---- 著名的Office工具條可以隨意拖放,其實實現起來很簡單:在Form上放一CoolBar控件,再在CoolBar控件上隨意放幾個ToolBar控件,它們的屬性設置代碼如下:

CoolBar1.DockSite=true;

ToolBar1.DragKind=dkDock;

ToolBar1.DragMode= dmAutomatic;

---- 其它ToolBar的屬性設置與ToolBar1的屬性設置相同,編譯運行程序,拖動工具條試試,Cool極了吧。

二、任何兩上控件間的拖放

---- 與此操作有關的幾個函數有:

---- BeginDrag:開始執行拖放操作,如果控件的DragMode為dmManual,則必須調用此函數,如果DragMode為dmAutomatic,則不用調用。

---- OnDragOver:當被拖放的對象經過此控件時觸發此事件,其中的參數Accept表示是否接受拖放的對象。

---- OnDragDrop:當放下被拖放的對象時觸發此事件。

---- 下面舉例說明拖放的實現過程:

---- 在CB5中新建一工程,在Form1上放兩個ListBox,分別命名為ListBox1,ListBox2,打開ListBox1的Items屬性框,隨便輸入幾行字符串。

---- 其屬性設置如下:

ListBox1->MultiSelect=true; // MultiSelect屬性設為true,表示可以多選
ListBox1->DragMode= dmAutomatic;
ListBox2->MultiSelect=true;
ListBox2->DragMode= dmAutomatic; //兩個ListBox拖放事件相同,可以互相拖放
ListBox2->OnDragOver= ListBox1DragOver;
ListBox2->OnDragDrop= ListBox1DragDrop;
ListBox2->OnStartDrag= ListBox1StartDrag;

在頭文件中設置兩個int型變量CurIndex,NewIndex

程序代碼如下:

//-----------------------------------------------------------
#include < vcl.h >
#pragma hdrstop
#include "unit1.h"
#include "FileCtrl.hpp"
//-----------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//----------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
     : TForm(Owner)
{
}

//----------------------------------------------------------

void __fastcall TForm1::ListBox1StartDrag(TObject *Sender,  TDragObject *&DragObject)
{
    //開始執行拖放事件時記錄ListBox->ItemIndex;
    CurIndex=((TListBox *)Sender)->ItemIndex;
}

//----------------------------------------------------------

void __fastcall TForm1::ListBox1DragDrop(TObject *Sender, TObject *Source,  int X, int Y)
{
int index;
if(Sender==Source) //如果Sender等於Source,表明在同一控件內執行操作,本例用來交換ListBox中的任意兩個Items
  {
    NewIndex=Y/(ListBox1->ItemHeight);//得到拖放後的ItemIndex
    //如果ItemIndex大於ListBox中的Item數,表示拖到最後一個
   NewIndex=NewIndex< ((TListBox *)Sender)- >Items->Count?
   NewIndex:((TListBox *)Sender)->Items->Count-1;
        //執行Move操作,移動Item
   ((TListBox *)Sender)->Items->Move(CurIndex,NewIndex);
   }
     //如果Sender不等於Source,表明在兩個控件間執行操作
     //此例是將數據從一ListBox拖到另一個ListBox
else
  { //若只選中一項
   if(((TListBox *)Source)->SelCount==1)
      {
      ((TListBox *)Sender)->Items->Add(((TListBox *)Source)-> Items->Strings[((TListBox *)Source)->ItemIndex]);
     ((TListBox *)Source)->Items->Delete(((TListBox *)Source)-> ItemIndex);
      }
       //多選操作
     if(((TListBox *)Source)->SelCount>=1)
     {
     //循環操作,測試哪些項被選中
     for(index=0;index< ((TListBox *)Source)- >Items->Count; index++)
     if(((TListBox *)Source)->Selected[index])
       ((TListBox *)Sender)->Items->Add(((TListBox *)Source)-> Items->Strings[index]);
      //從後向前刪除Source控件中數據
   for(index=((TListBox *)Source)->Items->Count-1;index>=0;index--)
       if(((TListBox *)Source)->Selected[index])
     ((TListBox *)Source)->Items->Delete(index);
   }
   }
}

//----------------------------------------------------------

void __fastcall TForm1::ListBox1DragOver(TObject *Sender, TObject *Source,int X, int Y, TDragState State, bool &Accept)
{
//本例中如果原控件各目標控件都為ListBox控件,則接受拖放
Accept = Source->ClassNameIs("TListBox")&& Sender->ClassNameIs("TListBox");
}

運行程序,用鼠標拖拖看。

//----------------------------------------------------------

本程序在PWin98+BCB5下編譯運行通過

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