27 Mart 2010 Cumartesi

Çoklu Dil Uygulamaları

Ö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... Alıntıdır.

Hiç yorum yok:

Yorum Gönder