200分 紧急求助:问个窗口移动,鼠标点击问题!(200分)

  • 主题发起人 主题发起人 老李无敌
  • 开始时间 开始时间

老李无敌

Unregistered / Unconfirmed
GUEST, unregistred user!
本人想拖动窗口能象拖动标题一样移动窗体,点击右键弹出菜单.<br><br>下面过程,实现了拖动,但屏蔽了右键.<br>procedure tform1.wmchittest(var message : twmnchittest);<br>begin<br>&nbsp; inherited;<br>&nbsp; message.Result := htcaption;<br>end;<br><br>如果用<br>procedure tform1.wmchittest(var message : tmessage);<br>begin<br>&nbsp; &nbsp; case message.msg of<br> wm_nchittest : ....<br>&nbsp; &nbsp; &nbsp; &nbsp; WM_LBUTTONDOWN : ....<br>&nbsp; &nbsp; end;<br>inherited;<br>end;<br>能实现吗?如何实现?有更好的办法吗?请详细说明!<br>谢谢!!
 
直接处理WM_LBUTTONDOWN消息即可,处理前只要判断一下鼠标位置是否在客户区<br>给你一遍文章仅供你参考:<br><br>无标题窗口的移动 <br>出自:http://grace7450.xiloo.com 2002年10月06日 22:57 <br><br>  在 Delphi 编程中有时要对无标题窗体进行移动,以下就结合本人的经验介绍几种对无标题窗体移动的方法。<br><br>方法一:<br>  通过响应“wm_NCHitTest” 消息来移动窗体。Windows 发送“wM_NCHitTest” 消息来确定鼠标操作是否发生在窗体的客户区,或边框的特殊区上( 非客户区)。如果 Windows 发现用户单击了窗体标题,系统将移动窗体,单击了窗体边框,则系统将开始改变窗体大小。<br><br>例程如下:<br><br>...<br>private<br> { Private declarations }<br>  Procedure MoveForm(var M:TWMNCHITTEST);Message WM_NCHITTEST;<br> //声明一自定义事件,拦截“WM_NCHITTEST”消息<br>public<br>...<br>{$R *.DFM}<br><br>Procedure TForm1.MoveForm (var M:TWMNCHITTEST);<br>begin<br> inHerited;//继承,窗体可以继续处理以后的事件<br> if (M.Result=HTCLIENT) //如果发生在客户区<br>and ((GetKeyState(vk_CONTROL) &lt; 0)//检测“Ctrl”键是否按下<br>then M.Result:=HTCAPTION; //更改“.Result”域的值<br>end; <br><br>方法二:<br>  通过为 Application.OnMessage 创建一个处理程序获得 Windows 消息,可以调整应用程序对不同消息的响应或为不能正常识别的消息提供服务。这里受到窗体客户区的鼠标按下的消息后,发送一条在标题栏内按下的消息。<br><br>例程如下:<br><br>...<br> procedure FormCreate(Sender: TObject);<br>private<br> { Private declarations }<br> procedure AppMessage(var Msg:TMsg;var Handled:Boolean);<br>...<br><br>{$R *.DFM}<br><br>procedure TForm1.FormCreate(Sender: TObject);<br>begin<br> Application.OnMessage:=AppMessage;<br> //捕捉消息:将程序的收到消息事件与消息过滤过程关联起来 <br>end;<br><br>procedure TForm1.AppMessage(var Msg:TMsg;var Handled:Boolean);<br>begin<br> if (Msg.message=WM_LButtonDown) and<br> //如果鼠标左键按下的话<br> (DefWindowProc(Handle, WM_NCHitTest, 0, GetMessagePos)=HTClient) and<br> //判断光标是否在客户区内<br> ((GetKeyState(vk_CONTROL) &lt; 0)<br> //检测“Ctrl”键是否按下<br> then<br> begin<br>  SendMessage(Handle, WM_NCLButtonDown, HTCaption, GetMessagePos);<br>  //发送鼠标在标题栏内按下的消息<br>  Handled:=true;<br> end;<br>end; <br><br>方法三:<br>  直接向窗体发送一条“wm_SysCommand” 消息,需要使用未归档的“sc_DragMove” 标志,定义如下:<br>const<br> sc_DragMove:LongInt=$F012;<br><br>   我们只能向 TWinControl 派生组件发送该消息,而且只能响应鼠标按下事件,因为系统会在此时捕获鼠标(当释放鼠标键时,拖动操作是没有意义的)。<br><br>例程如下:<br><br>...<br>const<br> sc_DragMove:longint=$F012;<br><br>implementation<br><br>{$R *.DFM}<br><br>procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;Shift: TShiftState; X, Y: Integer);<br>begin<br> if ssCtrl in Shift then<br> //判断“Ctrl”键是否按下<br> Begin<br>  ReleaseCapture;<br>  //释放鼠标事件的对象<br>  (Sender as TWinControl).PerForm(wm_SysCommand, sc_DragMove, 0);<br>  //发送消息<br> end;<br>end; <br><br>  这种方法适用与窗体与组件,如想移动组件,将其“OnMouseDown” 事件写成与 Form 的“OnMouseDown” 事件一样即可。 如只想移动窗体可按以下方法编写代码:<br>procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;Shift: TShiftState; X, Y: Integer);<br>begin<br> if SsCtrl in Shift then<br> Begin<br>  ReleaseCapture;<br>  SendMessage(handle, wm_SysCommand, sc_DragMove, 0);<br> end;<br>end; <br><br>运行结果:<br>  按下“Ctrl” 键拖动鼠标即可移动窗体。<br><br>总结:<br>  要实现无标题窗体的移动有很多种方法,还可以通过检测鼠标的位置(坐标)来确定 Form 的“left” 与“top” 值等方法,在此不再详细举例.<br><br>以上程序均在 Delphi 3.0 下编译通过。 <br><br>&nbsp;<br>
 
