码迷,mamicode.com
首页 > 移动开发 > 详细

使用SetWindowPos API函数移动窗口后,还需修改Delphi的属性值,以备下次使用,否则就会出问题(不是API不起作用,而是使用了错误的坐标值)

时间:2015-08-30 06:30:49      阅读:632      评论:0      收藏:0      [点我收藏+]

标签:

单独改变坐标的代码如下,可不断左移:

procedure TForm1.Button1Click(Sender: TObject);
begin
  SetWindowPos(panel1.Handle, 0, panel1.Left-10, panel1.Top, panel1.Width, panel1.Height, SWP_NOZORDER + SWP_NOACTIVATE);
end;

照理每次改变坐标,都会调用SetBounds,都会调用SetWindowPos函数,可是一旦我屏蔽UpdateBounds函数,控件从第二次开始,就没有效果了:

procedure TForm1.Button1Click(Sender: TObject);
begin
  panel1.Left:=panel1.Left-10;
end;

这是为什么呢?原因是,在使用API达到相应的目的之后,必须修改Delphi的属性值,以备下次使用。否则Delphi下次还是按照原来的left值再减去10,这样看上去就没有被移动。所以关键是UpdateBounds里的代码:

procedure TWinControl.UpdateBounds;
var
  ParentHandle: HWnd;
  Rect: TRect;
  WindowPlacement: TWindowPlacement;
begin
  GetWindowRect(FHandle, Rect); // API,取得客户区,注意第二个参数是指针,但Delphi里直接使用

  // important 如果具有子窗口风格,就要根据父控件在屏幕上的位置重新显示
  if GetWindowLong(FHandle, GWL_STYLE) and WS_CHILD <> 0 then
  begin
    ParentHandle := GetWindowLong(FHandle, GWL_HWNDPARENT); // API,fixme 还可以这样简单取得父控件句柄?就这一处
    if ParentHandle <> 0 then
    begin
      Windows.ScreenToClient(ParentHandle, Rect.TopLeft); // API
      Windows.ScreenToClient(ParentHandle, Rect.BottomRight);
    end;
  end;

  // important 使用API取得实际效果后,也要改变Delphi的属性值,否则属性值还是保持上一次的值,这样下一次看起来就无法移动了
  // 错误:显示完以后,根据windows内部信息更新Win控件的属性
  // important 如果这里exit,那么只有第一次的时候坐标可以移动,后面都无法移动了。说到底都是通过这里起作用的
  FLeft := Rect.Left;
  FTop := Rect.Top;
  FWidth := Rect.Right - Rect.Left;
  FHeight := Rect.Bottom - Rect.Top;
  // 更新坐标和长宽后,要重新铆接
  // fixme 难道不用对齐吗,别处好多地方也都是这样
  UpdateAnchorRules;
end;

的最后几句。这样就达到了修改值的目的。

--------------------------------------------------------------------

另一种办法改变Windows窗口的坐标(亲测):

procedure TForm1.Button2Click(Sender: TObject);
var
  WindowPlacement: TWindowPlacement; // Windows结构类型,包含最大化最小化窗口位置等6项内容
begin
  WindowPlacement.Length := SizeOf(WindowPlacement);
  GetWindowPlacement(Panel1.Handle, @WindowPlacement);  // API,取得结构体指针,包括7项内容
  // 更改窗口的位置信息
  WindowPlacement.rcNormalPosition := Panel1.BoundsRect;
  WindowPlacement.rcNormalPosition.Left := WindowPlacement.rcNormalPosition.Left - 10;
  WindowPlacement.rcNormalPosition.Right := WindowPlacement.rcNormalPosition.Right - 10;
  SetWindowPlacement(Panel1.Handle, @WindowPlacement);
end;

 

使用SetWindowPos API函数移动窗口后,还需修改Delphi的属性值,以备下次使用,否则就会出问题(不是API不起作用,而是使用了错误的坐标值)

标签:

原文地址:http://www.cnblogs.com/findumars/p/4770277.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!