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

时间:2020-12-01 21:52:53
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?

12 个解决方案

#1


SetCapture()和ReleaseCapture()必须成对使用
当你不在需要继续获得鼠标消息就要应该调用ReleaseCapture()释放掉,否则别的线程想调用就会失败

http://blog.csdn.net/lanyzh0909/article/details/5543399

#2


引用 1 楼 rouqing 的回复:
SetCapture()和ReleaseCapture()必须成对使用
当你不在需要继续获得鼠标消息就要应该调用ReleaseCapture()释放掉,否则别的线程想调用就会失败

http://blog.csdn.net/lanyzh0909/article/details/5543399


不太懂为什么SendMessage前要先ReleaseCapture?

#3


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

#4


捕捉的代码呢?实际上如果只是拖动组件的话,不需要SetCapture也是可以的。

#5


引用 4 楼 DelphiGuy 的回复:
捕捉的代码呢?实际上如果只是拖动组件的话,不需要SetCapture也是可以的。


就这几行代码,我试了,如果注释掉ReleaseCapture(),那SendMessage(Panel1->Handle,WM_SYSCOMMAND,SC_MOVE+HTCAPTION,0) 无法移动Panel1。
鼠标在控件上点击,VCL代码里面有没有调用了SetCapture?

#6


我的意思是处理MouseDown、MouseMove、MouseUp也是可以实现拖动的,不需要SetCapture、ReleaseCapture

#7


引用 6 楼 DelphiGuy 的回复:
我的意思是处理MouseDown、MouseMove、MouseUp也是可以实现拖动的,不需要SetCapture、ReleaseCapture


没错,用MouseDown、MouseMove、MouseUp来改变相对位移可以移动控件,
它这个例子主要是用到SendMessage(Panel1->Handle,WM_SYSCOMMAND,SC_MOVE+HTCAPTION,0),
我想搞懂为什么SendMessage之前要先ReleaseCapture,它这个代码里面没有SetCapture。

#8


如果没有SetCapture,ReleaseCapture应该没有作用啊。

#9


引用 8 楼 DelphiGuy 的回复:
如果没有SetCapture,ReleaseCapture应该没有作用啊。


就是,鼠标在控件上按下,不知道VCL代码里面有没有调用了SetCapture?
SetCapture捕获鼠标会导致什么情况呢?对这个API不是很理解。

#10


SetCapture捕捉鼠标消息到指定hwnd,包括在hwnd之外的鼠标消息(但是鼠标按键消息其他窗口仍然能获得)。

#11


引用 10 楼 DelphiGuy 的回复:
SetCapture捕捉鼠标消息到指定hwnd,包括在hwnd之外的鼠标消息(但是鼠标按键消息其他窗口仍然能获得)。


那主要是移动消息了,按键消息其他窗口能获得,捕获的窗口也能同时获得吗?

#12


是可以的。但是在其他窗口按键之后,捕获就会部分失效,因为只有激活的窗口可以捕获窗口位置之外的鼠标消息,后台窗口如果SetCapture,只有指针出现在该窗口的可见部分上的时候才有效。

#1


SetCapture()和ReleaseCapture()必须成对使用
当你不在需要继续获得鼠标消息就要应该调用ReleaseCapture()释放掉,否则别的线程想调用就会失败

http://blog.csdn.net/lanyzh0909/article/details/5543399

#2


引用 1 楼 rouqing 的回复:
SetCapture()和ReleaseCapture()必须成对使用
当你不在需要继续获得鼠标消息就要应该调用ReleaseCapture()释放掉,否则别的线程想调用就会失败

http://blog.csdn.net/lanyzh0909/article/details/5543399


不太懂为什么SendMessage前要先ReleaseCapture?

#3


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

#4


捕捉的代码呢?实际上如果只是拖动组件的话,不需要SetCapture也是可以的。

#5


引用 4 楼 DelphiGuy 的回复:
捕捉的代码呢?实际上如果只是拖动组件的话,不需要SetCapture也是可以的。


就这几行代码,我试了,如果注释掉ReleaseCapture(),那SendMessage(Panel1->Handle,WM_SYSCOMMAND,SC_MOVE+HTCAPTION,0) 无法移动Panel1。
鼠标在控件上点击,VCL代码里面有没有调用了SetCapture?

#6


我的意思是处理MouseDown、MouseMove、MouseUp也是可以实现拖动的,不需要SetCapture、ReleaseCapture

#7


引用 6 楼 DelphiGuy 的回复:
我的意思是处理MouseDown、MouseMove、MouseUp也是可以实现拖动的,不需要SetCapture、ReleaseCapture


没错,用MouseDown、MouseMove、MouseUp来改变相对位移可以移动控件,
它这个例子主要是用到SendMessage(Panel1->Handle,WM_SYSCOMMAND,SC_MOVE+HTCAPTION,0),
我想搞懂为什么SendMessage之前要先ReleaseCapture,它这个代码里面没有SetCapture。

#8


如果没有SetCapture,ReleaseCapture应该没有作用啊。

#9


引用 8 楼 DelphiGuy 的回复:
如果没有SetCapture,ReleaseCapture应该没有作用啊。


就是,鼠标在控件上按下,不知道VCL代码里面有没有调用了SetCapture?
SetCapture捕获鼠标会导致什么情况呢?对这个API不是很理解。

#10


SetCapture捕捉鼠标消息到指定hwnd,包括在hwnd之外的鼠标消息(但是鼠标按键消息其他窗口仍然能获得)。

#11


引用 10 楼 DelphiGuy 的回复:
SetCapture捕捉鼠标消息到指定hwnd,包括在hwnd之外的鼠标消息(但是鼠标按键消息其他窗口仍然能获得)。


那主要是移动消息了,按键消息其他窗口能获得,捕获的窗口也能同时获得吗?

#12


是可以的。但是在其他窗口按键之后,捕获就会部分失效,因为只有激活的窗口可以捕获窗口位置之外的鼠标消息,后台窗口如果SetCapture,只有指针出现在该窗口的可见部分上的时候才有效。