mantikli bir döngü yapisi

Delphi'de kod yazma ile ilgili sorularınızı bu foruma yazabilirsiniz.
ikra
Üye
Mesajlar: 901
Kayıt: 28 Nis 2005 01:26
Konum: Simdilik Topragin Üstü

Mesaj gönderen ikra »

öncelikle sorunum ile ugrasan herkesin duacisi oldugumu belirtmek isterim.

ben TComponent olarak gönderip componentcount yerine controlcount seklinde döngüye sokmusum. components yerine de haliyle controls kullanmisim. bu nedenle recursive arama ihtiyaci duymusum. 12 saat ten sonra pc basinda oturmak sakincali oluyor demek ki :oops:

sorunu her iki sekilde de cözmek mümkün oldu haliyle.

tekrar hepinizin duacisi oldugumu belirtir saygilar sunarim.
zihninize, klavyenize saglik!
aLonE CoDeR
Kıdemli Üye
Mesajlar: 1223
Kayıt: 26 Nis 2005 04:08

Mesaj gönderen aLonE CoDeR »

İyi de child da olsa sonuçta o bir formdur, bunun componentcount la alakası nedir?
Kullanıcı avatarı
Murat DİCLE
Kıdemli Üye
Mesajlar: 702
Kayıt: 19 Nis 2006 04:12
Konum: İstanbul
İletişim:

Mesaj gönderen Murat DİCLE »

evet bir form bende onu diyorum. bu nedenle bir batımda tüm bileşenlere ulaşmak için bu kodlar gerekiyor.

neyse zaten arkadaş işini gördü. benim yaptığımı anlıyabilmek için modüler programlama ve böyle bir şeye ihtiyaç duyulması gerekmektedir. şu an bunu sizlere izah edemedim.

sorulan soru alt bileşenlere erişim hakkında idi.
aLonE CoDeR
Kıdemli Üye
Mesajlar: 1223
Kayıt: 26 Nis 2005 04:08

Mesaj gönderen aLonE CoDeR »

muratdicle yazdı:benim yaptığımı anlıyabilmek için modüler programlama ve böyle bir şeye ihtiyaç duyulması gerekmektedir. şu an bunu sizlere izah edemedim.
bu güzeldi :D
Kullanıcı avatarı
Murat DİCLE
Kıdemli Üye
Mesajlar: 702
Kayıt: 19 Nis 2006 04:12
Konum: İstanbul
İletişim:

Mesaj gönderen Murat DİCLE »

yapacam bir örnek sırf bu iş için göndercem :D o zaman daha anlaşılır olacağına inanıyorum.

çok yakında. bizi izlemeye devam edin.
Akin_Delphi
Üye
Mesajlar: 163
Kayıt: 06 Nis 2006 12:22

Mesaj gönderen Akin_Delphi »

muratdicle yazdı:

Kod: Tümünü seç

procedure TMusonyaCYL.DoAppllyLanguage;
      procedure AraBul(C : TComponent);
      var i  : integer;
          PI : PPropInfo ;
          S  : String;
      aFont  : TFont;
      begin
         for i := 0 to C.ComponentCount - 1 do
            begin
               if C.Components[i].ComponentCount > 0 then AraBul(C.Components[i]);
               try
                  if CDS.Locate('LangCode;ObjectName', VarArrayOf([UpperCase(LangPrefix), UpperCase(C.Components[i].Name)]), []) then
                     begin
                        S := WideStringToString(CDS['Text'], CDS['CodePage']);
                        if Pos('TTNT', UpperCase(C.Components[i].ClassType.ClassName)) = 1 then
                           begin
                              PI := GetPropInfo(C.Components[i].ClassInfo, 'Caption');
                              if Assigned(PI) then SetWideStrProp(C.Components[i], PI, CDS['Text']);
                              PI := GetPropInfo(C.Components[i].ClassInfo, 'BiDiMode');
                              if Assigned(PI) then SetOrdProp(C.Components[i], PI, CDS['BiDiMode']);
                              Continue;
                           end;
                        aFont := TFont(GetOrdProp(C.Components[i], 'Font'));
                        if assigned(aFont) then aFont.Charset := GetCharSet(CDS['CodePage']);
                        PI := GetPropInfo(C.Components[i].ClassInfo, 'Caption');
                        if Assigned(PI) then SetStrProp(C.Components[i], PI, S);
                        PI := GetPropInfo(C.Components[i].ClassInfo, 'BiDiMode');
                        if Assigned(PI) then SetOrdProp(C.Components[i], PI, CDS['BiDiMode']);
                        //if TControl(C.Components[i]).Visible then TControl(C.Components[i]).Repaint;
                     end;
               except
               end;
            end;
      end;
