问题: 鼠标左键在界面内任意处按下后移动窗体(100分)

  • 主题发起人 主题发起人 EdwardZhou
  • 开始时间 开始时间
E

EdwardZhou

Unregistered / Unconfirmed
GUEST, unregistred user!
鼠标左键在界面内任意处按下后可以移动窗体用响应WM_NCHITTEST来实现:<br>&nbsp; procedure TfrmMain.WMNCHitTest(var Msg: TWMNCHitTest);<br>&nbsp; begin<br>&nbsp; inherited;<br>&nbsp; if Msg.Result = htClient then<br>&nbsp; &nbsp; Msg.Result &nbsp;:= htCaption;<br>&nbsp; end;<br>&nbsp; a.请问其中机理是什么?这样从TWMNCHitTest到Msg.Result?(50分)<br>&nbsp; b.如果我的form上有panel,如何让鼠标左键在panel上按下后也可以移动窗体?(50分)
 
window自己控制
 
WM_NCHITTEST<br>The WM_NCHITTEST message is sent to a window when the cursor moves, or when a <br>mouse button is pressed or released. If the mouse is not captured, the message<br>&nbsp;is sent to the window beneath the cursor. Otherwise, the message is sent to <br>the window that has captured the mouse. <br><br>WM_NCHITTEST <br>xPos = LOWORD(lParam); &nbsp;// horizontal position of cursor <br>yPos = HIWORD(lParam); &nbsp;// vertical position of cursor <br>&nbsp;<br>Parameters<br>xPos <br>Value of the low-order word of lParam. Specifies the x-coordinate of the cursor.<br>&nbsp;The coordinate is relative to the upper-left corner of the screen. <br>yPos <br>Value of the high-order word of lParam. Specifies the y-coordinate of the cursor<br>. The coordinate is relative to the upper-left corner of the screen.<br><br>当窗口需要确定鼠标位置时Windows向窗口发送WM_NCHITTEST信息,可以处理该信息使<br>Windows认为鼠标在窗口标题上。对于对话框和基于对话的应用程序,可以截获并处理<br>该信息, 如果函数返回HTCLIENT 则表明鼠标在客房区域,返回HTCAPTION表明鼠标在<br>Windows的标题栏中。<br><br>实际上就是让windows认为你点击的是标题拦,所以可以移动。 &nbsp;<br><br>----------------------------------------------<br>更简单的方法是这样,在MouseDown中处理。<br>//通过Panel移动窗体。<br>procedure TForm1.Panel1MouseDown(Sender: TObject; Button: TMouseButton;<br>&nbsp; Shift: TShiftState; X, Y: Integer);<br>begin<br>&nbsp; ReleaseCapture;<br>&nbsp; perform(WM_SysCommand, $F012, 0); //如果你写Panel.perform(),还可以在窗体上移动panel<br>end;<br>//移动窗体。<br>procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;<br>&nbsp; Shift: TShiftState; X, Y: Integer);<br>begin<br>&nbsp;ReleaseCapture;<br>&nbsp;SendMessage(handle,wm_SysCommand,$F012,0);<br>end;<br><br>但我不知道这样做原理是什么。
 
根据x,y调整form的left和top
 
这个事件发生在鼠标左键在客户区下按时,<br>你的代码是告诉操作系统,鼠标是在标题标按下的。<br>于是系统就会按照你在标题栏处按下去执行动作,<br>所以就会有移动窗口有效果。<br><br>至于在panel上实现,我COPY一段吧<br>procedure TForm1.PanelMouseMove(Sender : TObeject; Shift: TShiftState;X,Y:Inter);<br>begin<br>&nbsp; if ssleft in shift then<br>&nbsp; &nbsp; &nbsp;releasecapture;<br>&nbsp; &nbsp; &nbsp;self.perform(WM_SYSCOMMAND,$F012,0);<br>end;
 
1,不清楚<br>2:procedure XXXX.panel1MouseDown(Sender: TObject; Button: TMouseButton;<br>&nbsp; Shift: TShiftState; X, Y: Integer);<br>begin<br>&nbsp; if Button = mbLeft then<br>&nbsp; begin &nbsp;<br>&nbsp; &nbsp; ReleaseCapture;<br>&nbsp; &nbsp; Perform(WM_SysCommand, $f017, 0); <br>&nbsp; end;<br>end;
 
1 在客户区点击时,将返回值改为在“标题条点击”,这样就可以移动了。<br><br><br>2 <br><br>procedure TForm1.Panel1MouseDown(Sender: TObject; Button: TMouseButton;<br>&nbsp; Shift: TShiftState; X, Y: Integer);<br>begin<br>&nbsp; if ssleft in shift then releasecapture;<br>&nbsp; form1.Perform (WM_NCLBUTTONDOWN ,htCaption,0);<br>end;<br>
 
试一试这样:<br>procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;<br>&nbsp; Shift: TShiftState; X, Y: Integer);<br>begin<br>ReleaseCapture;<br>&nbsp; SendMessage(Handle, WM_SYSCOMMAND, $F012, 0);<br>end;
 
谢谢诸位,可是我个人觉得回答不是十分贴切,<br>对a,“你的代码是告诉操作系统,鼠标是在标题标按下的。”这从代码可以看出,问题是<br>&nbsp; &nbsp; &nbsp; 在Delphi中如果你按ctrl+c看TWMNCHitTest结构时,msg的result这么来的?这是我提<br>&nbsp; &nbsp; &nbsp; 问的目的,抱歉没有说清楚。<br>对b,问题解决。可是为什么?WM_SYSCOMMANDD的wParam为$f012,$f017都可以,可是查MSDN<br>&nbsp; &nbsp; &nbsp; 给Delphi的messages单元都没有发现这个参数,这两个参数代表什么?<br>谢谢并希望诸位高手继续参与,我想问个究竟!谢谢!
 

Similar threads

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