Delphi 如何在运行时动态调整弹出窗口的大小?

Delphi 如何在运行时动态调整弹出窗口的大小?,delphi,Delphi,我尝试创建一个自定义组合框控件,弹出一个树视图。 一切看起来都很好。 但是,当我尝试向该控件添加运行时调整大小功能时,弹出窗口(Treeview)只是移动,不会更改其大小 如有任何建议,将不胜感激 弹出窗口的代码段: 创建时: ControlStyle := ControlStyle + [csNoDesignVisible, csReplicatable, csDoubleClicks]; begin inherited CreateParams(Params); with Para

我尝试创建一个自定义组合框控件,弹出一个树视图。 一切看起来都很好。 但是,当我尝试向该控件添加运行时调整大小功能时,弹出窗口(Treeview)只是移动,不会更改其大小

如有任何建议,将不胜感激

弹出窗口的代码段:

创建时

ControlStyle := ControlStyle + [csNoDesignVisible, csReplicatable, csDoubleClicks];
begin
  inherited CreateParams(Params);
  with Params do
  begin
    Style := Style or WS_POPUP or WS_VSCROLL or WS_BORDER;
    ExStyle := WS_EX_TOOLWINDOW;
    AddBiDiModeExStyle(ExStyle);
    //WindowClass.Style := CS_SAVEBITS; {this would prevent ondoubleclick event}
  end;
begin
  inherited;
  if FDragStyle<>dsMove then begin
    FDragPos:=point(x,y);
    FDragged:=true;
  end;
end;
begin
  inherited;
  FDragged:=false;
end;
在创建参数时

ControlStyle := ControlStyle + [csNoDesignVisible, csReplicatable, csDoubleClicks];
begin
  inherited CreateParams(Params);
  with Params do
  begin
    Style := Style or WS_POPUP or WS_VSCROLL or WS_BORDER;
    ExStyle := WS_EX_TOOLWINDOW;
    AddBiDiModeExStyle(ExStyle);
    //WindowClass.Style := CS_SAVEBITS; {this would prevent ondoubleclick event}
  end;
begin
  inherited;
  if FDragStyle<>dsMove then begin
    FDragPos:=point(x,y);
    FDragged:=true;
  end;
end;
begin
  inherited;
  FDragged:=false;
end;
鼠标移动时:

var
  ARect, RR: TRect;
  DragStyle: TDragStyle;
  Procedure SetDragStyle(ds:TDragStyle; c:TCursor);
  begin
    FDragStyle:=ds;
    Cursor:=c;
  end;
begin
  inherited;
  FMouseMoveSelected := GetNodeAt(x, y);
  if FDragged then begin
    case FDragStyle of
       dsSizeLeft :begin
                      SetWindowPos(Handle, HWND_TOP, Left+(x-FDragPos.X), Top, Width, Height,
                        SWP_NOACTIVATE or SWP_SHOWWINDOW);
                      //Left:=Left+(x-FDragPos.X); {alternate code that doesn't work either}
                   end;
    end;
    FDragPos:=Point(x,y);
  end else begin
    SetDragStyle(dsMove,crDefault);
    ARect := GetClientRect;
    RR:=ARect;
    InflateRect(RR,-2,-2);
    if (x>=0) and (x<=Width) and (y>=0) and (y<=Height) and (not PtInRect(RR,Point(x,y))) then begin
      if (x<=RR.Left) then begin
        //if (y<=RR.Top) then SetDragStyle(dsSizeTopLeft,crSizeNWSE)else
        if (y>=RR.Bottom) then SetDragStyle(dsSizeBottomLeft,crSizeNESW)
        else SetDragStyle(dsSizeLeft,crSizeWE); 
      end else if (x>=RR.Right) then begin
        //if (y<=RR.Top) then SetDragStyle(dsSizeTopRight,crSizeNESW) else
        if (y>=RR.Bottom) then SetDragStyle(dsSizeBottomRight,crSizeNWSE)
        else SetDragStyle(dsSizeRight,crSizeWE);
      end else begin
        //if (y<=RR.Top) then SetDragStyle(dsSizeTop,crSizeNS) else
        if (y>=RR.Bottom) then SetDragStyle(dsSizeBottom,crSizeNS)
        else SetDragStyle(dsMove,crDefault);
      end;
    end;
  end;
end;
end;

您在
SetWindowPos
调用中混合了客户端坐标和屏幕坐标。这是因为你正在浮动一个不应该浮动的窗口,而VCL对此一无所知。当您参考其左侧的
时,VCL返回一个相对于其父级的坐标,可能是表格。也不要更改在拖动过程中开始拖动时保存的点(即FDragPos):


您在
SetWindowPos
调用中混合了客户端坐标和屏幕坐标。这是因为你正在浮动一个不应该浮动的窗口,而VCL对此一无所知。当您参考其左侧的
时,VCL返回一个相对于其父级的坐标,可能是表格。也不要更改在拖动过程中开始拖动时保存的点(即FDragPos):


你为什么不设置WS_THICKFRAME样式并完成它?是的,对。很好的建议。它调整了大小,而不需要我的鼠标事件代码。我试过了。现在,问题是它会调整所有方向的大小,所以我应该实现额外的例程,以防止从左侧和顶部调整大小。谢谢,不客气。不管你是否使用它,我发布了一个我认为是错误的答案。如果你只想调整它的一些边缘大小,你可能会发现在WM_NCHITTEST上搜索很有用。你为什么不设置WS_THICKFRAME样式并完成它?是的,对。很好的建议。它调整了大小,而不需要我的鼠标事件代码。我试过了。现在,问题是它会调整所有方向的大小,所以我应该实现额外的例程,以防止从左侧和顶部调整大小。谢谢,不客气。无论你是否使用它,我都发布了一个我认为是错误的答案。如果你希望它只调整一些边缘的大小,你可能会发现在WM_NCHITTEST上的搜索很有用。谢谢你的片段。这绝对回答了我的问题,但做了一些修改:(1)FDragPos:=点(x,y)应该设置在底部和右下DragStyle上,FDragPos.y:=y应该设置在左下DragStyle上。(2) 我们必须在鼠标按钮按下事件上捕获句柄(setcapture(handle)),否则在将光标移开时将不会执行调整大小。再一次,谢谢。谢谢你的片段。这绝对回答了我的问题,但做了一些修改:(1)FDragPos:=点(x,y)应该设置在底部和右下DragStyle上,FDragPos.y:=y应该设置在左下DragStyle上。(2) 我们必须在鼠标按钮按下事件上捕获句柄(setcapture(handle)),否则在将光标移开时将不会执行调整大小。再一次,谢谢。