begin
   .
   .
   .
      if Assigned(Owner) And (Owner.HasParent) And (Owner.Owner is TForm) then
         AraBul(Owner.Owner)
      else
         if Assigned(Owner) And (Owner is TComponent) then
            AraBul(Owner);
   .
   .
   .
end;
PI : PPropInfo; ve PI := GetPropInfo(C.Components.ClassInfo, 'Caption'); kullanımına bakınız. Bileşen içinde CAPTION varmı onu sorguluyor. eğer varsa PI geriye dönüyor. Yoksa PI = nil olmaktadır.

Eğer CAPTION var ise

if Assigned(PI) then SetStrProp(C.Components, PI, S);


Bir şey ekleme gereksinimi duydum. Bu GetPropInfo, SetStrProp vs. gibi fonksiyonları kullanmak için uses kısmına TypInfo unitini eklemek gerekli. Eğer bunu eklemezseniz bu komutları IDE bulamaz ve dolayısıyla uygulamayı derleyemez. Belki birileri denemeye kalkar diye eklesem iyi olur dedim.

Saygılarımla
Hakan Can
Üye
Mesajlar: 634
Kayıt: 04 Mar 2005 04:27
Konum: Ankara

Mesaj gönderen Hakan Can »

Olayı çok karışık hale getirmişsiniz.
Önce soruyu soran arkadaş yanlış bir şey yapmış konu yanlışın üzerine inşa edilmiş. Yanlış olan arkadaşın ComponentCount yerine ControlCount kullanması ve bunu foruma ısrarla ComponentCount diye söylemesi. Gerçi sonradan düzeltmiş ama sonuçta yok MDI'dı yok Child'dı yok modüler programlamaydı, yanlış üstüne yanlış konular geldi.

Sonuç olarak önemli olan doğruları ortaya koyabilmek. Yazılımda doğrular sınırsız. Ben hiç unutmam. Turbo Pascal 3.0'la yeni tanışmıştım. Bir program yazdım. Printerdan 22 sayfa çıktı aldım ve kendimle gurur duyuyordum. "Ne büyük programcıyım. Tam 22 sayfalık program yazdım." Ancak bir iki gün sonra aynı programı iç içe iki döngü yazılabildiğini öğrenip yarım sayfaya sığdırınca o zaman anladım programcılığın ve benim programcılığımın ne olduğunu.

Aslında benim vurgulamak istediğim de buydu. Yani basit ve standart çözümler varken çok karmaşık çözümlere gitmek doğru değil. Ama ben illa da 22 sayfa yazıp kendimi çok büyük programcı olarak görecem diyorsanız o sizin tercihiniz.

Bu konularla ilgili Screen.FormCount, Screen.DataModuleCount ve bunlarla ilgili diğer özellikleri ve daha önce belirttiğim Form.ComponentCount veya Form.ControlCount'ları sade bir şekilde kullanmayı tercih ediyorum.

Recursive procedure ve function'ları da kullanıyorum. Ancak recursive kullanımında çok dikkatli olmak gerekiyor. Zira her an "Stack overflow" hatası meydana gelebiliyor. Gerçi onu da global değişken kullanarak vs. kontrol ediyorum. Ama bazen bunu yapamıyorsunuz.

İyi çalışmalar.
Akin_Delphi
Üye
Mesajlar: 163
Kayıt: 06 Nis 2006 12:22

Mesaj gönderen Akin_Delphi »

Hakan Can yazdı:Olayı çok karışık hale getirmişsiniz.
Sonuç olarak önemli olan doğruları ortaya koyabilmek. Yazılımda doğrular sınırsız. Ben hiç unutmam. Turbo Pascal 3.0'la yeni tanışmıştım. Bir program yazdım. Printerdan 22 sayfa çıktı aldım ve kendimle gurur duyuyordum. "Ne büyük programcıyım. Tam 22 sayfalık program yazdım." Ancak bir iki gün sonra aynı programı iç içe iki döngü yazılabildiğini öğrenip yarım sayfaya sığdırınca o zaman anladım programcılığın ve benim programcılığımın ne olduğunu.

Aslında benim vurgulamak istediğim de buydu. Yani basit ve standart çözümler varken çok karmaşık çözümlere gitmek doğru değil. Ama ben illa da 22 sayfa yazıp kendimi çok büyük programcı olarak görecem diyorsanız o sizin tercihiniz.
KISS (Keep it Simple Stupid - Yani Basit İş Yap *****) prensibi. Gerçekten program yazmak belirli bir süre uğraştıktan sonra çok sorun değil. Ancak dediğiniz gibi güzel ve verimli program yazabilmek gerçekten sorun.

Ancak burada vurgulamam gereken bir durum var, TypInfo birimi içerisinde bulunan fonksiyonlar jenerik prosedür ve fonksiyon yazmak için çok gerekli.

