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