Delphi Uygulamalarında Çoklu Dil  Uygulamaları  Hazırlayan

Delphi Uygulamalarında Çoklu Dil Uygulamaları

    Önsöz

    Özellikle internet kullanımında meydana gelen yükseliş ve bağlı olarak bu büyük ağ üzerinde çalışan uygulamalarda görülen çeşitlilik oldukça dikkate değer bir gelişme göstermektedir. Gerek firmaların çokuluslu yapılara bürünmeleri, gerekse de çalışan profilinin globalleşmesi (!) nedeniyle uygulamaların değişik dillerdeki arayüzleri desteklemesi ihtiyacı günden güne artmaktadır. Başlangıçta web uygulamalarında sıkça gördüğümüz bu özellik, N-tier mimarisiyle dünya genelinde kullanılan windows uygulamalarında da görülmeye başlanmıştır. Bu dökümanla,bu konuda daha önce edinilmiş deneyimler ışığında pratik bir dil dönüştürücü kod verilmiş ve örnek bir uygulamayla da kullanımı modellenmiştir.

  
 Kullanılan Yöntem
  
    Bu bölümde incelenen yöntemle hazırlanmış bir Progress 4GL uygulaması, şu anda 4 ayrı dilde simultane olarak çalışmaktadır. Burada verilen yöntem sadece arabirimin dilinin değiştirilmesini kapsamakta, verilerin dönüşümünü kapsamamaktadır.

    Çoklu Dil Desteği Olan Uygulamalarda Dikkat Edilecekler

    Eğer çokdilli bir uygulama geliştiriliyorsa, dikkat edilmesi gereken birkaç nokta sözkonusudur. Özellikle rdbms konsepti kullanılıyorsa.

  •  Tüm flag alanlar, veritabanında integer olarak tutulmalıdır. Bu sayede dil değiştiğinde de ilgilialanın caption ı düzgünce değiştirilebilir.
     

  • Çoktan seçmeli alanlar için seçenekleri stringtable dan aldıktan sonra parse edecek bir rutin geliştirilmelidir.
     

  • Bileşenlerin tüm dillerdeki açıklamalarını alacak kadar bir genişliği olmalıdır. Bu sayede dil değiştirince bileşenin açıklamasının sığmaması gibi bir sorun ortaya çıkmayacaktır.

    Bileşen Ağacında Yürümek

    Temel metodoloji olarak, uygulama kapsamındaki tüm bileşenlerin (Component) bir ağaç yapısı içerisinde birbirine bağlı olmasından yararlanılmıştır. Bu durum sadece delphi için değil, VB ve Progress 4GL gibi gui geliştirme araçlarının pekçoğunda mevcuttur. Bu bileşen ağacı üzerinde recursive bir şekilde yürünerek bileşenlerin kullanıcı arayüzünde görünen başlıklarının değiştirilmesi ana metod olarak ortaya çıkmaktadır. Tüm bileşenler, container olanlar ve olmayanlar olarak ikiye ayrılabilir. Container bileşenler, diğer bileşenleri bünyelerinde barındırabilen bileşenlerdir. Barındıramayanlar ise container olmayanlar olarak nitelendirilebilir. Birkaç örnek verecek olursak;
 

  • Container: Tapplication, Tform, Tpanel,...
     

  • Container olmayan: Tlabel, TradioButton,...
     

    Container olan bileşenler, içerinde barındırdıkları diğer bileşenlerin bilgisinin tutulduğu iki ayrı property ye sahiptirler. Bunlar;
 

  • ComponentCount
     

  • Components
    property leridir. Bu ikisi kullanılarak bileşen ağacı üzerinde yürümek mümkün olmaktadır.
     

    Bileşenlere Ait String ID lerine Erişmek
   
Bir bileşene ait bilgiye ulaştıktan sonra ne olacaktır ? Öncelikle uygulama hazırlanırken tüm bileşenler bir temel dile göre yerleştirilirler (Misal Türkçe). Visible tüm bileşenlerin “tag” propertysi mevcuttur ve buradan hareketle de dönüşüm işlemi gerçekleştirilebilir. Tüm bileşenlere birer unique ID (“tag”) ataması yapacağız. Takip eden bölümlerde verilen örneklerde bunun nasıl yapıldığı gösterilmektedir. Örneğin formumuzun başlığı “Stok Giriş” olsun. Formun tag idsi 100 olarak verilmiş olsun. (Diğer bileşenlere de 101 102 gibi verilebilir). Uygulamada bulunması muhtemel mesaj sayısına göre bir ayırma işlemi yapılması gerekmektedir. Örneğin,
 

  • 1-10000 arası id ler Türkçe
     

  • 10001-20000 arası id ler İngilizce

     

  • 20001-30000 arası id ler İtalyanca
    gibi. Buradan da anlaşılacağı gibi herbir visible bileşenin 1-10000 arasında bir değeri olmalıdır.
    Yukarda verdiğimiz form örneğindeki başlık için;
     

  • Türkçesi: 100
     

  • İngilizcesi: 10100
     

  • İtalyancası: 20100
    Uygulamada nasıl kullanıldığı takip eden bölümlerde verilmiştir.


    String lerin Depolanması ve Runtime Esnasında Erişilmesi
   