Yani şöyle düşünün, elinizde bir form var. Siz bu formun üzerine bir panel koyuyorsunuz ve belirli kriterlere göre başka bir form oluşturup bu formun parent özelliğini bu panele aktarıyorsunuz. Yeni oluşturulan formun çeşitli özelliklerini (örneğin üzerinde bulunan DBEditlerin datasource özelliklerini) değiştirmeniz gerek. Şimdi yeni oluşturulan formun bir adı yoksa (eğer bu yolu seçmişseniz), tekrarlayıcı (recursive) döngüler de kullansanız neyin ne olduğuna tek tek isimleriyle ulaşmak sorun oluyor (hatta bazı durumlarda oluşturulan bileşenlerin ismi bile olmayabiliyor :oops: ).

Tekrarlayıcı döngüler içerisinde typeinfo fonksiyonlarını kullanmanız tekrar kullanılabilir kod yazmak için önemli, diye düşünüyorum. Böylelikle atıyorum yukarıda verdiğim örnekteki panele on beş değişik formu çalışma anında (on-the-fly) oluşturup atadığınızda, ana formda bulunan tek bir jenerik prosedür ya da fonksiyonla istediğiniz özelliği değiştirebiliyorsunuz ve her bir forma girip ayrı ayrı kod yazmanıza gerek kalmıyor.
Saygılarımla
aLonE CoDeR
Kıdemli Üye
Mesajlar: 1223
Kayıt: 26 Nis 2005 04:08

Mesaj gönderen aLonE CoDeR »

Bahsettiğiniz şeyler kısaca @muratdicle'nin dediği modüler programlama daha da özü OOP tekniğinin bir yansımasıdır."Böl-parçala-yönet" ve "öyle kod yaz ki aptallar bile anlasın" yazılım mühendisliğinin temelini oluşturan olgular olarak lanse edilmiştir.Konu uzadıkça uzar detaylandırmaya lüzum yok.Uzun konuları okumayı üşengeçlikten ötürü tercih etmiyorum.

Kolay gele..
Kullanıcı avatarı
Murat DİCLE
Kıdemli Üye
Mesajlar: 702
Kayıt: 19 Nis 2006 04:12
Konum: İstanbul
İletişim:

Mesaj gönderen Murat DİCLE »

Tabi soru sorarken detaylar vermek önemli bu konu başlığındaki gibi olaylar dallanabiliyor.

Soru içinde
sinirsiz sub taramasi yapacak bir döngü kurmaliyim.
gibi bir şey olduğunda elbette benim ilk verdiğim örnek kaçınılmaz oluyor. Burdan tabi sorudan ne algılandığı da önemli, benim ne algıladığım gibi. Benim vaktiyle başıma gelen bir sorunun bu arkadaşında başına geldiğini ve günlerce bunu çözmek için uğraşmam aklıma geldiği gibi.

Sonuçta her halukarda tekli form olduğunda benim verdiğim örnek fazla uzun kalmaktadır. Bu aynı 2+2 yi toplamak için ASM kodu yazmak gibi birşey.

Tabi yinede bir sorumluk içerisinde sizlerin bir gün ihtiyacı olmacağını zannederek yazdıklarımında yabana atılmamasını tavsiye ediyorum.

Akin_Delphi arkadaşımızın dediği gibi ikinci verdiğim örnekte doğru demiş USES kısmını TypeInfo eklemeniz gerekmektedir. Bunu es geçmişim.

Ee bu kadar şeyler yazdık bişiler verdik karşılıklı olarak, bu konu başlığı altındaki verilmiş örnekleri baz alarak size bir Ev ödevi vereyim:

Bir uygulama içindeki tüm nesneleri formları vb. şeyleri hiyararşi içinde TREEView'de gösteren bir program yazın. uygulama içinde en az 2 MDIChild, 2 adet harici form ve dilediğiniz kadar bileşen koyabilirsiniz.

Şöyle bir sonuç çıksın ortaya

Kod: Tümünü seç

Application --+
              |
              +Form1--+
              |       |
              |       +-- Edit1
              |       +-- Edit2
              |       +-- Label1
              |       +--Panel1 -+
              |       |          |
              |       |          +-- Label2
              |       |          +-- Edit3
              |       |
              |       +-- Button1
              |
              +Form2 --+
                       |
                       +-- vs. vs. vs.


Maksat spor olsun :D

herkese kolay gelsin.
Sevgiler ve saygılar...
Hakan Can
Üye
Mesajlar: 634
Kayıt: 04 Mar 2005 04:27
Konum: Ankara

Mesaj gönderen Hakan Can »

Kod: Tümünü seç

procedure GetAllComponentNamesOfComponent(aComponent: TComponent; aList: TStrings; const aLeftStr: string; aDepth: Integer);
var
  I: Integer;
  aAllLeftStr: string;
