Cure_shy

我的学习历程

用户操作
[即时聊天] [发私信] [加为好友]
舒红怡ID:cureSHY
6582次访问,排名15652(1),好友0人,关注者0人。
原本是小舒,现却成老舒,不想再隐身了,希望所有知道我的都找上门来吧!
cureSHY的文章
原创 4 篇
翻译 0 篇
转载 4 篇
评论 1 篇
Cure_shy的公告
我又开始学习了!
最近评论
文章分类
收藏
    相册
    存档
    软件项目交易
    订阅我的博客
    XML聚合  FeedSky
    订阅到鲜果
    订阅到Google
    订阅到抓虾
    订阅到BlogLines
    订阅到Yahoo
    订阅到GouGou
    订阅到飞鸽
    订阅到Rojo
    订阅到newsgator
    订阅到netvibes

    原创 DELPHI中的拖动开发(2)收藏

    新一篇: TStringGrid使用(1) | 旧一篇: DELPHI中拖放的操作

    9.2开发拖放功能的一般步骤

      拖放作为Windows提供的一种方便操作对象的功能,在Delphi中可以很容易地开发
    出来。根据拖放操作的过程可以把开发步骤划分为四个阶段,即:

      ●开始拖动操作

      ●接收拖动项目

      ●放下拖动项目

      ●终止拖动操作

      在介绍过程中我们将结合一个TabSet(标签集)的拖放操作实例。界面设计如图。
    在运行时当用户把一个标签拖动到另一个标签的位置时,该标签将移动到该位置并引起
    标签集的重新布置。

      

      9.2.1开始拖动操作

      当拖动模式(DragMode)设置为dmAutomatic时,用户在源控件上按下鼠标时拖动自动
    开始;当设置为dmManual时通过处理鼠标事件来决定拖动是否开始。如果想开始拖动调
    用BeginDrag方法。

      在TabSet拖放中,我们用下面的MouseDown事件处理过程来开始一个标签的拖动。

      首先判断按下的是否是左键,而后再判断项目是否合法。

    procedure TForm1.TabSet1MouseDown(Sender: TObject; Button: TMouseButton;

    Shift: TShiftState; X, Y: Integer);

    var

    DragItem: Integer;

    begin

    if Button = mbLeft then

    begin

    DragItem := TabSet1.ItemAtPos(Point(X, Y));

    if (DragItem > -1) and (DragItem < TabSet1.Tabs.Count) then

    TabSet1.BeginDrag(False);

    end;

    end;


      9.2.2接收拖动项目

      一个控件能否接收拖动项目是由该控件的OnDragOver事件决定的。在TabSet拖动中,主要是利用鼠标的位置进行判断。


    procedure TForm1.TabSet1DragOver(Sender, Source: TObject; X, Y: Integer;

    State: TDragState; var Accept: Boolean);

    var

    DropPos: Integer;

    begin

    if Source = TabSet1 then

    begin

    DropPos := TabSet1.ItemAtPos(Point(X, Y));

    Accept := (DropPos > -1) and (DropPos <> TabSet1.TabIndex) and

    (DropPos < TabSet1.Tabs.Count);

    end;

    else

    Accept := False;

    end;


      9.2.3放下拖动项目

      当OnDragOver事件处理过程返回的Accept为True且项目被放下时,由OnDragDrop事
    件处理过程来完成拖动放下后的响应。在TabSet拖放实例中是改变标签的位置。

    procedure TForm1.TabSet1DragDrop(Sender, Source: TObject; X, Y: Integer);

    var

    OldPos: Integer;

    NewPos: Integer;

    begin

    if Source = TabSet1 then

    begin

    OldPos := TabSet1.TabIndex;

    NewPos := TabSet1.ItemAtPos(Point(X, Y));

    if (NewPos > -1) and (NewPos <> OldPos) then

    TabSet1.Tabs.Move(OldPos, NewPos);

    end;

    end;


      9.2.4结束拖动操作

      结束拖动操作的方式有两种:或者是用户释放了鼠标键或者是程序用EndDrag方法
    强行中止拖动。结束拖动操作的后果有两种:放下被接受或放下被忽略。

      拖动操作结束后源控件都要收到一条消息响应拖动结束事件OnEndDrag。

      9.3  拖放应用实例:文件管理器的拖放支持

      在第六章最后开发的文件管理器应用实例,虽然功能上已初具规模,但在操作上
    与Windows的文件管理器相比还有很大不足。其中最大的缺陷是它不支持文件的拖放移动
    和拖放拷贝。在这一章结束的时候,我们可以来弥补这一缺陷了。

      文件拖放移动指的是当用户把一个文件拖动到目录树下的某一目录并放下时,文件
    将自动移动到该目录中;文件拖放拷贝指的是当用户把一个文件拖动到某个驱动器标签
    上并放下时,文件将自动拷贝到该驱动器的当前目录下。作为源控件的文件列表框和作
    为目标控件的目录树、驱动器标签可以位于不同的子窗口。驱动器的当前目录是任一子
    窗口的最新操作结果,而不论这一子窗口与拖动源、拖动目标是否有关系。

      为了实现上述功能,有两个问题必须首先解决:

      1.如何记录每一驱动器的当前目录?

      为此我们定义了一个全局变量:

      

      var CurentDirList: Array[0...25] of string[70];

      在DirectoryOutline的OnChange事件中:

    procedure TFMForm.DirectoryOutlineChange(Sender: TObject);

    begin

    CreateCaption;

    FileList.clear;

    FileList.Directory := DirectoryOutline.Directory;

    FileList.Update;

    CurrentDirList[DriveTabSet.TabIndex] := DirectoryOutline.Directory;

    FileManager.DirectoryPanel.Caption := DirectoryOutline.Directory;

    end; 


      由于DriveTabSet在响应OnDragDrop事件前先响应OnClick事件,并由该事件激
    发DirectoryOutline的Onchange事件,因而可保证在任何时候OnDragDrop事件中用
    到的CurrentDirList数组项不为空字符串。

      2.如何保证移动、拷贝与子窗口的无关性?

      在这里一个关键问题是我们判断源控件时是用is操作符进行类型检查:

      If Source is TFileList then …

      如果我们用下面的语句:

      

      If Source = FileList then

      …

      则移动、拷贝操作将限制在本子窗口范围内。

      当解决了上述问我们的工作就只是遵循拖放的一般开发步骤,按步就班来完成了。

      1.FileList开始拖动操作

    procedure TFMForm.FileListMouseDown(Sender: TObject; Button: TMouseButton;

    Shift: TShiftState; X, Y: Integer);

    begin

    if Button = mbLeft then

    with Sender as TFileListBox do

    begin

    if ItemAtPos(Point(X, Y), True) >= 0 then

    BeginDrag(False);

    end;

    end;

      ItemAtPos用来检查当前是否有文件存在。而BeginDrag方法传递参数False,允许FileList单独处理鼠标事件而并不开始拖动。事实上这种情况是大量存在的。

      

      2.DirectoryOutline、DriveTabSet决定是否能接受拖动的就地放下。


    procedure TFMForm.DirectoryOutlineDragOver(Sender, Source: TObject; X,

    Y: Integer; State: TDragState; var Accept: Boolean);

    begin

    if Source is TFileListBox then

    Accept := True;

    end;


    procedure TFMForm.DriveTabSetDragOver(Sender, Source: TObject; X,

    Y: Integer; State: TDragState; var Accept: Boolean);

    var

    PropPos: Integer;

    begin

    if Source is TFileListBox then

    with DriveTabSet do

    begin

    PropPos := ItemAtPos(Point(X,Y));

    Accept := (PropPos > -1) and (PropPos < Tabs.Count);

    end;

    end;


      DirectoryOutline是无条件的接受,而DriveTabSet需检查是否是合法的标签。

      

      3.拖动放下的响应

      DirectoryOutline的拖动放下用于实现文件移动功能。程序中调用ConfirmChange 事件
    处理过程,目标路径由DirctoryOutline.Items[GetItem(X,Y)].FullPath来得到。


    procedure TFMForm.DirectoryOutlineDragDrop(Sender, Source: TObject; X,

    Y: Integer);

    begin

    if Source is TFileListBox then

    with DirectoryOutline do

    begin

    ConfirmChange('Move',FileList.FileName, Items[GetItem(X, Y)].FullPath);

    end;

    end;

      DriveTabSet的拖动放下用于实现文件拷贝功能。程序中把当前位置转化为相应的驱
    动器号,目标路径由CurrentDirList[DriveTabSet.TabIndex]获得。

    procedure TFMForm.DriveTabSetDragDrop(Sender, Source: TObject; X,Y: Integer);

    var

    APoint: TPoint;

    begin

    APoint.X := X; APoint.Y := Y;

    DriveTabSet.TabIndex := DriveTabSet.ItemAtPos(APoint);

    if Source is TFileListBox then

    with DriveTabSet do

    begin

    if CurrentDirList[TabIndex] <> '' then

    ConfirmChange('Copy',TheFilename,CurrentDirList[TabIndex]);

    end;

    end;


      4.FileList响应拖动结束,更新文件列表

    procedure TFMForm.FileListEndDrag(Sender, Target: TObject; X, Y: Integer);

    begin

    if Target <> nil then FileList.Update;

    end;

    发表于 @ 2004年11月11日 16:41:00|评论(loading...)|编辑

    新一篇: TStringGrid使用(1) | 旧一篇: DELPHI中拖放的操作

    评论

    #彭为 发表于2004-11-28 16:18:00  IP:
    TrackBack来自《开发笔记:DELPHI中的拖动开发(1)(2) 》

    Ping Back来自:blog.csdn.net
    发表评论  


    登录
    Csdn Blog version 3.1a
    Copyright © Cure_shy