首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > .NET >

TImage拖拽为什么变成了一个新窗囗,该如何解决

2012-03-13 
TImage拖拽为什么变成了一个新窗囗我delphi7,在Form上放一个TImage,然后设置DragKind为dkDock,设置DragMod

TImage拖拽为什么变成了一个新窗囗
我delphi7,在Form上放一个TImage,然后设置DragKind为dkDock,设置DragMode为dmAutomatic,然后运行拖拽时发现TImage脱离了Form,自己变成了一个新窗囗,这是为什么?

[解决办法]
在C++ Builder中实现拖放功能

.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;
//如果Sender等于Source,表明在同一控件内执行操作
//本例用来交换ListBox中的任意两个Items
if(Sender==Source)
{
//得到拖放后的ItemIndex
NewIndex=Y/(ListBox1-> ItemHeight);
//如果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 ");
}
运行程序,用鼠标拖拖看。

[解决办法]
TO 楼主: 你既然想用停靠,那我就按停靠的思路给你解决的. 如果不用Form.DockSite := True;那么连你说的 "奇数 "停靠, "偶数 "单独打开一个窗口,都不会出现.

停靠就是这样的. 你可以在两个Form 之间拖放试试,就不出现这种情况了.

热点排行