鼠标拖动Panel控件改变位置为什么要先ReleaseCapture?

ooolinux 2016-10-19 10:33:18
void __fastcall TForm1::Panel1MouseDown(TObject *Sender,
TMouseButton Button, TShiftState Shift, int X, int Y)
{
if(Button==mbLeft)
{
ReleaseCapture();
SendMessage(Panel1->Handle,WM_SYSCOMMAND,SC_MOVE+HTCAPTION,0);
}
}


为什么要先ReleaseCapture?
...全文
1415 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
huang123dao 2019-03-17
  • 打赏
  • 举报
回复
引用 16 楼 ooolinux 的回复:
觉得上面的理解还是不对,我重新理解了一下,鼠标拖动Panel,就是鼠标左键按下以后移动,按下的动作会由VCL产生SetCapture调用,使Panel(有Handle属于窗口控件)捕获了鼠标消息。因此只有ReleaseCapture以后,再
SendMessage(Panel1->Handle, WM_NCLBUTTONDOWN, HTCAPTION, 0);
模拟鼠标在Panel标题栏(窗口控件都有标题栏,虽然Panel看起来没有)按下,接下来的鼠标移动消息(没有被任何窗口捕获)使得,在标题栏按下加上移动鼠标,系统就处理为拖动Panel窗口(改变位置)了。


比较认同这种说法
ooolinux 2019-03-15
  • 打赏
  • 举报
回复
引用 13 楼 huang123dao 的回复:
先ReleaseCapture,应该就释放了鼠标捕获,使得系统不会向form发送鼠标消息。

然后再执行 SendMessage(hwnd, WM_NCLBUTTONDOWN, HTCAPTION, 0),

意思是不是就是向窗体发送一个消息,这个消息告诉它:鼠标左键在非客户区(标题栏)被按下。

然后窗体对该消息进行响应:鼠标在标题栏被按下,窗体会跟随鼠标移动。这个应该是系统内部运行机制。

而且该过程中,窗体不会再响应鼠标移动的消息,因为已经释放鼠标捕获了。


我的理解是这样的,鼠标拖动Panel,就是鼠标左键按下以后移动,按下的动作会由VCL产生SetCapture,使Panel客户区捕获了鼠标消息,因此直接
SendMessage(Panel1->Handle,WM_SYSCOMMAND,SC_MOVE+HTCAPTION,0);没有产生效果,如果先ReleaseCapture,再SendMessage模拟鼠标在Panel(属于窗口控件)标题栏按下,这个模拟按下代替了原来的客户区按下(偷梁换柱),以后移动鼠标就是相当于在按下标题栏的情况下移动鼠标,所以能移动Panel了。
两种SendMessage效果是一样的:
SendMessage(Panel1->Handle,WM_SYSCOMMAND,SC_MOVE+HTCAPTION,0);
SendMessage(Panel1->Handle, WM_NCLBUTTONDOWN, HTCAPTION, 0);
参考:
https://bbs.csdn.net/topics/392399775
ooolinux 2019-03-15
  • 打赏
  • 举报
回复
引用 17 楼 早打大打打核战争 的回复:
应该就是VCL为了支持拖放而捕捉了鼠标的缘故


不太明白~
  • 打赏
  • 举报
回复
应该就是VCL为了支持拖放而捕捉了鼠标的缘故
ooolinux 2019-03-15
  • 打赏
  • 举报
回复
觉得上面的理解还是不对,我重新理解了一下,鼠标拖动Panel,就是鼠标左键按下以后移动,按下的动作会由VCL产生SetCapture调用,使Panel(有Handle属于窗口控件)捕获了鼠标消息。因此只有ReleaseCapture以后,再
SendMessage(Panel1->Handle, WM_NCLBUTTONDOWN, HTCAPTION, 0);
模拟鼠标在Panel标题栏(窗口控件都有标题栏,虽然Panel看起来没有)按下,接下来的鼠标移动消息(没有被任何窗口捕获)使得,在标题栏按下加上移动鼠标,系统就处理为拖动Panel窗口(改变位置)了。
ooolinux 2019-03-15
  • 打赏
  • 举报
回复
链接:https://pan.baidu.com/s/1RiJ12GPeC1ztzvlAFUuQug
提取码:lyzc
复制这段内容后打开百度网盘手机App,操作更方便哦
huang123dao 2019-03-14
  • 打赏
  • 举报
