أدخل النص التالي ضمن قسم التصاريح العامة:
' يجب التصريح عن كل المتحولات
Option Explicit
أدخل النص التالي ضمن الإجراء chkBold_Click():
Private Sub chkBold_Click()
txtTest.FontBold = chkBold.Value
End Sub
أدخل النص التالي ضمن الإجراء chkItalic_Click():
Private Sub chkItalic_Click()
txtTest.FontItalic = chkItalic.Value
End Sub
أدخل النص التالي ضمن الإجراء chkStrike_Click():
Private Sub chkStrike_Click()
txtTest.FontStrikethru = chkStrike.Value
End Sub
أدخل النص التالي ضمن الإجراء chkUnderline_Click()للنموذج frmShowFont:
Private Sub chkUnderline_Click()
txtTest.FontUnderline = chkUnderline.Value
End Sub
أدخل النص التالي ضمن الإجراء cmdExit_Click():
Private Sub cmdExit_Click()
End
End Sub
أدخل النص التالي ضمن الإجراء mnu10Points_Click():
Private Sub mnu10Points_Click()
txtTest.FontSize = 10
End Sub
أدخل النص التالي ضمن الإجراء mnu12Points_Click():
Private Sub mnu12Points_Click()
txtTest.FontSize = 12
End Sub
أدخل النص التالي ضمن الإجراء mnuCourier_Click():
Private Sub mnuCourier_Click()
txtTest.FontName = "Courrier"
End Sub
أدخل النص التالي ضمن الإجراء mnuMSSansSerif_Click():
Private Sub mnuMSSansSerif_Click()
txtTest.FontName = "MS Sans Serif"
End Sub
احفظ المشروع بالطريقة المعتادة.
تنفيذ برنامج عرض الخطوط
لنشاهد ما كتبناه قيد التنفيذ:
نفّذ برنامج عرض الخطوط.
اكتب شيئاً ما داخل مربع النص (انظر الشكل 10-4).
يظهر النص الذي أدخلته بالخط الافتراضي (الخط المحدد أثناء مرحلة التصميم).
الشكل10-4 الخط الافتراضي لبرنامج عرض الخطوط.
ضع علامة اختيار في خانة الاختيار خط عريض.
يتغير خط مربع النص إلى خط غامق Bold. كما في الشكل 10-5.
الشكل10-5 وضع علامة اختيار في خانة الاختيار خط عريض.
ضع علامة اختيار في خانة الاختيار خط مائل.
يستجيب البرنامج بتغيير نص مربع النص إلى خط مائل Italic، وبما أنه توجد علامة اختيار في خانة الاختيار خط عريض، فسيظهر النص بخط غامق ومائل في نفس الوقت (الشكل 10-6).
الشكل 10-6 وضع علامتي اختيار في خانتي الاختيار خط عريض و خط مائل.
ضع علامة اختيار في خانة الاختيار يتوسطه خط وألغها من خانتي الاختيار خط عريض وخط مائل، وراقب النتائج.
يستجيب البرنامج بإزالة الخط الغامق والخط المائل من النص، ومرور خط من النص (الشكل 10-7).
الشكل 10-7 وضع علامة اختيار في خانة يتوسطه خط.
ضع إشارة في خانة الاختيار تحته خط.
يستجيب البرنامج بتسطير النص في مربع النص (الشكل 10-.
بدّل حجم الخط باختيار حجم ما من القائمة الأحجام.
الشكل 10-8 وضع علامة اختيار في خانة الاختيار تحته خط.
يستجيب البرنامج بتبديل حجم النص إلى الحجم الذي اخترته، يبين الشكل 10-9 مربع النص بعد اختيار الحجم 12.
الشكل 10-9 تحديد حجم الخط بإسناد القيمة 12 للخاصية FontSize.
انقر الزر خروج لإنهاء البرنامج.
كيف يعمل برنامج عرض الخطوط
يُغيِّر البرنامج، خصائص الخط المستخدم في مربع النص، تبعاً لاختياراتك.
نص الإجراء chkBlod_Click()
يُنفذ هذا الإجراء آلياً، عند نقر خانة الاختيار chkBlod (خانة خط عريض):
Private Sub chkBold_Click()
txtTest.FontBold = chkBold.Value
End Sub
تُسند القيمة True إلى الخاصية FontBold لمربع النص، عندما تساوي الخاصية Value لخانة الاختيار chkBold القيمة True.
وعلى العكس، تُسند القيمة False إلى الخاصية FontBold لمربع النص txtTest، عند إزالة علامة الاختيار من الخانة chkBold، أي عندما تساوي الخاصية Value لخانة الاختيار chkBold إلى False.
تعمل الإجراءات chkItalic_Click، chkStrike_Click، chkUnderline_Click بشكل مشابه لعمل الإجراء chkBold_Click.
يُسند الإجراء chkItalic_Click() إحدى القيمتينTrue أو False للخاصية FontItalic.
يُسند الإجراء chkStrike_Click() إحدى القيمتين True أو False للخاصية FontStrike.
يُسند الإجراء chkUnderline_Click() إحدى القيمتين Trueأو False للخاصية FontUnderline.
نص الإجراء mnu10Points_Click()
يُنفذ الإجراء mnu10Points_Click() عند اختيار 10نقاط من القائمة أحجام:
Private Sub mnu10Points_Click()
txtTest.FontSize = 10
End Sub
يُسند هذا الإجراء القيمة 10 إلى الخاصية FontSize لمربع النص txtText، ويعمل الإجراء mnu10Point_Click() بنفس الطريقة، ولكن يسند القيمة 12 إلى الخاصية FontSize.
نص الإجراء mnuCourier_Click()
ينفذ الإجراء mnuCourier_Click() عند اختيار الخطCourier 10 من القائمة أحجام:
Private Sub mnuCourier_Click()
txtTest.FontName = "Courrier"
End Sub
يُسند هذا الإجراء نوع الخط Courier إلى الخاصية FontName لمربع النص txtText، يعمل الإجراء mnuMsSamsSerif_Click() بطريقة مشابهة بإسناد نوع الخط MsSamsSerif للخاصية FontName.
المصطلح WYSIWYG
يقصد بالمصطلح WYSIWYG أن ما تشاهده هو ما تحصل عليه، وهو مأخوذ من العبارة What You See Is What Yow Get، ويُستخدم هذا المصطلح للدلالة على قدرة البرنامج على إنتاج نسخة طبق الأصل على الطابعة لما تشاهده على الشاشة، يتطلب الحصول على برامج WYSIWYG حقيقية مائة بالمائة، دقة برمجية كبيرة، لأن المستخدمين يمكن أن يمتلكوا طابعات وشاشات وخطوط مختلفة.
برنامج الخطوط
يوضح برنامج الخطوط كيف يمكن لبرنامجك اتخاذ القرار بشأن الخطوط المتوفرة في النظام. يمكن استعمال التقنية المستخدمة من قبل برنامج الخطوط لإنتاج برامج WYSIWYG.
التمثيل المرئي لبرنامج الخطوط
سنبدأ كعادتنا بالتمثيل المرئي للبرنامج:
أنشئ مشروعاً تنفيذياً قياسياً Standard EXE، واحفظ نموذج المشروع بالاسم Fonts.frm في الدليل C:\VB5Prg\Ch10 واحفظ ملف المشروع بالاسم Fonts.Vbp في الدليل C:\VB5Prg\Ch10.
أنشئ النموذج frmFonts طبقاً للجدول 10-3.
يُفترض أن يبدو النموذج المكتمل كذاك المبين في الشكل10-10
الشكل 10-10 النموذج frmFonts (طور التصميم).
الجدول 10-3. جدول خصائص النموذج frmFonts.
الكائن الخاصية القيمة
Form Name frmFonts
Caption برنامج الخطوط
RightToLeft True
ComboBox Name cboFontsPrinter
Sorted True
Style 2-Dropdown List
RightToLeft True
ComboBox Name cboFontsScreen
Sorted True
Style 2-Dropdown List
RightToLeft True
CommandButton Name cmExit
Caption &خروج
RightToLeft True
Label Name lblPrinter
Caption الخطوط المتاحة على الطابعة
RightToLeft True
Label Name lblScreen
Caption الخطوط المتاحة على الشاشة
RightToLeft True
Label Name lblSample
Caption فيجول بيسك5 Visual Basic5
Alignment 2-Center
BorderStyle 1-Fixed Single
RightToLeft True
Label Name lblSampleInfo
Caption مثال:
RightToLeft True
يطالبك الجدول 10-3 بوضع مربعي التحرير والسرد في النموذج frmFonts.
يظهر مستطيل أصفر يحمل الرسالة ComboBox (مربع التحرير والسرد) عندما تضع مؤشر الفأرة فوق رمز مربعي التحرير والسرد ComboBox في إطار مربع الأدوات، وبهذه الطريقة تتأكد من وجود هذا الرمز في مربع الأدوات.
إدخال نص برنامج الخطوط
سندخل الآن نص برنامج الخطوط:
أدخل النص التالي ضمن قسم التصاريح العامة General Declartions للنموذج frmFonts:
'يجب التصريح عن كل المتحولات
Option Explicit
Dim gNumOfPrinterFonts
Dim gNumOfScreenFonts
أدخل النص التالي ضمن الإجراء cboFontsScreen_Click():
Private Sub cboFontsScreen_Click()
'اختار المستخدم خطاً جديداً على الشاشة
' لهذا غير خط اللافتة بما يتوافق مع ما اختاره المستخدم
lblSample.FontName = cboFontsScreen.Text
End Sub
أدخل النص التالي ضمن الإجراء cmdNumberOfFonts_Click():
Private Sub cmdNumberOfFonts_Click()
MsgBox "عدد خطوط الشاشة:" + Str(gNumOfScreenFonts)
MsgBox "عدد خطوط الطابعة:" + Str(gNumOfPrinterFonts)
End Sub
أدخل النص التالي ضمن الإجراء Form_Load():
Private Sub Form_Load()
Dim I
gNumOfScreenFonts = Screen.FontCount - 1
gNumOfPrinterFonts = Printer.FontCount - 1
For I = 0 To gNumOfScreenFonts - 1
cboFontsScreen.AddItem Screen.Fonts(I)
Next
For I = 0 To gNumOfPrinterFonts - 1
cboFontsPrinter.AddItem Printer.Fonts(I)
Next
cboFontsScreen.ListIndex = 0
cboFontsPrinter.ListIndex = 0
End Sub
أدخل النص التالي ضمن الإجراء cmdExit_Click():
Private Sub cmdExit_Click()
End
End Sub
احفظ المشروع.
تنفيذ برنامج الخطوط
لنشاهد ما كتبناه قيد التنفيذ:
نفّذ برنامج الخطوط.
انقر على الزر عدد الخطوط.
يستجيب البرنامج بإظهار مربعي رسالة، يعطيان عدد الخطوط المتوفرة لكل من الشاشة والطابعة.
اختر خطاً من خطوط الشاشة المتوفرة.
يتغير نوع خط اللافتة الافتراضي والمسماة مثال.
تبعاً للخط المختار (انظر الشكل 10-11).
الشكل 10-11 اختيار نوع الخط Arial Arabic.
كما يوضح الشكل 10-12 ما يمكن أن يظهر عند تجول المستخدم عبر لائحة خطوط الطابعة المتوفرة.
الشكل 10-12 إظهار خطوط الطابعة.
ملاحظة
لا يتغير نوع خط النص المكتوب في اللافتة مثال، عند اختيار خط طابعة جديد، وإنما يتغير عند اختيار نوع خط شاشة جديد.
كيف يعمل برنامج الخطوط
يستخلص برنامج الخطوط، أنواع الخطوط المتوفرة لكل من الشاشة والطابعة ويظهرها في مربعي التحرير والسرد الخاص بكل منهما.
نص قسم التصاريح العامة
يصرح هذا القسم عن متحولين عامين:
'يجب التصريح عن كل المتحولات
Option Explicit
Dim gNumOfPrinterFonts
Dim gNumOfScreenFonts
يمثل هذان المتحولان عدد خطوط الشاشة وخطوط الطابعة المتوفرة، تُشاهِد كل إجراءات النموذج هذين المتحولين بسبب التصريح عنهما في قسم التصاريح العامة.
نص الإجراء Form_Load()
ينفذ هذا الإجراء عند بدء تحميل النموذج:
Private Sub Form_Load()
Dim I
gNumOfScreenFonts = Screen.FontCount - 1
gNumOfPrinterFonts = Printer.FontCount - 1
For I = 0 To gNumOfScreenFonts - 1
cboFontsScreen.AddItem Screen.Fonts(I)
Next
For I = 0 To gNumOfPrinterFonts - 1
cboFontsPrinter.AddItem Printer.Fonts(I)
Next
cboFontsScreen.ListIndex = 0
cboFontsPrinter.ListIndex = 0
End Sub
يؤدي استخدام العبارة التالية إلى معرفة عدد خطوط الشاشة المتوفرة في الحاسب الشخصي الذي يُنفذ برنامج الخطوط هذا عليه، وذلك بالاستعانة بالخاصية FontCount.
gNumOfScreenFonts = Screen.FontCount - 1
وكذلك، تُسهم العبارة التالية بمعرفة عدد الخطوط المتوفرة للطابعة بالاستعانة بالخاصية FontCount.
gNumOfPrinterFonts = Printer.FontCount - 1
يملأ الإجراء بعد ذلك، مربع السردcboFontsScreen بأنواع خطوط الشاشة:
For I = 0 To gNumOfScreenFonts - 1
cboFontsScreen.AddItem Screen.Fonts(I)
Next
كما يملأ الإجراء مربع السردcboFontsPrinter بأنواع خطوط الطابعة، أي:
For I = 0 To gNumOfPrinterFonts - 1
cboFontsPrinter.AddItem Printer.Fonts(I)
Next
ملاحظة
تُستخلص الخطوط المتوفرة لكل من الطابعة والشاشة بواسطة الخاصية Fonts. فمثلاً تستخدم العبارة التالية لإسناد أول خط من خطوط الشاشة المتوفرة إلى المتحول الكتابي CurrentScreenFont:
CurrentScreenFont = Secreen.Fonts(0)
وتستخدم العبارة التالية لإسناد تاسع خط طابعة متوفر، إلى المتحول الكتابي CurrentPrinterFont: (انتبه إلى أن العد يبدأ من الصفر).
CurrentPrinterFont = Printer.Fonts(
ثم يُجهز الإجراء بعد ذلك مربع السرد، بحيث يشير إلى أول عنصر:
cboFontsScreen.ListIndex = 0
ثم يُبدّل خط النص الذي تورده اللافتة مثال (العنوان Caption) تبعاً للخاصية Text الحالية لمربع سرد أنواع خطوط الشاشة:
lblSample.FontName = cboFontsScreen.Text
وأخيراً، يُجهز الإجراء مربع السرد cboFontsPrinter بإسناد القيمة صفر للخاصية ListIndex بحيث يشير إلى أول خط متوفر:
cboFontPrinter.ListIndex = 0
نص الإجراء cboFontsScreen_Click ()
يُنفذ نص هذا الإجراء عند اختيار خط شاشة جديد من مربع السرد cboFontsScreen (وهو المربع الذي يقع تحت اللافتة "الخطوط المتاحة على الشاشة"):
Private Sub cboFontsScreen_click()
lblSample.FontName = cboFontsScreen.Text
End Sub
يُبدّل الإجراء بعدها، خط اللافتة مثال إلى الخط الذي اخترته.
نص الإجراء cmdNumberOfFonts_Click()
ينفذ هذا الإجراء تلقائياً عند نقر الزر عدد الخطوط:
Private Sub cmdNumberOfFonts_Click()
MsgBox "عدد خطوط الشاشة:" + Str(gNumOfScreenFonts)
MsgBox "عدد خطوط الطابعة:" + Str(gNumOfPrinterFonts)
End Sub
يُظهر هذا الإجراء عدد خطوط الشاشة المتوفرة، وعدد خطوط الطابعة المتوفرة أيضاً، باستخدام عبارتي MsgBox. يخزّن عدد خطوط كل من الشاشة والطابعة في المتحولين gNumOfScreenFonts و gNumOfPrinterFonts على التوالي، وتحدّث قيمة هذين المتحولين من قبل الإجراء Form_Load().
الطريقة Print
يمكن استخدام الطريقة Print في نموذج أو في عنصر تحكم الصورة، فمثلاً استخدم العبارة التالية لإظهار النص "Testing....." في النموذج frmMyForm:
frmMyForm.Print "Testing....."
أو استخدم العبارة التالية مثلاً، لإظهار النص Testing... في عنصر تحكم الصورة المدعو picMyPicture:
picMyPicture.Print "Testing...."
تستخدم الفاصلة المنقوطة ( ; ) لإخبار فيجول بيسك بوضع النص على نفس السطر، فمثلاً يؤدي استخدام العبارتين التاليتين:
frmMyForm.Print "This is line number 1 and ";
frmMyForm.Print "it continues..."
إلى توليد الخرج التالي:
This is line number 1 and it continues...
تولد العبارة التالية نفس الخرج السابق:
frmMyForm.Print _
"This is line "; "number 1 and "; "it continues..."
محو نص
يمكنك استخدام الطريقة Cls لمحو نص كان مكتوباً في نموذج أوفي عنصر الصورة، فمثلاً لمحو النموذج frmMyForm استخدم ما يلي:
frmMyForm.Cls
أما لمحو عنصر التحكم picMyPicture فاستخدم ما يلي:
picMyPicture.Cls
تمحو الطريقة Cls النصوص والأشكال المرسومة بالطرق الرسومية المختلفة (Line، Circle، PSet ... الخ).
وضع نص عند موقع محدد
تستخدم الخاصيتان CurrentX و CurrentY لمثل هذا الغرض، فمثلاً لوضع النص Testing في النموذج frmMyForm عند العمود 5 والسطر 6، استخدم ما يلي:
frmForm.CurrentX = 5
frmForm.CurrentY = 6
frmMyForm.Print "Testing"
وبشكل مشابه، استخدم العبارات التالية لوضع النص Testing في عنصر الصورة المدعو picMyPicture عند العمود 11 والسطر 10:
picMyPicture.CurrentX = 11
picMyPicture.CurrentY = 10
picMyPicture.Print "Testing"
برنامج الفهرس
يوضح برنامج الفهرس كيف تستخدم الخاصيتين TextHeight وTextWidth اللتين تسمحان بمعرفة ارتفاع وعرض نص معين.
فمثلاً تؤدي العبارة التالية إلى إسناد قيمة ارتفاع النص "AaBbCc" إلى المتحول HeightOfabc:
HeightOfabc = frmMyForm.TextHeight("AaBbCc")
تكون القيمة المعادة من الخاصية TextHeight بنفس الوحدات المشار إليها (أي المحددة) بالخاصية ScaleMode.
تصور أن النص AaBbCc عبارة عن مستطيل مغلق، تُسند العبارة السابقة ارتفاع ذلك المستطيل الوهمي إلى المتحول HeightOfabc، والذي يتحدد بارتفاع أعلى رمز بين الرموز AaBbCc.
تعتبر الخاصية TextHeight مفيدة جداً، عندما ترغب بحساب الخاصية CurrentY لسطر محدد، لنفترض مثلاً أنك أظهرت تسعة سطور، ثم رغبت بعد ذلك برسم خط أفقي تحت السطر التاسع، سنحتاج إلى حساب الإحداثيY للسطر العاشر، واستخدام هذه القيمة لإسنادها للخاصية CurrentY، إليك طريقة حساب CurrentY لمثل هذه الحالة:
CurrentY = frmMyForm.TextHeight("AaBbCc") * 9
تُعيد الخاصية TextWidth عرض النص. فمثلاً لحساب عرض النص Index، استخدم هذه العبارة:
WidthOfIndex = frmMyForm.TextWidth("Index")
تصور ثانية، أن كلمة Index مغلقة بمستطيل، تُسند العبارة السابقة عرض ذلك المستطيل الوهمي إلى المتحول WidthOfIndex.
إذاً تعيد الخاصيتين TextHeight و TextWidth ارتفاع وعرض النص، تبعاً للقيمة الحالية للخاصية FontSize والخاصية FontName.
التمثيل المرئي لبرنامج الفهرس
أنشئ مشروعاً قياسياً جديداً Standard EXE، واحفظ نموذج المشروع بالاسم Index.frm في الدليل C:\VB5Prg\Ch10 واحفظ ملف المشروع بالاسمIndex.vbp في ذات الدليل.
أنشئ النموذج frmIndex تبعاً للجدولين10-4 و 10-5.
يفترض أن يبدو النموذج المكتمل كذاك المبين في الشكل 10-13.
الشكل 10-13 النموذج frmIndex (طور التصميم).
الجدول 10-4. جدول خصائص النموذج frmIndex.
الكائن الخاصية القيمة
Form Name frmIndex
Caption برنامج الفهرس
BackColor White
RightToLeft True
Menu (انظر الجدول 10-5) (انظر الجدول 10-5)
الجدول 10-5. جدول قائمة النموذج frmIndex.
العنوان الخاصية Name
&ملف mnuFile
…&عرض الفهرس mnuDisplayIndex
…&حذف الفصل الثاني mnuEraseCh2
…&مسح النص mnuClear
…- mnuSep1
…&خروج mnuExit
إدخال نص برنامج الفهرس
سنباشر الآن بكتابة نص برنامج الفهرس:
أدخل النص التالي ضمن قسم التصاريح العامة للنموذج frmIndex:
'يجب التصريح عن كل المتحولات
Option Explicit
Dim gDots
أدخل النص التالي ضمن الإجراء Form_Load() للنموذج frmIndex:
Private Sub Form_Load()
gDots = String$(84, ".")
End Sub
أدخل النص التالي ضمن الإجراء mnuClear_Click() للنموذج frmIndex:
Private Sub mnuClear_Click()
frmIndex.Cls
End Sub
أدخل النص التالي ضمن الإجراء mnuDisplayIndex_Click() للنموذج frmIndex:
Private Sub mnuDisplayIndex_Click()
frmIndex.Cls
CurrentY = 100
CurrentX = (frmIndex.ScaleWidth - _
frmIndex.TextWidth("الفهرس ")) / 2
frmIndex.FontUnderline = True
frmIndex.Print "الفهرس"
frmIndex.FontUnderline = False
CurrentY = frmIndex.TextHeight("VVV") * 2
CurrentX = 100
Print "الفصل 1" + gDots + "الكمبيوتر"
CurrentY = frmIndex.TextHeight("VVV") * 3
CurrentX = 100
Print "الفصل 2" + gDots + "الشاشة"
CurrentY = frmIndex.TextHeight("VVV") * 4
CurrentX = 100
Print "الفصل 3" + gDots + "الطابعة"
CurrentY = frmIndex.TextHeight("VVV") * 5
CurrentX = 100
Print "الفصل 4" + gDots + "النهاية"
End Sub
أدخل النص التالي ضمن الإجراء mnuEraseCh2_Click() للنموذج frmIndex:
Private Sub mnuEraseCh2_Click()
Dim LengthOfLine
Dim HeightOfLine
CurrentY = frmIndex.TextHeight("VVV") * 3
CurrentX = ScaleWidth - 100
LengthOfLine = frmIndex.TextWidth("الفصل 2" + _
gDots + "الشاشة")
HeightOfLine = frmIndex.TextHeight("ل")
frmIndex.Line -Step(-LengthOfLine, HeightOfLine), _
RGB(255, 255, 255), BF
End Sub
أدخل النص التالي ضمن الإجراء mnuExit_Click() للنموذج frmIndex:
Private Sub mnuExit_Click()
End
End Sub
احفظ المشروع بالطريقة المعتادة.
تنفيذ برنامج الفهرس
نفّذ برنامج الفهرس.
انقر عرض الفهرس من القائمة ملف.
يستجيب البرنامج بإظهار الفهرس المبين في الشكل 10-14.
انقر حذف الفصل الثاني من القائمة ملف.
يستجيب البرنامج بحذف سطر الفصل الثاني (انظر الشكل 10-15).
الشكل 10-14 إظهار الفهرس.
الشكل 10-15 حذف سطر الفصل الثاني.
اختر مسح النص من القائمة ملف.
يستجيب البرنامج بحذف النص من النموذج.
انقر زر الخروج لإنهاء البرنامج.
كيف يعمل برنامج الفهرس
يُظهر برنامج الفهرس نصاً باستخدام الطريقة Print.كما تستطيع إظهار النص في أي موقع بتحديد أو تعديل قيمة الخاصتين CurrentX، CurrentY.
نص قسم التصاريح العامة
يُصرح عن المتحول gDots في هذا القسم مما يعني أنه يصبح مرئياً لكل إجراءات النموذج frmIndex.
نص الإجراء Form_Load()
يُنفذ هذا الإجراء آلياً عند تحميل النموذج frmIndex:
Private Sub Form_Load()
gDots = String$(84, ".")
End Sub
يحفظ هذا الإجراء 84 نقطة في المتحول gDots.
نص الإجراء mnuClear_Click
يُنفذ هذا الإجراء آلياً عند اختيار مسح النص من القائمة ملف:
Private Sub mnuClear_Click()
frmIndex.Cls
End Sub
يستخدم هذا الإجراء الطريقة Cls لمحوالنموذج.
نص الإجراء mnuDisplayIndex_Click
ينفذ الإجراء mnuDisplayIndex_Click عند اختيار عرض الفهرس من القائمة ملف. يبدأ الإجراء بمحو النموذج لحذف أي نص سابق ثم يسند القيمة 100 إلى الخاصية CurrentY:
frmIndex.Cls
CurrentY = 100
وبما أن CurrentY تساوي الآن 100، فهذا يعني أن النص سوف يظهر على بعد 100 Twips عن قمة النموذج كما استخدمت العبارة التالية:
CurrentX = (frmIndex.ScaleWidth - _
frmIndex.TextWidth(الفهرس" / 2")
لإظهار النص Text عند منتصف النموذج (ارجع إلى الشكل 10-15).
يلي ذلك إسناد القيمة True إلى الخاصية FontUnderLine للنموذج، ثم استخدام الطريقة Print لطباعة كلمة الفهرس:
frmIndex.FontUnderline = True
frmIndex.Print "الفهرس"
ثم يعيد الإجراء إسناد القيمة False إلى الخاصية FontUnderLine لإظهار ما تبقى من نصوص بدون تسطير:
frmIndex.FontUnderline = False
تُحدّث قيمة CurrentY لسطر "الفصل 1" كما يلي:
CurrentY = frmIndex.TextHeight("VVV") * 2
طبعاً استخدمت الأحرف "VVV" لمعرفة ارتفاع النص، بفرض أن هذه الأحرف هي أسمك الأحرف الموجودة.
وأُسندت القيمة 100 إلى CurrentX بحيث يبعد السطر بمقدار 100 Twips عن يمين النموذج:
CurrentX = 100
والآن، وبعد تحديث قيمة كل من CurrentX وCurrentY، استخدمت الطريقة Print لإظهار النص:
Print "الفصل 1" + gDots + "الكمبيوتر"
يتم إظهار ما تبقى من أسطر بنفس الطريقة.
يؤدي تجاهل كتابة اسم الكائن قبل الطريقة Print إلى إظهار النص على النموذج الفعال حالياً وهكذا، فإن العبارة:
frmIndex.Print "الفهرس"
تولد نفس النتيجة التي تنتجها العبارة:
Print "الفهرس"
كذلك تُحدّث قيمة الخاصيتين CurrentX وCurrentY في هذا الإجراء، دون ذكر اسم النموذج قبلهما، لأن فيجول بيسك يفترض النموذج الفعال الحالي عند عدم ذكر اسم الكائن، فمثلاً، بفرض أن النموذج الحالي الفعال هو frmIndex، تعتبر العبارتان التاليتان متطابقتين:
frmIndex.CurrentY = 100
CurrentY = 100
نص الإجراء mnuEraseCh2_Click()
يُنفذ هذا الإجراء عند اختيار حذف الفصل الثاني من القائمة ملف:
Private Sub mnuEraseCh2_Click()
Dim LengthOfLine
Dim HeightOfLine
CurrentY = frmIndex.TextHeight("VVV") * 3
CurrentX = ScaleWidth - 100
LengthOfLine = frmIndex.TextWidth("الفصل 2" + _
gDots + "الشاشة")
HeightOfLine = frmIndex.TextHeight("ل")
frmIndex.Line -Step(-LengthOfLine, HeightOfLine), _
RGB(255, 255, 255), BF
End Sub
يسند الإجراء، الموقع الذي سيبدأ منه سطر "الفصل 2"إلى الخاصيتين CurrentX وCurrentY ويرسم مربعاً ذا خلفية بيضاء، ويحسب عرض المربع باستخدام الخاصية TextWidth.
إظهار الجداول
تستطيع استخدام الطريقة Print لإظهار جداول في النموذج أو في عنصر تحكم الصورة.
اتبع الخطوات التالية لرؤية كيفية إنجاز ذلك:
أضف القائمة جدول وبند القائمة عرض جدول إلى نظام قوائم برنامج الفهرس.
الجدول 10-6. جدول قوائم النموذج frmIndex.
العنوان الخاصية Name
&ملف mnuFile
…&عرض الفهرس mnuDisplayIndex
…&حذف الفصل الثاني mnuEraseCh2
…&مسح النص mnuClear
…- mnuSep1
…&خروج mnuExit
&جدول mnuTable
…ع&رض الجدول mnuDisplayTable
أدخل النص التالي ضمن الإجراء mnuDisplayTable_Click للنموذج frmIndex:
Private Sub mnuDisplayTable_Click()
frmIndex.Cls
frmIndex.FontName = "MS Sans Serif"
frmIndex.FontSize = 10
frmIndex.Print "الفصل" , "الشرح" , "الصفحة"
frmIndex.Print
frmIndex.Print "1" , "الكمبيوتر" , "1"
frmIndex.Print "2" , "الشاشة" , "14"
frmIndex.Print "3" , "الطابعة" , "45"
frmIndex.Print "4" , "النهاية" , "65"
End Sub
احفظ المشروع بالطريقة المعتادة.
تنفيذ نسخة برنامج الفهرس المحسنة
لنشاهد ما كتبناه قيد التنفيذ:
نفّذ النسخة المحسنة من برنامج الفهرس.
اختر عرض جدول من القائمة جدول.
يستجيب البرنامج بإظهار الجدول المبين في الشكل 10-16.
اختر خروج من القائمة ملف لإنهاء البرنامج.
الشكل 10-16 إظهار فهرس جدولي.
يستخدم نص الإجراء mnuDisplayTable_Click الطريقة Print مع الفواصل (,):
frmIndex.Print "الفصل" , "الشرح" , "الصفحة"
تتسبب هذه العبارة بإظهار السلسلة الأولى بدءاً من العمود صفر، وتظهر السلسلة الثانية بدءاً من العمود 14، أما السلسلة الثالثة (أي "الصفحة") فتظهر ابتداءً من العمود 28.
يفهم فيجول بيسك من الفواصل، تغيير مواقع الطباعة إلى مناطق يحدد فيجول بيسك كل منطقة طباعة بـ 13 رمز في الحالة الافتراضية.
ملاحظة
استخدم طريقة Print مع الفواصل لطباعة السلاسل التي تبدأ عند مواقع طباعة مختلفة فمثلاً، تؤدي العبارات التالية:
Print "abc","def","ghi"
Print "nop","qrs","tuf"
Print "abc","def","ghi"
إلى توليد الخرج التالي:
abc def ghi
nop qrs tuf
abc def ghi
تعريف مناطق جديدة للطباعة
يمكنك استخدام التابع الوظيفي Tab() لتعريف مناطق جديدة للطباعة.
استبدل نص الإجراء mnuDisplayTable_Click() بالنص التالي:
Private Sub mnuDisplayTable_Click()
frmIndex.Cls
frmIndex.FontName = "MS Sans Serif"
frmIndex.FontSize = 10
frmIndex.Print Tab(5); "الفصل"; Tab(20); _
"الشرح"; Tab(50); "الصفحة"
frmIndex.Print
frmIndex.Print Tab(5); "1"; Tab(20); _
"الكمبيوتر"; Tab(50); "1"
frmIndex.Print Tab(5); "2"; Tab(20); _
"الشاشة"; Tab(50); "14"
frmIndex.Print Tab(5); "3"; Tab(20); _
"الطابعة"; Tab(50); "45"
frmIndex.Print Tab(5); "4"; Tab(20); _
"النهاية"; Tab(50); "65"
End Sub
نفّذ برنامج الفهرس.
اختر عرض جدول من القائمة جدول.
يستجيب البرنامج بإظهار الجدول كما في الشكل 10-17.
الشكل 10-17 إطار برنامج الفهرس.
يحدد وسيط التابع الوظيفي Tab() رقم العمود الذي سيظهر النص عنده، فمثلاً تظهر العبارة التالية النص بدءاً من العمود الخامس:
frmIndex.Print Tab(5); "1"; Tab(20); _
"الكمبيوتر"; Tab(50); "1"
الوسيط الأول في هذه العبارة هو Tab(5)، والذي يُسند القيمة 5 للخاصية CurrentX، أما الفاصلة المنقوطة فتعني لفيجول بيسك، استئناف الطباعة على نفس السطر الحالي.
الوسيط الثالث في العبارة هو Tab(20)، والذي يُسند القيمة 20 للخاصية CurrentX، وتأمر الفاصلة المنقوطة فيجول بيسك، بإبقاء الطباعة على نفس السطر وبهذا تظهر السلسلة "الكمبيوتر" بدءاً من العمود 20.
إذاً، يمكّنك التابع الوظيفي Tab() من إظهار النص عند أي عمود تشاء.
صياغة الأرقام والتواريخ والأزمنة
يُستخدم التابع الوظيفي Format$() لإظهار الأرقام والتواريخ والأزمنة بطرق مختلفة. توضح الفقرتان التاليتان كيف يعمل هذا التابع.
صياغة الأرقام
يمكنك التحكم بالطريقة التي يُظهر فيجول بيسك الأرقام بها، وذلك بواسطة التابع Format$(). يمتلك هذا التابع وسيطين: الأول يمثل الرقم المطلوب إظهاره، والثاني يخدم كتعليمات صياغة Format Instruction، فمثلاً لإظهار الرقم 45.6 بحيث يسبقه عدد من الأصفار، استخدم العبارة التالية:
Print Format$(45.6,"000000.00")
فيتولد ما يلي:
000045.60
الرقم 45.6 يمتلك خانتين على يسار الفاصلة العشرية وخانة واحدة على يمينها، أما الوسيط الثاني فيحتوي (000000.00)، مما يعني وجوب إظهار ست خانات على يسار الفاصلة العشرية وخانتين على يمينها، وبما أن 45.6 يمتلك خانتين فقط على يسار الفاصلة العشرية، يضيف فيجول بيسك أربعة أصفار قبل الرقم، وبما أن 45.6 يمتلك خانة واحدة على يمين الفاصلة العشرية، يضيف فيجول بيسك صفر واحد في نهاية الرقم.
تستخدم هذه الميزة، لإظهار الأعداد في عمود، عندما تدعو الحاجة لإظهار الفواصل العشرية تحت بعضها، أي كما يلي:
000324.45
000123.40
123456.67
000004.90
132123.76
صياغة التواريخ والأزمنة
تستطيع مثلاً، استخدام العبارة التالية لإظهار تاريخ اليوم الحالي:
Print Format$(Now,"m/d/yy")
فإذا كان اليوم الحالي هو 4 تموز 1998، فسوف ينتج الخرج التالي:
7/4/98
يستخدم التابع الوظيفي Now، كأول وسيط في التابع Format$() للحصول على التاريخ، ويزود الوسيط (m/d/yy) طريقة لصياغة التاريخ بشكل شهر/يوم/سنة.
لاحظ أن خرج التابع Now يتعلق بقيمتي تاريخ ووقت الحاسب PC المستخدم.
يمكنك إظهار التاريخ بصيغ أخرى فمثلاً استخدم العبارة التالية:
Print Format$(Now,"dddd, mmmm dd, yyyy")
لتوليد الخرج التالي:
Sunday, April 11, 1999
واستخدم العبارة التالية:
Print Format$(Now,"mmmm-yy")
لتوليد الخرج التالي:
April-99
يمكن استخدام التابع الوظيفي Now أيضاً لإظهار الوقت الحالي. فمثلاً تستطيع استخدام هذه العبارة:
Print Format$(Now,"h:mm:ss a/p")
لتوليد الخرج التالي:
4:23:59 a
برنامج الطباعة
يستعرض برنامج الطباعة مدى سهولة إرسال المعطيات إلى الطابعة، بواسطة الطريقة PrintForm.
التمثيل المرئي لبرنامج الطباعة
سنبدأ كعادتنا بالتمثيل المرئي لنموذج البرنامج:
أنشئ مشروعاً قياسياً تنفيذياً جديداً Standard EXE، واحفظ نموذج المشروع بالاسم Print.Frm في الدليل C:\VB5Prg\Ch10 واحفظ ملف المشروع بالاسم Print.Vbp في ذات الدليل.
أنشئ النموذج frmPrint وفق الجدول 10-7.
يفترض أن يبدو النموذج المكتمل كذاك المبين في الشكل 10-18.
الشكل 10-18 النموذج frmPrint (طور التصميم).
الجدول 10-7. جدول خصائص النموذج frmPrint.
الكائن الخاصية القيمة
Form Name frmPrint
Caption برنامج الطباعة
BackColor Whit
RightToLeft True
CommandButton Name cmPrint
Caption &طباعة
RightToLeft True
CommandButton Name cmExit
Caption &خروج
RightToLeft True
إدخال نص برنامج الطباعة
تأكد من احتواء قسم التصاريح العامة للنموذج frmPrint على العبارة Option Explicit:
'يجب التصريح عن كل المتحولات
Option Explicit
أدخل النص التالي ضمن الإجراء cmdExit_Click() للنموذج frmPrint:
Private Sub cmdExit_Click()
End
End Sub
أدخل النص التالي ضمن الإجراء cmdPrint_Click() للنموذج frmPrint:
Private Sub cmdPrint_Click()
Printer.Print "بسم الله الرحمن الرحيم"
Printer.EndDoc
End Sub
احفظ المشروع باختيار Save Project من القائمة File لفيجول بيسك.
تنفيذ برنامج الطباعة
تحقق بأن الطابعة جاهزة للطباعة.
نفّذ برنامج الطباعة.
انقر على الزر طباعة.
يستجيب البرنامج باستخدام الطابعة لطباعة هذا النص:
"بسم الله الرحمن الرحيم"
كيف يعمل برنامج الطباعة
يستخدم البرنامج الطريقة Print لإرسال المعطيات إلى الطابعة. أما الطريقة EndDoc فترسل أمر بدء الطباعة إلى جهاز الطابعة.
نص الإجراء cmdPrint_Click()
ينفذ الإجراء cmdPrint_Click() عند النقر على زر طباعة:
Private Sub cmdPrint_Click()
Printer.Print "بسم الله الرحمن الرحيم"
Printer.EndDoc
End Sub
ويستخدم الطريقة Print مع الكائن Printer. تتم طباعة الوسيط الممرر للطريقة Print (أي "بسم الله الرحمن الرحيم")، حال تنفيذ الطريقة EndDoc.
ملاحظة
تستطيع الذهاب للفصل 22، وقراءة الفقرة الخاصة بتعريب كائن الطابعة، لزيادة الفائدة.
تحسين برنامج الطباعة
تُرسل الطريقة Print النص إلى الطابعة، سنحسن الآن برنامج الطباعة بحيث يطبع محتويات النموذج frmPrint:
استبدل نص الإجراء cmdPrint_Click() بالنص التالي:
Private Sub cmdPrint_Click()
frmPrint.PrintFrom
Printer.EndDoc
End Sub
احفظ المشروع بالطريقة المعتادة.
تنفيذ النسخة المحسنة لبرنامج الطباعة
لنشاهد أثر ما كتبناه:
نفّذ نسخة برنامج الطباعة المحسنة.
يستجيب البرنامج بطباعة محتويات النموذج.
انقر الزر خروج لإنهاء البرنامج.
نص نسخة الإجراء cmdPrint_Click() المحسنة
تُرسل الطريقة PrintForm محتويات النموذج إلى الطابعة نقطة نقطة (Pixel By Pixel):
frmPrint.PrintFrom
وآخر شيء يفعله هذا الإجراء هو تنفيذ الطريقة EndDoc التي تحمل الطابعة على طباعة المعطيات التي تلقتها.
ملاحظة
تستخدم الطريقة PrintForm لإرسال صورة عن النموذج إلى الطابعة، فمثلاً لإرسال محتويات النموذج frmMyForm إلى الطابعة، استخدم العبارة التالية:
frmMyForm.PrintForm
كان مفروضاً في الإصدارات السابقة لفيجول بيسك إسناد القيمة True إلى الخاصية AutoRedraw للنموذج المطلوب طباعته، حتى تتمكن الخاصية PrintForm من العمل بشكل مناسب. أما في إصدار فيجول بيسك 5، فلا داعي لذلك.
طباعة عدة صفحات
يمكنك طباعة عدة صفحات باستخدام الطريقة NewPage. يحتفظ فيجول بيسك بمسار عدد الصفحات المطبوعة، عن طريق تحديث الخاصية Page.
اتبع الخطوات التالية لطباعة عدة صفحات:
استبدل نص الإجراء cmdPrint_Click() بالنص التالي:
Private Sub cmdPrint_Click()
Printer.Print "This is Page Number " + Str(Printer.Page)
Printer.NewPage
Printer.Print "This is Page Number " + Str(Printer.Page)
Printer.EndDoc
End Sub
نفّذ برنامج الطباعة.
انقر زر طباعة.
يستجيب البرنامج بطباعة صفحتين:
الصفحة الأولى تحمل الرسالةThis is Page Number 1.
الثانية تحمل الرسالة This is Page Number 2.
انقر الزر خروج لإنهاء البرنامج.
يطبع الإجراء cmdPrint_Click() السلسلة التالية:
Printer.Print "This is Page Number " + Str(Printer.Page)
تحتوي الخاصية Page رقم الصفحة الحالية. يحدّث فيجول بيسك قيمة الخاصية Page بإسناد القيمة 1 إليها باعتبار أن هذه الصفحة هي أول صفحة مطبوعة.
يصرح الإجراء بعد ذلك عن صفحة جديدة باستخدام الطريقة NewPage:
Printer.NewPage
ويرسل هذه السلسلة إلى الطابعة:
Printer.Print "This is Page Number " + Str(Printer.Page)
وبما أن القيمة الحالية لـ Page تساوي 2، تطبع الطابعة النص:
This is Page Number 2
طباعة الصور والرسوم
إذا كان المطلوب طباعة صورة ما، فيمكن وضعها في عناصر تحكم الصور Picture Controls، ثم طباعة النموذج باستخدام الطريقة PrintForm، بمعنى آخر، بغض النظر عن ما تضعه في النموذج، فإنه سوف يرسل للطابعة.
الطباعة بجودة أفضل
يوضح برنامج الطباعة، مدى سهولة إرسال المعطيات إلى الطابعة بواسطة إحدى الطريقتين Print أوPrintForm، وللحصول على دقة أفضل تستطيع استخدام الطرق الرسومية الأخرى Pest وLine وCircle الموصوفة سابقاً.
الرسم على الطابعة يتم كالرسم على النموذج، فتستطيع تحديد الخاصيتين CurrentX وCurrentY كما في العبارتين:
Printer.CurrentX = 0
Printer.CurrentY = 0
واستخدام خصائص مثل:
Printer.ScaleLeft
Printer.ScaleTop
Printer.Width
Printer.Height
أو تستطيع استخدام الخاصيتين TextHight وTextWidth لوضع النص في مكان محدد على الورقة.
استبدل نص الإجراء cmdPrint_Click() بالنص التالي:
Private Sub cmdPrint_Click()
Printer.DrawWidth = 4
Printer.Line (1000, 1000)-Step(1000, 1000)
Printer.Cirle(3000, 3000), 1000
Printer.EndDoc
End Sub
يُسند هذا الإجراء القيمة 4 إلى الخاصية DrawWidth للطابعة، ثم يرسم خطاً ودائرة، وينفذ الطريقة EndDoc. يبين الشكل 10-19 الخرج الناتج.
كما تلاحظ لا يوجد اختلاف بين نص البرنامج الذي يرسم على نموذج وبين الرسم على الطابعة.
الشكل 10-19 رسم خط ودائرة على الطابعة.
الخلاصة
تعلمنا فى هذا الفصل كيفية تحديد الخط المستعمل في النصوص بواسطة الخصائص FontName وFontSize وFontItalic وFontUnderLine وFontTransparent.
كما تعلمنا كيف نستخلص الخطوط المتوفرة لكل من الشاشة والطابعة بواسطة الخاصية Fonts، وكيف نستخلص عدد هذه الخطوط بواسطة الخاصية FontCount وكيفية استخدام الخاصيتين TextWidth وTextHight إضافة إلى استعمال التابع الوظيفي Tab().
كما تناول هذا الفصل آلية إرسال المعطيات DATA (نصوص أو رسوم) إلى الطابعة باستخدام تقنيتين:
- الطريقة PrintForm التي ترسل صورة النموذج نقطة نقطة إلى الطابعة.
- الطريقة Print والطرق الرسومية، مثل:
Printer.Print "Abc"
Printer.Line -(1000, 1000)
Printer.Cirle(400, 500), 800
الفصل الحادي عشر
التفاعل بين تطبيقات الويندوز
بما أن البرامج التي تكتبها في فيجول بيسك، هي تطبيقات ويندوز. فإن هذا يعني أن بإمكان تطبيقاتك الاستفادة من ميزات نظام الويندوز. سوف تتعلم في هذا الفصل استخدام ميزتين: الحافظة وحلقات زمن التوقف.
الحافظة
يمكن لبرامج فيجول بيسك استخدام حافظة النظام ويندوز. والحافظة عبارة عن منطقة تُستخدم لنقل المعطيات، سواء أكانت نصوصاً أم صوراً.
برنامج الحافظة
سنكتب الآن برنامجاً يدعى برنامج الحافظة، يمكّنك من كتابة أي نص في مربع نص. وإنجاز عمليات التحرير القياسية (نسخ، قص، لصق) في ويندوز. يمتلك البرنامج قائمة تعديل قياسية. يمكن استخدامها لنسخ Copy أو قص Cut أو لصق Paste أي نص.
التمثيل المرئي لبرنامج الحافظة
سنبدأ كعادتنا بالتمثيل المرئي لنموذج البرنامج.
أنشئ الدليل C:\VB5Prg\Ch11، لحفظ العمل المنجز في هذا الدليل.
أنشئ مشروعاً جديداً من النوع Standard EXE.
احفظ نموذج المشروع باسم Clip.Frm في الدليل السابق واحفظ ملف المشروع باسم Clip.Vbp في ذات الدليل.
أنشئ النموذج frmClip طبقاً للجدولين 11-1 و 11-2.
يفترض أن يبدو النموذج المكتمل كذلك المبين في الشكل 11-1.
الشكل 11-1 النموذج frmClip.
الجدول 11-1. جدول خصائص برنامج الحافظة.
الكائن الخاصية القيمة
Form Name frmClip
RightToLeft True
Caption برنامج الحافظة
Text Box Name TxtUserArea
MultiLine True
ScrollBars 3-Both
Text (اجعله فارغاً)
Left 0
Top 0
Menu انظر الجدول 11-2 انظر الجدول 11-2
الجدول 11-2. جدول قائمة برنامج الحافظة.
العنوان الاسم مفتاح الاختزال Shortcut
&ملف mnuFile None
…&خروج mnuExit None
&تعديل mnuEdit None
…&نسخ mnuCopy Ctrl+C
…&قص mnuCut Ctrl+X
…&لصق mnuPaste Ctrl+V
إدخال نص برنامج الحافظة
سنباشر الآن كتابة نص برنامج الحافظة:
تحقق بأن قسم التصاريح العامة يحوي العبارة:
'يجب التصريح عن كل المتحولات
Option Explicit
أدخل النص التالي ضمن الإجراء Form_Resize():
Private Sub Form_Resize()
txtUserArea.Width = frmClip.ScaleWidthtxtUserArea.Height = frmClip.ScaleHeight
End Sub
أدخل النص التالي ضمن الإجراء munCopy_Click():
Private Sub mnuCopy_Click()
Clipboard.Clear
Clipboard.SetText txtUserArea.SelText
End Sub
أدخل النص التالي ضمن الإجراء munCut_Click():
Private Sub mnuCut_Click()
Clipboard.Clear
Clipboard.SetText txtUserArea.SelText
txtUserArea.SelText = ""
End Sub
أدخل النص التالي ضمن الإجراء munPaste_Click():
Private Sub mnuPaste_Click()
txtUserArea.SelText = Clipboard.GetText()
End Sub
أدخل النص التالي ضمن الإجراء munExit_Click():
Private Sub mnuExit_Click()
End
End Sub
احفظ المشروع باختيار البند Save Project من قائمة File لفيجول بيسك.
تنفيذ برنامج الحافظة
لنشاهد أثر ما كتبناه:
نفّذ برنامج الحافظة ولاحظ مزاياه الكثيرة (رغم أننا لم نكتب إلا قدراً يسيراً من النص).
تمرن على عمليات القص والنسخ واللصق التي يوفرها هذا البرنامج، جرب مثلاً كتابة نص في مربع النص ثم انسخ جزء من هذا النص إلى مكان آخر ضمن مربع النص ذاته أو خارجه كأن تنقله إلى برنامج وورد Word أو إلى الدفتر Word Pad.
اختر البند خروج من قائمة ملف لإنهاء البرنامج.
كيف يعمل برنامج الحافظة
يستخدم برنامج الحافظـة الإجراء Form_Resize() لملء كامل النموذج بمربع النص. وتنجز الإجراءات munCopy_Click() و munCut_Click() و munPaste_Click() عمليات التحرير القياسية (قص ونسخ ولصق).
الإجراء Form_Resize()
ينفذ هذا الإجراء آلياً عند ظهور النموذج لأول مرة (عند تشغيل البرنامج) أو عند تغيير حجم النموذج.
يفترض أن يملأ مربع النص كامل منطقة العمل في النموذج أثناء التنفيذ. ولهذا يعتبر الإجراء Form_Resize() مكاناً مناسباً لوضع جزء البرنامج الذي يمكن مربع النص من ملء النموذج، وتستطيع إنجاز ذلك بإسناد قيمة الخاصيتين ScaleWidth و ScaleHeight للخاصيتين Width وHeight التابعتين لمربع النص على التوالي:
Private Sub Form_Resize()
txtUserArea.Width = frmClip.ScaleWidthtxtUserArea.Height = frmClip.ScaleHeight
End Sub
لنفترض أنك أسندت للخاصيتين Top و Left التابعتين لمربع النـص القيـمة صفر أثناء مرحلة التصميم، بما معناه أن الزاوية اليسرى العليا لمربع النص يجب أن تقع عند الزاوية اليسرى العليا للنموذج. وعندما ينفذ الإجراء Form_Resize() يحدد عرض مربع النص بعرض النموذج ScaleWidth وارتفاعه بارتفاع النموذج ScaleHeight.
نص الإجراء munCopy_Click()
ينفذ الإجراء munCopy_Click() عند اختيار البند نسخ من قائمة تعديل:
Private Sub mnuCopy_Click()
Clipboard.Clear
Clipboard.SetText txtUserArea.SelText
End Sub
ويعمل على نسخ الجزء المضاء من النص إلى الحافظة.
تمحو أول عبارة في الإجراء محتويات الحافظة، أي:
Clipboard.Clear
ثم تنسخ المنطقة المضاءة إلى الحافظة:
Clipboard.SetText TxtUserArea.SelText
نص الإجراء munCut_Click()
ينفذ الإجراء munCut_Click() عند اختيار المستخدم البند قص من قائمة تعديل:
Private Sub mnuCut_Click()
Clipboard.Clear
Clipboard.SetText txtUserArea.SelText
txtUserArea.SelText = ""
End Sub
يقصد بعملية القص، اقتطاع الجزء المضاء من النص ونقله إلى الحافظة:
تمحو أول عبارة في الإجراء محتويات الحافظة:
Clipboard.Clear
ثم تنسخ العبارة الثانية النص المنتقى إلى الحافظة:
Clipboard.SetText TxtUserArea.SelText
ثم تقتطع العبارة الثالثة النص المضاء:
TxtUserArea.SelText = ""
نص الإجراء munPaste_Click()
ينفذ هذا الإجراء عند اختيار البند لصق من قائمة تعديل:
Private Sub mnuPaste_Click()
txtUserArea.SelText = Clipboard.GetText()
End Sub
يقصد بعملية اللصق استبدال المنطقة المضاءة من مربع النص بمحتويات الحافظة. أو حشر محتويات الحافظة في مربع النص مكان وجود المشيرة إذا لم يكن المستخدم قد اختار جزءً من النص. وينجز ذلك بواسطة العبارة التالية:
TxtUserArea.SelText = Clipboard.GetText()
الخاصية SelLength
تعرّف هذه الخاصية كمتحول من النوع Long، وتحتوي على عدد الأحرف المضاءة حالياً (أي المنتقاة، والانتقاء أو الاختيار يتم بالضغط على المفتاح Shift من لوحة المفاتيح وتحريك الفأرة إلى نهاية الجزء المطلوب اختياره ثم تحرير المفتاح Shift).
ورغم أن برنامج الحافظة لا يستخدم هذه الخاصية إلا أنك قد تجد لها استخداماً في مشاريع فيجول بيسك المستقبلية.
فمثلاً لتحديد عدد الرموز التي تم اختيارها للتو في مربع النص المدعو txtMyTextBox استخدم العبارة التالية:
NumberOfCharacters = txtMyTextBox.SelLength
نقل الصور من وإلى الحافظة: برنامج الحافظة2
وضح برنامج الحافظة كيفية نقل نص بين الحافظة ومربع النص. تمتاز الحافظة بقدرتها على احتواء الصور أيضاً. يوضح برنامج الحافظة2 كيفية ذلك:
التمثيل المرئي لبرنامج الحافظة2
سنبدأ كعادتنا بطور التمثيل المرئي لنموذج البرنامج:
أنشئ مشروعاً من النوع Standard EXE.
احفظ نموذج المشروع باسم AnyData.Frm في الدليل C:\VB5Prg\Ch11 واحفظ ملف المشروع باسم AnyData.Vbp في ذات الدليل.
أنشئ النموذج frmAnyData طبقاً للجدولين11-3 و 11-4.
يفترض أن يبدو النموذج المكتمل كذاك المبين في الشكل 11-2.
الشكل 11-2 النموذج frmAnyData.
الجدول 11-3. جدول خصائص برنامج الحافظة2.
الكائن الخاصية القيمة
Form Name frmAnyData
Caption برنامج الحافظة 2
RightToLeft True
PictureBox Name picMyPicture
ListBox Name lstList
RightToLeft True
ComboBox Name cboList
Text (اتركه فارغاً)
RightToLeft True
TextBox Name txtUserArea
Text (اتركه فارغاً)
MultiLine True
ScrollBars 3-Both
RightToLeft True
Menu (انظر الجدول 11-4) (انظر الجدول 11-4)
الجدول 11-4. جدول قائمة برنامج الحافظة2.
العنوان الاسم مفتاح الاختزال Shortcut
&ملف mnuFile None
…&خروج mnuExit None
&تعديل mnuEdit None
…&نسخ mnuCopy Ctrl+C
…&قص mnuCut Ctrl+X
…&لصق mnuPaste Ctrl+V
إدخال نص برنامج الحافظة2
سندخل الآن نص برنامج الحافظة2:
كالعادة يجب أن يحوي قسم التصاريح العامة على العبارة التالية:
'يجب التصريح عن كل المتحولات
Option Explicit
أدخل النص التالي ضمن الإجراء Form_Load():
Private Sub Form_Load()
cboList.AddItem "كمبيوتر"
cboList.AddItem "شاشة"
cboList.AddItem "طابعة"
lstList.AddItem "واحد"
lstList.AddItem "اثنان"
lstList.AddItem "ثلاثة"
End Sub
أدخل النص التالي ضمن الإجراء picMyPicture_GotFocus():
Private Sub picMyPicture_GotFocus()
picMyPicture.BorderStyle = 1
End Sub
أدخل النص التالي ضمن الإجراء picMyPicture_LostFocus():
Private Sub picMyPicture_LostFocus()
picMyPicture.BorderStyle = 0
End Sub
أدخل النص التالي ضمن الإجراء mnuCopy_Click():
Private Sub mnuCopy_Click()
Clipboard.Clear
If TypeOf Screen.ActiveControl Is TextBox Then
Clipboard.SetText Screen.ActiveControl.SelText
ElseIf TypeOf Screen.ActiveControl Is ComboBox Then
Clipboard.SetText Screen.ActiveControl.Text
ElseIf TypeOf Screen.ActiveControl Is PictureBox Then
Clipboard.SetText Screen.ActiveControl.Picture
ElseIf TypeOf Screen.ActiveControl Is ListBox Then
Clipboard.SetText Screen.ActiveControl.Text
Else
End If
End Sub
أدخل النص التالي ضمن الإجراء mnuCut_Click():
Private Sub mnuCut_Click()
mnuCopy_Click
If TypeOf Screen.ActiveControl Is TextBox Then
Screen.ActiveControl.SelText = ""
ElseIf TypeOf Screen.ActiveControl Is ComboBox Then
Screen.ActiveControl.SelText = ""
ElseIf TypeOf Screen.ActiveControl Is PictureBox Then
Screen.ActiveControl.Picture = LoadPicture()
ElseIf TypeOf Screen.ActiveControl Is ListBox Then
If Screen.ActiveControl.ListIndex >= 0 Then
Screen.ActiveControl.RemoveItem _
Screen.ActiveControl.ListIndex
End If
Else
End If
End Sub
أدخل النص التالي ضمن الإجراء mnuPaste_Click():
Private Sub mnuPaste_Click()
If TypeOf Screen.ActiveControl Is TextBox Then
Screen.ActiveControl.SelText = Clipboard.GetText()
ElseIf TypeOf Screen.ActiveControl Is ComboBox Then
Screen.ActiveControl.Text = Clipboard.GetText()
ElseIf TypeOf Screen.ActiveControl Is PictureBox Then
Screen.ActiveControl.Picture = Clipboard.GetData()
ElseIf TypeOf Screen.ActiveControl Is ListBox Then
Screen.ActiveControl.AddItem Clipboard.GetText()
Else
End If
End Sub
أدخل النص التالي ضمن الإجراء munExit_Click():
Private Sub mnuExit_Click()
End
End Sub
احفظ المشروع باختيار البند Save Project من قائمة File.
تنفيذ برنامج الحافظة2
لنشاهد ما كتبناه قيد التنفيذ:
نفّذ برنامج الحافظة2.
يمكّنك البرنامج من نسخ وقص ولصق المعطيات من وإلى الحافظة. والمعطيات قد تكون صوراً أو نصوصاً.
اتبع الخطوات التالية لنسخ صورة من برنامج الرسام Paint إلى مربع الصورة الموجود في برنامج الحافظة2:
نفّذ برنامج الرسام أثناء عمل برنامج الحافظة2.
ارسم شيئاً ما في برنامج الرسام.
انسخ جزءاً من الشكل المرسوم إلى الحافظة، بتحديد ذلك الجزء، ثم اختيار البند نسخ من قائمة عرض التابعة لبرنامج الرسام. يوضح الشكل 11-3 جزء من الصورة تم نسخه إلى الحافظة.
انتقل إلى برنامج الحافظة2.
تحقق بأن عنصر التحكم picMyPicture فعّال الآن (انقر عليه بواسطة الفأرة).
اختر البند لصق من قائمة تعديل التابعة لبرنامج الحافظة2.
يستجيب برنامج الحافظة2 بنسخ الصورة المقيمة في الحافظة إلى مربع الصورة picMyPicture.
الشكل 11-3 استخدام برنامج الرسام لرسم صورة بهدف نسخها إلى برنامج الحافظة2.
الشكل 11-4 نسخ الصورة إلى برنامج الحافظة2.
يمكّنك برنامج الحافظة2 أيضاً من نسخ وقص ولصق النصوص من وإلى مربع النص أو مربع السرد أو مربع السرد والتحرير.
تمرّن على فعاليات برنامج الحافظة2. لا تستطيع لصق الصورة في مربع السرد أو مربع النص أو في مربع السرد والتحرير. كذلك لا تستطيع لصق نص في مربع الصورة. وقبل أن تتمكن من لصق المعطيات في كائن ما، لا بد من اختيار ذلك الكائن أولاً بالنقر عليه (يجب أن ينتقل التركيز إليه).
كيف يعمل برنامج الحافظة 2
يستخدم برنامج الحافظة2 الإجراءات munCopy_Click() و munCut_Click() و munPaste_Click() لنقل المعطيات من وإلى الحافظة Clipboard.
نص الإجراء Form_Laod()
ينفذ الإجراء Form_Laod() آلياً عند تشغيل البرنامج:
Private Sub Form_Load()
cboList.AddItem "كمبيوتر"
cboList.AddItem "شاشة"
cboList.AddItem "طابعة"
lstList.AddItem "واحد"
lstList.AddItem "اثنان"
lstList.AddItem "ثلاثة"
End Sub
يملأ هذا الإجراء كل من مربع السرد ومربع السرد والتحرير بثلاثة بنود.
نص الإجراء picMyPicture_GotFocus()
ينفذ الإجراء picMyPicture_GotFocus() عندما ينتقل التركيز إلى مربع الصورة (أي عند اختيار مربع الصورة):
Private Sub picMyPicture_GotFocus()
picMyPicture.BorderStyle = 1
End Sub
ما الفائدة من هذا الإجراء ؟ !
لا يعطي فيجول بيسك أي دلالة واضحة عند اختيار مربع الصورة، بخلاف ما هو الحال عليه في مـربع النص أو مربع السرد أو مربع السرد والتحرير. ولهذا فإن العبارة التي أدخلناها ضمن الإجراء picMyPicture_GotFocus()، تبدل الخاصية BorderStyle بحيث تتمكن من تمييز أن مربع الصورة تم انتقاؤه. إذ أن إسناد القيمة 1 إلى الخاصية BorderStyle يتسبب بوضع حافة لعنصر تحكم الصورة.
نص الإجراء picMyPicture_LostFocus()
ينفذ هذا الإجراء عند عدم اختيار مربع الصورة (بعكس الإجراء السابق تماماً):
Private Sub picMyPicture_LostFocus()
picMyPicture.BorderStyle = 0
End Sub
إذاً، أسندت العبارة الوحيدة في هذا الإجراء القيمة صفر إلى الخاصية BorderStyle، ويتسبب ذلك بإزالة الحافة المحيطة بعنصر تحكم الصورة، وهذا ما يساعد على تمييز أن مربع الصورة ليس منتقىً الآن.
نص الإجراء munCopy_Click()
يُنفذ هذا الإجراء عندما يختار المستخدم البند نسخ من قائمة تعديل. يمحو نص هذا الإجراء محتويات الحافظة وينسخ المحتويات المضاءة إلى الحافظة:
Private Sub mnuCopy_Click()
Clipboard.Clear
If TypeOf Screen.ActiveControl Is TextBox Then
Clipboard.SetText Screen.ActiveControl.SelText
ElseIf TypeOf Screen.ActiveControl Is ComboBox Then
Clipboard.SetText Screen.ActiveControl.Text
ElseIf TypeOf Screen.ActiveControl Is PictureBox Then
Clipboard.SetText Screen.ActiveControl.Picture
ElseIf TypeOf Screen.ActiveControl Is ListBox Then
Clipboard.SetText Screen.ActiveControl.Text
Else
End If
End Sub
إذاً يمحو هذا الإجراء محتويات الحافظة أولاً، ثم ينسخ محتويات عنصر التحكم الفعّال إلى الحافظة، ولهذا يتوجب أولاً معرفة نوع العنصر الفعال. ينجز الإجراء ذلك باستخدام سلسلة من عبارات الشرط If TypeOf.
تتحقق أول عبارة شرطية If TypeOf إذا كان عنصر التحكم الفعّال هو مربع نص، ويتم نسخ النص المضاء في مربع النص إلى الحافظة:
Clipboard.SetText Screen.ActiveControl.SelText
أما إذا كان العنصر الفعال هو مربع السرد والتحرير، فيتم نسخ النص المضاء إلى الحافظة:
Clipboard.SetText Screen.ActiveControl.Text
وإذا كان العنصر الفعال هو مربع صورة، يتم نسخ الصورة إلى الحافظة.
Clipboard.SetData Screen.ActiveControl.Picture
وأخيراً إذا كان العنصر الفعال هو عنصر السرد، يتم نسخ النص المضاء إلى الحافظة:
Clipboard.SetText Screen.ActiveControl.Text
ملاحظة
تمثل قيمة المتحول Screen.ActiveControl عنصر التحكم الفعّال حالياً. يجدّد البرنامج آلياً هذا المتحول أثناء التنفيذ، وكما ترى يعتبر هذا المتحول مفيداً لإنجاز المهام على عنصر التحكم الفعّال الحالي.
نص الإجراء munCut_Click()
يُنفذ هذا الإجراء عند اختيار البند قص من قائمة تعديل:
Private Sub mnuCut_Click()
mnuCopy_Click
If TypeOf Screen.ActiveControl Is TextBox Then
Screen.ActiveControl.SelText = ""
ElseIf TypeOf Screen.ActiveControl Is ComboBox Then
Screen.ActiveControl.SelText = ""
ElseIf TypeOf Screen.ActiveControl Is PictureBox Then
Screen.ActiveControl.Picture = LoadPicture()
ElseIf TypeOf Screen.ActiveControl Is ListBox Then
If Screen.ActiveControl.ListIndex >= 0 Then
Screen.ActiveControl.RemoveItem _
Screen.ActiveControl.ListIndex
End If
Else
End If
End Sub
يعرّف القص، بأنه نسخ أولاً للمعطيات المنتقاة، ثم حذفها من الأصل. ولهذا ينفذ هذا الإجراء أولاً، الإجراء munCopy_Click():
mnuCopy_Click
ثم يستخدم سلسلة من عبارات If TypeOf لمعرفة نوع عنصر التحكم الفعال الحالي وتقرير طريقة حذف المعطيات التي تم نسخها.
فإذا كان عنصر التحكم الفعال الحالي هو مربع نص، يحُذف النص المنسوخ بواسطة العبارة:
Screen.ActiveControl.SelText = ""
والشكل مشابه بالنسبة لمربع السرد والتحرير، حيث يحُذف النص المنسوخ بواسطة العبارة:
Screen.ActiveControl.Text = ""
بينما يُستخدم التابع الوظيفي LoadPicture() لمحو مربع الصورة.
Screen.ActiveControl.Picture = LoadPicture()
وبسبب عدم تحديد اسم صورة لتحميلها بواسطة التابع الوظيفي LoadPicture() (وذلك بعدم ذكر اسم الصورة بين القوسين وتركهما فارغين). يمحو هذا التابع الصورة الحالية، وهو بالضبط ما نبتغيه.
أما إذا كان عنصر التحكم الفعال هو مربع سرد. فلا بد قبل حذف العنصر، من التأكد أن قيمة الخاصية ListIndex أكبر من أو تساوي الصفر. تمثل الخاصية ListIndex رقم البند المنتقى حالياً. ولهذا يجب التحقق من وجود عنصر منتقى حالياً في مربع السرد (فمثلاً إذا كانت قيمة الخاصية ListIndex تساوي -1 فهذا يعني أنه لا يوجد عنصر منتقى حالياً في مربع السرد).
نص الإجراء munPaste_Click()
ينفذ هذا الإجراء عند اختيار البند لصق من قائمة تعديل:
Private Sub mnuPaste_Click()
If TypeOf Screen.ActiveControl Is TextBox Then
Screen.ActiveControl.SelText = Clipboard.GetText()
ElseIf TypeOf Screen.ActiveControl Is ComboBox Then
Screen.ActiveControl.Text = Clipboard.GetText()
ElseIf TypeOf Screen.ActiveControl Is PictureBox Then
Screen.ActiveControl.Picture = Clipboard.GetData()
ElseIf TypeOf Screen.ActiveControl Is ListBox Then
Screen.ActiveControl.AddItem Clipboard.GetText()
Else
End If
End Sub
يستخدم هذا الإجراء كسابقيه، سلسلة من عبارات If TypeOf لتحديد نوع العنصر الفعّال الحالي، ويستخدم الطريقة المناسبة لنقل المعطيات إلى العنصر الفعال الحالي.
استخدام التابع الوظيفي GetFormat() لتحديد نوع المعطيات الموجودة في الحافظة
كما ذكرنا، تعتبر الحافظة قادرة على الإمساك بالصور والنصوص على حد سواء. يستخدم التابع الوظيفي GetFormat() لمعرفة نوع المعطيات الموجودة حالياً في الحافظة.
فمثلاً، تحدد العبارة التالية، ما إذا كانت المعطيات الموجودة في الحافظة نصية أم لا:
If Clipboard.Getformat (vbCFText( Then
'يوجد في الحافظة معلومات نصية
End If
يعيد التابع GetFormat (vbCFText) القيمة True إذا كانت الحافظة تحوي نصاً.
أما لتحديد ما إذا كانت الحافظة تحوي صورة نقطية، فاستخدم العبارة التالية:
If Clipboard.Getformat (vbCFBitmap) Then
'يوجد في الحافظة صورة نقطية
End If
يعيد GetFormat (vbCFBitmap) القيمة True إذا كانت الحافظة ممسكة بصورة.
الزمن الضائع Idle Time
تمر لحظات كثيرة أثناء تنفيذ برامج فيجول بيسك، بحيث لا ينفذ فيها أي شيء (وقت ضائع). خذ مثالاً، برنامج يصدر صوت رنين Beep مائة مرة، ثم ينتظر إعادة نقر زر يدعى رنين لإصدار صوت الرنين مجدداً. يمر البرنامج في زمن ضائع بانتظار نقر أو ضغط الزر رنين وقد يطول هذا الوقت الضائع.
تستطيع إنجاز مهام أخرى أثناء مرور الوقت الضائع، بالتحول إلى برامج أخرى في ويندوز، فمثلاً عندما يكون البرنامج السابق متوقفاً عن إصدار الرنين، تستطيع حينها الانتقال إلى برامج أخرى، ومتابعة العمل.
أما عندما تنقر الزر رنين، ليبدأ البرنامج بإصدار الرنين مائة مرة، حينها لا تستطيع الانتقال إلى برامج أخرى في ويندوز، إلى أن ينتهي البرنامج من إصدار الرنين لمائة مرة.
برنامج العد
سنكتب الآن برنامجاً يدعى برنامج العد، لعد الأرقام من 1 إلى 999.
التمثيل المرئي لبرنامج العد
أنشئ مشروعاً جديداً بنوع StandardEXE.
احفظ نموذج المشروع باسم Count.Frm في الدليل C:\VB5Prg\Ch11 واحفظ ملف المشروع باسم Count.Vbp في ذات الدليل.
أنشئ نموذج برنامج العد تبعاً للجدول 11-5.
يُفترض أن يبدو النموذج كما في الشكل 11-5.
الشكل 11-5 النموذج frmCount.
الجدول 11-5. جدول خصائص برنامج العد.
الكائن الخاصية القيمة
Form Name frmCount
Caption برنامج العد
RightToLeft True
CommandButton Name cmdExit
Caption &خروج
RightToLeft True
CommandButton Name cmdPause
Caption &توقف مؤقت
RightToLeft True
CommandButton Name cmdStart
Caption ا&بدأ
RightToLeft True
Label Name lblResult
Alignment 2-Center
BorderStyle 1-Fixed Single
Caption (اجعله فارغاً)
RightToLeft True
إدخال نص برنامج العد
تحقق من وجود العبارة Option Explicit ضمن قسم التصاريح العامة.
'يجب التصريح عن كل المتحولات
Option Explicit
أدخل النص التالي ضمن الإجراء cmdExit_Click():
Private Sub cmdExit_Click()
End
End Sub
أدخل النص التالي ضمن الإجراء cmdStart_Click():
Private Sub cmdStart_Click()
Dim Counter As Integer
Counter = 1
' Counter from 1 to 999
Do While Counter < 1000
1b1Result.Caption = Str$(Counter)
Counter = Counter + 1
Loop
End Sub
ملاحظة
لاحظ أننا لم نطلب منك حتى هذه النقطة، كتابة أي شيء ضمن الإجراء cmdPause_Click().
تنفيذ برنامج العد
لنشاهد أثر ما كتبناه:
نفّذ برنامج العد.
انقر الزر ابدأ العد.
يبدو البرنامج وكأنه لا يفعل شيئاً لفترة، ثم يظهر الرقم 999. ويعتمد سرعة ذلك كله على سرعة الحاسب المستخدم.
قد تتوقع لدى قراءتك لنص الإجراء cmdStart_Click() أن البرنامج سيظهر كل الأرقام من 1 إلى 999، ولفهم السبب الذي منع البرنامج من ذلك، تأمل العبارات المسئولة عن إظهار الأرقام. هذه هي العبارة المسئولة عن تغيير عنوان اللافتة:
lblResult.Caption = Strs(Counter)
لفيجول بيسك قدرة على إنعاش الشاشة (وهي معدل إعادة تجديد محتويات الشاشة Refresh Rate) فقط أثناء الزمن الضائع (أي عندما ينتهي تنفيذ الإجراء ويعود البرنامج إلى الزمن الضائع Idle Time).
تذكر أن نقر زر خروج أثناء التعداد لا يُنهي البرنامج، لأن البرنامج يستطيع تمييز حوادث النقر فقط أثناء الأزمنة الضائعة. وحالما ينتهي التعداد يعود البرنامج إلى الزمن الضائع ويستجيب لحادثة نقر الزر خروج.
ملاحظة
إذا كان الحاسب الذي تستخدمه سريعاً، فلعل استبدال العبارة:
Do While Counter < 1000
في الإجراء cmdStart_Click() بالعبارة:
Do While Counter < 10000
يساعدك على تمييز الحلقة بشكل أفضل، لأنك قد لا تتمكن من مشاهدة تنفيذ الحلقة مع القيم الصغيرة إذا كان حاسبك بالغ السرعة (Pentium MMX).
تعديل برنامج العد
اتبع الخطوات التالية لتعديل برنامج العد بحيث تُظهر اللافتة كل رقم من 1 وحتى 999 أثناء التعداد:
أضف العبارة التالية إلى الإجراء cmdStart_Click():
lblResult.Refresh
يفترض أن يبدو الإجراء cmdStart_Click() كما يلي:
Private Sub cmdStart_Click()
Dim Counter As Integer
Counter = 1
' Counter from 1 to 999
Do While Counter < 1000
1b1Result.Caption = Str$(Counter)
lblResult.Refresh
Counter = Counter + 1
Loop
End Sub
تتسبب الطريقة Refresh بإعادة إنعاش الشاشة فوراً.
استخدم الطريقة Refresh للتسبب بإعادة إنعاش أي كائن:
Object.Refresh
تنفيذ نسخة برنامج العد المحسنة
لنشاهد تأثير ما كتبناه:
نفّذ نسخة برنامج العد المحسنة.
تُظهر اللافتة الآن كل رقم من 1 وحتى 999 أثناء التعداد. لاحظ أن النقر على خروج أثناء التعداد لا يُنهي البرنامج، ما هو السبب ؟ ! السبب أن البرنامج أثناء تنفيذ الإجراء cmdStart_Click() ليس في زمن ضائع (ولهذا فالبرنامج لا يمكنه الاستجابة لنقر الزر خروج).
المزيد من التحسين على برنامج العد
لنحسن برنامج العد بحيث يستجيب للنقر بواسطة الفأرة على الزر خروج أثناء التعداد. سنحتاج إلى كتابة إجراء يدعى Main()، والذي سيكون أول إجراء يُنفذ عند تشغيل البرنامج.
اختر البند Project1 Properties من قائمة Project.
يستجيب فيجول بيسك بإظهار نافذة خصائص المشروع.
اختر الصفحة General في مربع الحوار السابق.
ألقِ نظرة على الحقل المدعو Startup Object، والذي يظهر في صفحة General، وبما أنك ترغب أن يكون الإجراء Main() هو أول إجراء ينفذ عند تشغيل برنامج العد، لهذا غيّر الحقل Startup Object إلى Main() وفق ما يلي:
ضع الحقل Startup Object على Sub Main، ثم انقر الزر Ok (انظر الشكل 11-6).
الشكل 11-6 وضع الحقل Startup Object على Sub Main.
والآن، الإجراء Main() هو أول إجراء ينفذ عند تشغيل برنامج العد.
سنكتب الآن الإجراء Main(). يحتاج فيجول بيسك إلى أن يكون Main() ضمن وحدة نمطية (Module) مستقلة. لهذا السبب أضف وحدة نمطية جديدة إلى المشروع:
اختر البند Add Module من قائمة Project.
يستجيب فيجول بيسك بإظهار مربع الحوار Add Module.
اختر الرمز Module في صفحة New لمربع الحوار Add Module ثم انقر الزر فتح.
يستجيب فيجول بيسك بإضافة وحدة نمطية Module جديدة إلى المشروع. الاسم الافتراضي للوحدة النمطية المضافة حديثاً هو Module1.Bas. يمكنك مشاهدة ذلك في إطار المشروع باختيار البند Project Explores من قائمة View.
احفظ الوحدة النمطية المضافة حديثاً باسم CountM.Bas كما يلي:
تحقق من توضع الإضاءة على Module1.Bas في إطار المشروع ثم اختر
Save Module1 As من قائمة File لفيجول بيسك.
يستجيب فيجول بيسك بإظهار مربع الحوار Save File As.
احفظ الوحدة النمطية المضافة حديثاً باسم CountM.Bas في الدليل C:\VB5Prg\Ch11.
سيحتوي إطار المشروع الآن على Count.Frm وCountM.Bas.
سنضيف إجراءً يدعى Main() في الجزء المدعو CountM.Bas:
تأكد من تمركز الإضاءة على CountM.Bas في الإطار Project.
انقر على الرمز View Code الذي يظهر أقصى يسار الرموز على شريط الأدوات
Tool Bar لإطار المشروع (لأنك على وشك إضافة إجراء إلى الوحدة النمطية CountM.Bas).
اختر البند Add Procedure من قائمة Tools.
يستجيب فيجول بيسك بإظهار مربع الحوار Add Procedure.
اكتب Main في الحقل Name لمربع الحوار Add Procedure، وتحقق بأن Type موضوع على Sub وأن Scope موضوع على Public (انظر الشكل 11-7)، وأخيراً انقر الزر Ok.
يستجيب فيجول بيسك بإضافة الإجراء Main() في CountM.Bas. يبين الشكل 11-8 الإجراء Main().
الشكل 11-7 إضافة الإجراء Main() إلى الوحدة النمطية Country.Bas.
الشكل 11-8 الإجراء Main().
أدخل النص التالي في قسم التصاريح العامة:
'يجب التصريح عن كل المتحولات
Option Explicit
أدخل النص التالي في الإجراء Main() الموجود في الوحدة النمطية CountM.Bas:
Public Sub Main()
Dim Counter
frmCount.Show
Do While DoEvents()
If ggflag = 1 Then
Counter = Counter + 1
frmCount.lblResult.Caption = Str$(Counter)
If Counter = 999 Then
Counter = 1
End If
End If
Loop
End Sub
أدخل النص التالي في الإجراء cmdPause_Click() للنموذج frmCount:
Private Sub cmdPause_Click()
ggflag = 0
End Sub
بدل نص الإجراء cmdStartr_Click() للنموذج frmCount بحيث يغدو كما يلي:
Private Sub cmdStart_Click()
ggflag = 1
End Sub
أدخل النص التالي ضمن الإجراء Form_Load() للنموذج frmCount:
Private Sub Form_Load()
ggflag = 0
End Sub
احفظ المشروع باختيار البند Save Project من قائمة File لفيجول بيسك.
تنفيذ النسخة المحسنة من برنامج العد
لنشاهد أثر ما كتبناه:
نفّذ نسخة برنامج العد المحسنة.
يعد البرنامج من 1 إلى 999 ثم يكرر التعداد … وهكذا. ويظهر كل رقم أثناء التعداد في اللافتة.
انقر الزر إيقاف مؤقت.
كما تلاحظ، تسبب ذلك بإيقاف التعداد.
انقر الزر ابدأ لاستئناف التعداد.
افتح برامج أخرى أثناء قيام برنامج العد بالتعداد وأنجز ما ترغب من الأعمال، كأن تفتح نافذة الرسام وترسم شكلاً ما (انظر الشكل 11-9) لاحظ أن البرنامج يعد أثناء عملك ضمن برنامج الرسام.
الشكل 11-9 تنفيذ برنامج العد وبرنامج الرسام سوية.
الإجراء Main()
الإجراء Main() هو أول إجراء يُنفذ عند تشغيل البرنامج.
ولهذا فإن العبارة الأولى فيه مسئولة عن إظهار النموذج:
frmCount.Show
ملاحظة
استخدم الطريقة Show كأول عبارة في الإجراء Main() لإظهار النموذج. لأن الإجراء Main() هو أول إجراء يُنفذ عند تشغيل البرنامج، ولن يحمل النموذج آلياً.
تدعى الحلقة Do While DoEvents() بحلقة الوقت الضائع idle Loop:
Public Sub Main()
Dim Counter
frmCount.Show
Do While DoEvents()
If ggflag = 1 Then
Counter = Counter + 1
frmCount.lblResult.Caption = Str$(Counter)
If Counter = 999 Then
Counter = 1
End If
End If
Loop
End Sub
يوضح الشكل 11-10 الانسياب المنطقي لهذه الحلقة. لاحظ أن البرنامج يبقى في حالة دوران لا نهائية.
إنهاء الحلقة الغير المنتهية
يعيد التابع الوظيفي DoEvents() عدد النماذج المفتوحة حالياً. فإذا أغلقت النموذج frmCount، فهذا يعني عدم تبقي نماذج مفتوحة في البرنامج، وبالتالي يعيد التابع الوظيفي DoEvents() القيمة صفر. يتسبب هذا بإنهاء الحلقة، والتي تنهي بدورها البرنامج.
الشكل 11-10 حلقة الوقت الضائع Do While DoEvents().
تنفيذ جسم الحلقة Do While DoEvents()
حسب ما يوضحه الشكل 11-10 ينفذ جسم هذه الحلقة في حال وجود نموذج مفتوح.
العبارة الأولى في الحلقة، هي عبارة If التي تتحقق من قيمة المتحول ggFlag. لنفترض أنك نقرت على الزر ابدأ للتو، مما يؤدي إلى إسناد القيمة 1 للمتحول ggFlag، وبالتالي تُنفذ عبارتي If وتزيد قيمة المتحول، وتجدّد خاصية Caption للافتة.
لا يمر البرنامج في زمن ضائع أثناء تنفيذ جسم الحلقة Do While. مما يعني أن البرنامج لا يستطيع الاستجابة إلى حوادث معينة أثناء تنفيذ الحلقة هذه، فمثلاً. لا يستجيب لحادثة الضغط على الزر إيقاف مؤقت. تدعى الحوادث التي تجري في غير الأزمنة الضائعة بالحوادث المعلقة Pending Events. فمثلاً النقر على الزر إيقاف مؤقت أثناء تنفيذ البرنامج لجسم الحلقة Do While يسبب حادثة معلقة.
يحتوي جسم الحلقة Do While على العبارة التالية:
frmCount.lblResult.Caption = Str$(Counter)
تتسبب هذه العبارة بظهور حادثة معلقة، لأن الخاصية Caption للافتة lblResult، لا يمكن تعديلها إلا في الزمن الضائع فقط.
حسب ما يوضحه الشكل 11-10، حالما تُنفذ الحلقة Do While، يعيد البرنامج تنفيذ الحلقة DoEvents() مرة ثانية (إلى ما لا نهاية).
التابع الوظيفي DoEvents()
يتوجب عليك إجبار البرنامج على الدخول في زمن ضائع، حتى يتمكن النظام ويندوز من التعامل مع الحوادث المعلقة، وهذا هو دور التابع الوظيفي DoEvents().
يتعامل البرنامج مع الحوادث المعلقة عندما يمر في زمن ضائع. فمثلاً عملية إعادة إنعاش اللافتة IblResult حادثة معلقة، كذلك النقر على الزر إيقاف مؤقت أثناء تنفيذ الحلقة Do While عملية معلقة أيضاً. ولهذا فإن استخدام DoEvents() يسمح للبرنامج بالدخول في زمن ضائع، مما يسمح له بمعالجة الحوادث المعلقة. ثم يعود البرنامج إلى تنفيذ الحلقة Do While وتبدأ المعالجة كاملة من جديد.
ملاحظة
يقوم التابع DoEvents() عند استخدامه مع الحلقة Do While بوظيفتين:- القيمة المعادة من هذا التابع تمثل عدد النماذج المفتوحة حالياً. وتنهى الحلقة عند عدم وجود أي نماذج مفتوحة.- يُجبر هذا التابع الوظيفي البرنامج، على الدخول في زمن ضائع، مما يسمح لويندوز بتنفيذ الحوادث المعلقة.
نص قسم التصاريح العامة للوحدة النمطية CountM.Bas
يتضمن هذا القسم العبارتين:
التصريح عن المتحول ggFlag في هذا المكان يعني أنه مرئي (متاح) لكل الإجراءات الموجودة في الوحدات النمطية الأخرى أو النماذج. ويستخدم هذا المتحول كل من الإجراءات Form_Load() و cmdStart_Click() و cmdPause_Click() للنموذج frmCount كما يستخدم من قبل الإجراء Main() الموجود في الوحدة النمطية CountM.Bas.
نص الإجراء cmdPause_Click()
يُنفذ هذا الإجراء أثناء الزمن الضائع، إذا نقرت الزر إيقاف مؤقت خلال تنفيذ الحلقة
Do While DoEvents(). يسند هذا الإجراء للمتحول ggFlag القيمة صفر، مما يتسبب بإيقاف عملية التعداد في الإجراء Main:
Private Sub cmdPause_Click()
ggflag = 0
End Sub
نص الإجراء cmdStart_Click()
يسند هذا الإجراء للمتحول ggFlag القيمة واحد، مما يتسبب بعمل معالجة التعداد في الإجراء Main():
Private Sub cmdStart_Click()
ggflag = 1
End Sub
الخلاصة
تعلمنا فى هذا الفصل كيف يتمكن برنامج مكتوب بفيجول بيسك من الإستفادة من مظاهر ويندوز الأساسية. فتعلمنا كيفية إنجاز نسخ وقص ولصق (صور أو نصوص) من وإلى الحافظة، كما تعلمنا استخدام الطريقة Refresh اللازمة لإعادة رسم الكائنات، وكيفية كتابة نص برنامج يمكن تنفيذه فى الأزمنة الضائعة.
الفصل الثاني عشر
لوحة المفاتيح
سنتعلم في هذا الفصل كيف يستجيب برنامجك لحوادث لوحة المفاتيح، وكيفية التحقق من الضغط على أحد المفاتيح أو تحريره، وآلية معالجة معطيات الإدخال الواردة من لوحة المفاتيح.
تركيز لوحة المفاتيح Focus
كما تبين لنا من الفصول السابقة، الكائن الذي يمتلك تركيز لوحة المفاتيح هو الكائن الذي يستجيب لإدخالها. وعندما يكون تركيز لوحة المفاتيح عند عنصر تحكم ما، فإنه سوف يُبدي تغيراً ما في شكله على الشاشة. فمثلاً عندما يكون التركيز على زر أمر، يظهر مستطيل منقط حول عنوان زر الأمر هذا، وعندما يكون التركيز موضوعاً عند شريط تمرير، فسوف تجد أن مؤشره يومض.
حوادث لوحة المفاتيح
تترافق فعاليات لوحة المفاتيح مع الحوادث التالية:
KeyDown (ضغط مفتاح).
KeyUp (تحرير مفتاح).
KeyPress (ضغط مفتاح آسكي).
الحادثة KeyDown
تحصل هذه الحادثة، عند ضغط أحد المفاتيح على لوحة المفاتيح إلى الأسفل، مثال، الضغط على أي مفتاح على لوحة المفاتيح، عندما يكون التركيز على زر أمر يدعى cmdPushMe، مما ينتج عنه تنفيذ الإجراء cmdPushMe_KeyDown() آلياً.
الحادثة KeyUp
تحصل هذه الحادثة عند تحرير أحد المفاتيح على لوحة المفاتيح. مثال، تحرير مفتاح ما على لوحة المفاتيح عندما يكون التركيز على زر أمر يدعى cmdPushMe، مما ينتج عنه تنفيذ الإجراء cmdPushMe_KeyUp() آلياً.
الحادثة KeyPress
تحصل هذه الحادثة عند الضغط على مفتاح ما، له شفرة آسكي ASCII مرافقة. فمثلاً، إذا ضغطت على المفتاح A عندما يكون التركيز عند زر الأمر المدعو cmdPushMe، فسوف يُنفذ الإجراء cmdPushMe_KeyUp()، أما إذا ضغطت على المفتاحF1 مثلاً فإن الحادثة cmdPushMe_KeyPress() لن تقع، لأن المفتاح F1 لا يملك شفرة ASCII مرافقة.
برنامج المفاتيح
يوضح برنامج المفاتيح كيفية استخدام حوادث لوحة المفاتيح الثلاث الآنفة الذكر.
التمثيل المرئي لبرنامج المفاتيح
نبدأ كعادتنا بطور التمثيل المرئي لنموذج برنامج المفاتيح:
أنشئ الدليل C:\VB5Prg\Ch12.
أنشئ مشروعاً جديداً من النوع Standard EXE، واحفظ نموذج المشروع بالاسم Keys.frm في الدليل C:\VB5Prg\Ch12، واحفظ المشروع في ذات الدليل بالاسم
Keys.Vbp.
أنشئ النموذج طبقاً للجدول 12-1.
يُفترض أن يظهر النموذج المكتمل كما في الشكل 12-1.
الشكل 12-1 النموذج frmKeys في مرحلة التصميم.
الجدول 12-1. جدول خصائص البرنامج frmKeys.
الكائن الخاصية القيمة
Form Name frmKeys
Caption برنامج المفاتيح
RightToLeft True
CommandButton Name cmdExit
Caption &خروج
RightToLeft True
CommandButton Name cmdPushMe
Caption ا&ضغط هذا الزر
RightToLeft True
Label Name lblInfo
Alignment 2-Center
BorderStyle 1-Fixed Single
Caption (اجعله فارغاً)
RightToLeft True
إدخال نص برنامج المفاتيح
اكتب العبارة Option Explicit في قسم التصاريح العامة للنموذج frmKeys:
'يجب التصريح عن كل المتحولات
Option Explicit
اكتب النص التالي ضمن الإجراء cmdExit_Click() للنموذج frmKeys:
Private Sub cmdExit_Click()
End
End Sub
أدخل النص التالي ضمن الإجراء cmdPushMe_Click():
Private Sub cmdPushMe_keydown(KeyCode As Integer,_
Shift As Integer)
lblInfo.Caption = "لقد ضغطت أي مفتاح"
lblInfo.Caption = lblInfo.Caption + vbCrLf
lblInfo.Caption = lblInfo.Caption + "KeyCode=" + _
Str(KeyCode)
lblInfo.Caption = lblInfo.Caption + vbCrLf
lblInfo.Caption = lblInfo.Caption + "Shift=" + _
Str(Shift)
End Sub
احفظ المشروع باختيار البند Save Project من القائمة File لفيجول بيسك.
تنفيذ برنامج المفاتيح
لنشاهد أثر ما كتبناه:
نفّذ برنامج المفاتيح.
انقر الزر اضغط هذا الزر.
يستجيب برنامج المفاتيح بوضع مستطيل منقط حول عنوان الزر، مما يعني أن هذا الزر يمتلك الآن تركيز لوحة المفاتيح (لأننا اخترناه من الخطوة السابقة بالنقر عليه).
اضغط أي مفتاح على لوحة المفاتيح.
يستجيب البرنامج بإظهار شفرة المفتاح الذي ضغطته، في اللافتة lblInfo، حسب ما يبينه الشكل 12-2.
الشكل 12-2 برنامج المفاتيح والضغط على أي مفتاح.
اضغط على مفاتيح أخرى على لوحة المفاتيح، ولاحظ كيف تُظهر اللافتةlblInfo شفرة المفتاح المضغوط.
اضغط على المفتاح Num Lock، ولاحظ أن البرنامج يعلن بأن القيمة المرافقة لهذا المفتاح تساوي 144، العلاقة بين الأرقام التي تظهر والمفاتيح المضغوطة مشروحة لاحقاً في هذا الفصل.
اضغط على المفتاح Shift ثم أتبع ذلك بالضغط على المفتاح Ctrl ثم المفتاح Alt، (أي اضغط على المفتاح Alt مع إبقاء الضغط على مفتاح Shift ومفتاح Ctrl).
تُظهر اللافتة الأرقام 1 ثم 3 ثم 7، الصلة بين هذه الأرقام وبين مفاتيح التحكم: Alt و Ctrl و Shift مبينة لاحقاً في هذا الفصل.
انقر الزر خروج لإنهاء برنامج المفاتيح.
كيف يعمل برنامج المفاتيح
يستخدم برنامج المفاتيح الحادثة KeyDown للاستجابة للمفاتيح المضغوطة على لوحة المفاتيح.
نص الإجراء cmdPushMe_KeyDown()
يُنفذ الإجراء cmdPushMe_KeyDown() عندما يمتلك الزر اضغط هذا الزر، تركيز لوحة المفاتيح، ثم يُضغط أحد المفاتيح من لوحة المفاتيح:
Private Sub cmdPushMe_Keydown(KeyCode As Integer,_
Shift As Integer)
lblInfo.Caption = "لقد ضغطت أي مفتاح"
lblInfo.Caption = lblInfo.Caption + vbCrLf
lblInfo.Caption = lblInfo.Caption + "KeyCode=" + _
Str(KeyCode)
lblInfo.Caption = lblInfo.Caption + vbCrLf
lblInfo.Caption = lblInfo.Caption + "Shift=" + _
Str(Shift)
End Sub
يحوي الإجراء cmdPushMe_KeyDown() وسيطين، يدعى الأول KeyCode، وهو عبارة عن عدد صحيح يمثل شفرة المسح Scan Code للمفتاح المضغوط، ويدعى الثاني Shift، ويمثل حالة المفاتيح Alt و Ctrlو Shift.
لتحديد المفتاح المضغوط، يمكنك مقارنة قيمة الوسيط الأول KeyCode مع ثوابت لوحة المفاتيح في فيجول بيسك، فمثلاً، إذا ضغط المستخدم على المفتاح Num Lock فإن قيمة الوسيط KeyCode سوف تساوي قيمة الثابت vbKeyNumLock، وبشكل مشابه فإن الضغط على المفتاح F1، يعني أن قيمة الوسيط KeyCodeستساوي vbKeyF1، والضغط على المفتاح 2 يعني أن قيمة الوسيط KeyCode ستساوي vbKey2، والضغط على المفتاح Home يعني أن KeyCode تساوي vbKeyHome … وهكذا.
يعطي الجدول 12-2 لائحة بمعاني قيم الوسيط الثاني للإجراء cmdPushMe_KeyDown(). فمثلاً، عندما تكون قيمة الوسيط الثاني تساوي 3 فهذا يعني أنه تم الضغط على كلا المفتاحين Shift و Ctrl بدون الضغط على Alt.
الجدول 12-2. القيم الممكنة للوسيط الثاني للإجراء cmdPushMe_KeyDown()
قيمة الوسيط Shift حالة المفتاح Alt حالة المفتاح Ctrl حالة المفتاح Shift
0 غير مضغوط غير مضغوط غير مضغوط
1 غير مضغوط غير مضغوط مضغوط
2 غير مضغوط مضغوط غير مضغوط
3 غير مضغوط مضغوط مضغوط
4 مضغوط غير مضغوط غير مضغوط
5 مضغوط غير مضغوط مضغوط
6 مضغوط مضغوط غير مضغوط
7 مضغوط مضغوط مضغوط
يُسند نص الإجراء cmdPushMe_KeyDown() سلسلة حرفية تمثل قيمة الوسيطين السابقين إلى الخاصية Caption التابعة للافتة lblInfo.
lblInfo.Caption = "لقد ضغطت أي مفتاح"
lblInfo.Caption = lblInfo.Caption + vbCrLf
lblInfo.Caption = lblInfo.Caption + "KeyCode=" + _
Str(KeyCode)
lblInfo.Caption = lblInfo.Caption + vbCrLf
lblInfo.Caption = lblInfo.Caption + "Shift=" + _
Str(Shift)
يُستخدم التابع الوظيفي Str()، لتحويل القيمة الرقمية إلى قيمة نصية، يمكن وضعها في الخاصية Caption التابعة للافتة. يُحول التابع الوظيفي Str(KeyCode) الوسيط KeyCode من قيمة رقمية من النوع الصحيح إلى قيمة نصية String وكذلك يحول التابع الوظيفي Str(Shift) الوسيط Shift من قيمة رقمية إلى قيمة نصية أيضاً.
استخدم الثابت vbCrLf بغرض توزيع السلسلة الكتابية على أكثر من سطر.
التحقق من تحرير Released مفتاح ما
كما لاحظنا، يمكن استخدام وسيطي الحادثة KeyDown للتحقق من عملية ضغط أي مفتاح. تمتلك الحادثة KeyUp نفس الوسيطين المستخدمين في الحادثة KeyDown، باستثناء أن هذه الحادثة تحصل عند تحرير المفتاح من الضغط وليس عند ضغطه.
أدخل النص التالي ضمن الإجراء cmdPushMe_KeyUp() للنموذج frmKeys حتى تتعرف على الحادثة KeyUp بشكل أوضح:
Private Sub cmdPushMe_KeyUp(KeyCode As Integer,_
Shift As Integer)
lblInfo.Caption = "لقد حررت أي مفتاح"
lblInfo.Caption = lblInfo.Caption + vbCrLf
lblInfo.Caption = lblInfo.Caption + "KeyCode=" + _
Str(KeyCode)
lblInfo.Caption = lblInfo.Caption + vbCrLf
lblInfo.Caption = lblInfo.Caption + "Shift=" + _
Str(Shift)
End Sub
احفظ المشروع بالطريقة المعتادة.
نفّذ برنامج المفاتيح، وانقر الزر اضغط هذا الزر.
يستجيب البرنامج بإظهار مستطيل منقط حول الزر، مما يعني أن الزر يمتلك الآن تركيز لوحة المفاتيح.
اضغط مفتاحاً ما.
يستجيب البرنامج بإظهار الرقم المرافق للمفتاح المضغوط.
حرر المفتاح المضغوط.
يستجيب برنامج المفاتيح بإظهار قيمة المفتاح المحرر.
انقر الزر خروج لإنهاء برنامج المفاتيح.
يمتلك الإجراء cmdPushMe_KeyUp() نفس وسيطي الإجراء cmdPushMe_KeyDown()، إلا أن الإجراء cmdPushMe_KeyDown() يعلن عن المفتاح المضغوط، بينما يعلن الإجراء cmdPushMe_KeyUp() عن المفتاح المحرر.
التحقق من مفتاح ذي شفرة ASCII (ASCII Key)
تُستخدم الحادثة KeyPress، للتحقق من الضغط على مفتاح ذي شفرة ASCII، اتبع الخطوات التالية للتعرف على عمل الحادثة KeyPress بشكل أوضح:
أدخل النص التالي في الإجراء cmdPushMe_KeyPress() للنموذج frmKeys:
Private Sub cmdPushMe_keyPress(KeyAscii As Integer)
Dim Char
Char = Chr(KeyAscii)
lblInfo.Caption = "KeyAscii = " + Str(KeyAscii) + _
"Char = " + Char
End Sub
أَلغِ عمل عبارات الإجراء cmdPushMe_KeyDown()، أي بوضع فاصلة علوية في بداية كل عبارة بحيث تصبح كملاحظة.
نفّذ برنامج المفاتيح.
انقر الزر اضغط هذا الزر.
يستجيب البرنامج بإظهار مستطيل منقط حول الزر، مما يشير إلى أن تركيز لوحة المفاتيح متوضع عند هذا الزر.
اضغط على المفتاح A وأبقه مضغوطاً.
يستجيب برنامج المفاتيح بإظهار قيمة ASCII لهذا المفتاح، والتي تساوي 97 للحرف a الصغير، و65 للحرف A الكبير.
اضغط على المفتاح F1 وأبقه مضغوطاً.
لا يُظهر برنامج المفاتيح أية قيمة في اللافتة lblInfo لأن F1 لا يمتلك شفرة ASCII، ولهذا لا تحصل الحادثة KeyPress عند الضغط على F1.
انقر الزر خروج لإنهاء برنامج المفاتيح.
نص cmdPushMe_KeyPress()
يُنفذ هذا الإجراء عند الضغط على مفتاح آسكي ASCII Key، يمتلك هذا الإجراء وسيطاً واحداً فقط يمثل قيمة ASCII للمفتاح المضغوط.
يحول التابع الوظيفي Chr() القيمةKeyAscii الصحيحة إلى حرف:
Char = Chr(KeyAscii)
المتحول Char يحتفظ الآن برمز المفتاح المضغوط، فمثلاً، يحتوي Char على الرمز Z إذا ضغط المستخدم على الحرف Z، تُسند آخر عبارة في هذا الإجراء سلسلة إلى الخاصية Caption للافتة lblInfo:
lblInfo.Caption = "KeyAscii =" + Str(KeyAscii)+ _
" Char=" +Char
وبهذا، يتمكن المستخدم من مشاهدة رمز المفتاح المضغوط، إضافة إلى قيمة ASCII المرافقة له.
اعتراض المفاتيح بواسطة الإجراء Form_ KeyPress()
يتمكن النموذج من امتلاك تركيز لوحة المفاتيح، عندما لا يكون فيه عناصر تحكم، أو عندما تكون هذه العناصر معطّلة. ولكن في معظم البرامج، يمتلك النموذج بعض عناصر التحكم الفعّالة، ولهذا لا تُنفذ الإجراءات Form_KeyDown() و Form_KeyUp() وForm_KeyPress() أبداً.
ولإجبار البرنامج على تنفيذ هذه الإجراءات، حتى عندما لا يمتلك النموذج تركيز لوحة المفاتيح، أسند القيمة True إلى الخاصية KeyPreview للنموذج. اتبع الخطوات التالية لرؤية تأثير الخاصية KeyPreview على سير العمل:
أسند القيمة True إلى الخاصية KeyPreview للنموذج frmKeys.
ألغِ عمل الإجراءات cmdPushMe_KeyDown() و cmdPushMe_KeyUp() وcmdPushMe_KeyPress()، بوضع فاصلة علوية ( ' ) قبل عبارات هذه الإجراءات.
أدخل النص التالي ضمن الإجراء Form_KeyPress():
Private Sub Form_keyPress(KeyAscii As Integer)
Dim Char
Char = Chr(KeyAscii)
lblInfo.Caption = "KeyAscii =" + Str(KeyAscii)+ _
" Char=" + Char
End Sub
احفظ عملك.
نفّذ برنامج المفتاح.
اضغط أي مفتاح آسكي.
تُظهر اللافتة lblInfo. المفتاح المضغوط بغض النظر عن عنصر التحكم الذي يمتلك تركيز لوحة المفاتيح، (طبعاً هذا بسبب إسناد القيمة True إلى الخاصية KeyPreview للنموذجfrmKeys).
تستطيع بطريقة مشابهة استخدام الإجراء Form_KeyDown()، والإجراء Form_KeyUp()، لتصيّد المفاتيح المضغوطة حتى وإن لم يمتلك النموذج تركيز لوحة المفاتيح. وعلى كل حال، نعود إلى تذكيرك بضرورة إسناد القيمة True إلى الخاصية KeyPreview للنموذج، في حال أردت تصيّد المفاتيح التي تضغط أثناء عمل البرنامج.
تُمكّن الخاصية KeyPreview البرنامج، من تصيّد حوادث لوحة المفاتيح، مما يسمح لك بكتابة نص برنامج معين، يستجيب لضغطات المفاتيح، بغض النظر عن عنصر التحكم الذي يمتلك تركيز لوحة المفاتيح.
برنامج متصيد المفاتيح
يوضّح برنامج متصيد المفاتيح، كيف يتمكن برنامجك من تصيّد مفاتيح آسكي (المفاتيح التي لها شفرات آسكي موافقة).
التمثيل المرئي لبرنامج متصيد المفاتيح
كالعادة أنشئ مشروعاً جديداً من نوع Standard EXE، واحفظ نموذج المشروع بالاسم Upper.frm في الدليل C:\VB5Prg\Ch12 واحفظ ملف المشروع في ذات الدليل بالاسم Upper.Vbp.
أنشئ النموذج تبعاً للجدول 12-3.
يُفترض أن يظهر النموذج المكتمل كما في الشكل 12-3.
الشكل 12-3 النموذج frmUpper (طور التصميم).
الجدول 12-3. جدول خصائص البرنامج frmUpper.
الكائن الخاصية القيمة
Form Name frmUpper
Caption برنامج متصيد المفاتيح
RightToLeft True
CommandButton Name cmdExit
Caption &خروج
RightToLeft True
TextBox Name txtUserArea
ScrollBars 3-Both
Text (اجعله فارغاً)
RightToLeft True
إدخال نص برنامج متصيد المفاتيح
سنكتب الآن نص برنامج متصيد المفاتيح:
اكتب العبارة Option Explicit في قسم التصاريح العامة General Declarations.
'يجب التصريح عن كل المتحولات
Option Explicit
اكتب النص التالي ضمن الإجراء cmdExit_Click() للنموذج frmUpper:
Private Sub cmdExit_Click()
End
End Sub
تنفيذ برنامج متصيد المفاتيح
نفّذ برنامج متصيد المفاتيح.
اكتب شيئاً ما في مربع النص.
جرب الضغط على المفتاح Enter للانتقال إلى السطر التالي.
يرفض برنامج متصيد المفاتيح الانتقال إلى السطر التالي في مربع النص، لأن الخاصية MultiLine لمربع النص txtUserArea تساوي False حالياً. لاحظ أن الحاسب يصدر صوت رنين، كلما ضغطت المفتاح Enter، لتنبيهك أنك تضغط مفتاحاً غير مسموحٍ به.
انقر الزر خروج لإنهاء برنامج متصيد المفاتيح.
تصيد المفتاح Enter
كما بيَّنا، يعطي الحاسب صوت رنين، كلما ضغط المستخدم على مفتاح غير مسموح به. يمكننا تصيّد الحادثة، ومغافلة برنامج متصيد المفاتيح كما يلي:
أدخل النص التالي ضمن الإجراء txtUserArea_KeyPress() للنموذج frmUpper:
Private Sub txtUserArea_KeyPress(KeyAscii As Integer)
'Enter إلغاء ضغطة المفتاح
If KeyAscii = vbKeyReturn Then
KeyAscii = 0
End If
End Sub
نفّذ برنامج متصيد المفاتيح.
اكتب شيئاً ما في مربع النص ثم اضغط على Enter.
كما تشاهد لا يسمح لك مربع النص بالانتقال إلى السطر التالي، لكن الحاسب لا يصدر صوتاً عندما نضغط على Enter.
أنهِ البرنامج بالنقر على الزر خروج.
نص الإجراء txtUserArea_KeyPress()
ينفذ هذا الإجراء عند الضغط على مفتاح آسكي ما، يتحقق الإجراء من الضغط عل المفتاح Enter. فإذا تم الضغط على Enter، يغير الإجراء قيمة الوسيط KeyASCII إلى الصفر، فيعتقد مربع النص أنك ضغطت على المفتاح ذي قيمة الآسكي صفر (كأنك لم تضغط أي مفتاح)، وهذا هو السبب الذي يمنع الحاسب من إصدار صوت عند الضغط على Enter.
يوضح نص الإجراء txtUserArea_KeyPress() أن هذا الإجراء، ينفذ قبل أن تسنح الفرصة لمربع النص بمعالجة المفتاح المضغوط.
تعديل برنامج متصيد المفاتيح
عدّل برنامج متصيد المفاتيح كما يلي:
غير خانة الخاصية MultiLine لمربع النص txtUserArea إلى True.
نفّذ برنامج متصيد المفاتيح.
اكتب شيئاً ما في مربع النص واضغط Enter.
كما تلاحظ، لا يسمح لك بالانتقال إلى السطر التالي لأن المفتاح Enter يتم تصيده من قبل الإجراء txtUserArea_KeyPress()، وإلغاء دوره بتغيير قيمة الوسيط KeysASCII إلى الصفر، مما يثير لدى مربع النص الاعتقاد بأنك لم تضغط شيئاً.
أنهِ البرنامج بالطريقة المعتادة.
تحويل رموز ASCII إلى حروف كبيرة (تحويل الحرف الصغير إلى كبير)
قد يحتاج المستخدم في بعض البرامج إلى تحويل الحروف الصغيرة إلى كبيرة فقط، أو صغيرة فقط، لتوضيح كيفية إنجاز ذلك، غير نص الإجراء txtUserArea_KeyPress() بحيث يبدو كما يلي:
Private Sub TxtUserArea_keyPress(KeyAscii As Integer)
Dim Char
Char = Chr(KeyAscii)
KeyAscii = Asc(UCase(Char))
End Sub
نفّذ برنامج متصيد المفاتيح.
اكتب شيئاً ما ضمن مربع النص.
كما تشاهد تظهر الأحرف كأحرف كبيرة بغض النظر عن حالة المفتاحين Shift و
Caps Lock.
أنهِ البرنامج بالطريقة المعتادة.
يستخدم نص الإجراء txtUserArea_KeyPress() التابع الوظيفي Chr() لتحويل شفرة الحرف المضغوط إلى رمز أو حرف:
Char = Chr(KeyAscii)
ثم يحوّل الرمز نفسه إلى رمز كبير (حرف كبير)، فمثلاً، القيمة المعادة من UCase("a") هي A، والقيمة المعادة من UCase("A") هي أيضاً A.
يحوّل الإجراء بعد ذلك، القيمة المعادة من التابع الوظيفي UCase()، إلى قيمة صحيحة باستخدام التابع الوظيفي Asc():
KeyAscii = Asc(UCase(Char))
يعيد التابع الوظيفي Asc() قيمة صحيحة، تمثل قيمة الآسكي للوسيط الممرر له.
باختصار نقول، يُزوّد الإجراء txtUserArea_KeyPress() قيمة صحيحة، تمثل قيمة آسكي ASCII للمفتاح المضغوط، تحوّل هذه القيمة إلى حرف، ثم يحوّل الحرف إلى حرف كبير، ثم يُسند قيمة آسكي للحرف الكبير، إلى الوسيط KeyAscii مرة أخرى. وهكذا يعتقد مربع النص، أن المستخدم ضغط على حرف (رمز) كبير.
ملاحظة
يوجد تابع وظيفي معاكس لوظيفة التابع UCase() (Upper Case)، وهو التابع LCase() (Lower Case)، ووظيفته تحويل الأحرف إلى أحرف صغيرة دائماً.
ينبغي التنويه أنه ليس لهذه الوظائف أي تأثير على النصوص العربية، وتعيد النص كما هو بدون تغيير. فمثلاً، تعود العبارة التالية:
Print UCase("فيجول بيسك")
بالنتيجة:
فيجول بيسك
الخاصية Cancel
تُستخدم الخاصية Cancel لتوفير استجابة للضغط على المفتاح Esc، اتبع الخطوات التالية لرؤية دور الخاصية Cancel:
نفّذ برنامج متصيد المفاتيح.
اضغط المفتاح Esc من على لوحة المفاتيح.
كما تشاهد، لا يستجيب البرنامج للمفتاح Esc، بغض النظر عن موقع تركيز لوحة المفاتيح.
انقر الزر خروج لإنهاء برنامج متصيد المفاتيح.
غير حالة الخاصية Cancel للزر خروج إلى True.
نفّذ برنامج متصيد المفاتيح.
اضغط المفتاح Esc على لوحة المفاتيح.
يستجيب البرنامج للمفتاح Esc كما لو أن المستخدم ضغط على زر الأمر خروج، وهذا بغض النظر عن عنصر التحكم الذي يستحوذ على تركيز لوحة المفاتيح. وهذا بسبب إسناد القيمة True إلى الخاصية Cancel لزر الأمر خروج.
بشكل مشابه، يؤدي إسناد القيمة True إلى الخاصية Default للزر خروج إلى أثر استجابة البرنامج للضغط على المفتاح Enter وكأنه نقر على الزر خروج مما يتسبب بإنهاء البرنامج، وهذا بغض النظر عن أين يقع تركيز لوحة المفاتيح.
برنامج المفتاح Tab
يسمح لك ويندوز بالانتقال من عنصر تحكم لآخر، بواسطة المفتاح Tab (نقل تركيز لوحة المفاتيح من عنصر تحكم إلى آخر)، بينما يؤدي الضغط على Shift + Tab إلى الانتقال باتجاه معاكس، يوضح برنامج المفتاح Tab آلية العمل هذه.
أنشئ مشروعاً جديداً من النوع Standard EXE، واحفظ نموذج المشروع بالاسم Tab.frm في الدليل C:\VB5Prg\Ch12 واحفظ ملف المشروع بالاسم Tab.Vbp في الدليل نفسه.
أنشئ نموذج المشروع وفق الجدول 12-4.
يُفترض أن يظهر النموذج المكتمل كما في الشكل 12-4.
الجدول 12-4. جدول خصائص النموذج frmTab.
الكائن الخاصية القيمة
Form Name frmTab
Caption برنامج المفتاح Tab
RightToLeft True
CommandButton Name Command1
Caption Command1
TabIndex 0
CommandButton Name Command2
Caption Command2
TabIndex 1
CommandButton Name Command3
Caption Command3
TabIndex 2
CommandButton Name Command4
Caption Command4
TabIndex 3
CommandButton Name Command5
Caption Command5
الكائن الخاصية القيمة
TabIndex 4
CommandButton Name Command6
Caption Command6
TabIndex 5
CommandButton Name Command7
Caption Command7
TabIndex 6
CommandButton Name Command8
Caption Command8
TabIndex 7
CommandButton Name Command9
Caption Command9
TabIndex 8
CommandButton Name Command10
Caption Command10
TabIndex 9
CommandButton Name cmdExit
Caption &خروج
TabIndex 10
CheckBox Name Check1
Caption Check1
TabIndex 11
CheckBox Name Check2
Caption Check2
TabIndex 12
CheckBox Name Check3
Caption Check3
TabIndex 13
Horizontal Scroll Bars Name HScroll1
Max 50
TabIndex 14
الشكل 12-4 النموذج frmTab (طور التصميم).
إدخال نص برنامج المفتاح Tab
تأكد من احتواء قسم التصاريح العامة على العبارة OptionExplicit:
'يجب التصريح عن كل المتحولات
Option Explicit
أدخل النص التالي ضمن الإجراء cmdExit_Click() للنموذج frm:
Private Sub cmdExit_Click()
End
End Sub
تنفيذ برنامج المفتاح Tab
نفّذ برنامج المفتاح Tab.
انقل تركيز لوحة المفاتيح من عنصر تحكم لآخر، بضغط المفتاح Tab، أو على مفاتيح الأسهم، لاحظ أن مفتاحي الأسهم اليميني واليساري يستخدمان لتحريك الزالقة عندما يوضع التركيز عند شريط التمرير.
أنهِ البرنامج بنقر الزر خروج.
الخاصية TabIndex
تحدد الخاصية TabIndex الترتيب الذي تستقبل عناصر التحكم وفقه تركيز لوحة المفاتيح. فمثلاً، إذا كان تركيز لوحة المفاتيح حالياً عند عنصر تحكم، وقيمة الخاصية TabIndex لهذا العنصر تساوي 5، يؤدي الضغط على المفتاح Tab إلى انتقال تركيز لوحة المفاتيح إلى العنصر الذي تساوي فيه قيمة الخاصية TabIndex إلى 6، بينما إذا كانت قيمة الخاصية TabIndex تساوي 5، فإن الضغط على Shift+Tab يؤدي إلى نقل تركيز لوحة المفاتيح إلى عنصر التحكم الذي تساوي قيمة الخاصية TabIndex فيه إلى 4.
يعمل ترتيب الانتقال وفق Tab بطريقة دائرية: فإذا كان عنصر التحكم الذي يمتلك حالياً تركيز لوحة المفاتيح يحمل أعلى قيمة للخاصية TabIndex، فإن الضغط مجدداً على Tab سيؤدي إلى انتقال تركيز لوحة المفاتيح، إلى العنصر الذي تساوي قيمة الخاصية TabIndex فيه إلى الصفر، وبالعكس عند الضغط على Shift + Tab وأنت في عنصر تحكم قيمة الخاصية TabIndex فيه تساوي الصفر، ينتقل تركيز لوحة المفاتيح إلى عنصر التحكم الذي يحمل أعلى قيمة للخاصية TabIndex.
ملاحظة
لا تتقبل بعض عناصر التحكم تركيز لوحة المفاتيح، مثالها عنصر تحكم اللافتة Label.
يُسند فيجول بيسك أرقام متسلسلة إلى الخاصية TabIndex، فهذه الخاصية لأول عنصر تساوي الصفر، وتساوي TabIndex للعنصر الذي يليه 1، وهكذا وعموماً تستطيع تغيير قيمة الخاصية TabIndex لتحديد الترتيب الذي يناسبك ضمن البرنامج.
برنامج التركيز
يستعرض برنامج التركيز، الطريقة التي تمكّن البرنامج من اكتشاف متى يمتلك عنصر التحكم أو يفقد تركيز لوحة المفاتيح.
التمثيل المرئي لبرنامج التركيز
سنبدأ كالعادة بطور التمثيل المرئي للنموذج البرنامج:
أنشئ مشروعاً جديداً من النوع Standard EXE، واحفظ نموذج المشروع بالاسم Focus.frm في الدليل C:\VB5Prg\Ch12 واحفظ ملف المشروع بالاسم Focus.Vbp في الدليل C:\VB5Prg\Ch12.
أنشئ النموذج طبقاً للجدول 12-5
يُفترض أن يظهر النموذج المكتمل كما في الشكل 12-5.
الجدول 12-5. جدول خصائص البرنامج frmFocus.
الكائن الخاصية القيمة
Form Name frmFocus
Caption برنامج التركيز
RightToLeft True
CommandButton Name cmdExit
Caption &خروج
RightToLeft True
CommandButton Name cmdLoad
Caption &تحميل
RightToLeft True
CommandButton Name cmdSave
Caption &حفظ
RightToLeft True
Label Name lblInfo
Alignment 2-Center
BorderStyle 1-Fixed Single
Caption (اجعله فارغاً)
RightToLeft True
Label Name LblTitle
Caption هل أضاع التركيز أم حصل عليه؟
RightToLeft True
TextBox Name txtUserArea
MultiLine True
Text (اجعله فارغاً)
RightToLeft True
الشكل 12-5 النموذج frmFocus (طور التصميم).
إدخال نص برنامج التركيز
أدخل العبارة OptionExplicit في قسم التصاريح العامة:
'يجب التصريح عن كل المتحولات
Option Explicit
أدخل النص التالي ضمن الإجراء cmdExit_Click():
Private Sub cmdExit_Click()
End
End Sub
أدخل النص التالي ضمن الإجراء txtUserArea_GotFocus():
Private Sub txtUserArea_GotFocus()
lblInfo.Caption = "لقد حصل مربع النص على التركيز"
End Sub
أدخل النص التالي ضمن الإجراء txtUserArea_LostFocus():
Private Sub txtUserArea_LostFocus()
lblInfo.Caption = "لقد أضاع مربع النص التركيز"
End Sub
تنفيذ برنامج التركيز
نفّذ برنامج التركيز.
انقل تركيز لوحة المفاتيح إلى مربع النص المدعو txtUserArea بالنقر داخله بواسطة الفأرة، أو باستخدام المفتاح Tab أو مفاتيح الأسهم.
تُظهر اللافتةlblInfo الرسالة التالية، عند انتقال تركيز لوحة المفاتيح إلى مربع النص.
لقد حصل مربع النص على التركيز
انقل تركيز لوحة المفاتيح بعيداً عن مربع النص txtUserArea، كأن تنقر على أحد الزرين حفظ أو تحميل.
تظهر اللافتة lblInfo الرسالة التالية، عند انتقال تركيز لوحة المفاتيح عن مربع النص.
لقد أضاع مربع النص التركيز
أنهِ البرنامج بنقر الزر خروج.
كيف يعمل برنامج التركيز
يستخدم البرنامج الحادثتين GotFocus (حصل على التركيز) و LostFocus (أضاع التركيز)، لاكتشاف ما إذا كان مربع النص قد استحوذ أو خسر تركيز لوحة المفاتيح.
نص الإجراء txtUserArea_GotFocus()
يُنفذ هذا الإجراء عند انتقال تركيز لوحة المفاتيح إلى مربع النص، ويُسند رسالة إلى الخاصية Caption للافتة lblInfo مضمونها، أن مربع النص يستحوذ الآن على تركيز لوحة المفاتيح:
Private Sub txtUserArea_GotFocus()
lblInfo.Caption = "لقد حصل مربع النص على التركيز"
End Sub
نص الإجراء txtUserArea_LostFocus()
يُنفذ هذا الإجراء عند ضياع تركيز لوحة المفاتيح من مربع النص، ويُسند رسالة إلى الخاصية Caption للافتة lblInfo مضمونها، أن مربع النص فقد تركيز لوحة المفاتيح:
Private Sub txtUserArea_LostFocus()
lblInfo.Caption = "لقد أضاع مربع النص التركيز"
End Sub
الخلاصة
تعلمنا في هذا الفصل، كيفية تحديد المفتاح المضغوط باستخدام الحوادث KeyDown وKeyUp وKeyPress، وتعلمنا أنه عندما تكون قيمة KeyPreview مساوية إلى True، فإن الإجراءات Form_KeyDown() وForm_KeyUp() وForm_KeyPress()، سوف تُنفذ، بغض النظر عن عنصر التحكم الذي يمتلك تركيز لوحة المفاتيح.
كما تعلمنا أيضاً دور الخاصية TabIndex وأثرها على ترتيب إنتقال تركيز لوحة المفاتيح جيئة وذهاباً، عند ضغط المفتاح Tab وشاهدنا أيضاً كيف تحصل الحادثتان GotFocus و LostFocus عندما يستحوذ عنصر تحكم ما على تركيز لوحة المفاتيح أو يفقده.
الفصل الثالث عشر
عناصر تحكم نظام الملفات
يركّز هذا الفصل على استخدام عناصر تحكم نظام الملفات، لكتابة برنامج يمكّن المستخدم من اختيار ملف ما من أي محرك أقراص.
توجد ثلاثة أنواع من عناصر التحكم هذه، وهي:
مربع سرد الأدلة Drive List Box.
مربع سرد الملفات File List Box.
مربع سرد السواقات Directory List Box.
تُستخدم الأنواع الثلاثة هذه، جنباً إلى جنب في برنامج نموذجي، يسمح للمستخدم باختيار الملفات من محركات الأقراص المختلفة. ليظهر مربع حوار مخصص، عندما يرغب المستخدم باختيار ملف ما، ويحوي هذا المربع على عناصر التحكم الثلاثة هذه (انظر الشكل 13-1).
يمكنك بعدها اختيار الملف المطلوب، بانتقاء محرك الأقراص المناسب من مربع سرد محركات الأقراص، ثم انتقاء دليل معين من مربع سرد الأدلة، وأخيراً اختيار ملف من مربع سرد الملفات.
الشكل 13-1 عناصر تحكم نظام الملفات الثلاث.
ملاحظة
تعلمنا من الفصل السادس، كيفية استخدام عنصر التحكم Common Dialog لإظهار مربع الحوار فتح، أو مربع الحوار حفظ. وكما رأينا من ذلك الفصل، فإن عملية إضافة عنصر تحكم مربعات الحوار الشائعة في البرامج بالغة السهولة.
إذاً ما هو الدافع إلى تعلم كيفية استخدام عناصر تحكم نظام الملفات ؟!.
سيتبين لك من هذا الفصل، أنها تعطي قدرة أكبر على التحكم، مما تعطيه مربعات الحوار الشائعة.
برنامج الحجم
سنكتب برنامجاً ندعوه برنامج الحجم، ويتضمن ثلاثة عناصر تحكم نظام الملفات، وتستطيع استخدامه لاختيار ملف ما من محرك أقراص، وإظهار حجم الملف المنتقى.
يُفترض في برنامج الحجم إنجاز ما يلي:
إظهار نموذج على الشاشة لاختيار الملفات عند تشغيل البرنامج، حسب ما يبينه الشكل13-2. يحتوي إطار برنامج الحجم، على مربع تحرير وسرد يدعى نوع الملف، ويقع تحت مربع سرد الملفات، ويمكّنك من اختيار نوع ملف محدد من لائحة أنواع الملفات الجاهزة.
إظهار لائحة محركات الأقراص المتوافرة، وتمكين المستخدم الاختيار من بينها.
إظهار لائحة الملفات الموجودة حالياً، في الدليل الذي يختاره المستخدم من مربع سرد الأدلة.
إظهار اسم الملف في مربع النص اسم الملف لدى اختياره من مربع لائحة الملفات.
إظهار حجم الملف المنتقى عند نقر الزر موافق. (انظر الشكل 13-3).
الشكل 13-2 برنامج الحجم.
الشكل 13-3 إظهار حجم الملف المنتقى.
إنهاء تنفيذ البرنامج لدى الضغط على المفتاح Esc.
إظهار الملفات المنتمية إلى النوع الذي تختاره من مربع التحرير والسرد (نوع الملف) فقط، فمثلاً عند اختيار الملفات النصية (*. TXT)، تظهر الملفات ذات الامتداد TXT فقط في مربع سرد الملفات.
التمثيل المرئي لبرنامج الحجم
سنبدأ كعادتنا بطور التمثيل المرئي لنموذج البرنامج:
أنشئ الدليل C:\VB5Prg\Ch13 لأننا سنستعمله لحفظ العمل المنجز.
أنشئ مشروعاً جديداً من النوع Standard EXE.
احفظ نموذج المشروع بالاسم Size.Frm في الدليل C:\VB5Prg\Ch13 واحفظ ملف المشروع بالاسم Size.Vbp في الدليل C:\VB5Prg\Ch13.
أنشئ النموذج طبقاً للجدول 13-1.
يُفترض أن يبدو النموذج المكتمل كما في الشكل13-2.
ملاحظة
يوضح الشكل 13-4 مواقع الرموز التي تمثل عناصر تحكم نظام الملفات الثلاث، في إطار مربع الأدوات. طبعاً قد تختلف هذه المواقع عمّا هو عليه في شريط الأدوات لدى المستخدم.
الشكل 13-4 رموز عناصر تحكم نظام الملف في إطار مربع الأدوات.
الجدول 13-1. جدول خصائص برنامج الحجم.
الكائن الخاصية القيمة
Form Name frmSize
Caption برنامج الحجم
RightToLeft True
CommandButton Name cmdOk
Caption &موافق
RightToLeft True
CommandButton Name cmdCancel
Caption إل&غاء
RightToLeft True
Directory List Box Name dirDirectory
Drive List Box Name drvDrive
File List Box Name filFiles
TextBox Name txtFileName
Text (اجعله فارغاً)
ComboBox Name cboFileType
Style 2-Dropdown List
Label Name lblFileName
Caption اسم الملف:
RightToLeft True
Label Name lblFileType
Caption نوع الملف:
RightToLeft True
Label Name lblDirectory
Caption الأدلة:
RightToLeft True
Label Name LblDirName
الكائن الخاصية القيمة
Caption (اجعله فارغاً)
BorderStyle 1-Fixed Single
RightToLeft True
Label Name lblDrive
Caption السواقة:
RightToLeft True
إدخال نص برنامج الحجم
أدخل العبارة Option Explicit في قسم التصاريح العامة للنموذج frmSize:
'يجب التصريح عن كل المتحولات
Option Explicit
اكتب النص التالي ضمن الإجراء Form_Load():
Private Sub Form_Load()
cboFileType.AddItem "All files (*.*)"
cboFileType.AddItem "Text files(*.TXT)"
cboFileType.AddItem "Doc files (*.DOC)"
cboFileType.ListIndex = 0
lblDirName.Caption = dirDirectory.Path
End Sub
اكتب النص التالي ضمن الإجراء drvDrive_Change():
Private Sub drvDrive_Change()
On Error GoTo DriveError
dirDirectory.Path = drvDrive.Drive
Exit Sub
DriveError:
MsgBox "Drive Error !", vbExclamation, "Error"
drvDrive.Drive = dirDirectory.Path
Exit Sub
End Sub
اكتب النص التالي ضمن الإجراء dirDirectory_Change():
Private Sub dirDirectory_Change()
filFiles.Path = dirDirectory.Path
lblDirName.Caption = dirDirectory.Path
End Sub
اكتب النص التالي ضمن الإجراء cboFileType_Click():
Private Sub cboFileType_Click()
Select Case cboFileType.ListIndex
Case 0
filFiles.Pattern = "*.*"
Case 1
filFiles.Pattern = "*.TXT"
Case 2
filFiles.Pattern = "*.DOC"
End Select
End Sub
أدخل النص التالي ضمن الإجراء filFiles_Click():
Private Sub filFiles_Click()
txtFileName.Text = filFiles.filename
End Sub
أدخل النص التالي ضمن الإجراء cmdOk_Click():
Private Sub cmdOk_Click()
Dim PathAndName As String
Dim FileSize As String
Dim Path As String
'
If txtFileName.Text = "" Then
MsgBox "يجب أن تختار ملفاً!", _
vbMsgBoxRight Or vbMsgBoxRtlReading, "برنامج الحجم"
Exit Sub
End If
If Right(filFiles.Path, 1) <> "\" Then
Path = filFiles.Path + "\"
Else
Path = filFiles.Path
End If
If txtFileName.Text = filFiles.filename Then
PathAndName = Path + filFiles.filename
Else
PathAndName = txtFileName.Text
End If
On Error GoTo FileLenError
'
FileSize = Str(FileLen(PathAndName))
MsgBox "حجم الملف " + PathAndName + ":هو " _
+ FileSize + " بايت",vbMsgBoxRight Or vbMsgBoxRtlReading,_
"برنامج الحجم"
Exit Sub
FileLenError:
MsgBox "لم أستطع إيجاد حجم الملف " + PathAndName, _
vbMsgBoxRight Or vbMsgBoxRtlReading, _
"برنامج الحجم"
Exit Sub
End Sub
أدخل النص التالي ضمن الإجراء filFiles_DblClick():
Private Sub filFiles_DblClick()
txtFileName.Text = filFiles.filename
cmdOk_Click
End Sub
أدخل النص التالي ضمن الإجراء cmdCancel():
Private Sub cmdCancel_Click()
End
End Sub
احفظ المشروع باختيار Save Project من القائمة File لفيجول بيسك.
تنفيذ برنامج الحجم
لنشاهد عمل برنامج الحجم:
نفّذ برنامج الحجم وتمرن على شتى عناصر التحكم التي تظهر على الشاشة.
لاحظ المظاهر التالية عند تشغيلك لبرنامج الحجم:
تظهر أدلة محرك الأقراص الذي تنتقيه، في مربع سرد الأدلة، حاول اختيار محرك أقراص من مربع سرد محركات الأقراص.
عند اختيار محرك أقراص غير جاهز، تظهر رسالة خطأ، ويسترجع مربع السرد قيمته الأصلية. فمثلاً لدى محاولتك القراءة من محرك الأقراص A ولم يكن هنالك قرص مرن، تظهر رسالة خطأ، ويسترجع مربع سرد المحركات قيمته الافتراضية (وهيC.
يؤدي النقر المزدوج على الدليل المطلوب في مربع سرد الأدلة إلى اختياره.
تظهر حال اختيار أحد الأدلة، ملفات ذلك الدليل في مربع سرد الملفات، ويظهر اسم الدليل الحالي فوق مربع سرد الأدلة.
يظهر اسم الملف في مربع النص المدعو اسم الملف حال توضع الإضاءة فوقه، في مربع سرد الملفات.
بعد اختيار نوع ملف مختلف، من المربع نوع الملف، يُظهر مربع سرد الملفات فقط الملفات التي تنتمي للنوع الذي اخترته. لاحظ أنك لا تستطيع الكتابة في منطقة النص لمربع التحرير والسرد، وذلك بسبب إسناد القيمة DropDown إلى الخاصية Style لمربع التحرير والسرد أثناء طور التصميم.
تظهر عند نقر الزر موافق رسالة تُعطي حجم الملف المنتقى.
يمكنك كتابة اسم الملف، في مربع النص اسم الملف بدلاً من انتقائه من مربع سرد الملفات.
يؤدي ضغط المفتاح Enter إلى نفس دور نقر الزر موافق وذلك بسبب إسناد القيمة True إلى الخاصية Default للزر موافق خلال زمن التصميم.
يؤدي ضغط المفتاح Esc إلى نفس دور نقر الزر إلغاء الذي أُسندَت القيمة True إليه أثناء زمن التصميم.
انقر الزر إلغاء لإنهاء برنامج الحجم.
كيف يعمل برنامج الحجم
تمتلك عناصر تحكم نظام الملفات - كباقى عناصر التحكم الأخرى- حوادث وخصائص. ويحدد نص إجراءات الحوادث المختلفة لها، كيف تتخاطب عناصر التحكم مع بعضها.
نص الإجراء Form_Load()
يُنفذ الإجراء Form_Load() آلياً عند تشغيل البرنامج. ويتم في هذا الإجراء تجهيز مربع التحرير والسرد cboFileType واللافتة lblDirName:
Private Sub Form_Load()
cboFileType.AddItem "All files (*.*)"
cboFileType.AddItem "Text files(*.TXT)"
cboFileType.AddItem "Doc files (*.DOC)"
cboFileType.ListIndex = 0
lblDirName.Caption = dirDirectory.Path
End Sub
تُستخدم الطريقة AddItem ثلاث مرات، لملء مربع cboFileType بثلاثة عناصر:
All files (*.*), Text files (*.TXT), Doc files (*.DOC)
إسناد القيمة صفر إلى الخاصيةListIndex لمربع نوع الملفات cboFileType، يجعلها تشير إلى أول بند من بنوده، ألا وهو البند All Files (*.*).
وأخيراً إسناد القيمة الابتدائية للخاصية Path لمربع سرد الأدلة، إلى الخاصية Caption للافتة lblDirName، وهي الدليل الحالي، وهكذا منذ بدء تشغيل البرنامج، تُظهر اللافتة LblDirName اسم الدليل الحالي.
نص الإجراء drvDrive_Change()
يُنفّذ الإجراء drvDrive_Change() آلياً، عند تغيير محرك الأقراص في مربع سرد المحركات. يجدّد هذا الإجراء الخاصية Path لمربع سرد الأدلة، بإسناد محرك الأقراص الجديد الذي تم اختياره إليها:
Private Sub drvDrive_Change()
On Error GoTo DriveError
dirDirectory.Path = drvDrive.Drive
Exit Sub
DriveError:
MsgBox "Drive Error !", vbExclamation, "Error"
drvDrive.Drive = dirDirectory.Path
Exit Sub
End Sub
قبل أن يغيّر الإجراء، الخاصية Path لمربع سرد الأدلة، كتبنا سطر مصيدة الأخطاء. تُعتبر مصيدة الأخطاء هذه لازمة، لأن تغيير مسار Path مربع سرد الأدلة، قد ينجم عنه خطأ ما.
فمثلاً، قد يغير المستخدم مربع سرد السواقات، إلى محرك الأقراص A:، إلا أن A: ليس جاهزاً في تلك اللحظة. فيتسبب تغيير المسار Path في مربع سرد الأدلة إلى A: بظهور خطأ. ولتلافي حصول خطأ أثناء زمن التنفيذ، وُضعت المصيدة الممثلة بالعبارة التالية:
On Error Go To DriveError
فإذا ظهر خطأ ما الآن أثناء تنفيذ هذه العبارة:
dirDirectory.Path = drvDrive.Drive
فسيعمل فيجول بيسك على نقل تنفيذ البرنامج إلى نص البرنامج الواقع تحت اللافتة
DriveError:. ليُظهر نص البرنامج الوارد تحت هذه اللافتة، رسالة خطأ ويسترجع القيمة الأصلية لمحرك الأقراص، وذلك باستخدام العبارة التالية:
drvDrive.Drive = dirDirectory.Path
لاحظ أن قيمة dirDirectory.Path لم تتغير (أي ما زالت محافظة على قيمتها الأصلية)، لأن العبارة التي تسببت في الخطأ (في حال حدوثه) لم تنفذ بعد.
لا يحصل خطأ، إذا كان محرك الأقراص المنتقى جاهزاً، وبالتالي يتغير مسار Path مربع سرد الأدلة، إلى محرك الأقراص المنتقى، ونتيجة ذلك، يستعرض مربع سرد الأدلة، الأدلة الموجودة في محرك الأقراص الذي انتقيته.
نص الإجراء dirDirectory_Change()
يُنفذ الإجراء dirDirectory_Change()، عند تبديل الدليل الحالي في مربع سرد الأدلة. يُحدّث نص هذا الإجراء، الخاصية Path لمربع سرد الملفات، ويُسند الدليل الجديد إلى الخاصية Caption للافتة lblDirName:
Private Sub dirDirectory_Change()
filFiles.Path = dirDirectory.Path
lblDirName.Caption = dirDirectory.Path
End Sub
يُظهر مربع سرد الملفات، الملفات المحتواة في الدليل الذي اختاره المستخدم، نتيجة لإسناد الخاصية Path لمربع سرد الأدلة، إلى الخاصية Path لمربع سرد الملفات.
نص الإجراء cboFileType_Click()
يُنفذ هذا الإجراء، نتيجة اختيار نوع ملفات آخر، من مربع نوع الملفات cboFileType، يُحدّث هذا الإجراء الخاصية Pattern لمربع سرد الملفات تبعاً لنوع الملف المنتقى:
Private Sub cboFileType_Click()
Select Case cboFileType.ListIndex
Case 0
filFiles.Pattern = "*.*"
Case 1
filFiles.Pattern = "*.TXT"
Case 2
filFiles.Pattern = "*.DOC"
End Select
End Sub
تُستخدم العبارة الشرطية Select Case لتحديد نوع الملف الذي اخترته من مربع سرد أنواع الملفات cboFileType. لنفترض أن الإجراء Form_Load() ملأ المربع cboFileType بثلاثة بنود هي:
All Files (*.*) , Text Files(*.TXT) , Doc Files(*.DOC)
تُنفذ عبارة Case الموافقة للبند الذي اخترته من مربع نوع الملفات، فمثلاً لدى اختيار البند الثاني Text Files (*.TXT) تنفذ العبارة التالية:
filFiles.Pattern = "*.TXT"
ونتيجة لذلك، يُظهر مربع سرد الملفات، فقط الملفات ذات الامتداد TXT.
نص الإجراء filFiles_Click()
يُنفذ الإجراء filFiles_Click() عند اختيار ملف ما من الملفات الموجودة في مربع سرد الملفات. يُحدّث نص هذا الإجراء، مربع النص txtFileName باسم الملف المنتقى:
Private Sub filFiles_Click()
txtFileName.Text = filFiles.filename
End Sub
نص الإجراء cmdOk_Click()
يُنفذ الإجراء cmdOk_Click() عند نقر الزر موافق، ويُظهر نص هذا الإجراء حجم الملف الذي تم اختياره للتو:
Private Sub cmdOk_Click()
Dim PathAndName As String
Dim FileSize As String
Dim Path As String
'عند عدم اختيار ملف أخبر المستخدم وأنه هذا الإجراء
If txtFileName.Text = "" Then
MsgBox "يجب أن تختار ملفاً!", _
vbMsgBoxRight Or vbMsgBoxRtlReading, _
"برنامج الحجم"
Exit Sub
End If
'\تحقق من أن المسار ينتهي بالرمز
If Right(filFiles.Path, 1) <> "\" Then
Path = filFiles.Path + "\"
Else
Path = filFiles.Path
End If
If txtFileName.Text = filFiles.filename Then
PathAndName = Path + filFiles.filename
Else
PathAndName = txtFileName.Text
End If
On Error GoTo FileLenError
'
FileSize = Str(FileLen(PathAndName))
MsgBox "حجم الملف " + PathAndName + ":هو " _
+ FileSize + " بايت",vbMsgBoxRight Or vbMsgBoxRtlReading,_
"برنامج الحجم"
Exit Sub
FileLenError:
MsgBox "لم أستطع إيجاد حجم الملف " + PathAndName, _
vbMsgBoxRight Or vbMsgBoxRtlReading, "برنامج الحجم"
Exit Sub
End Sub
أول شيء يفعله الإجراء، هو التأكد من أنك اخترت ملفاً ما، وذلك بمقارنة الخاصية Text لمربع النص txtFileName مع رمز الفراغ (""). فإذا تحقق الشرط تظهر رسالة مفادها أنك لم تختر ملفاً ويتم إنهاء الإجراء:
If txtFileName.Text = "" Then
MsgBox "يجب أن تختار ملفاً!", _
vbMsgBoxRight Or vbMsgBoxRtlReading, _
"برنامج الحجم"
Exit Sub
End If
أما إذا تأكد الإجراء من أن المستخدم انتقى ملفاً، فيتم عند ذلك تحديث المتحول Path بإسناد مسار الملف المنتقى إليه.
يُستخدم التابع الوظيفي Right() للتأكد بأن الرمز الواقع أقصى يمين المسار المنتقى، هوالرمز "\"، فإذا لم يكن كذلك فإنه يضيفه إلى المتحول Path.
If Right(filFiles.Path, 1) <> "\" Then
Path = filFiles.Path + "\"
Else
Path = filFiles.Path
End If
وبعد أن يصبح المتحول Path جاهزاً، يغدو بالوسع تحديث قيمة المتحول PathAndName بواسطة عبارة If شرطية:
If txtFileName.Text = filFiles.filename Then
PathAndName = Path + filFiles.filename
Else
PathAndName = txtFileName.Text
End If
تتحقق هذه العبارة، من تطابق الاسم المضاء في مربع سرد الملفات، مع الاسم الموجود في مربع النص txtFileName.
فإذا كان هنالك اختلاف، فهذا يعني أنك كتبت يدوياً مسار واسم الملف، لهذا يتم إسناد الشيء الذي كتبته إلى المتحول PathAndName. أما إذا تطابق الاسمان، فعندها تُسند السلسلة التالية إلى المتحول PathAndName:
Path + filFile.filename
وبعد تجهيز المتحول PathAndName، يصبِح بالوسع استخدام التابع الوظيفي FileLen() لإيجاد حجم الملف، وباعتبار أن استخدام التابع الوظيفي FileLen() قد يؤدي إلى حدوث خطأ أثناء زمن التنفيذ (كأن تدخل اسم ملف غير موجود)، فقد وُضعَت مصيدة للخطأ بواسطة العبارة التالية:
On Error GoTo FileLenError
فإذا وقع خطأ أثناء تنفيذ العبارة التالية:
FileSize = Str(FileLen(PathAndName))
ينتقل التنفيذ إلى العبارة الواقعة تحت اللافتة FileLenError:، والتي تُظهر بدورها رسالة خطأ، ويتم بعدها إنهاء البرنامج:
FileLenError:
MsgBox "لم أستطع إيجاد حجم الملف " + PathAndName, _
vbMsgBoxRight Or vbMsgBoxRtlReading, "برنامج الحجم"
Exit Sub
أما إذا لم يتسبب التابع الوظيفي FileLen() بوقوع خطأ، فعند ذلك يتم إظهار حجم الملف على الشاشة وإنهاء الإجراء:
MsgBox "حجم الملف " + PathAndName + ":هو " _
+ FileSize + " بايت",vbMsgBoxRight Or vbMsgBoxRtlReading,_
"برنامج الحجم"
Exit Sub
نص الإجراء filFiles_DblClick()
يُنفذ هذا الإجراء، عند النقر المزدوج على أحد الملفات الموجودة في مربع سرد الملفات. يُسند نص هذا الإجراء، اسم الملف الذي تم النقر المزدوج عليه، إلى مربع النص txtFileName ويُنفذ الإجراء cmdOk_Click():
Private Sub filFiles_DblClick()
txtFileName.Text = filFiles.filename
cmdOk_Click
End Sub
نص الإجراء cmdCancel_Click()
يُنفذ هذا الإجراء عند نقر الزر إلغاء، وينهي تنفيذ البرنامج:
Private Sub cmdCancel_Click()
End
End Sub
سمات مربع لائحة الملفات
يمكن لأي ملف امتلاك أي من السمات الأربعة التالية:
Read Only للقراءة فقط: الملف الذي يحمل هذه السمة، معد للقراءة فقط ولا يمكن تعديله أو حذفه أو الكتابة فيه ما لم يتم إزالة هذه السمة عنه.
Hidden مخفي: لا يتمكن أمر نظام التشغيل DOS المدعو Dir، من إظهار الملفات التي تحمل هذه السمة.
System تابع للنظام: تمتلك ملفات نظام التشغيل DOS هذه السمة، وهذه الملفات لا يمكن حذفها أو تعديلها بالكتابة عليها، ما لم تزال عنها هذه السمة.
Archive تمت أرشفته: تُوضع هذه السمة على الملفات التي أجري عليها نسخ احتياطي بواسطة الأمر BackUp (أو أي من خدمات النسخ الاحتياطي الأخرى). وتستخدم هذه السمة كراية، للدلالة على أن الملف تم نسخه احتياطياً. يتم إزالة هذه السمة آلياً من قبل النظام، عند أي تعديل للملف، للدلالة على أنه قد أجري عليه تعديل، ويحتاج إلى إجراء نسخ احتياطي مرة ثانية.
تُحدِد السمات Attribute لمربع سرد الملفات، أي الملفات سيتم إظهارها في مربع سرد الملفات، وذلك بالاعتماد على سمات الملفات. علماً أن السمات لمربع سرد الملفات هي Read Only وArchive وNormal وSystem وHidden، ويمكن أن تحمل كل منها إحدى القيمتين True أو False. فمثلاً لإظهار الملفات المعدة للقراءة فقط، ستحتاج إلى تكليف سمات مربع سرد الملفات المدعو filMyFiles كما يلي:
filMyFiles.ReadOnly = True
filMyFiles.Archive = False
filMyFiles.Normal = False
filMyFiles.System = False
filMyFiles.Hidden = False
برنامج اختيار ملف
أوضح برنامج الحجم كيفية بناء نموذج يسمح لك باختيار ملف من محرك أقراص. وباعتبار أن الكثير من البرامج تحتاج إلى مثل هذا النموذج، فإنها لفكرة حسنة أن نبني نموذجاً لمربع حوار عام الغرض، يُنجز عملية اختيار الملفات من محركات الأقراص والأدلة الفرعية.
يوضح برنامج اختيار ملف، كيفية بناء واستخدام مثل هذا النموذج والذي ندعوه هنا اختيار ملف:
قبل المباشرة بكتابة برنامج اختيار ملف، لابد لنا من تحديد الأعمال التي يتوجب عليه إنجازها:
عند تنفيذ البرنامج، يجب أن يظهر شريط قوائم يحمل القائمة ذات العنوان ملف (انظر الشكل 13-5).
الشكل 13-5 برنامج اختيار ملف.
تملك القائمة ملف بندين هما: اختيار ملف و خروج (انظر الشكل 13-6).
الشكل 13-6 بنود القائمة ملف.
يظهر مربع الحوار اختيار ملف عند اختيار بند القائمة اختيار ملف من القائمة ملف (الشكل 13-7). يُغلق مربع الحوار بعد اختيار ملف ويُظهر الملف المنتقى.
يتم إنهاء تنفيذ البرنامج، باختيار خروج من القائمة ملف.
الشكل 13-7 مربع الحوار اختيار ملف.
التمثيل المرئي لبرنامج اختيار ملف
سنبدأ كعادتنا بطور التمثيل المرئي لنموذج برنامج اختيار ملف:
أنشئ مشروعاً جديداً من النوع Standard EXE.
احفظ نموذج المشروع بالاسم Select.Frm في الدليل C:\VB5Prg\Ch13، واحفظ ملف المشروع بالاسم Select.Vbp في الدليل ذاته.
أنشئ النموذج طبقاً للجدولين13-2 و 13-3.
يُفترض أن يظهر النموذج المكتمل كما في الشكل13-5.
الجدول 13-2. جدول خصائص برنامج اختيار ملف.
الكائن الخاصية القيمة
Form Name frmSelect
Caption برنامج اختيار ملف
RightToLeft True
Menu (انظر الجدول 13-3) (انظر الجدول 13-3)
الجدول 13-3. جدول قائمة النموذج frmSelect.
العنوان الاسم
ملف mnuFile
…&اختيار ملف mnuSelectFile
…- mnuSep1
…&خروج mnuExit
ينبغي علينا الآن، تشكيل نموذج آخر وتسميته GetFile.Frm، لأن هذا النموذج سيُستخدم كمربع حوار عام الغرض، ويدعى اختيار ملف.
يُعتبر النموذج GetFile.Frm متطابقاً إلى درجة كبيرة مع النموذج Size.Frm، لهذا فبدلاً من إعادة كتابته، سوف ننسخ الملف Size.Frm إلى نفس الدليل الذي يقع فيه الملف Select.frm، وسنغير الاسم من Size.frm إلى GetFile.frm، ثم سنضيفه (أي GetFile.Frm) إلى المشروع Select.Vbp.
إليك الآن طريقة إنجاز ذلك:
استخدم مستكشف ويندوز لتشكيل نسخة أخرى عن الملف Size.frm، وسمها بالاسم GetFile.frm.
يُفترض أن يحوي الدليل C:\VB5Prg\Ch13 الآن، الملفين Size.frm و GetFile.frm.
أضف الملف GetFile.Frm إلى المشروع Select.Vbp باتباع الخطوات التالية:
ارجع إلى فيجول بيسك.
اختر Add Form من القائمة Project.
يستجيب فيجول بيسك بإظهار مربع الحوار Add Form.
اختر الصفحة Existing في مربع الحوار Add Form، (لإنا نرغب بإضافة نموذج موجود إلى المشروع(.
استخدم الصفحة Existing لمربع الحوار Add Form لاختيار الملف GetFile.frm من الدليل C:\VB5Prg\Ch13 ثم انقر الزر فتح.
يستجيب فيجول بيسك بإضافة الملف GetFile.frm إلى المشروع Select.Vbp ويمكنك إظهار الإطار Project والتحقق من أن المشروع Select.VBP يحوي الآن نموذجين هما:
Select.frm.
GetFile.frm.
حتى هذه النقطة، يعتبر النموذج GetFile.Frm متطابق تماماً مع النموذج.
يتوجب عليك تغيير الخاصية Name والخاصية Caption للنموذج GetFile.Frm كما يلي:
اختر النموذج GetFile.frm بوضع الإضاءة على البند GetFile.frm في إطار المشروع، ثم انقر الرمز View Object (يوجد رمز هذا الزر في الزاوية اليسرى العليا من إطار المشروع).
غيّر الخاصية Name للنموذج GetFile.frm من frmSize إلى frmGetFile.
غيّر الخاصية Caption للنموذج GetFile.frm من برنامج الحجم، إلى اختيار ملف.
انتهى الآن طور التمثيل المرئي للنموذج frmGetFile. ويُفترض أن يظهر هذا النموذج كما في الشكل 13-7.
إدخال نص البرنامج اختيار ملف
يمتلك برنامج اختيار ملف الآن نموذجين: frmSelect و frmGetFile. سندخل عبر الفقرات التالية نص برنامج إجراءات هذين النموذجين. (لاحظ أن نصوص وإجراءات النموذج frmGetFile جاهزة مسبقاً، لأننا كتبناها أثناء تصميم النموذج frmSize).
إدخال نص النموذج frmSelect
أدخل النص التالي في قسم التصاريح العامة للنموذج frmSelect:
'يجب التصريح عن كل المتحولات
Option Explicit
أدخل النص التالي في الإجراء Form_Load() للنموذج frmSelect:
Private Sub Form_Load()
Load frmGetFile
frmGetFile.cboFileType.AddItem "All files(*.*)"
frmGetFile.cboFileType.AddItem "Text files(*.TXT)"
frmGetFile.cboFileType.AddItem "Doc files(*.DOC)"
frmGetFile.cboFileType.ListIndex = 0
End Sub
أدخل النص التالي ضمن الإجراء mnuSelectFile_Click():
Private Sub mnuSelectFile_Click()
frmGetFile.Caption = "اختيار ملف"
frmGetFile.Show 1
If frmGetFile.Tag = "" Then
MsgBox "لم تختر أي ملف"
Else
MsgBox "لقد اخترت الملف" + frmGetFile.Tag
End If
End Sub
أدخل النص التالي في الإجراء mnuExit_Click() للنموذج frmSelect:
Private Sub mnuExit_Click()
End
End Sub
إدخال نص النموذج frmGetFile
اتفقنا أن هذا النموذج مكتوب ومكتمل، فقد نسخناه عن نموذج المثال السابق (أي النموذج frmSize) ولا يلزمه سوى بعض التعديلات والإضافات.
أدخل النص التالي في الإجراء Form_Load() للنموذج frmGetFile بحيث يبدو كالتالي:
Private Sub Form_Load()
LblDirName.Caption = dirDirectory.Path
End Sub
سنحافظ على نص الإجراء drvDrive_Change() على حاله، لهذا تأكد فقط أنه مطابق لما يلي:
Private Sub drvDrive_Change()
On Error GoTo DriveError
dirDirectory.Path = drvDrive.Drive
Exit Sub
DriveError:
MsgBox "Drive Error !", vbExclamation, "Error"
drvDrive.Drive = dirDirectory.Path
Exit Sub
End Sub
سنحافظ على نص الإجراء dirDirectory_Click() على حاله، لهذا تأكد فقط من تطابقه مع ما يلي:
Private Sub dirDirectory_Change()
filFiles.Path = dirDirectory.Path
LblDirName.Caption = dirDirectory.Path
End Sub
عدّل الإجراء cboFileType_Click() بحيث يبدو كما يلي:
Private Sub cboFileType_Click()
Dim PatternPos1 As Integer
Dim PatternPos2 As Integer
Dim PatternLen As Integer
Dim Pattern As String
PatternPos1 = InStr(1, cboFileType.Text, "(") + 1
PatternPos2 = InStr(1, cboFileType.Text, ")") - 1
PatternLen = PatternPos2 - PatternPos1 + 1
Pattern = Mid(cboFileType.Text, PatternPos1, PatternLen)
filFiles.Pattern = Pattern
End Sub
سنحافظ على نص الإجراء filFiles_Click() بدون تغير، تأكد فقط من تطابقه مع ما يلي:
Private Sub filFiles_Click()
txtFileName.Text = filFiles.filename
End Sub
عدّل نص الإجراء cmdOk_Click() للنموذج frmGetFile بحيث يصبح كما يلي:
Private Sub cmdOk_Click()
Dim PathAndName As String
Dim Path As String
'
If txtFileName.Text = "" Then
MsgBox "يجب أن تختار ملفاً!", _
vbMsgBoxRight Or vbMsgBoxRtlReading, _
"برنامج الحجم"
Exit Sub
End If
If Right(filFiles.Path, 1) <> "\" Then
Path = filFiles.Path + "\"
Else
Path = filFiles.Path
End If
If txtFileName.Text = filFiles.FileName Then
PathAndName = Path + filFiles.FileName
Else
PathAndName = txtFileName.Text
End If
frmGetFile.Tag= PathAndName
frmGetFile.Hide
End Sub
سنحافظ على نص filFiles_DblClick() بدون تغيير، لهذا تأكد من مطابقته لما يلي:
Private Sub filFiles_DblClick()
txtFileName.Text = filFiles.filename
cmdOk_Click
End Sub
عدّل الإجراء cmdCancel_Click() للنموذج frmGetFile بحيث يصبح كما يلي:
Private Sub cmdCancel_Click()
frmGetFile.Tag = ""
frmGetFile.Hide
End Sub
احفظ المشروع بالطريقة المعتادة.
تنفيذ برنامج اختيار ملف
اختر العنصر Select File من القائمة File.
يظهر مربع الحوار المدعو اختيار ملف على الشاشة بصفة مشروطة Modal، وبهذا طالما أن مربع الحوار مفتوح، لا يمكنك العودة إلى البرنامج. وسوف تسمع صوت رنين Beep إذا نقرت بواسطة الفأرة مثلاً على نافذة البرنامج.
تمرن على شتى عناصر التحكم الموجودة في مربع الحوار اختيار ملف.
أنهِ برنامج اختيار ملف، باختيار خروج من القائمة ملف.
كيف يعمل برنامج اختيار ملف
يستخدم برنامج اختيار ملف، النموذج frmGetFile كمربع حوار Modal، عندما يحتاج إلى تزويده باسم ملف.
إجراءات النموذج frmSelect
تشرح الفقرتان التاليتان كيفية عمل الإجراءين Form_Load() وmnuSelectFile_Click() للنموذج frmSelect.
نص الإجراء Form_Load()
يُنفَذ هذا الإجراء عند بدء تشغيل البرنامج، ويتم بواسطته تحميل مربع الحوار frmGetFile وتجهيز مربع أنواع الملفات cboFileType التابع له:
Private Sub Form_Load()
Load frmGetFile
frmGetFile.cboFileType.AddItem "All files(*.*)"
frmGetFile.cboFileType.AddItem "Text files(*.TXT)"
frmGetFile.cboFileType.AddItem "Doc files(*.DOC)"
frmGetFile.cboFileType.ListIndex = 0
End Sub
تُستخدم عبارة Load لتحميل مربع الحوار frmGetFile إلى الذاكرة.
لا يؤدي تحميل النموذج في الذاكرة، إلى إظهاره على الشاشة، وإنما يحمّل إلى الذاكرة بغية تمكين الإجراءات الأخرى من إظهاره بدون تأخير، وإمكانية التعامل مع عناصره أيضاً.
يجُهّز الإجراء بعد فراغه من تحميل مربع الحوار frmGetFile، مربع أنواع الملفات cboFileType للنموذج frmGetFile، فيملؤه بثلاثة بنود:
All Files (*.*).
Text File (*.TXT).
DOC Files (*.Doc).
ثم يتم إسناد القيمة صفر إلى الخاصية ListIndex للمربع cboFileType، للدلالة على إظهار أول بند من هذه البنود وهو All Files (*.*).
نص الإجراء mnuSelectFile _Click()
يُنفذ هذا الإجراء عند اختيار البند اختيار ملف من القائمة ملف، يُظهر هذا الإجراء النموذج frmGetFile كمربع حوار محدد أو مشروط (Modal)، ثم يستخدم مربع الحوار لإيجاد الملف الذي اختاره المستخدم من خَرْج مربع الحوار. يُقدَم خَرْج مربع الحوار (اسم الملف الذي اختاره المستخدم) عبر الخاصية Tag للنموذج frmGetFile:
Private Sub mnuSelectFile_Click()
frmGetFile.Caption = "اختيار ملف"
frmGetFile.Show 1
If frmGetFile.Tag = "" Then
MsgBox "لم تختر أي ملف"
Else
MsgBox "لقد اخترت الملف" + frmGetFile.Tag
End If
End Sub
تُسنِد العبارة الأولى في الإجراء، العنوان اختيار ملف إلى الخاصية Caption للنموذج frmGetFile:
frmGetFile.Caption = "إختيار ملف"
ثم يلي ذلك إظهار النموذج على الشاشة كمربع حوار محدد أو مشروط (Modal)، وذلك باستخدام الطريقة Show:
frmGetFile.Show 1
بما أن القيمة 1 تمثل قيمة الوسيط Style للطريقة Show، فإن هذا يعنى يعني أن مربع الحوار، سوف يظهر كنموذج مشروط (Modal).
يُسند نص برنامج النموذج frmGetFile اسم الملف المنتقى، إلى الخاصية Tag لهذا النموذج.
وعند عدم اختيار ملف (أو نقر الزر إلغاء مثلاً)، فإن الخاصية Tag تُسنَد لها سلسلة خالية (Null).
لذلك تُفحص قيمة الخاصية Tag، فإذا احتوت على سلسلة نصية، كان ذلك هو اسم الملف المنتقى، ويتم عرضه في رسالة للمستخدم، أما إذا احتوت على سلسلة خالية Null، فهذا يعني أن المستخدم لم يختر ملفاً أو أنه نقر الزر إلغاء، وفي كلتا الحالتين، تُعرض رسالة على المستخدم، تفيد بأنه لم يختر ملفاً:
If frmGetFile.Tag = "" Then
MsgBox "لم تختر أي ملف"
Else
MsgBox "لقد اخترت الملف" + frmGetFile.Tag
End If
إجراءات النموذج frmGetFile
توضح الفقرات القادمة عمل نصوص إجراءات النموذج frmGetFile.
نص الإجراء Form_Load()
يُنفّذ الإجراء Form_Load() عند تحميل النموذج frmGetFile. يجدّد هذا الإجراء الخاصية Caption للافتة lblDirName، بتكليفها قيمة المسار Path لمربع سرد الأدلة:
Private Sub Form_Load()
lblDirName.Caption = dirDirectory.Path
End Sub
نص الإجراء drvDrive_Change()
نص هذا الإجراء هو نفس نص الإجراء drvDrive_Change() في برنامج الحجم.
نص الإجراء dirDirectory_Change()
نص هذا الإجراء مطابق لنص الإجراء dirDirectory_Change() في برنامج الحجم.
نص الإجراء cboFileType_Click()
يُنفّذ الإجراء cboFileType_Click() عند إجراء اختيار من المربع cboFileType، ويُجدّد نص هذا الإجراء، الخاصية Pattern لمربع سرد الملفات:
Private Sub cboFileType_Click()
Dim PatternPos1 As Integer
Dim PatternPos2 As Integer
Dim PatternLen As Integer
Dim Pattern As String
PatternPos1 = InStr(1, cboFileType.Text, "(") + 1
PatternPos2 = InStr(1, cboFileType.Text, ")") - 1
PatternLen = PatternPos2 - PatternPos1 + 1
Pattern = Mid(cboFileType.Text, PatternPos1, PatternLen)
filFiles.Pattern = Pattern
End Sub
تحتوي الخاصية Text لمربع سرد أنواع الملفات cboFileType (cboFileType.Text) على نوع الملف الذي اخترته.
فمثلاً، إذا كانت cboFileType.Text مساوية إلى Text Files (*.TXT)، عندها تكون الخاصية Pattern تساوي *.TXT.
يعمل الإجراء على تحديد موقع أول حرف من أحرف العينة (التي تساوي *.TXT)، وذلك بتحديد موقع رمز أول قوس هلالى افتتاحى يصادفه، وإضافة واحد إليه:
PatternPos1 = InStr(1, cboFileType.Text, "(") + 1
وبهذه الطريقة يتمكن من معرفة موقع الرمز (*).
بشكل مماثل، يحدد الإجراء موقع آخر حرف من أحرف العينة (التي تساوي *.TXT)، وذلك بتحديد موقع رمز أول قوس هلالي إغلاقي يصادفه، وإنقاص واحد منه:
PatternPos2 = InStr(1, cboFileType.Text, ")") - 1
ثم يحسب طول العينة، بطرح قيمة المتحول PatternPos1 من قيمة المتحول PatternPos2، ثم يجمع الناتج مع الواحد أي:
PatternLen = PatternPos2 - PatternPos1 + 1
وأخيراً، يستخلص نص العينة، باستخدام التابع الوظيفي Mid():
Pattern = Mid(cboFileType.Text, PatternPos1, PatternLen)
تُسنِد العبارة الأخيرة في الإجراء، العينة المستخلصة، إلى الخاصية Pattern لمربع سرد الملفات.
filFiles.Pattern = Pattern
ونتيجة الأمر، يُظهر مربع سرد الملفات، الملفات التي تطابق العينة المستخلصة فقط.
نص الإجراء filFiles_Click()
نص هذا الإجراء هو نفس نص الإجراء filFiles_Click() في برنامج الحجم.
نص الإجراء cmdOk_Click()
ينفذ هذا الإجراء عند النقر بالفأرة على الزر موافق:
Private Sub cmdOk_Click()
Dim PathAndName As String
Dim Path As String
If txtFileName.Text = "" Then
MsgBox "يجب أن تختار ملفاً!", _
vbMsgBoxRight Or vbMsgBoxRtlReading, _
"برنامج الحجم"
Exit Sub
End If
If Right(filFiles.Path, 1) <> "\" Then
Path = filFiles.Path + "\"
Else
Path = filFiles.Path
End If
If txtFileName.Text = filFiles.FileName Then
PathAndName = Path + filFiles.FileName
Else
PathAndName = txtFileName.Text
End If
frmGetFile.Tag= PathAndName
frmGetFile.Hide
End Sub
كما تلاحظ، هذا الإجراء مشابه كثيراً للإجراء cmdOk_Click() في برنامج الحجم، وأول شيء يفعله الإجراء هو التأكد من اختيار ملف، وذلك بمقارنة الخاصية Text لمربع النص txtFileName مع السلسلة الخالية Null. فإذا حدث تطابق، فهذا يعني أن المستخدم لم ينتق شيئاً وتظهر رسالة خطأ وينتهي الإجراء:
If txtFileName.Text = "" Then
MsgBox "يجب أن تختار ملفاً!", _
vbMsgBoxRight Or vbMsgBoxRtlReading, _
"برنامج الحجم"
Exit Sub
End If
وبعد التحقق من اختيار ملف، يُحدّث المتحول Path، بإسناد مسار الملف المنتقى إليه (اسم الدليل). يُستخدم التابع الوظيفي Right() للتحقق من أن آخر رمز في مسار الملف المنتقى، هو الرمز (\)، فإذا لم يكن كذلك، فلا بد من إضافته إلى نهاية المسار:
If Right(filFiles.Path, 1) <> "\" Then
Path = filFiles.Path + "\"
Else
Path = filFiles.Path
End If
تعتبر العبارة السابقة لازمة، لأن الخاصية filFiles.Path تحتوي على الرمز (\) إضافة لحرف محرك الأقراص، وذلك عند اختيار ملف من الدليل الرئيسي لمحرك الأقراص (مثلاً C:\).
أما عند اختيار الملف من مكان آخر غير الدليل الرئيسي، فلن تحتوي الخاصية filFiles.Path على الرمز (\) في نهايته (ستكون مثلاً C:\TRY بدلاً من C:\TRY\)، ولهذا لا بد من استخدام عبارة الشرط If لضمان وجود الرمز (\) بغض النظر عن مكان اختيار الدليل.
يُصبح بالإمكان تحديث المتحول PathAndName، حالما يصبح المتحول Path جاهزاً. وحسبما يتضح من اسم المتحول PathAndName فإنه يفترض أن يحوي على الاسم الكامل للملف (أي المسار إضافة إلى اسم الملف). تستخدم عبارة If لإسناد الاسم الكامل للملف إلى المتحول PathAndName:
If txtFileName.Text = filFiles.FileName Then
PathAndName = Path + filFiles.FileName
Else
PathAndName = txtFileName.Text
End If
تتحقق عبارة If هذه بأن الملف المضاء حالياً في مربع سرد الملفات، هو نفسه الملف الوارد في مربع النص اسم الملف. فإذا لم يكن التطابق موجوداً فهذا يعني أن المستخدم أدخل المسار واسم الملف يدوياً، ولهذا يتم تحديث المتحول PathAndName، وإسناد السلسلة التي أدخلها المستخدم إليه.
أما عند حدوث التطابق، فستسند السلسلة Path + filFiles.FileName إلى المتحول PathAndName.
تُستخدم قيمة المتحول PathAndName بعد ذلك، لإسنادها إلى الخاصية Tag للنموذج frmGetFile:
frmGetFile.Tag = PathAndName
تُستخدم الخاصية Tag للنموذج لحفظ خرْج النموذج frmGetFile.
يعلم الإجراء الذي أظهر النموذج frmGetFile، بواسطة هذه الخاصية frmGetFile.Tag، اسم ومسار الملف الذي اختاره المستخدم.
تُزيل آخر عبارة في الإجراء، النموذج من الشاشة، بواسطة الطريقة Hide:
frmGetFile.Hide
تقوم الطريقة Hide بإخفاء النموذج فقط من الشاشة، دون إزالته من الذاكرة.
وتعود السيطرة إلى الإجراء الذي أظهر النموذج frmGetFile، لإكمال تنفيذ باقي تعليماته.
نص الإجراء filFiles_DblClick()
نص هذا الإجراء يطابق تماماً ذاك الموجود في برنامج الحجم.
نص الإجراء cmdCancel_Click()
يُنفذ الإجراء cmdCancel_Click() عند نقر الزر إلغاء:
Private Sub cmdCancel_Click()
frmGetFile.Tag = ""
frmGetFile.Hide
End Sub
اتفقنا أن الخاصية Tag تُستخدم للاحتفاظ بمسار واسم الملف المنتقى. تُسند سلسلة خالية Null إلى هذه الخاصية، وذلك لأن المستخدم نقر الزر إلغاء، بمعنى أنه أراد الخروج دون اختيار ملف معين.
frmGetFile.Tag = ""
تُزيل آخر عبارة في الإجراء النموذج frmGetFile من الشاشة باستخدام الطريقة Hide:
frmGetFile.Hide
وبعد تنفيذ هذه العبارة، يُزال النموذج frmGetFile من الشاشة، وتعود السيطرة ثانية إلى الإجراء الذي أظهر النموذج frmGetFile.
الخلاصة
تعلمنا من هذا الفصل، كيفية إستخدام عناصر تحكم نظام الملفات، لكتابة برامج تمكنك من إختيار الملفات، كما تعلمنا أيضاً كيفية كتابة نموذج عام الغرض (النموذج frmGetfile) لإستخدامه من قبل أى برنامج يتطلب إختيار ملفات.
الفصل الرابع عشر
الوصول إلى الملفات
تحتاج الكثير من البرامج إلى قراءة وكتابة البيانات في الملفات على الأقراص. سنتعلم في هذا الفصل كيفية تشكيل الملفات وكيفية قراءة البيانات من الملفات، وكتابة البيانات عليها.
هنالك ثلاث طرق للوصول إلى الملفات:
الوصول العشوائي Random Access.
الوصول التسلسلي Sequential Access.
الوصول الثنائي Binary Access.
يعلمك هذا الفصل كيف تستخدم كل تقنية من تقنيات الوصول إلى الملفات، حتى تستطيع التعامل معها.
الملفات ذات الوصول العشوائي
يشبه هذا الملف قاعدة البيانات Database، فهو مؤلف من سجلات متطابقة الحجم، وكل سجل مؤلف من حقول تستخدم لحفظ البيانات، يبين الشكل 14-1 ملف ذي وصول عشوائي، يتألف كل سجل من سجلاته من حقلين، الحقل الأول عبارة عن سلسلة بطول 5 بايتات مخصصة لحفظ اسم الشخص، والحقل الثاني عبارة عن سلسلة بطول بايتين، يحفظ فيها عمر الشخص.
إذاً يبلغ طول كل سجل سبعة بايتات، تشكّل البايتات السبعة الأولى، أول سجل. والبايتات السبعة الثانية، ثاني سجل. وهكذا. ويحفظ كل سجل بيانات شخص ما.
الشكل 14-1 ملف ذو وصول عشوائي.
برنامج الهاتف
يوضح برنامج الهاتف، كيفية إنشاء ومعالجة الملفات ذات الوصول العشوائي. يمكنك البرنامج من التعامل مع ملف قاعدة بيانات يدعى Phone.DAT، يحتفظ بسجلات الأشخاص وأرقام هواتفهم.
التمثيل المرئي لبرنامج الهاتف
أنشئ مشروعاً جديداً من النوع Standard EXE.
أنشئ الدليل C:\VB5Prg\Ch14. واحفظ نموذج المشروع بالاسم Phone.Frm في الدليل C:\VB5Prg\Ch14، واحفظ ملف المشروع باسم Phone.Vbp في نفس الدليل.
أنشئ النموذج طبقاً للجدول 14-1.
يُفترض أن يظهر النموذج المكتمل كما في الشكل 14-2.
الجدول 14-1. جدول خصائص برنامج الهاتف.
الكائن الخاصية القيمة
Form Name frmPhone
Caption (اجعله فارغاً)
RightToLeft True
CommandButton Name cmdNew
Caption &جديد
RightToLeft True
CommandButton Name cmdNext
Caption ال&تالي
RightToLeft True
CommandButton Name cmdPrevious
Caption ال&سابق
RightToLeft True
CommandButton Name cmdExit
Caption &خروج
RightToLeft True
TextBox Name txtName
Text (اجعله فارغاً)
MaxLength 40
RightToLeft True
TextBox Name txtPhone
Text (اجعله فارغاً)
MaxLength 100
RightToLeft True
TextBox Name txtComments
Text (اجعله فارغاً)
MaxLength 40
الكائن الخاصية القيمة
MultiLine True
ScrollBars 2-Vertical
RightToLeft True
Label Name lblName
Caption الاسم:
RightToLeft True
Label Name lblPhone
Caption رقم الهاتف:
RightToLeft True
Label Name lblComments
Caption ملاحظات:
RightToLeft True
إدخال نص برنامج الهاتف
سنحتاج مع النموذج PHONE.FRM إلى وحدة نمطية Module. وسنوضح سبب الحاجة إليه لاحقاً، أما الآن فإليك طريقة بنائه:
اختر Add Module من القائمة Project.
يستجيب فيجول بيسك بإظهار مربع الحوار Add Module.
اختر الرمز Module من الصفحةNew لمربع الحوار Add Module، ثم انقر الزر فتح.
يستجيب فيجول بيسك بإنشاء وحدة نمطية جديدة، ويُظهر إطار نص البرنامج الخاص بها، وكما تلاحظ يطلق فيجول بيسك عليه التسمية Module1.
احفظ الوحدة النمطية الجديدة بالاسم PHONE.BAS كالتالي:
اختر Save Module1 As من القائمة File واحفظ الملف بالاسم Phone.BAS في الدليل C:\VB5Prg\Ch14.
أدخل النص التالي في قسم التصاريح العامة للوحدة نمطية Phone.BAS:
'يجب التصريح عن كل المتحولات
Option Explicit
Type PersonInfo
Name As String * 40
Phone As String * 40
comments As String * 100
End Type
الشكل 14-2 نموذج برنامج الهاتف.
هذا هو كل النص الذي نحتاج كتابته في الوحدة النمطية. سنباشر الآن كتابة نص النموذج frmPhone:
أدخل النص التالي في قسم التصاريح العامة للنموذج frmPhone:
'يجب التصريح عن كل المتحولات
Option Explicit
Dim gPerson As PersonInfo
Dim gFileNum As Integer
Dim gRecordLen As Long
Dim gCurrentRecord As Long
Dim gLastRecord As Long
أنشئ إجراءً جديداً في النموذج frmPhone (باختيار Add Procedure من القائمة Tools) وسمّه SaveCurrentRecord().
أدخل النص التالي في الإجراء SaveCurrentRecord() الذي أنشأناه للتو:
Public Sub SaveCurrentRecord()
gPerson.Name = txtName.Text
gPerson.Phone = txtPhone.Text
gPerson.comments = txtComments.Text
Put #gFileNum, gCurrentRecord, gPerson
End Sub
أنشئ إجراءً جديداً في النموذج frmPhone وسمّه ShowCurrentRecord().
أدخل النص التالي في الإجراء ShowCurrentRecord() الذي أنشأناه للتو:
Public Sub ShowCurrentRecord()
Get #gFileNum, gCurrentRecord, gPerson
txtName.Text = Trim(gPerson.Name)
txtPhone.Text = Trim(gPerson.Phone)
txtComments.Text = Trim(gPerson.comments)
frmPhone.Caption = "السجل:" + Str(gCurrentRecord) + _
"/" + Str(gLastRecord)
End Sub
أدخل النص التالي في الإجراء Form_Load():
ليست هناك تعليقات:
إرسال تعليق