高手赐教,怎样实现这样的控件拖放?

qybao 2003-12-30 03:21:59
窗体的控件可以随意拖放,而且所有容器支持控件拖放(前提),
现在我想通过SendMessage发送消息实现该控件的拖放,
请问如何实现?

比如,窗体中的某个按钮(Button)在一个面板(Panel)上,
我现在知道该按钮(Button)的句柄,Panel的句柄可要可不要(我认为),
我想用SendMessage发送消息,使得按钮(Button)拖动到另一个面板(Panel)上,这个面板(Panel)的句柄也是可要可不要(我认为)。

本人的想法是这样的:
1.先给按钮(Button)发送鼠标左键按下的消息 WM_LBUTTONDOWN
2.然后再发送鼠标移动的消息 WM_MOUSEMOVE 把鼠标移到另一个面板(Panel)上
3.最后再发送鼠标左键释放消息 WM_LBUTTONUP
问题是发送鼠标移动消息的时候,什么反应也没有,不知道 WM_MOUSEMOVE 这个消息是如何发送的,而且我查看过帮助,发送该消息时,可以再带个参数 MK_LBUTTON ,这样可以在移动的时候同时也按住鼠标左键,是这样吗?

本人还想过另一种方法:
就是把按钮剪贴到剪贴板上,然后再从剪贴板复制到另一个面板上,这样会有什么问题吗?不过这样就需要知道目标面板(Panel)的句柄,而根据现有的条件,本人有可能无法获得目标Panel的句柄,因为是别人写的程序,里面的Panel很多,而且也没有相关的字符串标识(text,name或caption没有),但如果是鼠标拖动的话,可以找到位置(因为有相对位置)。

还望各位高手指点一下如何实现,或者给点思路和意见,分不够可以再加!

...全文
257 25 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
25 条回复
切换为时间正序
请发表友善的回复…
发表回复
piaoran688 2004-01-13
  • 打赏
  • 举报
回复
学习!
qybao 2004-01-06
  • 打赏
  • 举报
回复
to 12rain(中雨~百年孤独)
1.
Panel的句柄是未知的,正是因为窗体上有多个Panel,而且是别人写的程序,是不确定的,Panel上的控件也是不确定的,所以不能根据Panel上的控件去定位Panel;

2.
SetParent是不可行的,因为如果窗体不支持拖放,控件应该是“漂浮”在窗体上面,而不是强制设置为窗体的子窗体;

3.
之所以用消息处理,是因为用户对控件的拖放也是不确定的,用户不一定想拖放到某个Panel上,只是想拖到某个位置,如果该位置刚好有Panel或其他容器,而且支持拖放,那该控件就刚好成为Panel或容器的子窗体;

4.
我现在遇到的难点也就是鼠标移动消息不成功,我一直在找资料研究分析中;

5.
钩子函数我试过了,不过只能针对一个程序,而且也要发送消息来处理;问题是,我的程序是用来控制用户的程序的,用户的程序也是不定的,而且开发的语言也是不定的,那样钩子函数好像也不是好的解决方法;

不管怎样,多谢你的帮忙,这个问题解决了,一定要开帖庆祝!




qybao 2004-01-05
  • 打赏
  • 举报
回复
to 12rain(中雨~百年孤独)
Panel的句柄不一定能拿到的
首先我的程序是去控制别人的程序
Panel也是别人程序的Panel
我用EnumChildWindows或GetWindow得到子窗体句柄的时候
如果窗体上有多个Panel
而一般开发的人对Panel都不赋任何名称的(也就是空的Caption)
请问我该如何定位这个Panel?

而且SetParent有强制性
如果Panel不是Dockable
控件移动到Panel上时应该是“漂浮”的
但SetParent就会让控件变为Panel的子窗体
这样似乎也有背用户的要求
而且很有可能用户是把控件拖到桌面上的
所以我一直想用SendMessage来处理就是这个原因
只要鼠标按住控件然后移动一定的位置
至于移动以后停留在哪里就不管了
如果刚好在某个Panel上且该Panel是Dockable的
那就成为该Panel的子窗体
否则就“漂浮”着


12rain 2004-01-05
  • 打赏
  • 举报
回复
PS、

我用SendMessage(句柄,WM_MOUSEMOVE, x,y);//其中x,y我不知道如何设置
----------------------------------------------------------------------
SendMessage(Handle, WM_MOUSEMOVE, MK_LBUTTON, MakeWord(xPos, yPos));


xPos

Value of the low-order word of lParam. Specifies the x-coordinate of the cursor. The coordinate is relative to the upper-left corner of the client area.

yPos

Value of the high-order word of lParam. Specifies the y-coordinate of the cursor. The coordinate is relative to the upper-left corner of the client area.


12rain 2004-01-05
  • 打赏
  • 举报
回复
1、
Panel的句柄、如果Panel上有按钮或者其他控件、至少可以这样取得Panel.Handle := Windows.GetParent(Button.Hanle);

不要面板的句柄也行、可设为窗体的、至少要保证按钮可移出面板
Windows.SetParent(Button.Hanle, Form.Handle);
SetWindowPos(Button.Hanle, HWND_TOP, 100, 150, 0, 0, SWP_NOSIZE);

2、
试了一下你的发送WM_LBUTTONDOWN、WM_MOUSEMOVE消息的、鼠标点击是可以、但无法实现移动、是否需要再处理消息?或者不发送消息、写个钩子函数、只是好象也比较麻烦、只有句柄、不知道要怎么控制位置




cll007 2004-01-05
  • 打赏
  • 举报
回复
学习一下下哦
halfdream 2004-01-02
  • 打赏
  • 举报
