15-08-2010, 12:23 AM
بسم الله الرحمن الرحيم
السلام عليكم ورحمة الله
في هذا الدرس مثال بسيط حول استخدام مصادر التطبيق (Resources) لتغيير لغة الواجهة حسب الإعدادات الإقليمية للنظام بشكل تلقائي.
String Table:
يمكن باستخدام أي محرر Resource تخزين عدة جداول من النصوص تسمى StringTable حيث يحمل كل جدول رقم تعريفي للغة ورقم تعريفي لإقليم اللغة.
مثال:
في هذا المثال نقوم بإنشاء جدولين من النصوص بشكل يدوي (دون استخدام برامج)
حيث في الجدول الأول نخزن النصوص باللغة العربية (إقليم سورية)
وفي الجدول الثاني نخزن النصوص بلغة أجنبية (الفرنسية إقليم قياسي)
افتح ملف نصي واكتب فيه:
كود :
// --------- resources of type String -----------
STRINGTABLE
LANGUAGE LANG_ARABIC, SUBLANG_ARABIC_SYRIA
{
1001, "موافق"
1002, "إلغاء الأمر"
1003, "لغات:"
1004, "تطبيق متعدد اللغات"
1005, "حول التطبيق"
}
STRINGTABLE
LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT
{
1001, "&oK"
1002, "&Annuler"
1003, "Langues:"
1004, "Multi-langue avec Resources"
1005, "&A Propos..."
}
// --------- resources of type Icon -----------
MAINICON Icon "MAINICON.ico"SUBLANG_ARABIC_LIBYA، SUBLANG_ARABIC_EGYPT
والجدول الثاني للغة الفرنسية-افتراضي، وكان من الممكن استخدام أي من القيم: SUBLANG_FRENCH أو SUBLANG_FRENCH_CANADIAN... أوغيرها
كل هذه القيم وغيرها متوفرة كثوابت في المكتبة Windows.pas.
الآن احفظ الملف باسم Lang.rc مثلا.
قم بإنتاج ملف Resource من خلال سطر الأوامر:
كود :
BRCC32 Lang.rcنغير اسم ملف الـ Resource في التطبيق:
كود :
uses
Forms,
uMain in 'uMain.pas' {Form1};
[color=Red]{$R Lang.res}[/color]
begin
Application.Initialize;
Application.CreateForm(TForm1, Form1);الآن تطبيقنا يحتوي على مصادر نصية للغتين
لاستدعاء نص الزر OK نكتب:
كود :
btOk.Caption:= LoadStr(1001);ملاحظة: LoadStr من SysUtils وهي تستدعي LoadString من API بما يشبه الآتي:
كود :
function GetResString(uID: Cardinal): string;
begin
SetLength(Result , MAX_PATH);
LoadString(HInstance, uID, PChar(Result), MAX_PATH);
end;بعبارة أخرى كيف نعرف أن البرنامج سيستدعي كلمة "موافق" أو "OK"؟؟؟ ... هنا مربط الفرس!
البرنامج لا يعرف ذلك وليس بحاجة لمعرفة ذلك...
عند تشغيل البرنامج في Thread يحصل هذا الأخير على قيمة Cardinal تدعى Locale
تمثل هذه القيمة الإعدادات الإقليمية المطبقة في هذا الـ Thread
للحصول على هذه القيمة نستخدم GetThreadLocale تابع API لنشاهد هذه القيمة:
كود :
ShowMessage(IntToHex(GetThreadLocale, 8));مرر هذه القيمة لهذا التابع لنشاهد الصورة بوضوح:
كود :
function GetLanguage(wLang: Cardinal): string;
var
szLang: array[0..MAX_PATH] of Char;
begin
VerLanguageName(wLang, szLang, 50);
Result := szLang;
end;يقوم التطبيق عند إقلاعه بقراءة مصادره (الـ Resources) وفق هذه القيمة (Locale) التي تمثل اللغة الإقليمية المحددة.
الآن إقرأ عائد التابع GetSystemDefaultLCID باستخدام GetLanguage التي رأيناها آنفا.
هذا التابع يعيد اللغة الإقليمية للنظام. وهو اللغة التي تستخدم لفك ترميز Unicode (موجودة في الإعدادات الإقليمية التبويب الثالث في XP).
الخلاصة:
نكتب تابع يقوم بتطبيق لغة ممررة عبرة معلمة إلى الـ Thread الحالي للتطبيق، ثم يغير نصوص المكونات:
PHP كود :
procedure TForm1.SetLanguage(LangID: Cardinal);
begin
SetThreadLocale(LangID);
btOk.Caption:= LoadStr(1001);
btCancel.Caption:= LoadStr(1002);
end;
لتطبيق أية لغة:
PHP كود :
SetLanguage(LangID);
PHP كود :
function MAKELANGID(usPrimaryLanguage, usSubLanguage: LANGID): WORD;
begin
Result := ((usSubLanguage shl 10) + usPrimaryLanguage);
end;
PHP كود :
SetThreadLocale(MAKELANGID(LANG_ARABIC, SUBLANG_ARABIC_SYRIA));
PHP كود :
procedure TForm1.FormCreate(Sender: TObject);
begin
SetThreadLocale(GetSystemDefaultLCID);
end;
سورس المثال مرفق في المشاركة #4 (غير لغة الإقليم في الملف Lang.rc حسب إعدادات جهازك).
إستفسارات،ملاحظات، إنتقادات، إضافات أو تعديلات، اقتراحات، مظاهرات، مفاوضات، إنقلابات... مرحبا