begin
  if not Assigned(aComponent) or not Assigned(aList) then Exit;
  if aDepth < 0 then aDepth := 0;
  aAllLeftStr := DupeString(aLeftStr, aDepth); //uses StrUtils...
  for I := 0 to aComponent.ComponentCount - 1 do
  begin
    if aComponent.Components[I].Name = '' then
      aList.Add(aAllLeftStr + aComponent.Components[I].ClassName + ', isimsiz')
    else
      aList.Add(aAllLeftStr + aComponent.Components[I].Name);
    if aComponent.Components[I].ComponentCount > 0 then GetAllComponentNamesOfComponent(aComponent.Components[I], aList, aLeftStr, aDepth + 1);
  end;
end;

//Forma TreeView1 adında bir adet TTreeView ve Button1 adında TButton yerleştirmelisiniz...
procedure TAnaForm.Button1Click(Sender: TObject);
var
  aFileName: string;
  aList: TStringList;
begin
  aFileName := 'C:\xxxxxx.TXT'; //Temp klasöründe olmayan bir dosya adı uygun olacaktır...
  aList := TStringList.Create;
  try
    aList.Add('Application');
    GetAllComponentNamesOfComponent(Application, aList, Chr(VK_TAB), 1);
    aList.SaveToFile(aFileName);
    TreeView1.LoadFromFile(aFileName); 
  finally
    aList.Free;
    DeleteFile(aFileName);
  end;
end;
İyi çalışmalar.
En son Hakan Can tarafından 16 May 2006 04:01 tarihinde düzenlendi, toplamda 1 kere düzenlendi.
Kullanıcı avatarı
Murat DİCLE
Kıdemli Üye
Mesajlar: 702
Kayıt: 19 Nis 2006 04:12
Konum: İstanbul
İletişim:

Mesaj gönderen Murat DİCLE »

Güzel eline sağlık, denemedim ama çalışıyor gibi duruyor.

Yani görüldüğü gibi daldırgaç olması ve başlangıcı Application olarak vermemiz işi çözüyor. Ayrıca bu kodu deneyen şunu görecektir. TPanel gibi bilşenlerinde alt bileşenleri olabileceğini..

kolay gelsin...
Hakan Can
Üye
Mesajlar: 634
Kayıt: 04 Mar 2005 04:27
Konum: Ankara

Mesaj gönderen Hakan Can »

Kod: Tümünü seç

procedure GetAllComponentNamesOfComponent(aComponent: TComponent; aList: TStrings; const aLeftStr: string; aDepth: Integer);
var
  I, F: Integer;
  aAllLeftStr: string;
begin
  if not Assigned(aComponent) or not Assigned(aList) then Exit;
  if aDepth < 0 then aDepth := 0;
  aAllLeftStr := DupeString(aLeftStr, aDepth); //uses StrUtils
  with aComponent do
    for I := 0 to ComponentCount - 1 do
    begin
      if Components[I] is TWinControl then
        if Assigned(TWinControl(Components[I]).Parent) then Continue;
      if Components[I].Name = '' then
        aList.Add(aAllLeftStr + Components[I].ClassName + ', isimsiz')
      else
        aList.Add(aAllLeftStr + Components[I].Name);
      if Components[I].ComponentCount > 0 then
        GetAllComponentNamesOfComponent(Components[I], aList, aLeftStr, aDepth + 1)
      else
        if Components[I] is TWinControl then
           if TWinControl(Components[I]).ControlCount > 0 then GetAllComponentNamesOfComponent(TWinControl(Components[I]), aList, aLeftStr, aDepth + 1);
    end;
  if aComponent is TWinControl then
    with TWinControl(aComponent) do
      for I := 0 to ControlCount - 1 do
      begin
        if Controls[I].Name = '' then
          aList.Add(aAllLeftStr + Controls[I].ClassName + ', isimsiz')
        else
          aList.Add(aAllLeftStr + Controls[I].Name);
        if Controls[I].ComponentCount > 0 then
          GetAllComponentNamesOfComponent(Controls[I], aList, aLeftStr, aDepth + 1)
        else
          if Controls[I] is TWinControl then
            if TWinControl(Controls[I]).ControlCount > 0 then GetAllComponentNamesOfComponent(Controls[I], aList, aLeftStr, aDepth + 1);
      end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  aFileName: string;
  aList: TStringList;
begin
  aFileName := 'C:\xxxxxx.TXT';
  aList := TStringList.Create;
  try
    aList.Add('Application');
    GetAllComponentNamesOfComponent(Application, aList, Chr(VK_TAB), 1);
    aList.SaveToFile(aFileName);
    TreeView1.LoadFromFile(aFileName);
  finally
    aList.Free;
    DeleteFile(aFileName);
  end;
end;
İyi çalışmalar.
Cevapla