我已经一愁莫展,哪位帮忙搞定(关于WM_NCHITTEST)(100分)

  • 主题发起人 主题发起人 yeah
  • 开始时间 开始时间
Y

yeah

Unregistered / Unconfirmed
GUEST, unregistred user!
各位,如何手动发送WM_NCHITTEST消息?具体情况如下:<br>我做了一个Netants类似的拖放窗口(DropBasket),代码如下:<br>unit Unit1;<br><br>interface<br><br>uses<br>&nbsp; Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,<br>&nbsp; ExtCtrls, Menus;<br><br>type<br>&nbsp; TForm1 = class(TForm)<br>&nbsp; &nbsp; Image1: TImage;<br>&nbsp; &nbsp; PopupMenu1: TPopupMenu;<br>&nbsp; &nbsp; abadsdfasdf1: TMenuItem;<br>&nbsp; &nbsp; procedure FormCreate(Sender: TObject);<br>&nbsp; private<br>&nbsp; &nbsp; procedure WM_NCHITTEST(Var Message:TWMNCHITTEST); Message WM_NCHITTEST;<br>&nbsp; &nbsp; procedure WM_NCLBUTTONDBLCLK(Var Message:TWMNCLBUTTONDBLCLK); Message WM_NCLBUTTONDBLCLK;<br>&nbsp; &nbsp; procedure WM_NCRBUTTONUP(Var Message:TWMNCRBUTTONUP); Message WM_NCRBUTTONUP;<br>&nbsp; &nbsp; { Private declarations }<br>&nbsp; public<br>&nbsp; &nbsp; procedure CreateParams(Var Params:TCreateParams);override;<br>&nbsp; &nbsp; { Public declarations }<br>&nbsp; end;<br><br>var<br>&nbsp; Form1: TForm1;<br><br>implementation<br><br>{$R *.DFM}<br>uses main;<br>procedure TForm1.CreateParams(var Params: TCreateParams);<br>begin<br>&nbsp; inherited CreateParams(Params);<br>&nbsp; With Params do<br>&nbsp; begin<br>&nbsp; &nbsp; params.WndParent:=GetDesktopWindow;<br>&nbsp; &nbsp; EXSTYLE:=EXSTYLE or WS_EX_TOOLWINDOW OR WS_EX_TOPMOST;<br>&nbsp; end;<br>end;<br><br>procedure TForm1.FormCreate(Sender: TObject);<br>begin<br>&nbsp; SetWindowLong(Handle,GWL_STYLE,GetWindowLong(Handle,GWL_STYLE) and not ws_Caption);<br>&nbsp; Width:=40;<br>&nbsp; Height:=40;<br>&nbsp; Image1.Picture.Icon:=Application.Icon;<br>end;<br><br>procedure TForm1.WM_NCHITTEST(var Message: TWMNCHITTEST);<br>begin<br>&nbsp; Inherited;<br>&nbsp; if Message.Result=HTCLIENT then Message.Result:=HTCAPTION;<br>end;<br><br>procedure TForm1.WM_NCLBUTTONDBLCLK(var Message: TWMNCLBUTTONDBLCLK);<br>begin<br>&nbsp; inherited;<br>&nbsp; ShowMessage('I get DblClick Message!');<br>&nbsp; SetActiveWindow(frmMain.Handle);<br>end;<br><br>procedure TForm1.WM_NCRBUTTONUP(var Message: TWMNCRBUTTONUP);<br>begin<br>&nbsp; inherited;<br>&nbsp; PopupMenu1.Popup(Message.XCursor,Message.YCursor);<br>end;<br><br>end.<br><br>以上代码在win98中正常,可是今天,我在win2000中运行了此程序,<br>发现除了WM_NCHITTEST消息总是被触发(WM_NCRBUTTONUP也正常)外,<br>WM_NCLBUTTONDBLCLK消息却永远不被执行,当我双击窗体时,<br>窗口被最大化!(因为WM_NCHITTEST先被执行,而此时的双击被<br>理解为在标题栏上的双击,所以它总是执行最大化、还原两个动作。)<br>我要问的实际上不只是以上这个问题的解决办法,而且想知道<br>如何手动发送WM_NCHITTEST消息?我不知道如何在SendMessage中如何<br>指定Lparam参数(在WM_NCHITTEST消息中,它是一个TPoint)
 
参考下面的文章:<br><br>如何单击除了窗口标题栏以外的区域使窗口移动<br>&nbsp;<br>当窗口需要确定鼠标位置时Windows向窗口发送WM_NCHITTEST信息,可以处理该信息使Windows认为鼠标在窗口标题上。对于对话框和基于对话的应用程序,可以使用ClassWizard处理该信息并调用基类函数, 如果函数返回HTCLIENT 则表明鼠标在客房区域,返回HTCAPTION表明鼠标在Windows的标题栏中。<br>UINT CSampleDialog : : OnNcHitTest (Cpoint point )<br>{<br>&nbsp;UINT nHitTest =Cdialog: : OnNcHitTest (point )<br>&nbsp;return (nHitTest = =HTCLIENT)? HTCAPTION : nHitTest<br>}<br>&nbsp;上述技术有两点不利之处,<br>其一是在窗口的客户区域双击时,窗口将极大;<br>其二, 它不适合包含几个视窗的主框窗口。<br>还有一种方法,当用户按下鼠标左键使主框窗口认为鼠标在其窗口标题上,使用ClassWizard在视窗中处理WM_LBUTTODOWN信息并向主框窗口发送一个WM_NCLBUTTONDOWN信息和一个单击测试HTCAPTION。<br>void CSampleView : : OnLButtonDown (UINT nFlags , Cpoint point<br>)<br>{<br>&nbsp;CView : : OnLButtonDow (nFlags , pont )<br>&nbsp;//Fool frame window into thinking somene clicked<br>on<br>&nbsp;its caption bar .<br>&nbsp;GetParentFrame ( ) —&gt; PostMessage (<br>&nbsp;WM_NCLBUTTONDOWN ,<br>HTCAPTION , MAKELPARAM (poitn .x , point .y) )<br>}<br>&nbsp;该技术也适用于对话框和基于对的应用程序,只是不必调用<br>CWnd: :GetParentFrame 。<br>void CSampleDialog : : OnLbuttonDown (UINT nFlags, Cpoint point )<br>{<br>&nbsp;Cdialog : : OnLButtonDow (nFlags, goint )<br>&nbsp;//Fool dialog into thinking simeone clicked on its &nbsp;caption bar .<br>&nbsp;PostMessage (WM_NCLBUTTONDOWN , HTCAPTION , MAKELPARM (point.x, point. y) )<br>} <br>
 
我刚刚试了一下Makelparam宏,原来Delphi中也有,我以前写成MakeParam:(,怪不得。<br>我去试试,如能用WM_LBUTTONDOWN代替,分就送上了。
 
接受答案了.
 
后退
顶部