FindChildControl與FindComponent

來源:互聯網
上載者:User

標籤:

      前兩天編碼遇到了要使用FindChildControl方法擷取指定名稱的TSpeedButton按鈕,結果折騰了半天就是沒得結果(基礎不紮實,呵呵),於是趕緊搜尋了下,補習關於這兩個方法的用法。

       TWinControl類的FindChildControl方法在FWinControls中尋找返回指定名稱的可視且有表單的組件(繼承自TWinControl類)。該方法可以確定當前控制項是否含有(contain)指定名稱的繼承自TWinControl類的子控制項,其結果與指定要尋找的控制項的Parent屬性有關。如果未找到返回nil(NULL),該方法只尋找當前控制項的直接子控制項,不會迭代尋找子控制項的子控制項。

       TComponent類的FindComponent方法在FComponents中尋找返回指定名稱的組件。該方法可以確定當前組件是否擁有(Own)指定名稱的組件,其結果與指定尋找的組件在建立時指定的Owner屬性有關。表單設計器上的建立的組件其擁有者為表單,所以一般使用Self.FindComponent調用這個方法。該方法參數不區分大小寫。

       Parent屬性是指定控制項的父容器,控制項只能在父容器範圍內顯示和移動。Owner屬性是指定組件的所有者,它負責組件的建立和釋放。在表單編輯器中添加組件,則預設地將Owner屬性設定為所屬的表單,所以用表單的FindComponent肯定可以找到。如果動態建立組件,那麼必須指定其Owner和Parent,才可以調用相應方法找得到。而且,如果你放上去的是TWinControl的繼承類,那麼用FindChildControl就可以找到,否則就找不到。

       FindComponent非常簡單,下面重點說說FindChildControl這令人糾結的方法【注1】。      

       這裡先要瞭解下面幾個基類:

       1、TComponent  所有組件基類

       2、TControl         運行時可視組件(TWinControl和TGraphicControl的基類)

       3、TWinControl  可視且有表單的組件的基類

       TWincontrol就是Windows控制項陳列庫的基類,從TWinControl繼承下來的控制項,都是具備有控制項控制代碼的,也就是在Windows內部具備有唯一標記,能動態索引找到的。

       Delphi使用兩個列表來維護控制項的子控制項:FWinControls和FControls。前者儲存有控制代碼的控制項,即繼承自TWinControl的控制項;後者儲存無控制代碼的控制項,一般繼承自TGraphicControl的控制項。所以控制項的ControlCount屬性值為FWinControls.Count與FControls.Count之和。

[delphi] view plain copy  print?
  1. //ControlCount屬性的讀取方法  
  2. function TWinControl.GetControlCount: Integer;  
  3. begin  
  4.   Result := 0;  
  5.   if FControls <> nil then Inc(Result, FControls.Count);  
  6.   if FWinControls <> nil then Inc(Result, FWinControls.Count);  
  7. end;  

 

       在建立子控制項時會調用Insert方法來將子控制項添加到父容器的上述兩個列表。

[delphi] view plain copy  print?
  1. procedure TWinControl.Insert(AControl: TControl);  
  2. begin  
  3.   if AControl <> nil then  
  4.   begin  
  5.     if AControl is TWinControl then  
  6.     begin  
  7.       ListAdd(FWinControls, AControl);//如果是TWinControl則添加到FWinControls列表  
  8.       ...  
  9.     end   
  10.     else  
  11.       ListAdd(FControls, AControl);//否則添加到FControls列表  
  12.     ...  
  13.   end;  
  14. end;  

      下面再來看看FindChildControl的實現代碼,可以看到FindChildControl只尋找了FWinControls列表,這就是上面所說的它只尋找可視且有表單的組件,即繼承自TWinControl類的組件。

[delphi] view plain copy  print?
  1. function TWinControl.FindChildControl(const ControlName: string): TControl;  
  2. var  
  3.   I: Integer;  
  4. begin  
  5.   Result := nil;  
  6.   if FWinControls <> nil then  
  7.     for I := 0 to FWinControls.Count - 1 do  
  8.       if CompareText(TWinControl(FWinControls[I]).Name, ControlName) = 0 then  
  9.       begin  
  10.         Result := TControl(FWinControls[I]);  
  11.         Exit;  
  12.       end;  
  13. end;  

 

 

                   測試

    整個測試介面

1、Self.FindChildControl(表單調用)     

     測試代碼:

[delphi] view plain copy  print?
  1. //FindChildControl尋找  
  2. procedure TForm1.btn1Click(Sender: TObject);  
  3. var  
  4. c:TControl;  
  5. begin  
  6.   memo1.Clear;  
  7.   Memo1.Lines.Add(‘FindChildControl尋找‘+Edit1.Text+‘...‘);  
  8.   c:=self.FindChildControl(Edit1.Text);//表單調用  
  9.   if(c=nil)then  
  10.   Memo1.Lines.Add(‘未找到!‘)  
  11.   else  
  12.   begin  
  13.     Memo1.Lines.Add(‘找到!‘);  
  14.     Memo1.Lines.Add(‘父控制項名稱:‘+c.Parent.Name);  
  15.   end;  
  16. end;  

      測試結果:

