请问为什么鼠标在Panel上面的时候,窗体不能捕捉到wm_NCHitTest消息?如何解决???(100分)

  • 主题发起人 主题发起人 hlsl
  • 开始时间 开始时间
H

hlsl

Unregistered / Unconfirmed
GUEST, unregistred user!
请看下面的代码:注意,将窗体BorderStyle设置为bsNone,<br>窗体上如果放置一个alClient的Panel,这个代码就不起作用了[:(]。<br>换成 <br>procedure WMHitTest(Msg: TMessage);message WM_NCHITTEST;<br>实现也是一样的。[?]<br><br>代码如下:<br>interface<br><br>TForm1 = Class{TForm)<br>...<br>protected<br>procedure WndProc(var Message: TMessage); override;<br>end;<br>。。。<br><br>implementation<br><br>procedure TForm1.WndProc(var Message: TMessage);<br>var<br>&nbsp; Pt: TPoint;<br>Begin<br>&nbsp; &nbsp;if Message.Msg &lt;&gt; WM_NCHITTEST then<br>&nbsp; &nbsp;begin<br>&nbsp; &nbsp; &nbsp;inherited WndProc(Message);<br>&nbsp; &nbsp; &nbsp;Exit;<br>&nbsp; &nbsp;end;<br><br>&nbsp; &nbsp;Pt := Point(Message.LParamLo,Message.LParamHi);<br>&nbsp; &nbsp;if (Pt.X &lt; 5) and (Pt.Y &lt; 5) then<br>&nbsp; &nbsp; &nbsp; Message.Result := htTopLeft<br>&nbsp; &nbsp;else if (Pt.X &gt; Width - 5) and (Pt.Y &lt; 5) then<br>&nbsp; &nbsp; &nbsp; Message.Result := htTopRight<br>&nbsp; &nbsp;else if (Pt.X &gt; Width - 5) and (Pt.Y &gt; Height - 5) then<br>&nbsp; &nbsp; &nbsp; Message.Result := htBottomRight<br>&nbsp; &nbsp;else if (Pt.X &lt; 5) and (Pt.Y &gt; Height - 5) then<br>&nbsp; &nbsp; &nbsp; Message.Result := htBottomLeft<br>&nbsp; &nbsp;else if (Pt.X &lt; 5) then<br>&nbsp; &nbsp; &nbsp; Message.Result := htLeft<br>&nbsp; &nbsp;else if (Pt.Y &lt; 5) then<br>&nbsp; &nbsp; &nbsp; Message.Result := htTop<br>&nbsp; &nbsp;else if (Pt.X &gt; Width - 5) then<br>&nbsp; &nbsp; &nbsp; Message.Result := htRight<br>&nbsp; &nbsp;else if (Pt.Y &gt; Height - 5) then<br>&nbsp; &nbsp; &nbsp; Message.Result := htBottom<br>&nbsp; &nbsp;else<br>&nbsp; &nbsp; &nbsp; inherited;<br>end;
 
被人抢走了。
 
procedure WMNCHitTest(var M: TWMNCHitTest); <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; message wm_NCHitTest; <br><br>procedure TForm1.WMNCHitTest (var M: TWMNCHitTest); <br>begin <br>&nbsp; inherited; <br>&nbsp; if M.Result = htClient then <br>&nbsp; &nbsp;M.Result := htCaption; <br>end; <br><br>//很晚了,我要回去了,Good luck!
 
我不是不能响应窗体的WM_NCHITTEST消息。问题是如果鼠标在一个Panel上的时候,<br>Panel会捕捉到这个消息,而Form就捕捉不到了。<br>在窗体的 WM_NCHITTEST 消息响应里面写<br>procedure TForm1.NCHitTest(var Message: TWMNCHitTest);<br>begin<br>&nbsp; Caption := Format('%d:%d', [Message.XPos, Message.Ypos]);<br>&nbsp; inherited;<br>end;<br>然后在窗体上放一个Panel,可以看到,当鼠标在Panel上的时候,窗体的Caption不会变化了。<br>也就是说没有接收到这个消息。<br>如何能够在这种情况下让窗体也能接收到这个消息呢?
 
在panel的响应事件里给传formwm_NCHitTest消息,不就行了。
 
简单点,把Form1.BorderWidth设为5,即把Form1给“露”出来就行了。<br>另外提醒一个错误的地方,Pt应该这样得到——<br>&nbsp; &nbsp;Pt := ScreenToClient(Point(Message.LParamLo, Message.LParamHi));<br>因为Message里带进来的座标是相对于屏幕的,而你的判断是基于Form的。<br><br>再有,实现你想要的效果(调整窗口大小)可以不必截获WM_NCHITTEST,<br>你完全可以把Form1.BorderStyle设为正常的bsSizeable,<br>然后关键是在FormCreate事件里写上这么两句就OK了——<br>&nbsp; SetWindowLong(Handle, GWL_STYLE, GetWindowLong(Handle, GWL_STYLE) and not WS_CAPTION);//去掉标题栏<br>&nbsp; Height := Height + 1;//强制刷新<br>——试一下。
 
to mytree:<br>&gt;&gt;在panel的响应事件里给传formwm_NCHitTest消息,不就行了。<br>请问如何传递WM_NCHITTEST这个消息呢?我试过,好象不行啊。<br>to 5rain6sky:<br>这个方法我想过,但是有一个问题:我不想要窗体的边框,<br>所以我将BorderStyle设置为bsNone。因此只能通过WM_NCHITTEST来实现。<br><br>请各位予以继续关注,谢谢。<br><br><br>&nbsp;<br>
 
to hlsl:<br>那也好办,这样写——<br>&nbsp; SetWindowLong(Handle, GWL_STYLE, GetWindowLong(Handle, GWL_STYLE) xor (WS_CAPTION or WS_THICKFRAME));<br>——再试试!
 
在panel是bsClient时,上面的方法都是无效。<br>还是在panel的mouseDown力作判断吧,虽然麻烦一点。
 
WM_NCHITTEST是非客户区消息(微软语),非客户区包括窗体的边框、标题等(具体的请看下<br>Platform SDK)你的Panel放在客户区,所以无法处理WM_NCHITTEST,可以换个方法实施(如<br>OnmouseDown Event)
 
感谢各位关注,结束问题。
 
后退
顶部