计算机二级DELPHI控件:标题窗体拖动
来源:优易学  2011-12-10 17:50:04   【优易学:中国教育考试门户网】   资料下载   IT书店

  方法一:
  通过响应“wm_NCHitTest”消息来移动窗体。
  Windows发送“wM_NCHitTest”消息来确定鼠标操作是否发生在窗体的客户区,或边框的特殊区上(非客户区)。
  如果Windows发现用户单击了窗体标题,系统将移动窗体,单击了窗体边框,则系统将开始改变窗体大小。
  例程如下:
  private
  { Private declarations }
  Procedure MoveForm(var M:TWMNCHITTEST);Message WM_NCHITTEST;
  //声明一自定义事件,拦截“WM_NCHITTEST”消息
  public
  {$R *.DFM}
  Procedure TForm1.MoveForm (var M:TWMNCHITTEST);
  begin
  inHerited; //继承,窗体可以继续处理以后的事件
  if (M.Result=HTCLIENT) //如果发生在客户区
  and ((GetKeyState(vk_CONTROL) < 0) //检测“Ctrl”键是否按下
  then M.Result:=HTCAPTION; //更改“.Result”域的值
  end;
  方法二:
  通过为Application.OnMessage创建一个处理程序获得Windows消息,
  可以调整应用程序对不同消息的响应或为不能正常识别的
  消息提供服务。这里受到窗体客户区的鼠标按下的消息后,
  发送一条在标题栏内按下的消息。
  例程如下:
  procedure FormCreate(Sender: TObject);
  private
  { Private declarations }
  procedure AppMessage(var Msg:TMsg;var Handled:Boolean);
  {$R *.DFM}
  procedure TForm1.FormCreate(Sender: TObject);
  begin
  Application.OnMessage:=AppMessage;
  //捕捉消息:将程序的收到消息事件与消息过滤过程关联起来
  end;
  procedure TForm1.AppMessage(var Msg:TMsg;var Handled:Boolean);
  begin
  if (Msg.message=WM_LButtonDown) and
  //如果鼠标左键按下的话
  (DefWindowProc(Handle,WM_NCHitTest,0,GetMessagePos)=HTClient) and
  //判断光标是否在客户区内
  ((GetKeyState(vk_CONTROL) < 0)
  //检测“Ctrl”键是否按下
  then
  begin
  SendMessage(Handle
  WM_NCLButtonDown
  HTCaption
  GetMessagePos);
  //发送鼠标在标题栏内按下的消息
  Handled:=true;
  end;
  end;

  方法三:
  直接向窗体发送一条“wm_SysCommand”消息,需要使用未归档的“sc_DragMove”标志,定义如下:
  const
  sc_DragMove:LongInt=$F012;
  我们只能向TWinControl派生组件发送该消息,而且只能响应鼠标按下事件,因为系统会在此时捕获鼠标(当释放鼠标键时,拖动操作是没有意义的)。
  例程如下:
  const
  sc_DragMove:longint=$F012;
  implementation
  {$R *.DFM}
  procedure TForm1.FormMouseDown
  (Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X
  Y: Integer);
  begin
  if ssCtrl in Shift then
  //判断“Ctrl”键是否按下
  Begin
  ReleaseCapture;
  //释放鼠标事件的对象
  (Sender as TWinControl).PerForm(wm_SysCommand
  sc_DragMove
  0);
  //发送消息
  end;
  end;
  这种方法适用与窗体与组件,如想移动组件,将其“OnMouseDown”事件写成与Form的“OnMouseDown”事件一样即可。
  如只想移动窗体可按以下方法编写代码:
  procedure TForm1.FormMouseDown
  (Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X
  Y: Integer);
  begin
  if SsCtrl in Shift then
  Begin
  ReleaseCapture;
  SendMessage(handle, wm_SysCommand, sc_DragMove, 0);
  end;
  end;
  运行结果:
  按下“Ctrl”键拖动鼠标即可移动窗体。
  要实现无标题窗体的移动有很多种方法,还可以通过检测鼠标的位置(坐标)来确定Form的“left”与“top”值等方法,在此不再详细举例.
  ========================
  procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
  begin
  if ssleft in shift then
  releasecapture;
  perform(WM_SYSCOMMAND,$F012,0);
  end;

责任编辑:小草

文章搜索:
 相关文章
热点资讯
资讯快报
热门课程培训