回复
先ReleaseCapture,应该就释放了鼠标捕获,使得系统不会向form发送鼠标消息。

然后再执行 SendMessage(hwnd, WM_NCLBUTTONDOWN, HTCAPTION, 0),

意思是不是就是向窗体发送一个消息,这个消息告诉它:鼠标左键在非客户区(标题栏)被按下。

然后窗体对该消息进行响应:鼠标在标题栏被按下,窗体会跟随鼠标移动。这个应该是系统内部运行机制。

而且该过程中,窗体不会再响应鼠标移动的消息,因为已经释放鼠标捕获了。
  • 打赏
  • 举报
回复
是可以的。但是在其他窗口按键之后,捕获就会部分失效,因为只有激活的窗口可以捕获窗口位置之外的鼠标消息,后台窗口如果SetCapture,只有指针出现在该窗口的可见部分上的时候才有效。

ooolinux 2016-11-16
  • 打赏
  • 举报
回复
引用 10 楼 DelphiGuy 的回复:
SetCapture捕捉鼠标消息到指定hwnd,包括在hwnd之外的鼠标消息(但是鼠标按键消息其他窗口仍然能获得)。
那主要是移动消息了,按键消息其他窗口能获得,捕获的窗口也能同时获得吗?
  • 打赏
  • 举报
回复
SetCapture捕捉鼠标消息到指定hwnd,包括在hwnd之外的鼠标消息(但是鼠标按键消息其他窗口仍然能获得)。
ooolinux 2016-11-15
  • 打赏
  • 举报
回复
ooolinux 2016-11-15
  • 打赏
  • 举报
回复
引用 8 楼 DelphiGuy 的回复:
如果没有SetCapture,ReleaseCapture应该没有作用啊。
就是,鼠标在控件上按下,不知道VCL代码里面有没有调用了SetCapture? SetCapture捕获鼠标会导致什么情况呢?对这个API不是很理解。
  • 打赏
  • 举报
回复
如果没有SetCapture,ReleaseCapture应该没有作用啊。
ooolinux 2016-11-15
  • 打赏
  • 举报
回复
引用 6 楼 DelphiGuy 的回复:
我的意思是处理MouseDown、MouseMove、MouseUp也是可以实现拖动的,不需要SetCapture、ReleaseCapture
没错,用MouseDown、MouseMove、MouseUp来改变相对位移可以移动控件, 它这个例子主要是用到SendMessage(Panel1->Handle,WM_SYSCOMMAND,SC_MOVE+HTCAPTION,0), 我想搞懂为什么SendMessage之前要先ReleaseCapture,它这个代码里面没有SetCapture。
  • 打赏
  • 举报
回复
我的意思是处理MouseDown、MouseMove、MouseUp也是可以实现拖动的,不需要SetCapture、ReleaseCapture
ooolinux 2016-11-15
  • 打赏
  • 举报
回复
引用 4 楼 DelphiGuy 的回复:
捕捉的代码呢?实际上如果只是拖动组件的话,不需要SetCapture也是可以的。
就这几行代码,我试了,如果注释掉ReleaseCapture(),那SendMessage(Panel1->Handle,WM_SYSCOMMAND,SC_MOVE+HTCAPTION,0) 无法移动Panel1。 鼠标在控件上点击,VCL代码里面有没有调用了SetCapture?
  • 打赏
  • 举报
回复
捕捉的代码呢?实际上如果只是拖动组件的话,不需要SetCapture也是可以的。
ooolinux 2016-10-24
  • 打赏
  • 举报
回复
引用 1 楼 rouqing 的回复:
SetCapture()和ReleaseCapture()必须成对使用 当你不在需要继续获得鼠标消息就要应该调用ReleaseCapture()释放掉,否则别的线程想调用就会失败 http://blog.csdn.net/lanyzh0909/article/details/5543399
不太懂为什么SendMessage前要先ReleaseCapture?
纯冰糖 2016-10-19
  • 打赏
  • 举报
回复
SetCapture()和ReleaseCapture()必须成对使用 当你不在需要继续获得鼠标消息就要应该调用ReleaseCapture()释放掉,否则别的线程想调用就会失败 http://blog.csdn.net/lanyzh0909/article/details/5543399

1,221

社区成员

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

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