(1)尋找Button1(繼承自TWinControl)

(2)尋找Label1(繼承自TGraphicControl)

         

(3)尋找Button11(父容器為Panel1)

 

2、Panel1.FindChildControl

      測試代碼:

[delphi] view plain copy  print?
  1. //FindChildControl尋找——父控制項調用  
  2. procedure TForm1.btn4Click(Sender: TObject);  
  3. var  
  4. c:TControl;  
  5. begin  
  6.   memo1.Clear;  
  7.   Memo1.Lines.Add(‘FindChildControl尋找‘+Edit1.Text+‘...‘);  
  8.   c:=panel1.FindChildControl(Edit1.Text); //panel1調用  
  9.   if(c=nil)then  
  10.   Memo1.Lines.Add(‘未找到!‘)  
  11.   else  
  12.   begin  
  13.     Memo1.Lines.Add(‘找到!‘);  
  14.     Memo1.Lines.Add(‘父控制項名稱:‘+c.Parent.Name);  
  15.   end;  
  16. end;  

     測試結果:尋找Button11(父容器為Panel1)

     

 

3、Self.FindComponent

     測試代碼:

[delphi] view plain copy  print?
  1. //FindComponent尋找  
  2. procedure TForm1.btn2Click(Sender: TObject);  
  3. var  
  4. c:TComponent;  
  5. begin  
  6.   memo1.Clear;  
  7.   Memo1.Lines.Add(‘FindComponent尋找‘+Edit1.Text+‘...‘);  
  8.   c:=self.FindComponent(Edit1.Text);//表單調用  
  9.   if(c=nil)then  
  10.   Memo1.Lines.Add(‘未找到!‘)  
  11.   else  
  12.   begin  
  13.     Memo1.Lines.Add(‘找到!‘);  
  14.     Memo1.Lines.Add(‘擁有者名稱:‘+c.Owner.Name);  
  15.   end;  
  16. end;  

      測試結果
(1)尋找Button1(父容器為Form1)、Button11(父容器為Panel1)

      

(2)尋找Label1(繼承TCustomLabel→TGraphicControl)、SpeedButton1(繼承TGraphicControl)、Timer1(繼承TComponent)

  

 

4、Panel1.FindComponent

     測試代碼:

[delphi] view plain copy  print?
  1. procedure TForm1.Button6Click(Sender: TObject);  
  2. var  
  3. lbl:TLabel;  
  4. c:TComponent;  
  5. begin  
  6.   lbl:=TLabel.Create(Panel2);//動態建立並指定擁有者  
  7.   lbl.Name:=‘Label6‘;  
  8.   memo1.Clear;  
  9.   Memo1.Lines.Add(‘FindComponent尋找Label6...‘);  
  10.   c:=panel2.FindComponent(‘Label6‘);//擁有者調用  
  11.   if(c=nil)then  
  12.   Memo1.Lines.Add(‘未找到!‘)  
  13.   else  
  14.   begin  
  15.     Memo1.Lines.Add(‘找到!‘);  
  16.     Memo1.Lines.Add(‘擁有者名稱:‘+c.Owner.Name);  
  17.   end;  
  18.   {在表單上顯示還需加上以下代碼}  
  19.   lbl.Parent:=Panel2;//Parent預設為nil,所以“無顯示”  
  20.   lbl.Left:=50; //指定相對Parent的位置  
  21.   lbl.Top:=50;  
  22. end;  

    測試結果:


 

 

 

 

 

 注1:糾結倒不是因為這個方法本身,而是一開始我就寫了這個demo來測試這個方法的使用及其結果,當時也沒注意TLabel不是繼承自TWinControl(呵呵,平時都不怎麼關注這些,自然以為這些普通控制項都繼承自TWinControl),結果估計是編譯器出問題了,用Self.FindChildControl可以查詢到Label1,用Panel1.FindChildControl也可以查詢到Label(之前都是測試Label的),但就是在TabSheet.FindChildControl裡不能查到相應Label,而且編譯器也不能在FindChildControl裡設斷點,後來在網上看到說要將編譯器的一個開關開啟,但執行的結果還是一樣。第二天,無意中看到TLabel不是繼承自TWinControl,這就令人鬱悶了,怎麼之前能查詢到呢?馬上開啟demo從新運行了一次,結果就這樣突然都查不到了,真是令人蛋疼。好在最後驗證了這個方法的原理及其實現過程。

 

http://blog.csdn.net/tht2009/article/details/6954880

FindChildControl與FindComponent

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.