回复
可以去理解一下WINDOWS关于OLE拖放实现的思想,诸如IDataObject等.
在GOOGLE里面搜索应该有一些..
12rain 2004-01-01
  • 打赏
  • 举报
回复
SetParent可能需要这样调用WINDOWS.SetParent
12rain 2004-01-01
  • 打赏
  • 举报
回复
既然知道按钮的句柄、则可用SetWindowPos设置它的位置来实现控件的移动、
如果按钮是在面板上、则Panel的句柄也是需要的、可用GetParent取得(或者EnumChildWindows函数)、取得
目标面板的句柄后、用SetParent把按钮移到面板上(SetParent(button.handle, panel.handle)、再进行调整位置:
SetWindowPos(button.handle, HWND_TOP, 10, 10, 0, 0, SWP_NOSIZE);//X,Y:位置;
SWP_NOSIZE屏蔽cx,cy参数
hkbarton 2003-12-31
  • 打赏
  • 举报
回复
能把你的那个客户程序发给我一份吗?我可以帮你试试
我的mail是
hk.barton@sohu.com
qybao 2003-12-31
  • 打赏
  • 举报
回复
客户端提供的程序支持拖放
也就是可以用鼠标拖放该程序的控件从一个位置到另一个位置
就像我们打开文件夹一样
里面的文件或文件夹都可以拖放
不管实现原理如何
只要我用鼠标点击拖放移动总是可以的吧
既然可以
那就应该可以通过发送消息去自动实现而不用手动去拖放
目前我是发送WM_MOUSEMOVE消息时鼠标并没有移动
这是什么原因?
hkbarton 2003-12-31
  • 打赏
  • 举报
回复
客户提供的程序支持拖放,那拖放的原理是什么?还要看客户程序是怎么实现拖放的。我觉得和这个有关系
qybao 2003-12-31
  • 打赏
  • 举报
回复
to XXSingle(三笑留情〓★▲◆)
本来客户提供的程序就是支持拖放的
我的项目就是要做一个控制平台
让用户可以在我的平台上控制客户自己的程序
现在在拖放的实现上遇到了困难
所以来求救了
以前不是看到很多高手经常在这里活跃的吗
现在怎么都不见了
是放假了么
高手们,帮帮忙啊,分不够再加

XXSingle 2003-12-31
  • 打赏
  • 举报
回复
能得到句柄就相当不错了,楼主还想.............
qybao 2003-12-31
  • 打赏
  • 举报
回复
我想再说明一下:
我要移动的控件不是自己程序的控件
而是其他程序(别人写好的,而且开发语言是未知的)窗体里的控件
我通过Windows API获得了该控件的句柄
现在我想实现该控件的拖放
拖放的过程及结果也是在其他程序的窗体里
所以自己的程序的各种鼠标事件(MouseDown等等)应该是不适用的
那样只能控制自己程序窗体的控件
而不是其他程序窗体里的控件

我不知道大家明白我的意思吗?
我想通过自己的程序去控制别人的程序
移动的控件在别人的程序里
所以我认为只能通过发送消息来处理
但我发送消息后并没有能实现
鼠标左键按下和释放是可以的
就是鼠标移动的时候没反应
希望高手们帮我看看到底如何发送鼠标移动消息

多谢楼上的兄弟,虽然你们结果不是我想要的
这个问题现在是本人做的项目的一个难点
希望更多的高手来帮忙解决这个问题
qybao 2003-12-31
  • 打赏
  • 举报
回复
to zsy_good(只要坚定不移的走下去,那一定会成功)
不是这个意思
不管怎样
感谢你的帮助

zsy_good 2003-12-31
  • 打赏
  • 举报
回复
你还可以判断时候通过了容器,如果时。就可以设置parent属性
zsy_good 2003-12-31
  • 打赏
  • 举报
回复
最简单的
procedure TForm1.Button2MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
ReleaseCapture;
Button2.Perform(WM_SYSCOMMAND,$f012,0);
end;
qybao 2003-12-31
  • 打赏
  • 举报
回复
to hkbarton(宁静至远)(西南交大)
感谢你的热情帮助
不过客户程序是客户内部自己人开发的
具有一定的保密性
或者你自己写个小例子试试
你可以写两个程序
一个程序你可以设置窗体里的任意一个控件可以拖放(DragKind:=dkDock;DragMode:=Automatic)
并在该窗体里放两个Panel,设置支持拖放(DokeSite:=True)
不用添加什么代码,程序运行后,该控件可以通过鼠标在两个Panel里拖放
然后你再写另一个程序,通过发送Windows消息去控制第一个程序里的控件
让该控件也能在两个Panel里拖放
我用SendMessage(句柄,WM_MOUSEMOVE, x,y);//其中x,y我不知道如何设置,查看相关资料,如果x设置为MK_LBUTTON时相当于移动鼠标的同时按下了鼠标左键,y是鼠标移动的位置,高16位是纵坐标,低16位是横坐标,你能帮我试试看,通过WM_MOUSEMOVE如何实现鼠标移动?发送消息时里面的参数是什么,写出一段通过消息能成功移动鼠标的代码就可以了。
另外我还想问,如果用户需要移动的是文件夹里的文件或文件夹,不是通过复制粘贴,也是通过发送消息,让鼠标自动实现拖动文件或文件夹到新的位置,这样又该如何实现?因为文件夹的对象不像窗体对象一样可以获得句柄,或者还有什么新的方法吗?
兄弟,拜托你了!

道素 2003-12-31
  • 打赏
  • 举报
回复
对不起刚才没看全你的要求,先取消我前面的发言
加载更多回复(5)

1,183

社区成员

发帖
与我相关
我的任务
社区描述
Delphi Windows SDK/API
社区管理员
  • Windows SDK/API社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