Windows uygulamaları için kalıcı sabit değerleri (resim, yazı vs) uygulamayla birlikte dağıtabilmek için resource dosyaları kullanılabilir. Bu örnekte, bir stringtable oluşturulup uygulamaya gömülmüştür. Şayet dil desteği uygulamayı derlemeye gerek olmaksızın desteklensin
istenirse local bir dosyadan da runtime sırasında yüklenebilir.

    Uygulama
   
Aşağıda, yukarıda belirttiğimiz yöntemle bir uygulamadaki tüm bileşenleri gerçek zamanlı olarak diğer dillere dönüştüren kodları bulabilirsiniz;
 

procedure SetupLanguage(hRootComponent: TComponent);
var
    cCount : Integer ;
begin
    for cCount:=0 to hRootComponent.ComponentCount -1 do begin
        if (hRootComponent.Components[cCount].ComponentCount > 0) then begin
            SetupComponentLanguage(hRootComponent) ;
            SetupLanguage(hRootComponent.Components[cCount]);
        end
        else begin
            SetupComponentLanguage(hRootComponent.Components[cCount]) ;
        end ;
    end ;
end ;

procedure SetupComponentLanguage(hComponent:TComponent);
var
    hBuffer : Array[1..512] of Char ;
    PropInfo: PPropInfo ;
begin
    if (hComponent.tag > 0) then begin { is it ready for translation ? }
        PropInfo := GetPropInfo(hComponent.ClassInfo, 'Caption');
        if Assigned(PropInfo) then begin
            LoadString(hInstance, hComponent.tag + (lang * 10000),@hBuffer,sizeof(hBuffer)) ;
            SetStrProp(hComponent,PropInfo,string(hBuffer)) ;
        end;
    end ;
end;


    Yukarıdaki kodlar, verilen bileşenden aşağı doğru bileşen ağacında yürüyerek, 'Caption' property sini destekleyen bileşenlerin bu property sini tag lerindeki değeri kullanarak set etmektedir. Bu işlem yapılırken kullanılan lang değişkeninin sahip olduğu (0-Türkçe, 1-İngilizce, 2-İtalyanca,...) order numarası kullanılmıştır. Bir uygulamayı toptan bu işlemden geçirmek için;

   
SetupLanguage(Application);

kullanılabilir. Bununla birlikte tüm formların onCreate eventları içinde de;
   
   
SetupLanguage(self) ;

şeklinde bir kullanımla yüklenirken dinamik olarak dil değişiminin yapılması sağlanabilir.

    Hazırlanan örneğe ait resource dosyası;

STRINGTABLE
{
100, "Dil Testi"
101, "&Etiket 1"
102, "&Giri şKutusu 1"
103, "&Grup Kutusu 1"
104, "&Radio Dü me 1"
ğ
105, "&Radio Dü me 2"
ğ
106, "&Dil De i tir"
ğş
10100, "Language Test"
10101, "&Label 1"
10102, "&Edit 1"
10103, "&Group Box 1"
10104, "&RadioButton 1"
10105, "&RadioButton 2"
10106, "&Change Language"
}


   
Sonuç
   
Tüm geliştirme araçlarının çoklu dil desteği sağlamaya yönelik bileşenleri bulunmaktadır. Genellikle compile sırasında birden fazla executable oluşturulması sayesinde sağlanan bu özelliğe alternatif olarak, diğer dillerle de kullanılabilecek (kullanılmış) hızlı, küçük ve basit bir yöntem izah edilmeye çalışılmıştır. Uygulamalarınızda oluşabilecek bu gibi ihtiyaçlarda sizlere yardımcı olması dileğiyle...

 


   
Hazırlayan

   
Doğan Zorlu ( doganzorlu@doganzorlu.com )
bimeks borland component database delphi delphi.net delphi dersleri firebird help interbase makale oracle seminer software sybase veritabanı web