完全同意楼上的, 可是被他抢了先。 三种方法各有千秋, 不过我经常用第三种, 比较简单。代码如处:<br>procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;<br>&nbsp; Shift: TShiftState; X, Y: Integer);<br>begin<br>&nbsp; &nbsp; if Button = mbLeft then<br>&nbsp; &nbsp; &nbsp; &nbsp;begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ReleaseCapture;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Perform(WM_SYSCOMMAND, $F012, 0);<br>&nbsp; &nbsp; &nbsp; &nbsp;end;<br>end;<br><br>
 
同意,老问题了
 
谢谢您的答复,还有几个问题:<br>1.方法一我早试过,但不知如何使用鼠标右键,好象屏蔽了!<br>2.方法二中的Handled:=true;表示什么意思,有何作用!<br><br>3.方法二中的((GetKeyState(vk_CONTROL) &lt; 0)<br> //检测“Ctrl”键是否按下<br>------- 有何作用,放在那儿好象有错!<br><br>4.下面的程序为何,当右键点击后就无法移动了,把showmessage该成beep就好了,我该怎么做!<br><br><br><br>type<br>&nbsp; TForm1 = class(TForm)<br>&nbsp; &nbsp; procedure FormCreate(Sender: TObject);<br>&nbsp; private<br>&nbsp; &nbsp; { Private declarations }<br>&nbsp; public<br>&nbsp; &nbsp;procedure AppMessage(var Msg:TMsg;var Handled:Boolean);<br>&nbsp; &nbsp; { Public declarations }<br>&nbsp; end;<br><br>var<br>&nbsp; Form1: TForm1;<br><br>implementation<br>procedure tform1.AppMessage(var Msg:TMsg;var Handled:Boolean);<br>begin<br><br>&nbsp;if (Msg.message=WM_LButtonDown) and<br>&nbsp;(DefWindowProc(Handle, WM_NCHitTest, 0, GetMessagePos)=HTClient) then<br>&nbsp;begin<br>&nbsp; SendMessage(Handle, WM_NCLButtonDown, HTCaption, GetMessagePos);<br>&nbsp; Handled:=true;<br>&nbsp;end<br>&nbsp;else<br>&nbsp;if (Msg.message=WM_rButtonDown) and<br>&nbsp;(DefWindowProc(Handle, WM_NCHitTest, 0, GetMessagePos)=HTClient)<br>&nbsp;then<br>&nbsp;begin<br>&nbsp;showmessage('aa');<br>&nbsp;Handled:=true;<br>&nbsp;end;<br><br>end;<br>{$R *.dfm}<br><br>procedure TForm1.FormCreate(Sender: TObject);<br>begin<br>Application.OnMessage:=AppMessage;<br>end;<br><br>end.<br>
 

Similar threads

D
回复
0
查看
2K
DelphiTeacher的专栏
D
D
回复
0
查看
2K
DelphiTeacher的专栏
D
D
回复
0
查看
1K
DelphiTeacher的专栏
D
I
回复
0
查看
576
import
I
D
回复
0
查看
1K
DelphiTeacher的专栏
D
后退
顶部