2011-11-11 17 views
9

一些背景(TLabel and TGroupbox Captions Flicker on Resize延續的):添加非VCL窗口爲VCL對齊隊列

  • 所以,我有一個加載不同的插件,並在TPageControl創建 新標籤的應用爲每一個。
  • 每個DLL都有一個TForm與它關聯。
  • 這些表單是以它們的父hWnd作爲新的TTabSheet創建的。 由於VCL是 有關(不想使用動態RTL和插件在 其他語言)我不得不手動調整大小,因此TTabSheets不是表單的父代。

我只是似乎運行到這個「插件」類型的應用了很多新的問題(但很好的學習經驗)。

所以,我目前的努力是嘗試插入一個不插入TTabSheet的插件,但會直接在窗體上調整大小和對齊。

因爲這會更容易用圖片來解釋: Visual representation of question 現在我可以做手工校準和調整大小,但我寧願有VCL對齊程序(alClient,是alTop等 )爲我做。這樣我就不必考慮在其表單上設置插件對齊方式。

通過查看VCL源代碼後,我開始瀏覽對齊代碼以及它的調用方式。基本上當的TControl得到一個WM_RESIZE將:)這就要求AlignControl

  1. 呼叫重新調整(()
  2. AlignControl()將獲得客戶端矩形,並調用AlignControls()
  3. AlignControls()將調用DoAlign (),用於在這個順序中的每個TAlignment類型:是alTop,設爲alBottom,alLeft,正常的,alClient,alCustom,alNone
  4. DoAlign()通過FControls和FWinControls(其是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; 

SOOOO,想法?

編輯1:

好了,這個正確添加控件列表,並且符合了該TAlign集(那爲什麼我花8小時試圖想辦法的,我張貼在這裏,和那麼答案只是出現......哦也有人可能會發現這個問題,我的隨筆有用):

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; 

現在的問題是,在應用程序關閉的時候,我得到了無效的錯誤AV ......我將繼續!

編輯2: 好了,所以它是TWinControl.DestroyWindowHandle是提高了AV,因爲窗口句柄不存在了。我試圖想出一個乾淨的解決方案。

回答

9

TWinControl派生新類並覆蓋其虛擬DestroyWindowHandle()方法不釋放你提供HWNDTWinControl.DestroyWindowHandle()的默認實現調用Win32 API DestroyWnd()函數。

+0

這是比我做的更優雅的解決方案!完美,謝謝! – ThievingSix

+0

+1 sweet可以是 –

+0

+1。同意大衛 - 好! –