Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Windows 将非VCL窗口添加到VCL对齐队列_Windows_Delphi_Winapi_Delphi Xe_Vcl - Fatal编程技术网

Windows 将非VCL窗口添加到VCL对齐队列

Windows 将非VCL窗口添加到VCL对齐队列,windows,delphi,winapi,delphi-xe,vcl,Windows,Delphi,Winapi,Delphi Xe,Vcl,一些背景(某种程度上是以下内容的延续): 因此,我有一个应用程序,它加载不同的插件并创建 TPageControl上的每个新选项卡 每个DLL都有一个与其关联的TForm 创建表单时,将其父hWnd作为新的TTabSheet。 因为TTabSheets不像VCL那样是表单的父级 担心(不想使用动态RTL和中制作的插件) 其他语言)我必须手动处理大小调整 对于这种“插件”类型的应用程序,我似乎遇到了很多新问题(但学习经验非常丰富) 因此,我目前的努力是尝试有一个插件,它不会插入到TTabShe

一些背景(某种程度上是以下内容的延续):

  • 因此,我有一个应用程序,它加载不同的插件并创建 TPageControl上的每个新选项卡
  • 每个DLL都有一个与其关联的TForm
  • 创建表单时,将其父hWnd作为新的TTabSheet。 因为TTabSheets不像VCL那样是表单的父级 担心(不想使用动态RTL和中制作的插件) 其他语言)我必须手动处理大小调整
对于这种“插件”类型的应用程序,我似乎遇到了很多新问题(但学习经验非常丰富)

因此,我目前的努力是尝试有一个插件,它不会插入到TTabSheet中,而是直接在表单上调整大小和对齐

因为这更容易用图片来解释: 现在,我可以手动执行对齐和调整大小,但我更愿意让VCL对齐程序(alClient、alTop等)为我执行。那样的话,我只需要在形式上设置插件对齐,而不用考虑

在查看了VCL源代码之后,我开始逐步了解align代码及其调用方式。基本上,当TControl获得WM_RESIZE时,它将:

  • 调用调用AlignControl()的调用Realign()
  • AlignControl()将获取客户端rect并调用AlignControls()
  • AlignControls()将按以下顺序为每个TAlignment类型调用DoAlign():alTop、alBottom、alLeft、Okay、alClient、alCustom、alNone
  • DoAlign()将在FControls和FWInControl(即TLists)之间循环,并将它们适当对齐
  • 因此,我的想法是,如果我创建一个新的TWinControl,将它的句柄设置为插件窗体(窗口)句柄,并将它插入到FControls列表中,使用正确的对齐方式,它应该可以帮我完成工作

    我当然在这里,所以失败得很惨。我甚至在退出应用程序时收到一个关于无效窗口句柄的AV。我猜我创建的TWinControl试图释放不再存在的插件窗体(窗口)的句柄

    我所尝试的:

    procedure AddHandleToControlList(AHandle: DWORD; Align: TAlign);
    var
      NewWinControl : TWinControl;
    begin
      NewWinControl := TWinControl.Create(frmMain);
      NewWinControl.WindowHandle := AHandle;
      NewWinControl.Align := Align;
      NewWinControl.Width := frmMain.ClientWidth;
      NewWinControl.Height := 30;
      NewWinControl.Parent := frmMain;
    end;
    
    procedure AddHandleToControlList(AHandle: DWORD; Align: TAlign);
    var
      NewWinControl : TWinControl;
    begin
      NewWinControl := TWinControl.Create(frmMain);
      NewWinControl.WindowHandle := AHandle;
      NewWinControl.Align := Align;
      NewWinControl.Width := frmMain.ClientWidth;
      NewWinControl.Height := 30;
      TWinControl(frmMain).Insert(NewWinControl);
    end;
    
    苏欧,你有什么想法

    编辑1:

    好的,这正确地将控件添加到列表中,并符合TAlign集(为什么我花了8个小时试图弄明白一些事情,我在这里发布,然后答案就出现了……哦,有人可能会发现这个问题和我的漫谈很有用):

    现在的问题是,当应用程序关闭时,我得到无效错误AV…我将继续

    编辑2:
    好的,是TWinControl.DestroyWindowHandle引发AV,因为窗口句柄不再存在。我正在尝试想出一个干净的解决方案。

    TWinControl
    派生一个新类,并重写它的虚拟
    DestroyWindowHandle()
    方法,以不释放您提供的
    HWND
    TWinControl.DestroyWindowHandle()
    的默认实现调用Win32 API
    DestroyWnd()
    函数。

    这是一个比我所做的更优雅的解决方案!太好了,谢谢+哇。我不确定这是黑客还是诡计,但见鬼,给出一个随机窗口控件VCL特性肯定是有用的!谢谢你们两个!这不是一个黑客。TWinControl的
    CreateWindowHandle()
    DestroyWindowHandle()
    方法故意是虚拟的,以允许自定义窗口管理。
    procedure AddHandleToControlList(AHandle: DWORD; AName: PChar; ATop, ALeft, AWidth, AHeight: Integer; AAlign: TAlign);
    var
      NewWinControl : TWinControl;
    begin
      NewWinControl := TWinControl.Create(frmMain);
      With NewWinControl Do
        begin
        Name := AName;
        Top := ATop;
        Left := ALeft;
        Width := AWidth;
        Height := AHeight;
        Align := AAlign;
        WindowHandle := AHandle;
        Visible := True;
      end;
      TWinControl(frmMain).InsertControl(NewWinControl);
    end;