Professional Documents
Culture Documents
إلى أولئك المترفون في مكاتبهم الدافئة ،المكيَّفة ،المخ َّدمة بكافة وسائل
الراحة ،الذين نهبوا وقتنا وسرقوا مخصصاتنا ،وتركونا نحارب البرد والحر
والظروف ،لنكتب ما هو مكتوب ،ونحفظ ما هو محفوظ بغض النظر عن
منطقيته أو مصداقيته ،ليعطونا عالمات بقدر "حفظنا" للمسائل العلمية
ورضاهم عنا
أهديكم هذا الكتاب ألنه لوالكم لما انتقلت إلى البرمجة هربًا من فسادكم
(على فكرة األعداد السابقة ليست تألي ًفا ،برنامج وورد أحصاها)
كما أنه كتِب في زمن حرب قيل إنها سبع عجاف في حين أنها قرن أعجف،
وغاب عنه – عن الكتاب – الدعم كمصادر واستشارات ،ودعم فني وتقني..
وفي سياق متصل ،لي رجاء عندك ،إذا أحببت مشاركة أي كود أو فكرة أو
فقرة من محتويات هذا الكتاب فاذكر المصدر وال تنسبها لنفسك وذلك
لألسباب أعاله.
،2019/2/13حلب
35
الجزء األول
Console Application
37 الفصل صفر – أساسيات
39 المنطق البرمجي
41 أكواد أساسية – الفئة Console
42 استخدام خصائص وطرق الفئات
43 ايقاف البرنامج – انتظار أحد المفاتيح
43 تغيير عنوان نافذة المشروع
43 تغيير لون نافذة المشروع
43 طباعة عبارة نصية
46 رموز طباعة خاصة
48 أكواد متقدمة – الفئة MessageBox
52 الفصل األول – المتغيرات
54 أنواع المتغيرات
55 التصريح عن المتغيرات
56 إسناد القيم للمتغيرات
57 التصريح عن الثوابت
58 قراءة المعطيات
59 التحويل بين أنواع المتغيرات
60 أنواع المتغيرات بعمق
60 bool
60 char
63 DateTime
63 decimal
63 double
64 float
64 int
64 long
64 string
67 كائن StringBuilder
69 تنسيق العبارات النصية
70 التحكم باألخطاء Exception Handling
72 التحكم باستخدام try – catch
74 الروابط
77 التوابع الرياضية Math
79 تسلسل العمليات الرياضية
80 فكرة أخيرة – المبرمج ال يعلم كل العلوم!
82 أمثلة تطبيقية
90 الفصل الثاني – بنى التحكم
90 بنية الشرط If
94 بنية الشرط If .. Else
96 بنية الشرط المتعددة
98 بنية الشرط المختصر
98 بنية االختيار Switch
105 أمثلة تطبيقية
113 الفصل الثالث – بنى التكرار
113 حلقة For
117 حلقة do – while
117 حلقة while
119 حلقة label goto
120 التحكم بالحلقات
120 باستخدام continue
120 باستخدام break
121 أمثلة تطبيقية
134 الفصل الرابع – المصفوفات
134 التصريح عن المصفوفات
135 إسناد القيم لعناصر المصفوفات
136 التعامل مع المصفوفات
137 استخدام Array
138 الحلقات في المصفوفات
139 اللوائح Lists
139 التصريح عن اللوائح
139 التعامل مع اللوائح
141 القواميس Dictionaries
141 التصريح عن القواميس
141 إضافة العناصر للقواميس
142 طباعة عناصر القواميس
143 البحث عن العناصر في القواميس
143 حذف العناصر في القواميس
143 المكدسات Stacks
144 التصريح عن المكدسات
144 إضافة عناصر للمكدسات
144 طرح العناصر من المكدسات
147 أمثلة تطبيقية
161 الفصل الخامس – أنواع بيانات خاصة بك!
161 التراكيب Struct
163 التراكيب المتفرعة Nested Structs
163 مصفوفة من التراكيب Array of Structs
164 طرق خاصة بالتراكيب
165 المعددات Enum
172 الفصل السادس – الطرق ،التوابع واإلجراءات
176 تمرير المتغيرات
176 التمرير بالقيمة
176 التمرير بالمرجع
176 التمرير باإلخراج
179 تمرير عدد غير محدد من الوسطاء كمصفوفة
180 إرجاع التوابع كمصفوفة
183 الفصل السابع – الفئات Classes
186 المجمعات Assemblies
186 مجاالت األسماء Namespaces
187 إنشاء مجال أسماء
188 مجال الرؤية
189 التعريف االفتراضي
189 Public
189 Private
189 Protected
189 Internal
189 الكلمة static
190 التابع البناء Constructor
191 التابع الهدام Destructor
191 الخصائص Properties
194 الوراثة Inheritance
198 الفئات المجردة abstract
199 الفئات المغلقة sealed
199 الوظائف الوهمية virtual Methods
201 تعدد التعاريف Overloading
202 تعدد األشكال Polymorphisme
203 الواجهات Interfaces
205 المفوضات Delegates
206 التفويض المتعدد Multicasting
207 األحداث Events
209 الوظائف المجهولة Anonymous Methods
210 العبارة المدا Lamda expression
212 مكتبات االرتباط الحيوي dll
214 إنشاء مشروع dll
216 إضافة المكتبة إلى مراجع المشروع
218 مكتبات APIالجاهزة
220
الجزء الثاني
Windows Form Applications
222 الفصل الثامن – أساسيات 2
222 متصفح المشروع Solution Explorer
223 صندوق األدوات ToolBox
223 الخصائص Properties
223 قائمة األخطاء Error List
223 النموذج Form
223 محرر األكواد
225 استيراد المراجع
226 الخصائص Properties
229 األحداث Events
232 الفصل التاسع – مشاريع تطبيقية
233 مشروع TextToSpeech
238 مشروع EmailSender
244 مشروع WindowsExplorer
253 مشروع NotePadDataBase
259 مشروع SpeakToComputer
268 مشروع TabbedNotePad
280 مشروع WebBrowser
284 مشروع PopupMessage
288 مشروع MP3Reader
291 مشروع تحويل األعداد إلى كلمات
309 الفصل العاشر – الدوس وC#
310 ماهو موجه األوامر cmd؟
311 أوامر دوس
326 عمليات متقدمة على األوامر
329 أخطاء قد تواجهك
330 الملفات الدفعية Batch Files
336 تغليف الملفات الدفعية
337 حماية الملفات والبيانات
338 تشفير النصوص
341 حماية الملفات داخل صورة
353 حماية الملفات داخل قواعد البيانات
354 حماية الملفات بتحويلها إلى ملفات نظام مخفية
356 الفصل الحادي عشر – الرجستري
359 التعامل مع القيم والمفاتيح
359 نظرة عامة
360 تطبيق – 1نسخ الملف كمسار!
362 تطبيق – 2نسخ المجلد كمسار
362 تطبيق – 3نسخ تقرير عن محتويات المجلد
365 تطبيق – 4نسخ محتوى الملفات النصية!
366 تطبيق – 5نسخ محتوى الملفات النصية 2
368 تطبيق – 6خصائص الملفات باختصار
370 نشر المفاتيح ،تصديرها واستيرادها
373 مسح المفاتيح
373 التسجيل الصامت!
373 الرجستري من خالل C#
374 القيم والمفاتيح برمجيا
375 تطبيق – 7التحقق من المستخدم!
382 تطبيق – 8فكرة ،نسخة محدودة..
383 صيغة ملفات خاصة بك!
383 تطبيق – 9ربط برنامجك بصيغة خاصة به
397 الفصل الثاني عشر – قواعد بيانات SQL
398 إنشاء قاعدة بيانات
402 بعض أوامر قواعد البيانات
403 عرض البيانات select
405 عرض البيانات وفق شرط where
408 عرض البيانات وفق ترتيب معين order by
409 اإلضافة والحذف والتعديل insert, delete, update
410 التوابع الجاهزة
411 تجميع البيانات group by
412 النسخ االحتياطي
412 إنشاء اتصال مع قاعدة البيانات
413 االتصال باستخدام كائن بناء االتصال
414 القراءة من قاعدة البيانات
415 إضافة وحذف بيانات إلى قاعدة البيانات
416 تعديل بيانات قاعدة البيانات
418 استخدام SqlParameter
419 عرض البيانات في جدول عرض
421 التنقل بين البيانات والعمليات عليها
424 اإلجراءات المخزنة
429 SQL Injection
429 الربط بين أكثر من جدول
436 طبقة الوصول للبيانات DAL
437 االتصال وقطع االتصال بقاعدة البيانات
437 حذف البيانات
442 الفصل الثالث عشر – قواعد بيانات ACCESS
443 إنشاء قاعدة بيانات
444 إنشاء اتصال مع قاعدة البيانات
447 إضافة سجل جديد
449 حذف السجالت
450 تعديل السجالت
451 سهولة الوصول إلى البيانات
453 البحث عن السجالت
454 تجميع البيانات
456 إظهار البيانات في قائمة عرض ListView
459 إظهار البيانات في مخططات
462 حفظ الصور في قاعدة البيانات
468 النسخ االحتياطي
469 حماية قاعدة البيانات
471 إعادة ضبط كلمة السر
473 الفصل الرابع عشر – التقارير Reports
474 تصميم التقرير
477 ربط أداة عرض التقارير بالتقرير
477 عرض تقرير عن كافة المحتويات
478 عرض تقرير عن السجل المحدد
480 عرض تقرير عن نتائج البحث
483 الفصل الخامس عشر – تقنيات مفيدة ☺
483 محارف غير موجودة في كيبوردك!
487 التحكم بمدخالت صناديق اإلدخال
488 تأكيد الخروج من البرنامج
489 تغيير خط إحدى األدوات
489 عمليات مفيدة على ListBox
491 األيقونات في التطبيقات مثل األلوان في اللوحات!
493 الملحقات والمراجع
495 ملحق أ – جدول ASCII
496 ملحق ب – أكواد Alt
500 ملحق ج – الكلمات المحجوزة في C#
506 ملحق د – رموز الكائنات في الفيجوال ستوديو
507 المراجع
509 رسالة الكتاب
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
مقدمة
لطالما استهوتني C#في بداياتي ،وبدوري غضضت بصيرتي عنها كرا َم ًة
للغتي األم الفيجوال بيسك ،وضع ًفا مني ماديا ومعنويا ،باإلضافة إلى
أسباب أخرى تتعلق بالزمان وأسباب متعلقة باإلمكانيات .لم تسعفني
لغتي في مسائلي ومشاكلي البرمجية ،ولم تواكِبني مع تطورات العصر،
ف غليلي بأبسط أدوات التحكم حتى ..لكن لم أهاجر إلى C#لهذا ولم تش ِ
السبب ،ال أحب حاالت الطالق وال فراق االنتقام .
في بداياتي كنت أخاف من أي شيء يحوي كلمة " ".Netوأتحاشاه على
صفحات االنترنت وقنوات اليوتيوب وحتى في كلماتي ،وهذا ما قلل
اهتمامي ب .C#وبموازاة ذلك كان لفيجوال بيسك دوت نت ذات النصيب
من المعاداة ،هي لغة أخرى مختلفة تماما عن لغتي وال تحمل منها إال
اسمها مع لقب عائلة أخرى ،ولم أكن أرى ذلك إال تبليا منها.
غلت في C#شيئا فشيئا ،وظهر لي أنها ابنة عالم وناس ومحترمة تو ّ
وآدمية (وكافة صفات اللطف األخرى ،)..ساعدتني خلفيتي في C++في
ل آخر ذو مذاق مختلف.. تخطي غالبية المبادئ ،وكان للغتي األم فض ٌ
ماهي إال شهور حتى اكتسبت ثقافة كافية ألقول أنني أعتنق الـ C#
بجانب الفيجوال بيسك .وبالمصادفة ،اكتشفت أيضا أن Visual Basic.Net
ابنة عم ..C#.Net
20
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
هذا الكتاب ليس مرجعا في C#وال دليل استخدام وال يمثل إال نفسه،
ويمكن اعتباره ملخص صغير لألكواد األكثر تكرارا واألفكار والشروحات األكثر
تواجدا بين سطور أي برنامج .C#
بشكل أساسي ،سوف أقوم بتطبيق األكواد على فيجوال ستوديو .2012
ولن أشرح كيفية تنزيل أو تثبيت أو تكريك هذا البرنامج – أو البيئة البرمجية
– على اعتبار أن هذا الكتاب ليس مرجعا كما اتفقنا .كما أنني لن
أشررح كل شاردة وواردة في C#بكل ما تحتوي من طرق وفئات.
قد يخطر ببالك" :أنت بدأت بالكتاب في بدايات ،2018لماذا تقدم أمثلة
على برنامج قديم؟" ،سأجيبك بأن "الذي يعلم يعلم ،والذي ال يعلم يقول
كف عدس!" ،1جهاز الكمبيوتر لدي عندما ابتدأت الكتاب مواصفاتهCore 2 :
..1VideoCard ،4 Ram ،Dueوفهمك كفاية ،وبعد فترة اقتنيت Core i7-
،2670وانتقلت من SONY SPإلى GrandPimePlusلترافقني رسالة
"الذاكرة ممتلئة امسح بعض التطبيقات"!! (متخيل كم أن حالتي يائسة؟).
نبذة عن المؤلف
اسمي حسن الفحل ،سوري من مدينة حلب وأدرس في كلية اآلداب
الميكانيكية.2
أحب السباحة وكرة القدم وال أجيدهما ،كما أنني أحب القراءة إال أنه ال
وقت لدي (حاليّا على أقل تقدير).
21
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
في هذه األثناء كانت هناك شركة تسمى IBMتصمم حواسب آلية عليها
نظام تشغيل ،لكنه كان بسيطا وال يؤدي الكثير من الوظائف ،األمر الذي
أدى إلى الحاجة إلى تطويره..
ومع موازاة هذه األحداث ،تم تطوير نظام تشغيل ،DOSوهو اختصار لثالث
كلمات Disk Operating Systemقرص نظام التشغيل..
وبسبب صعوبة التعامل مع لغة التجميع ،تم إنشاء مفهوم جديد وهو
اإلجراءات ،Proceduresوهي عبارة عن مكتبات تضم إجراءات ودوال تمثل
األسطر البرمجية الكثيرة التي قلنا إنها للقيام بأعمال عادية وصغيرة ..وهذا
كان بداية ظهور لغات عرفت بالجيل الثالث للغات البرمجة مثل لفة سي
والفورترن..
باإلضافة إلى الشركة تلك ،كان هناك شركة اسمها ،SUN MicroSystems
ال أدري إذا ماكان اسمها اختصارًا لثالث كلمات أم أن معناه الكلمة "ابن" أم
أن معناها يوم الألحد ..المهم أنها أطلقت نظاما مفتوح المصدر يسمى
ُ
يونيكس ،ثم أنشئ نظام اللينكس والذي يستخدم الواجهات في عمله..
22
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
ثم تتالت النسخ فجاء Windows 2.Xليكون تطويرا لسابقه ،ثم جاء
Windows 3.Xليتعامل مع األيقونات بشكل أوسع وأفضل ،بذاكرة رام 2MB
كحد أدنى ،و 20MBمن مساحة القرص الصلب (الحظ الفرق في الحجم
وما يترتب عليه من إضافات ،عم أحكي جد).
في هذه األثناء ظهر مفهوم البرمجة كائنية التوجه ،أو ما يعرف بـ ،OOPمما
أدى لظهور الجيل الرابع من لغات البرمجة مثل سي ++وفيجوال بيسك..
ُ
ثم أطلق نظام Windows 95والذي كان يعتمد على ،DOSثم Windows
،97ثم ..Windows 98وعندها تم إنشاء برمجيات ..Microsoft Office
زادت أرباح الشركة بشكل هائل ،وحتى تلحق بها شركة ،SUNأطلقت لغة
اسمها ،JAVAوعندها ظهرت مكتبتان SDK :من إنتاج الشركة األولى،
و JDKمن إنتاج الثانية..
مع تطور البرمجيات ظهرت الحاجة لالهتمام بقواعد البيانات ،فقامت شركة
اسمها Fox Proباالهتمام بذلك ..وحتى ال تخسر شركة Microsoft
..وبعدها مباشرة أنشأت مكتبة خاصة حضورها اشترت الشركة
لقاعد البيانات اسمتها ..SQL
23
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
في هذه األثناء كانت شركة SUNتعمل على تطوير لغتها JAVAدون
الحاجة إلى وضع لغات عديدة وتفريعات بال طعمة ،بحيث يمكن لمبرمج
JAVAبرمجة قواعد البيانات والتعامل مع االنترنت من اللغة نفسها!..
بسبب تعدد لغات البرمجة ظهرت مشاكل عديدة مثل وجود أكواد في لغة
Visual Basicعلى امتداد نسخها وهي غير موجودة في C++مثال،
والعكس أيضا ..في حين أن هذه المشكلة ليست موجودة لدى شركة
SUNألنها ليست طماعة كثيرًا ..مما اضطر شركة Microsoftإلى أن تقلد
شركة SUNوتطلق لغة برمجة موحدة يستخدمها جميع زبائن الشركة..
بعد استشارات واتفاقات ،ارتأت الشركة إلى أن تكون هذه اللغة تعمل
تحت إطار أسمته إطار ،.Netوهو يجمع جميع لغات البرمجة التي أطلقتها
الشركة ..وقف أحد أعضاء الشركة – وكان لديه بعد نظر – وقال أنه من
المحتمل خسارة الشركة لماليين المبرمجين حول العالم ،إذ أن لغة Visual
Basicكانت األكثر انتشارًا ،وأضاف ستكون خطتنا على النحو التالي :نضع
لغة نهتم بها C#.Netوهي محور اهتمامنا ،ونضع لغة تمشاية حال تجذب
المبرمجين القدامى حتى ال نخسرهم ،واسمها ،Visual Basic.Net
ليعتقدوا أنها امتداد لسلسة لغات الفيجوال بيسك من 1وحتى ،6وهذا
يتطلب أن ننشئ لغة C#بكل مافيها ونضع رؤانا فيها (مع ترك بعض الرؤى
للنسخ القادمة حتى يبقى المبرمج متطلع ألمور جديدة ،)1ثم ننشئ
لغة مطابقة تماما للغة C#.Netبحيث تبدو أنها امتداد لـ .Visual Basic
2
وفي الواقع ،ال عالقة لـ Visual Basicبـ Visual Basic.Netوال بـ .C#.Net
1جرت العادة في الشركات العالمية والبرامج المحترمة – خصوصا التي تصدر بشكل سنوي – أال يتم
وضع جميع األفكار في النسخة الحالية وذلك حتى يضمنوا صدور نسخ جديدة بأفكار جديدة.
2راجع كتاب "دليلك المختصر -الهجرة من الفيجوال بسيك إلى الفيجوال سي شارب والعكس ".لخالد
السعداني ،حيث يتضمن نبذة عن اللغتين مع أهم الفروقات بينهما.
24
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
هذا من جهة ،ومن جهة أخرى فإن الفيجوال ستوديو – والذي يجمع لغات
دوت نت ضمن برنامج واحد – يحوي لغات كثيرة ليست فقط فيجوال بيسك
وسي ،#وعلى اعتبار أن الكثير من المبرمجين ينحازون للغات برمجة
محددة وال يرغبون بالتخلي عنها لتعلم لغة أخرى فإنه من المناسب جمع
جميع لغات ميكروسوفت ضمن بيئة واحدة بحيث يمكن للفريق البرمجي
أن يحتوي على مبرمجين للغات مختلفة .كما أن بعض اللغات تتميز عن
غيرها بأمور معينة ،فإذا ما تم جمع أكثر من لغة لتعمل على ذات البيئة
ً
مجاال للخروج بمنتجات من أكثر من لغة واحدة. فإن ذلك سيفتح
الفكرة والبرمجة
يقال أن الفكرة في البرمجة هي كل شيء ،كما أنها المفتاح األساسي
بشكل صحيح .وأصحاب هذا المقال يعتقدون أن هناك ٍ لتعلم البرمجة
احتمالية إلضاعة فترة كبيرة من عمرك هبا ًءا وأنت تتعلم البرمجة فقط ألنك
ال تملك فكرة تعمل عليها بعد تعلمك ..والفكرة برأيهم لن تتعلمها أو تبحث
عنها في مكان ما .الفكرة قد تأتي صدفة أو بعد تفكير عميق .والسؤال هو
هل يجب إيجاد الفكرة قبل تعلم البرمجة أم تعلم البرمجة ثم إيجاد الفكرة؟
قبل تعلم البرمجة ستكون الفكرة إنسانية بحتة وخيالية ،وعندها ستكون –
أنت – عندما تتعامل مع الفكرة ،مثلي ومثلك عندما نخطط لما سنفعله
في الفضاء أو في أعماق البحار.
أثناء تعلم البرمجة ستشعر أن الفكرة التي تتبناها غبية ومعاقة وساذجة
وستستغرب لماذا اخترعوا لغات بهذا الغباء ،وكيف أن البرامج المشهورة
والعالمية قد وصلت لهذه الشهرة والقوة بهذا المنطق الغبي .كالكود الذي
تتعرض له جميع الكائنات البشرية التي تتعلم البرمجة :كود تبديل رقمين
ببعضما ،والذي تحتاج لمتغير ثالث بال طعمة ألداء العملية.
أما بعد تعلم البرمجة فإنك ستعيش الفكرة بشكلين ،ستراها أمامك وفق
منظورين ،أحدهما برمجي واآلخر إنساني ..ستتخيل الطريق للوصول
للفكرة برمجيا وفي نفس الوقت ستتخيل النتائج محسوسة كما لو أنها
أمامك في لحظتها وكيف سيتعامل معها ويفهمها المستخدمون العاديون.
ستشعر أنك عازف بيانو محترف ومن حولك ال يفقهون شيئا بآالت العزف إال
أنهم يحبون نغمات البيانو..
25
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
ً
قوى ودقة َ
اإلنسان أذكى من الكمبيوتر مهما بلغ األخي ُر من ويقال أيضا إن
وسرعة ،لكن بالمقابل فإن مسأل ًة يحلها الكمبيوتر في لحظات قد ال تتجاوز
ثانية أو اثنتين يستغرق اإلنسان لحلها ساعات وربما أيام ،هذا يعني أن
الكمبيوتر أذكى ..ومع هذا فال تسمح للكلمات بالتحايل عليك ،فلعبة
الكلمات سهلة للغاية ،الفكرة أن اإلنسان يمكنه اختراع كمبيوتر بينما
الكمبيوتر ال يمكنه اختراع إنسان!
يوجد خارج الغرفة شخص آخر يرسل لمن في الغرفة مجموعة بيانات
مكتوبة باللغة الصينية – والتي ال يفهمها صديقنا داخل الغرفة – على
أوراق ليستلم غيرها من الغرفة كجواب لها .لتبسيط الموضوع يقوم
الشخص خارج الغرفة بإرسال ورقة عليها سؤال ،وصديقنا داخل الغرفة
عليه إعطاءه جوابا لهذا السؤال على ورقة أخرى ..لكن ال تنسى فصديقنا
ال يفهم الصينية!
الشخص خارج الغرفة عندا يستلم ورقة اإلجابة ،ويشعر أنها منطقية وهي
م السؤال واإلجابة م ًعا! ن من في الغرفة قد فه َسيعتقد أ ّ
ُ الحل المطلوب
لكن في الواقع الموضوع عبارة عن مطابقة رموز ليس إال..
26
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
صديقنا داخل الغرفة هو الكمبيوتر ،ليس لديه صفة الفهم أو اإلدراك أو ُ
الوعي ،وإنما يقوم بتنفيذ أوامر محددة بنا ًءا على معطيات وبيانات محددة..
وحتى من أجل أعقد وأدق أنظمة الذكاء االصطناعي فال يمكن إعطاء
الكمبيوتر ميزة الوعي واإلدراك والفهم ،األمر الذي يمتلكه اإلنسان بشكل
فطر ّ
ي!
لكن بالمقابل ،فالسفة آخرون قالوا إنه طالما هناك نتائج صحيحة لمعطيات
ما فإنه من الممكن إعطاء صفة الفهم للكمبيوتر ،ولو حتى فهم جزئي.
يعني أننا ال يمكن أن نقول إن اإلنسان داخل الغرفة يفهم الصينية ،لكن
ً
نوعا ل اإلرشادات – يفهمه! وهذا منطقي ن +جدو ُالنظام ككل – اإلنسا ُ
ما ،فالكمبيوتر ال يعلم ماذا تمثل أو تعني القيمة 1عند إسندها للمتغير
المسمى ،aوال 0عند إسنادها للمتغير ،bوال 9-عند إسنادها للمتغير ،c
لكن بالمقابل هو يعطيك ورقة مكتوب عليها العبارة،"x1 = -3, x2 = 3" :
هو فقط يعلم أن aو bو cهي متغيرات عددية ،وأن هناك مايربط المتغيرات
مع بعضها – مجموعة من المعادالت وبنى الشرط والتكرار – ولكنه ال يعلم
ماذا تمثل في الواقع!
الجدير بالذكر أن جميع اللغات التي تعمل ضمن بيئة الدوت نت بإمكانها
الوصول لذات النتيجة ،واختيار لغة البرمجة لهذا الغرض مبني على ميولك
ورغبتك وراحتك تجاه هذه اللغة ،بحيث أن المهارة تكمن في إمكانيتك
للوصول لهذه النتيجة على أكثر من لغة تعمل وفق بيئة الدوت نت..
27
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
عموما ،يمكنك القيام بما يلي في ،C#حيث لكل فرع من هذه الفروعِ
ٌ 1
فروع:
28
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
هذا األمر – أن أغلب الكتب موجهة للمبتدئين – منطقيّا على اعتبار أن
المحترفين أو المتوسطين بإمكانهم البحث واالطالع في المنتديات والمواقع
وقنوات اليوتيوب بح ًثا عن ضالتهم ،أما المبتدئين فيحتاجون من يمسك
بأيديهم وينقلهم من الال شيء إال المستوى المبتدئ أو من المبتدئ إال
المتوسط .ولكن ما أحاول قوله هو ماذا لو كانت هناك مراجع عربية تهتم
باالحتراف؟؟ بالتأكيد كان حالنا سيكون أفضل وبرامجنا ستكون منتشرة
بشكل أوسع وكان س ُيحسب لنا حساب في عالم التكنلوجيا والمعلومات
وسيكون لنا وجود وحضور ،إال أن مايحدث أن المحترفين في البرمجة لدينا
ل لديهم في الكتابة أوإما ُمحتكِرون ويكتفون بما جنوا ألنفسهم ،أو أن ال با َ
التأليف ويرغبون بالتعليم الشخصي – وج ًها لوجه – أو بقنوات اليوتيوب أو
المنتديات ..وأكرر ،اللهم إال بعض نجوم البرمجة العربية فعطاؤهم معروف
وفضلهم مشهور!!
هذا الكتاب مو ّ
جه لكل من المستويات التالية:
للمتوسطين فهو يسرد لهم المفاهيم التي يعرفونها ويشرح لهم مبادئ
البرمجة كائنية التوجه ،OOPكما يزودهم بمشاريع تطبيقية وأمثلة تطبيقية
مختلفة وفي مجاالت واسعة لتكون ذخرًا لهم إلنشاء تطبيقات خاصة بهم.
كما ينقلهم لبرمجة قواعد البيانات وأهم مايحتاجونه لذلك.
للمتقنين فهو يمثل سر ًدا سري ًعا لمعلوماتهم وترتيبًا ألفكارهم ومهاراتهم،
كما يمكن اعتباره مرج ًعا لتطبيقاتهم (حتى ولو أنني ال أحب ّذ ذلك لغياب
الدعم العلمي على محتوى الكتاب).
ومع األسف فهو ال يشكّل شيئا للمحترفين ألن الشريحة المستهدفة من
الكتاب هي الشريحة المتعلمة ال المعلمة ،كما أنني ل ّ
ما أصل لهذه
المرحلة بعد .
29
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
التعليم المقروء هو تعليم من الكتب ،والتي تعتمد بشكل كبير على درجة
ثقافة القارئ ،وهي أكاديمية غالبًا .أما المرئي منه فهو التعليم بمشاهدة
فيديوهات من اليوتيوب بشكل أساسي ،وغالبًا هو تطبيقي بامتياز لذلك
فهو الخيار األمثل ألغلب المتعلمين.
شخص ًيا فقد تعلمت البرمجة من اليوتيوب واعتمدت على كثير من الكتب
كمراجع ،وبرأيي فالفيديوهات مناسبة الكتساب المهارات والكتب مناسبة
صا إن كنت جدي ًدا على الكتساب المعلومات .بمعنى أنه عليك – خصو ً
دروسا على اليوتيوب للبرمجة ثم تطبقها علىً البرمجة – أن تشاهد
كمبيوترك ثم تقرأَ عنها من الكتب لتكسبَ المعلومات النظرية وترتب أفكارك
وتكسب المزيد والمزيد من األمثلة والتطبيقات .ويمكن تطبيق هذا
األسلوب على جميع لغات البرمجة.
وال بأس بمشاهدة فيديوهات ألناس وقراءة كتب ألناس آخرين ،مع أنه
يفضل في بداياتك أن تكتفي بمصدر واحد تتعلم منه ..وعندما تتجاوز مرحلة
"المبرمج متوسط المستوى" ،ال مشكلة في تعدد المصادر فببلوغك لهذه
المرحلة بإمكانك تمييز المحتوى الجيد من الرديء ،وبإمكانك ربط األفكار مع
بعضها سوا ًءا أشاهدت أو قرأت من مصدر واحد أو من عدة مصادر .ففي
هذا المرحلة – ومابعدها – أنت لديك األفكار والمهارات وتحتاج فقط لترتيبها
واكتساب المزيد وضمه لما تملك.
30
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
خطة الكتاب
ضا من المواضيع المتقدمة فيها، يناقش الكتاب أساسيات لغة C#وبع ً
ويعرّفك على كل ماتحتاجه لبناء تطبيقات صغيرة متكاملة ،وذلك بتعريفك
على مبادئ وأساسيات البرمجة ثم ينقلك للبرمجة كائنية التوجه والنوافذ
ً
فصال، وقواعد البيانات ومواضيع أخرى مختلفة موزعة على ستة عشر
مقسمة على جزأين ،األول يتحدث عن بيئة Consoleوالثاني يتحدث عن
النوافذ والمواضيع المتقدمة مثل قواعد البيانات وغيرها.
الفصل صفر يتحدث عن بعض األكواد التي ستحتاجها على امتداد الجزء
األول من الكتاب ،ويهيئك لتدخل إلى البرمجة وتفهم مفاهيمها.
الفصل األول يتحدث عن المتغيرات وماهيتها والفرق بين نوع وآخر ،وكيفية
استخدامها والروابط بينها ،والتحكم باألخطاء .كما يشرح كيفية التعامل مع
المسائل الرياضية في البرمجة .ويناقش بعض األمثلة التطبيقية.
الفصل الثاني يتحدث عن بنى التحكم وأهميتها في البرمجة ،بد ًءا من بنية
الشرط ifوانتها ًءا ببنية االختيار .switchويعرض بعض األمثلة التطبيقية.
الفصل الثالث يتحدث عن الحلقات والفرق بين نوع وآخر منها وأهميتها،
وكيفية استخدامها والتحكم بها .ويشرح بعض األمثلة التطبيقية.
الفصل الخامس يناقش كيفية إنشاء أنواع بيانات خاصة بك وهو مفيد ج ًدا
ً
كامال وبالتحديد عند إتقانك للفصل خصوصا عند انتهاءك من الجزء األول
السابع ،وهو أغنى فصول الكتاب.
الفصل السادس يعرّفك على التوابع واإلجراءات وهي مفاهيم مهمة للغاية
إذ إنها حولت مجرى تاريخ البرمجة عند اختراعها.
الفصل السابع يناقش مبادئ البرمجة كائنية التوجه بد ًءا من الفئات ومرورًا
بالكائنات وانتها ًءا بمكتبات االرتباط الحيوي .DLL
31
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
الفصالن الثاني عشر والثالث عشر ُيدخالنك إلى قواعد البيانات وأهم
أوامرها وذلك من خالل أمثلة بسيطة تخوّلك إلنشاء تطبيقات صغيرة
مفيدة.
تنسيق الكتاب
منا بأستاذي ،حجم شخصيا أفضل استخدام خط Tahomaفي كتبي تي ّ
الخط المستخدم ،14وفي العناوين العريضة ،20وفي األكواد 12إال ما ندر.
مالحظة
32
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
التواصل مع المؤلف
للحصول على أي دعم أو استشارة ،أو القتراح تعديالت على الكتاب أو
األعمال القادمة – إن قدر هللا لي ذلك – أو اقتراح أعمال بإمكانك التواصل
معي على بريد الصفحة الخاصة بالبرمجة :Eng27 – Programming
-فيسبوك https://www.facebook.com/Eng27Programming/
-تلغرام عبر المعرّف @Eng27Channel
كما يمكنك االشتراك بالبوت Eng27على التلغرام الذي أضع فيه بع ً
ضا من
منتجاتي ،وبعض الكتب التي من الممكن أن تكون مراجع جيدة يمكن
االستفادة منها ،وذلك عبر المعرّف ،@Eng27Botأو عبر قناتي على
اليوتيوب Hasan M. al-Fahlوالتي سأقوم بشرح كتابي عليها كل فقرة
على حدة ،كما سأنشر شروحاتي التي لم أتمكن من وضعها في هذا
الكتاب.
أو يمكنك التواصل معي عبر الواتساب أو التلغرام أو المكالمات الهاتفية عبر
الرقم .963954796627+
33
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
34
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
الجزء األول
Console Application
35
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
36
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
أحببت ابتداء فصول الكتاب بالفصل صفر تيمنا بالمبدأ البرمجي ،حيث يبدأ
العد من الصفر بشكل افتراضي .إذا كان هذا الكتاب هو بداياتك مع البرمجة
فأتمنى أن يعطيك انطباعا عنها ويوصلك لمبدئها.
جرت العادة في كتب البرمجة ،أن يتم إضافة شرح موجز عن الفيجوال
ستوديو ،لن أدخل بكل هذه التفاصيل ،سأهتم بالعنب بعض الشيء
وسأتحدث عن الناطور بشيء من اإليجاز الح ًقا إن احتجنا لذلك.
مالحظة
ً
افتراضيا ،اسم المشروع هو ،ConsoleApplication1ويزداد الرقم
تلقائيا مع كل مشروع جديد.
37
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
م تقسيم هذه األسطر إلى فئتين ،األولى مكتبات من خاللها كما تالحظ ت ّ
تتمكن من تنفيذ األكواد ،ويمكن استخدام مكتبة ما من خالل البادئة using
والتي تعني "باستخدام" ،أي باستخدام المكتبة الفالنية ،قم بتنفيذ أكواد
برنامجي .الفئة الثانية ،هي البرنامج بحد ذاته.
38
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
المراجع الرئيسية فيه ،إذا كنت جدي ًدا على C#التشغل بالك كثيرًا بها ومع
مرور األكواد ستؤلّف كتابًا بها إن أردت ،ماعليك إال أن تفهم المبدأ اآلن فقط.
تعتبر C#من اللغات كائنية التوجه ،OOPوفي مثل هذه اللغات يعتبر كل
شيء عبارة عن كائن ،Objectسنتعامل الحقا مع مربعات رسائل ،قوائم
منسدلة ،وأدوات مختلفة ،كل ماسبق عبارة عن كائنات بما فيها برنامجك
هو اآلخر كائن .ولكل كائن خصائص تميزه عن الكائنات األخرى وأفعال يقوم
بها وأحداث تمر بها .في برامج C#يتمثل الكائن بفئة – Classأو قد يترجم
للغة العربية بكلمة خلية – و ُيسبق باسم الفئة ،محتويات كل فئة تحصر ما
بين قوسين معقوفين { }.
إن كل فئة تحوي أقسا ًما وفئاتٍ داخها ،والستخدام الفئات الفرعية ُيكتب
اسم الفئة ،نقطة ،الفئة الفرعية ،نقطة .. ،وهكذا حتى الوصول للفئة أو
الطريقة أو الخاصية المطلوبة.
مالحظة
المترجم هو جزء من النظام ،باالشتراك مع البيئة البرمجية التي
تتعامل معها ،يقوم بترجمة أكوادك من اللغة البرمجية التي تفهمها،
إلى لغة اآللة التي يفهمها الحاسوب ،أي مجموعة أرقام مكونة من
0و 1مكررة بشكل كبير جدا.
المنطق البرمجي
في بداية هذا الكتاب تم عرض صورة معنونة بـ ،Programming logic
ومفادها أن البرمجة تعتمد على البيانات المخزنة ،المعطيات ،الحقائق
والثوابت وكل ماهو معرّف ..على عكس المنطق البشري الذي يتميز
بالمرونة والتعلم الذاتي واكتشاف المجهول..
قبل أن ندخل في عالم البرمجة سنطرح مثاال يمكن ألي كائن حي مشتق
من فئة البشر أن يفهمه..
39
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
لنفرض أنك أردت من أحدهم أمرا ماَ ،فلِ َتطلُبَ منه فإنك تأمره ،واألمر يأتي
على أكثر من نوع ..فيكون دعا ًءا إذا كان من األدنى لألعلى ،كما يكون أمرًا
إذا كان من األعلى لألدنى ..وأنت عندما تتعامل مع الكمبيوتر – كمبرمج أو
مستثمر – فإنك تأمره ،لذلك فأوامرك مطاعة (إلى ح ٍّ
د ما ،وبشروط)..
لنعد لفرضيتنا ،إذا أردت أمر أحدهم أن يعطيك كوب ما ٍء مثال ،فإنك
ستستخدم األمر التالي:
;)(أحضر_الماء
وأما إذا أردت تعبئة الكوب بالعصير مثال فإنك تستخدم األمر:
;)عصير(تعبئة.الكوب
ومعناها أنك ترغب بتعبئة الكوب بالعصير ،حيث أن ما بين قوسين هي
تفاصيل تحدد مميزات الفعل الذي يتم القيام به كما اتفقنا.
الحظ الكلمات العربية البسيطة هذه ،بتغييرها إلى اإلنكليزية فقط فإنك قد
كوّنت أكوادا برمجي ًة ذات معنى!!
لكن لحظة ،كيف يفهم الكمبيوتر علينا؟؟ أو بمعنى آخر هذه الكلمات
المكتوبة باللغة اإلنكليزية ،كيف يعرف الكمبيوتر أنها أكواد؟؟؟ ألنه بالتأكيد
40
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
ليست أية كلمة كو ًدا برمجيّا ..حتما هناك كلمات محددة تكتب بطريقة
محددة هي فقط أكواد اللغة .في الواقع فالجواب على هذا السؤال يحتاج
شرح مفهومين أساسيين في أي لغة ،هما IDEو.Compiler
الـ IDEأو بيئة التطوير المتكاملة هي أقرب ماتكون إلى محرر نصوص
يستقبل منك الكلمات اإلنكليزية ويعالجها ليتأكد من أنها أكواد ويحلل نوعها
فقد تكون متغيرات أو كلمات محجوزة أو طرق أو عبارات نصية ،أو قد ال
تمثل شيئا أصال..
كما أن بعض بيئات التطوير تعطيك ميزات أكثر من األخرى ،فقد تجد في
بعض اللغات أنه عند كتابة أسطر برمجية فإنها ستتحاذى بشكل معين..
في حين أن هذا األمر غير موجود في لغات أخرى.
والجدير بالذكر أن بيئة التطوير تعطيك إشارة على مكان وجود خطأ ضمن
أسطرك البرمجية ،أي أنها ستكون يدك اليمنى طوال حياتك..
ومن هنا فإن بيئة التطوير المتكاملة وظيفتها استقبال األكواد منك ،وبعدها
يأتي دور الـ Compilerأو المترجم والذي شرحناه في مالحظة سابقة.
إن الفكرة من وجود الفئات هو تسهيل البرمجة إلى حد كبير ،بحيث تُعطى
أنت األكواد الجاهزة على البارد المستريح ،2وتقوم ببرامج على أكمل وجه
بنفس الفكرة التي أعطت ميكروسوفت مكتبات APIالخاصة بها لزبائنها،
حيث إن هذه األكواد الجاهزة ال تراها وإنما مكتوبة ضمن ملفات معينة.
41
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
42
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
ابتدأت أكوادي بهذا الكود الذي ستستخدمه في جميع برامجك ،عند عدم
وجوده فإن البرنامج سوف ُيترجم ثم يغلق فورا ،جرب استخدام أي كود
برمجي تالي لهذا الكود ضمن هذا الفصل – أو الجزء بشكل عام – دون
استخدام هذا الكود وسترى أن نافذة مشروعك ستغلق فورا.
;)(Console.ReadKey
مالحظة
جميع األكواد في لغات الـ cيجب أن تنتهي بفاصلة منقوطة ،عدا
بعض البنى التي ستراها الحقا.
أغلب مشاكلك وأخطاءك البرمجية هي فاصلة منقوطة .
مالحظة
افتراضيا عنوان المشروع هو مسار المشروع.
الطرق – وهي توابع وإجراءات – تُلحق بقوسين () ،أما الخصائص فال
تلحق .هل الحظت أن هذه المالحظة تكررت بشكل كبير .
43
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
;)"Console.Write ("Eng27
يقوم الكود السابق بطباعة عبارة نصية ،مع إبقاء مؤشر الكتابة على
السطر نفسه الذي يتم الكتابة عليه ،أما لالنتقال للسطر التالي (طف
سطر) فالكود التالي سوف يشفي غليلك.
;)"Console.WriteLine ("Eng27
ضع هذا الكود – األسطر البرمجية – داخل التابع ،Mainثم ترجم المشروع
لتحصل على مايلي:
مالحظة
يمكن ترجمة المشروع عن طريق الضغط على زر F5أو الزر Start
ضمن القائمة .Debug
هذا أول مشروع لك ،وبهذا أكون قد قضيت على فرصة أن يكون أول
برنامج لك هو . Hello World
44
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
يمكن الحصول على نسخة تنفيذية exeمن البرنامج وذلك باالنتقال إلى
موقع المشروع ثم مجلد binثم ،Debugستجد بعض الملفات ومنها
الملف التنفيذي المطلوب ،شاب شعر رأسي حتى اكتشفت الطريقة .
لكن انتبه ،معامل الجمع (إشارة )+قد تستخدم للجمع وقد تستخدم
للربط بين النصوص ،وهذا ماستفهمه مع مرور األكواد بإذن هللا.
ونتيجة تنفيذ الكود ستكون مماثلة للكود الذي تربط فيه العبارات النصية
بإشارة ،+والذي سيكون أطول بكثير وأكثر عرضة لألخطاء.
45
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
تُستخدم هذه األحرف داخل العبارات النصية وتسمى عاد ًة مفاتيح الهروب
كترجمة حرفية لها ،أي أنها تحاط بإشا َرتَي تنصيص ،ويمكن أن تُضمن داخل
عبارة نصية موجودة مسبقا ،ويتعرف عليها المترجم بوجود المحرف \ قبلها.
الوظيفة الحرف
إعطاء صوت ،تنبيه \a
مسح حرف للخلف \b
سطر جديد \n
مسافة أفقية \t
مسافة شاقولية \v
طباعة ' '\
طباعة " "\
طباعة \ \\
طباعة محرف بمعرفة كود Unicodeخاص به \u
لكتابة مسار ملف أو مجلد ،عوضا عن استخدام الرمز \\. ”@”Path
قد تحتاج في بعض األحيان لطباعة الرمز " أو ' أو \ ،وعند استخدامك لهذه
الرموز منفردة فإن العبارة النصية ستكون مختلة ،لذلك تم اختراع التركيبة
الموجودة في الجدول السابق آخر سطرين ،كل الشكر لمخترعيها ^_^.
46
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
فاصل إعالني
بالنسبة لتطبيقات ،Consoleالمبرمجة ألغراض تعليمية أو تجريبية ،يمكن
استخدام تطبيق ،Dcoderحيث يدعم الكثير من اللغات البرمجية التي
تتعامل مع بيئة .Consoleالصورة التالية توضّح مثاال بسيطا تم تنفيذه
باستخدام هذا التطبيق.
مالحظة
تطبيق Dcoderال يعمل
إال إذا كنت متصال
باالنترنت .كما أنه يوفر
حفظ إمكانية لك
مشاريعك وتطبيقاتك.
هام
يدعم تطبيق Dcoderاللغات البرمجية والبيئات التالية:
C , C++ , C# , Java , Python , VB.Net , Pascal , Html , Css
والكثير الكثير من اللغات األخرى التي لم تسمع عنها إطالقا.
لألمانة أنا ال أقوم بدعاية لهذا التطبيق وإنما أدل القارئ على
أساليب تراعي ظروفه وتساعده على العمل والبرمجة والتعلم .
47
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
بيئة Consoleال تحوي نوافذ ،وال أدوات أو قوائم ،ال وجود لصناديق النصوص
أو أزرار األوامر ،فقط يوجد أكواد – نسميها أسطر برمجية – تُنفذ سطراً
سطراً مع إمكانيات كثيرة لقيادة وإدارة البرنامج أثناء التنفيذ.
مالحظة
في بعض لغات البرمجة ،يكون صندوق الرسائل من األمور القياسية
المعطاة مع النموذج ،في حين أن عليك إضافته في .C#
من أكواد المشروع ،قل لـ C#أنك تود استخدام محتويات المكتبة التي
أضفناها ،وذلك بالكود التالي:
ضعه في األكواد األولى من البرنامجusing System.Windows.Forms; //
48
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
الحظ أن مربع الرسالة قديم (من أيام Windows XPوماقبل ،انتبه للزر)،
كما أنه ال يحوي عنوان أو أي رموز أو أزرار إضافية .وهذا هو أبسط شكل
من أشكال مربعات الرسائل..
اعتقد أنه بات لديك تصور واضح عن كيفية ومتى نستخدم ،usingوما
الغرض منها ،اآلن لنتناقش عن تنسيق مربع الرسائل ،اإلضافات عليه،
ومتغيراته.
مالحظة
ً
يتم وضع الوسطاء الكثيرة للتوابع واإلجراءات – الطرق – عادة في
أسطر منفصلة حتى تسهل قراءة الكود!
بإمكانك ذلك بوضع فاصلة بعد كل وسيط ثم االنتقال للسطر التالي
عبر الضغط على زر .Enter
49
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
الحظ أنه بات للرسالة عنوان ،ورمز يعبر عن مزاج البرنامج وحالته ،باإلضافة
إلى أزرار عديدة ،مع إمكانية تحديد الزر االفتراضي ،باإلضافة إلى أنه ال
يمكن الضغط على زر الخروج ..عد للصندوق القياسي وقارن بينهما..
50
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
51
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
52
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
إن وجود المتغيرات وتنوعها وإحاطتها ببرامجك تعطيه قوة وسيطرة ودقة
في العمل ،يزداد الذكاء الصناعي لبرنامجك مع ازدياد متغيراتك والعالقات
فيما بينها وبنى التحكم في هذا البرنامج (والتي س ُتناقش في فصول
الحقة).
وبالمناسبة أيضا فالمتغيرات تمثل ذاكرة برنامجك ،واألكواد التي تسيّر هذه
المتغيرات هي عقل برنامجك ،لذلك فق ِوّ عالقتك بها ):
من أبسط األمثلة وأكثرها شيوعا هو التبديل بين قيم المتغيرات ،لديك
متغيران xو ،yولك ٍ ّ
ل قيمة ،ولغاية ما أردت أن يأخذ المتغير xقيمة ،y
وبالعكس ..الكود التالي يوضح ذلك:
;int x, y
;x = 5; y = 6
متغير مؤقت int temp; //
temp = x; // temp = 5
)x = y; // x = 6 (not 5
53
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
كما أن هناك إمكانية للحصول على ذات النتيجة بمتغيرات أقل ،لكن
الطريقة هذه تحتاج تشغيل مخ:
;int x, y
;x = 5; y = 6
x = x + y; // x = 5 + 6 = 11
y = x – y; // y = 11 – 6 = 5
x = x – y; // x = 11 – 5 = 6
;)(Console.ReadKey
أنواع المتغيرات
اتفقنا في مقدمة هذا الفصل على أنه لتخزين بيانات برنامجك سوا ًءا تلك
التي يدخلها المستخدم أو التي يحصيها البرنامج من تلقاء نفسه يجب أن
تخزّن في مايسمى بالمتغيرات.
54
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
مالحظة
العدد الصحيح هو العدد الذي يمكن كتابته دون استخدام كسور أو
فواصل عشرية.
العدد الطبيعي هو عدد صحيح موجب.
العدد الحقيقي هو عدد يمكن كتابته مع أو دون استخدام كسور أو
فواصل عشرية.
التصريح عن المتغيرات
هناك قواعد عديدة تحدد اسم المتغير أهمها أال يكون كلمة محجوزة 1وأال
يبدأ برقم ،وأال يحتوي على فراغات أو بعض الرموز مثل نقطة أو فاصلة
منقوطة ،وأال يحتوي إال على أحرف التينية ،كما أن C#حساسة لحالة
األحرف .هذا باإلضافة إلى قواعد أخرى كثيرة ،والجدير بالذكر هنا أن جميع
لغات البرمجة لها ذات المبدأ بالنسبة ألسماء المتغيرات ،مع فوارق
بسيطة .في الحقيقة الكثير من البنى والقواعد والمبادئ مشتركة في
جميع لغات البرمجة مع فوارق بسيطة ،إال أن الجوهر ذاته.
مالحظة
في ،C#عند وجود إشارة تحت اسم المتغير باللون األحمر فهذا
يعني أنه قد يكون اسم المتغير خاطئ ،أما عند وجودها باللون
األخضر فهذا يعني أن هذا المتغير لم يستخدم بعد.
راجع ملحقات الكتاب ،الملحق ج – الكلمات المحجوزة في C# 1
55
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
في C#ال يمكنك استخدام المتغيرات مالم تقم بالتصريح عنها ،على
عكس لغات أخرى كثيرة.
يمكن إسناد القيم للمتغيرات فو َر التصريح عنها ،ويمكن الحقا عند الحاجة.
الحظ أنه يجب تطابق نوع القيمة المسندة مع نوع المتغير ،بمعنى أن
تسند قيم صحيحة لمتغيرات صحيحة ،وقيم خاطئة لمتغيرات خاطئة (عم
أمزح ).
خطأ :1ال يمكن إسناد قيم نصية إلى متغير حرفي ،بمعنى أن
المتغير cيجب أن يحوي أحرف فقط على اعتبار أنه من النوع ،char
ويمكن إسناد القيم له بوضعها مابين إشارتي ' '.
خطأ :2ال يوجد متغير اسمه ،Dهناك متغير اسمه ،dحاول التفريق
بينهما.
مالحظة :يمكن إسناد أكثر من متغير لقيمة واحدة شرط َ أن تقب َ
ل
ُ
جميع المتغيرات هذه القيمة.
مالحظة
توفر جميع لغات البرمجة إمكانية ترك تعليقات ُيستفاد منها أثناء
البرمجة فقط ،وال يقرأها المترجم (هل تذكر المترجم؟ راجع
الصفحات األولى من هذا الكتاب) .تستخدم التعليقات عادة لعنونة
56
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
يقوم الكود السابق بإسناد قيمة الساعة الحالية للوقت إلى المتغير
،MyDateويمكن الحصول على كل من الثواني الحالية أو الدقائق أو
الساعات أو الشهر الحالي أو السنة الحالية ..والمزيد في الداخل.
التصريح عن الثوابت
على غرار المتغيرات ،يمكن لتطبيقك أن يحتاج إلى قيم ثابتة على طول
فترة تنفيذه ،يمكن التصريح عنها بإضافة الكلمة المحجوزة constإلى
ماقبل نوع المتغير أثناء التصريح ،مع إسناد قيمة .الحظ المثال:
;const double Pi = 3.14
مثال آخر:
)if (f == 32
{
C#’s Code
}
57
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
الكود السابق سيء برمجيا ،ماذا تعني 32؟؟! بالنسبة لك كمنشئ لهذا
الشرط فإنك تعلم معنى القيمة الثابتة ،32وتعلم ماذا سيحدث لو أن f
كانت لها القيمة ،32لكن أنا مثال عندما أقرأ كود برنامجك لن أفهمه ،لذلك
فهو سيء برمجيا .فالكود الجيد هو الكود المكتوب بأكسل الطرق
بأسهل العبارات .ماذا لو أردت تغيير القيمة في المستقبل وكان هذا
الشرط موجو ًدا بأكثر من مكان في برنامجك ،ماذا لو نسيت تعديل أحدها؟؟
سيختل البرنامج بالتأكيد( .ال تشغل بالك بما يعنيه الشرط وكيف ُيكتب
اآلن ،افهم الفكرة من الثوابت فقط).
ألم يصبح الكود أفضل برأيك؟؟ بإمكانك تغيير قيمة الثابت أثناء البرمجة في
أي وقت شئت ،وبالتالي فإن أي كود يحوي هذا الثابت سيعتمد عليه
وعلى قيمته التي برمجتها عليه .ثم إن عبارة f = FREEZINGأوضح من
م أن المتغير fوظيفته تخزين قيمة درجة تلك المتمثلة بـ ،f = 32فاآلن أف َه ُ
الحرارة أو مقارنتها (إال إذا كان ميولي أدبيًا).
قراءة المعطيات
58
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
كما الحظت ،فإنه من غير الممكن قراءة معطيات رقمية من خالل الطريقة
،ReadLineفهي تعيد قيمة نصية ..لكن بإمكانك تحويل العبارات النصية
التي يقرأها هذا األمر إلى نوع آخر وذلك باستخدام الفئة .Convert
;)(string s = Console.ReadLine
int i = Convert.ToInt32(s); // convert to int
long l = Convert.ToInt64(s); // convert to long
float f = Convert.ToSingle(s); // convert to float
double d = Convert.ToDouble(s); // convert to double
decimal c = Convert.ToDecimal(s); // convert to decimal
مالحظة
د أنه قد تكررت معك كلمات مثل إذا كنت جديدا على البرمجة ،الب ّ
إجراءات أو طرق ،ال تقلق ستتعرف عليها مع مرور األكود.
ّ
حساسة لنوع المتغيرات ،لذلك فإذا كانت َ
الحظت – عزيزي – فالبرمجة كما
لديك متغيرات من نوع معين وأردت أجراء عمليات من نوع آخر عليها فعليك
تحويل البيانات الواردة منها أو إليها لتتم العملية المطلوب.
طيب السؤال هو كيف أعرف متى يجب أن أحول من نوع إلى آخر؟؟؟
بشكل أساسي يجب عليك معرفة مايجب إدخاله للطرق وما سينتج عنها.
59
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
أما للتحويل من قيمة نصية إلى أي نوع آخر فيمكن عن طريق الفئة
Convertأو عن طريقة الدالة ،Parseفإذا أردت تحويل عبارة نصية إلى
قيمة من نوع doubleاستخدم .double.Parse
bool
char
هذا المتغير يخزّن المحارف ،ولكل محرف في كمبيوترك كود خاص به
يسمى كود Asciiوآخر ،Unicodeبإمكانك مراجعة الملحق أ – جدول
ASCIIوالملحق ب – أكواد Altفي آخر الكتاب لتتعرف على الموضوع أكثر.
60
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
إذا انتقلت لهناك وألقيت نظرة على األحرف المتاحة وشيفراتها ،فبالتأكيد
قد الحظت أن لكل حرف رقم يمثله بالنظام العشري وآخر بالنظام الست
عشري .فمثال الحرف Nله الشيفرة 78بالنظام العشري و 4eبالنظام
الست عشري ،جرب الكود التالي:
;)'Console.WriteLine('N
Console.WriteLine("\u004e"); //Unicode
Console.WriteLine((char)78); //Ascii
;)(Console.ReadKey
بشكل عام فأنواع المتغيرات – مثل charو intو stringوغيرها – ماهي إال
فئات جاهزة تمت برمجتها وبرمجة الخدمات التي يمكنك الحصول عليها
عند استخدامك إياها ،وأنت تستخدمها ببرودة أعصاب ..
لمستوى جيد في البرمجة وتعود إلى هذه الصفحات ستقول ً وعندما تصل
لي أننا عند تعريف المتغيرات ال نقوم باستنساخ فئات ،فكيف تقول أن هذه
المتغيرات هي كائنات؟؟ وسأجيبك أن عملية تعريف المتغيرات ماهي إال
صيغة مختصرة الستنساخ الفئات ،أي أن السطر األول هو اختصار لما يليه:
;char letter
;)(// char letter = new char
61
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
طبعا في حال كنت جديدا على البرمجة وقرأت السطور الحالية وارتبكت
فليست مشكلة ،فهذه األفكار غير موجهة لك (أقصد الفئات والكائنات
واالستنساخ وغيرها) .وعلى سيرة الطرق الجاهزة التي بإمكانك
استخدامها ،المتغيرات الحرفية تعطيك اإلمكانيات التالية:
62
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
DateTime
هذا ليس نوع متغير وإنما فئة ،والفئة هي مجموعة من الطرق والمتغيرات
معة مع بعضها ألداء وظائف معينة ،وستراها الح ًقا إن شاء هللا .إال أننا
مج ّ
سنناقشه هنا حتى تصبح لديك فكرة عن كيفية التعامل مع قيم للتاريخ أو
الوقت.
كما يمكن التعامل مع الوقت عبر كائنات من الفئة ( TimeSpanال تقلق إذا
لم تفهم بعض المصطلحات ،تأمل كيفية كتابة األكواد فقط):
;)TimeSpan time = new TimeSpan(10, 27, 0
decimal
هذا المتغير يخزن بيانات عشرية ذات دقة عالية تصل حتى 29رقم بعد
الفاصلة ،ومجال قيمها تصل إلى 28خانة (المليون 7خانات ،مابالك بـ 28
خانة؟!) .المتغيرات من هذا النوع مناسبة للبيانات المصرفية واألموال.
double
يخزن هذا المتغير بيانات عشرية أيضا ،إال أن دقته أقل تصل حتى 16رقم
بعض الفاصلة ،والمميز فيه أن مجال قيم بياناته يمكن أن تصل إلى 324
خانة .البيانات من هذا النوع مناسبة للعمليات العلمية والحسابات الدقيقة.
63
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
float
يعتبر هذا لمتغير الشقيق األصغر لـ ،doubleدقته تصل إلى 7أرقام بعد
الفاصلة فقط ،ويخزن بيانات خاناتها 28رقم بعد الفاصلة.
int
من أشهر المتغيرات التي يعرفها جميع سكان الكرة األرضية والكواكب
المجاورة هو هذا المتغير ،وهو متغير صحيح ال يحوي فاصلة عشرية،
ومجال قيم بياناته تصل حتى 10خانات ،أي مليار تقريبا.
long
الشقيق األكبر لـ intهو هذا المتغير ،شهرته أقل من المتغير السابق ،كما
أن مجال قيم بياناته تصل حتى 19خانة ،وللصراحة ال أعلم ماهو الرقم
الذي له 19خانة ☺.
string
64
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
كما يمكنك تخزين بيانات نصية مكونة من أكثر من سطر كما رأينا في
الفصل السابق:
;string word
;"word = "This is a simple string/nThis is other line
سأناقش بعض هذه التوابع ،وطريقة استخدامها هي كتابة اسم المتغير ثم
نقطة ثم الخاصية المطلوب التعامل معها.
.. واآلن تابع معي العمليات التالية على المتغير الذي عرفناه منذ ثانية
65
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
مالحظة
هناك فرق بين عدد العناصر ،Countوالطول .Length
هناك فرق بين التابع والخاصية ،التابع ُيلحق بإشارتي () أما الخاصية
فال تلحق.
-لمعرفة فيما إذا كان محتوى المتغير يحوي قيمة نصية معينة:
bool b = s.Contains("s"); //True
كما يمكن االستفادة من االستبدال وذلك إلزالة قيم نصية محددة ضمن
قيمة نصية أخرى:
string s2 = s.Replace("n", string.Empty); //s2 = Hasa
66
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
كما يمكنك إزالة الفراغات من نهاية القيمة النصية فقط أو من نهايتها فقط
استخدم الطرق TrimEndو.TrimStart
-بإمكانك تقسيم محتوى عبارة نصية إلى عناصر مصفوفة حسب قيمة ما:
;"string x = "This is sample text, we will split it by some punctuations. Try it
;)} 'string [] sss = x.Split(new char [] {',', '.
)foreach (string m in sss
;)Console.WriteLine(m
;)(Console.ReadKey
والنتيجة ستكون ثالثة أسطر ،كل سطر فيه جملة نصية واحدة مع بعض
الفراغات في بداية كل سطر.
كائن StringBuilder
قلنا قبل قليل أن التصريح عن المتغيرات يعني استنساخ فئة تمثل نوع
المتغير ،وناقشنا مثاال عن متغير حرفي ..ومالم أخبرك عنه هو لو أنه تم
تغيير قيمة المتغير فإنه سيعاد تعريفه من جديد ،أي أن:
;"" = string s
;"s = "Statement
;"s += ".
يكافئ:
;)(string s = new string
;"" = s
;)(s = new string
;"s = "Statement
;)(s = new string
;"s += ".
طبعا من جديد الكود غير موجه لك ،لكن الفكرة والغاية منه موجهة لك
بالتأكيد .عد إلى الكود األول المكون من ثالثة أسطر ،السطر األول كافأناه
بسطرين في الكود المكافئ وقلنا أنه يعني استنساخ فئة نوع المتغير ثم
إسناد القيمة للمتغير ،أما السطر الثاني من الكود األول فقلنا أنه يمثل
67
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
حيث يقوم الكود السابق بإضافة الرمز "*" للمتغير sألف مرة ..تخيل ألف
مرة ُيعاد فيها التعريف!!
وعو ً
ضا عن ذلك استخدام كائنات من نوع :StringBuilder
;)(StringBuilder sb = new StringBuilder
)for (int i = 0; i < 1000; i++
;)"*"(sb.Append
;)(string s = sb.ToString
;)Console.Write(s
;)(Console.ReadKey
68
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
كما يمكنك إضافة قيم للكائن هذا في سطر جديد باستخدام الطريقة
AppendLineكما هو حال الطريقة .WriteLine
وكما قلنا فهذا الكائن ال يقوم باستنساخ نفسه عند كل إسناد لذلك فهو
أفضل!
سبق وأن رأينا إمكانية التحويل من متغير إلى آخر ،في بعض األحيان تحتاج
ً
شكال ما بحيث تفهمه أنت والبرنامج على حد لتنسيق المتغيرات لتأخذ
سواء ..الجدول التالي يوضح رموز التنسيق:
الوصــف الرمز
تهيئة الرقم ليكون بشكل العملة المحلية ،يتعلق بإعدادات
c
كمبيوترك.
تهيئة الرقم بعدد خانات معين ،وهو مختص باألعداد
d
الصحيحة فقط.
تهيئة الرقم بواسطة الفاصلة ,لألالف والنقطة .للفواصل،
n
بدقة رقمين بعد الفصالة العشرية.
تهيئة الرقم ليظهر بالشكل العلمي ،بدقة ست أرقام بعد
e
الفاصلة العشرية.
تهيئة الرقم بعدد ثابت من األرقام العشرية. f
تهيئة عامة g
تهيئة الرقم ليظهر بالنظام الست عشري. x
69
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
سوء استخدام المتغيرات معناه أن تسند قيمة نصية مثال إلى رقمية أو
العكس ،أو أي نوعين آخرين من البيانات .قد تقول لي أننا في فقرة من
الفقرات أسندنا قيمة نصية لمتغير رقمي بعد تحويلها إليه ،أي باستخدام
الفئة ،Convertوسأجيبك بأن هذا الكالم صحيح جزئيا ،صحيح أننا أسندنا
قيمة نصية " "123إلى متغير رقمي بعد تحويلها لقيمة رقمية ،123لكن
القيمة النصية هذه ليست إال سلسلة من المحارف ألرقام .والخطأ الذي
يحصل نتيجة سوء استخدام المتغيرات هي أن تسند قيمة نصية ""abc
إلى رقمية.
70
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
المثال األول:
;int x, y
;x = 5; y = 0
!double z = x / y; //ERROR
المثال الثاني:
;int x
;)"Console.Write ("Enter Number :
;))(x = Convert.ToInt32 (Console.ReadLine
عند تنفيذ البرنامج وإدخال القيمة " "sssمثال ،ستحصل مباشرة على خطأ
بالشكل:
المثال الثالث:
;]int [] x = new int[5
!!x[17] = 27; //ERROR
71
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
try
{
C#'s Codes
.
.
}
)catch (EXCEPTION
}{Solution of the Exception error
finally
}{C#'s Code to do anyway
ومعنى الصيغة السابقة أنك تخبر C#أن يحاول بالكود المرفق بين أقواس
،tryفإذا وجد خطأً من النوع المعرّف داخل أقواس catchيقوم بما هو داخل
أقواسها ،وأخيرًا عند الخروج من try – catchسينفذ البرنامج محتويات
finallyسوا ًءا أكان هناك خطأ أم لم يكن.
72
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
ثم طباعة رسالة تعطي سبب، رصد الخطأ من نوع القسمة على صفر-
:وجود الخطأ
int x, y;
try
{
x = 5; y = 0;
double z = x / y;
}
catch (DivideByZeroException a)
{
Console.WriteLine(a.Message);
}
Console.ReadKey();
73
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
{
;)Console.WriteLine("try " + s
;s += 1
}
;)"!Console.WriteLine("\b Done
;)(Console.ReadKey
الروابط
تقسم الروابط إلى األنواع التالية :روابط رياضية ،منطقية ،مقارنة وإسناد.
حاول التفريق بين األنواع المختلفة للروابط ،وافهم كل أداة ربط ووظيفتها،
مع مرور األكواد ستالحظ الفرق بنفسك وستتمكن من استخدام أدوات
الربط دون الرجوع لهذه الفقرة حتى.
الروابط المنطقية تعيد قيمة Trueأو ،Falseصح أو خطأ .أكثِر منها في
ً
مرموقا فيه ،مع أن لها قيمتين فقط إال أنها تعني برامجك وأعطها مكانًا
الكثير ،وفي حياتنا اليومية هناك الكثير والكثير من األمور التي تأخذ قيمتين
فقط ،فمثال باب الغرفة يأخذ قيمتين مفتوح ومغلق ،المصباح يأخذ القيمتين
74
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
الجدول التالي يبين الفرق بين الروابط المختلفة ويحدد استخدام كل رابط:
75
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
مالحظة
هناك تقارب كبير بين لغات الـ Cالمختلفة ،من يفهم مبادئ لغة منها
بإمكانه استيعاب باقي اللغات ببساطة.
األمر مماثل لمن يتعامل مع لغات برمجة ليست من عائلة ،Cبعض
المبادئ مشتركة ،أو متقاربة ،مثل تعامل نظام التشغيل مع
المتغيرات ،أو التعامل مع الروابط .لكن هذا ال يعني أنها متماثلة في
كل شيء ،فقد تشترك بالمبدأ ،ولكنها مختلفة في األسلوب.
يمكنك القيام بالعمليات الرياضية المختلفة ثم حفظ الناتج ضمن متغير ،ثم
إظهار النتيجة عبر الطريقة ،WriteLineويمكن القيام بها دون وجود متغيرات
لحفظ الناتج ،الحظ األمثلة:
;Int a, b, c
;a = 5
;b = 6
;c = a + b
Console.Write (c); // 11
;Console.ReadKey
;Int a, b
;a = 5
;b = 6
Console.Write (a + b); // 11
;Console.ReadKey
;Int a, b
;a = 5
;b = 6
Console.Write (a + b + 4); // 15
;Console.ReadKey
;Int a, b, c
;a = 5; b = 6
;c = a + b
;c = c + 4
;c += 4; // c = c + 4
Console.Write (c); // 19
;Console.ReadKey
ئ ،فال توجد معادلة من الشكل ،c = c + 4 الكواد األخير رياضيا خاط ٌ
فمعناها أن 4 = 0بعد اختصار ،cوهذا مستحيل .أما برمجيا فمعناه أن
قيمة المتغير cالجديدة هي قيمته القديمة مضافا لها القيمة .4
76
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
وبالمثل:
;Int a = 3, b = 2
يطبع القيمة Console.write (a / b); // 1
;Double a = 3, b = 2
تطبع القيمة Console.write (a / b); // 1.5
;Int a = 3; double b = 2
تطبع القيمة Console.write (a / b); // 1.5
ربما تتساءل بعد كل هذه الفقرات ماهي التوابع؟! ال تستعجل على رزقك،
س ُتشرح الحقا بالتفصيل إن شاء هللا ،لكن حتى ال يأكلك الفضول
سأشرحها لك بإيجاز :التابع هو برنامج جزئي ،يحتوي على أكواد معينة
تقوم بوظيفة معينة ،بحيث يقل عدد أكواد البرنامج الرئيسي ،Main
وتسهل عملية مشاركة األكواد الخاصة بهذا التابع مع المبرمجين ،كما أن
عملية اكتشاف األخطاء ستكون أسهل ألن العمل المجزّأ يسهل تنقيحه
وتدقيقه .كما أن التوابع هي مجموعة من األكواد موجودة بشكل منفصل
عن البرنامج تحت عنوان محدد – هو اسم التابع – عند استدعاءها يتم
تنفيذ أوامرها .اآلن لنترك المواضيع المتقدمة لوقتها ولنناقش التوابع
الرياضية الجاهزة.
الجدول التالي يبين عدة توابع مستخدمة بكثرة مع تفصيلها رياضي ّا .التوابع
المثل ّثية تستقبل زوايا بالراديان حصرّا ،وهذا األمر مشترك من أجل جميع
لغات البرمجة على حد علمي.
77
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
78
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
79
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
)5(3 (−4)2
=𝑦 ( + 22 )+ 5 − 1
16 5
)5(3
=𝑦 )+ 22(3.2 + 5 − 1
16
)5(3
=𝑦 )+ 22(7.2
16
15
=𝑦 + 158.4
16
𝑦 = 0.9375 + 158.4
𝑦 = 159.3375
1ال يوجد شيء أسمه متغير بمجهول في البرمجة على عكس الرياضيات ،ال يمكنك إدخال معادلة من
الدرجة الثانية ل xوتطلب من الحاسوب حلها ،عليك إيجاد معادالت فيها متغيرات قيمها معلومة وليست
مجهولة ،وبنا ًءا عليها يتم إيجاد حلول المعادالت المطلوبة ..قد تقول "كيف تكون متغيرات وقيمها
معلومة؟!" وسأجيبك بأن هذه المتغيرات تتغير قيمها من قيمة ألخرى ،لكن هذا ال يعني أنها مجهولة،
كيف تريد من الحاسوب أن يؤسس ّ
حال مبنيّا على مجاهيل؟ باآلخر هو مجرد آلة وال يمكنه فعل
المعجزات.
80
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
ال أعلم لماذا يستخدمون حرف الهاء مكان التاء المربوطة ..في حين أنهم
ه لمجهول: يستخدمونها في أماكن أخرى!! المهم ،أجبتها في تعليق مو ّ
ج ٍ
"عندما تعطي سؤاال ما لمبرمج ،سوا ًءا أكان السؤال في الفيزياء أو
الرياضيات أو أي مجال علمي ،ال تفترض أنه يعلم طريقة حل السؤال ..هذا
بالنسبة للمبرمج ..أما نحن ،الذين نتعلم البرمجة ولم تمضِ سنون قليلة
حق سؤالك بطريقة حل على بدئنا فيها ،فال خبرة لدينا ..الزبدة :أَل ِ
"بالتنصيف" وسوف نحل لك سؤالك من عيوننا".
بالعودة لحديثنا ،الح ًقا ..عندما تصبح مبرمجا وتُعطى مسائل – أو طلبات
وأفكار لتضعها في برامج معينة – ال تطب ّق محتويات هذه الفقرة على
نفسك وتطلب الخطوات العلمية لحل البرنامج إال إن استعصى عليك ذلك،
وإنما حاول البحث عنها وتعلُّمَها ..س ُيكسبك هذا مهارة البحث ،ومهارة
العلم الذي تقوم بالبرمجة فيه..
العامل :هو ذاك اإلنسان الذي يعمل تحت إشراف المهندسين .تخيل لهذه الدرجة تعليمنا سيء. 2
81
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
أمثلة تطبيقية
. برنامج يحسب محيط ومساحة مستطيل بمعرفة بعداه-1
𝐴 =𝑎∙𝑏
𝑃 = 2 ∙ (𝑎 + 𝑏)
𝐴 = 0.5 ∙ 𝑎 ∙ 𝑏
𝑃 =𝑎+𝑏+𝑐
𝑐 = √𝑎2 + 𝑏 2 − 2 ∙ 𝑎 ∙ 𝑏 ∙ cos 𝛼
82
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
𝛼 الزاوية بين، أطوال أضالعهc وb وa ، محيطهP ، مساحة المثلثA حيث
.b وa ضلعين
const double pi = 3.14159;
double a, b, c, angle;
Console.Title = "Triangle..";
Console.Write("Enter one length of Triangle: ");
a = Convert.ToDouble(Console.ReadLine());
Console.Write("Enter another length of Triangle: ");
b = Convert.ToDouble(Console.ReadLine());
Console.Write("Enter the angle between them (deg): ");
angle = Convert.ToDouble(Console.ReadLine());
angle=angle*pi/180;
double area; area = Math.Round(0.5*a * b* Math.Sin(angle);
Console.WriteLine("A = " + area, 3));
c = Math.Sqrt(a * a + b * b - 2 * a * b * Math.Cos(angle));
Console.WriteLine("P = " + Math.Round(a+b+c, 3));
Console.ReadKey();
83
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
مالحظة
عند تعاملك مع الزوايا ضع في بالك أن لغات البرمجة تتعامل مع
الراديان ،لذلك عليك التحويل من الدرجات إليه.
قد تحتاج في بعض األحيان لتعريف متغيرات تستخدمها بشكل
مؤقت ،ستالحظ ذلك مع مرور األكواد.
𝑘 = 𝐶 + 273
9
𝑓 = 𝐶 ∙ + 32
5
;)"Console.Write ("Enter Temperature in Celsius :
;))(int C = Convert.ToInt32 (Console.ReadLine
;)Console.WriteLine ("k = {0}", C + 273
;)Console.WriteLine ("f = {0}", C * 9/5 + 32
;)(Console.ReadKey
-4يمكن حساب المسافة التي تقطعها سيارة خالل فترة زمنية ،حيث
تعطى المسافة بعالقة من الدرجة الثانية:
𝑠 = 0.5 ∙ 𝑎 ∙ 𝑡 2 + 𝑣 ∙ 𝑡 + 𝑠0
حيث sالمسافة المقطوعة a ،تسارع السيارة v ،سرعة السيارة
لحظة بدء الحركة أي عند s0و( .t0إن كل من aو vثوابت من أجل
الحركات المتغيرة بانتظام ،أما tفمتغير يتعلق باللحظة المدروسة،
و sالمسافة عند لحظة ما .)t
البرنامج التالي يحسب المسافة التي قطعتها سيارة خالل فترات
زمنية مختلفة ،الفاصل بين كل زمن وآخر هو 0.1مثال ،إذا ماكان
للتسارع قيمة ثابتة:
;)" = Console.Write("a
;))(double a = double.Parse(Console.ReadLine
;)" = Console.Write("v
;))(double v = double.Parse(Console.ReadLine
;)" = Console.Write("t
;))(double t = double.Parse(Console.ReadLine
;double s
;)"Console.WriteLine("t\ts
;)"Console.WriteLine("-------------
)for (double i = 0; i <= t; i += 0.1
84
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
{
المسافة االبتدائية معدومة فر ً
ضاs = 0.5 * a * i * i + v * i + 0; //
;))Console.WriteLine("{0}\t{1}", i, Math.Round(s, 3
}
;)(Console.ReadKey
;)" = Console.Write("h
;))(double h = double.Parse(Console.ReadLine
;const double g = 9.81
;)double t = Math.Sqrt(2 * h / g
;double v = g * t
;))Console.WriteLine("v = {0} m/s", Math.Round(v, 3
;))Console.WriteLine("t = {0} ss", Math.Round(t, 3
;)(Console.ReadKey
60 ومن أجل زاوية72 km/h مايعادل20 m/s تم الحساب من أجل سرعة
4 متر خالل أقل من35 درجة فكانت النتيجة أن القذيفة ستقطع مايزيد عن
(حاول دائما تذوق. ثانية1.8 متر بعد15.3 لتصل الرتفاع أعظمي،ثوان
.) جرب طعمتها ومعناها،النتائج
86
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
(𝑥 − 𝑥0 )2 + (𝑦 − 𝑦0 )2 = 𝑅2
87
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
88
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
89
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
الجيد في بنى التحكم أنها قريبة من اللغة البشرية ،تستخدم عبارات مثل
إذا حدث شيء ما ،عندها سيتنفذ شيء ما آخر.
90
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
مالحظة
عند وجود أمر واحد ضمن أوامر بنية الشرط ،C#'s Codesيمكن
االستغناء عن األقواس الكبيرة } {.
لنأخذ مثاال واقعيا لفهم الصيغة السابقة ،الحظ الكود الواقعي التالي:
)أحمد في المنزل( if
;سوف أزوره
;)(Console.ReadKey
بسيطة أليس كذلك!؟ هل تذكر فقرة الروابط في الفصل األول؟ قلنا عن
المتغير المنطقي أنه يأخذ قيمتين ..بنية ifتتعامل مع المتغيرات المنطقية،
بمعنى أنها تتعامل مع قيمتين فقط ،صح أو خطأ ..إذا كان الشرط محققا
فنفذ محتويات البنية ،وإال فال تنفذ.
قد تقول لي أنه بإمكانك أن تكتب بنية شرط ifتتعامل مع األعداد أو األحرف
أو النصوص أو ..إلخ من أنواع المتغيرات ..وسأجيبك بأنه كالمك صحيح
بإمكانك فعل ذلك لكن بالنتيجة بنية الشرط تتعامل مع النتيجة المنطقية
لناتج مقارنة متغير أو قيمة ما مع متغير أو قيمة ما أخريان.
;int x; x = 5
if (x > 0) // True
;)"Console.Write ("True
;)(Console.ReadKey
بالتأكيد الحظت أن xهو متغير يحمل قيمة صحيحة ،و 0هو قيمة صحيحة،
لكن إشارة المقارنة > هي ما حولت العبارة السابقة إلى قيمة منطقية.
دم الطالب على سبيل المثال ،أنت أستاذ في مدرسة ولديك طالب ،ق ّ
امتحانًا ما ،واحتجت بناء برنامج يحدد لك فيما إذا كان الطالب ناجحين أم ال.
(عالمة النجاح 60من مئة).
قد يخطر ببالك هذا الخاطر :لماذا سأقوم بتصميم برنامج كامل من أجل
تقرير ما إذا كان الطالب ناجحين أم ال ،بإمكاني مقارنة عالماتهم مع عالمة
النجاح بنفسي دون أن أتعذب وأصمم برامج بال طعمة.
عزيزي ،ال تؤاخذني بهذه الكلمة ،شكلك جديد على البرمجة ،جميع برامج
وأمثلة هذا الكتاب (وجميع برامج وأمثلة جميع الكتب في مجال البرمجة)
يمكن اعتبارها برامج جزئية لها أهداف ووظائف ما .في الواقع ،من الصعب
91
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
تصميم برنامج واحد كقطعة واحدة وإنما ُيصمم على دَفعات ،هذه الدفعات
هي عبارة عن برامج جزئية – تسمى توابع – يمكن برمجتها منفردة،
ويمكن ألكثر من مبرمج التعاون لبرمجة عدة برامج جزئية توزّع عليهم
بطريقة ما.
بالعودة للمثال ،فكّر معي قليال ،نحتاج لمقارنة عالمات طالب ما مع القيمة
االفتراضية ،60فإذا كانت أقل منها ستظهر رسالة خطأ .هذا يعني أننا
نحتاج متغيرين ،األول يحمل قيمة عالمات طالب ،واآلخر ثابت وهو .60
الحظ:
;const int Default = 60
;int Marks
;"?Console.Title = "IsFailed
;)" Console.Write("Enter Student Mark:
;))(Marks = Convert.ToInt16(Console.ReadLine
)if (Marks < Default
;)"Console.Write("Failed
;)(Console.ReadKey
وكشرح بسيط للبرنامج ،فالسطر األول يقوم بتعريف (التصريح عن) متغير
ثابت من نوع intقيمته ( 60ال يمكن أن تتغير قيمته الحقا) .السطر الثاني
يقوم بتعريف متغير من نوع intكذلك األمر .الثالث يغير عنوان البرنامج.
الرابع والخامس يظهران عبارة نصية تطلب من المستخدم إدخال قيمة ،ثم
يسند أحدهما القيمة للمتغير Marksبعد تحويلها من نصية إلى صحيحة
.intالزبدة بالسطر السادس ،والذي يحوي بنية شرط تتحقق من أن عالمة
طالب Marksهي أصغر من العالمة االفتراضية ،Defaultفإذا كان الشرط
محققا كانت نتيجته .Trueوالسطر السابع ُينفذ في حال تحقق الشرط
السابق ،وهو إظهار عبارة مفادها أن الطالب راسب .السطر األخير يوقف
النافذة مؤقتا ريثما يتكرم علينا المستخدم ويضغط على أحد األزرار.
92
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
الفكرة من المثال ليس فقط تجربة بنية الشرط ،الحظ أن عدد أوامر بنية
الشرط إذا كان أكثر من واحد فيجب استخدام أقواس وهذا ماذكرناه ساب ًقا،
وعند عدم استخدامها فإن أول تعليمة بعد أول سطر س ُتع َتبَر أم َر بنية
الشرط الوحيد.
ال داعي ألشرح أنه يمكن تعدد الشروط داخل شرط واحد أليس كذلك؟
األمر مماثل من أجل جميع الروابط المنطقية .أعتقد اآلن أن ّه باتت لديك
فكرة واضحة عن الفرق بين الروابط المنطقية وروابط المقارنة.
93
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
مالحظة
ال يجب تحديد شرط الحالة الثانية ،لغة البرمجة بطبيعة الحال تعكس
الشرط األول.
94
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
−√𝑥 + 1
, x<0
y={ 𝑥
√2 − x, x≥0
double x, y;
Console.WriteLine("Calculating y");
Console.Write("Enter x =");
x = Convert.ToDouble(Console.ReadLine ());
if (x >= 0)
{
y = Math.Log(2 - x);
Console.Write("y = " + y);
}
Else
{
y = (-Math.Sqrt(x) + 1) / x;
Console.Write("y = " + y);
}
Console.ReadKey();
:مثال آخر يخبرك فيما إذا كان اليوم الحالي هو فردي أم زوجي
bool b;
int day = DateTime.Now.DayOfYear;
//إسناد قيمة العبارة المنطقة المتمثلة بباقي القسمة إلى المتغير المنطقي
b = (day % 2 == 0);
if (b)
Console.WriteLine("day is an even number");
else
Console.WriteLine("day is an odd number");
Console.ReadKey();
95
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
والمثال التالي يريك كيفية إنشاء بنية شرط متفرعة ،لمعرفة الحرف
المدخل هل هو كبير أم صغير في حال كان حرفا أصال ،أما في حال لم يكن
حرفا يظهر لك عبارة بذلك:
;)" Console.Write("Enter a character:
;)(char c = (char)Console.Read
))if (Char.IsLetter(c
{
))if (Char.IsLower(c
;)"Console.WriteLine("The character is lowercase.
else
;)"Console.WriteLine("The character is uppercase.
}
else
;)"Console.WriteLine("Not an alphabetic character.
;)(Console.ReadKey
96
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
مالحظة
.Else بإمكانك عدم استخدام بنية
.If يجب عليك وضع شرط كما هو الحال فيElse If في بنية
𝑎 𝑥2 + 𝑏 𝑥 + 𝑐 = 0
إن تصميم األمثل للبرنامج يعتمد على خوارزميتك وبناءك لخطوات سير
من الطبيعي عند حل معادلة من الدرجة الثانية أن نمر بالخطوات.البرنامج
:التالية
97
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
;)"!Console.WriteLine("Cannot be Solved
;)(Console.ReadKey
ال تحاول دائما االعتماد على المشاريع مفتوحة المصدر ،أو الدروس
والمشاريع الجاهزة ،أو مكتبات األكواد ،حاول فقط أن تستوحي الفكرة من
هؤالء جمي ًعا مع ابتكار أفكار وأساليب خاصة بك ،مع الحفاظ على مراجع
ثابتة تعود إليها عند الضرورة ،وال بأس أن تكون هذه المشاريع مفتوحة
المصدر أو الدروس والمشاريع الجاهزة أو مكتبات األكواد هي هذه المراجع،
فليس بالضرورة أن تكون المراجع دائما نظرية جافة..
أمر آخر خذه بعين االعتبار ،األمثلة التي أضعها في هذا الكتاب بعيدة ج ًدا
عن الواقعية وهي مسيسة قدر اإلمكان لخدمة الفقرة الراهنة ،فلم أتناول
جميع االحتماالت على المسائل المدروسة عند حل المسألة حتى ال
أشتت تركيزك ،أو أهوّل لك الفكرة وأع ّقدها ..في المثال األخير ماذا لو
أدخل المستخدم قيم ًة غير رقمية مثال ؟ أو كان الثابت Aمعدوم ؟؟
ماذا لو ترك قيمة المتغيرة فارغة ؟؟؟ البرنامج الناجح هو ذاك الحاوي
على أكثر عدد من االحتماالت بأبسط وأكسل الطرق ،والبرنامج األنجح هو
ذاك الحاوي على توابع وفئات تجزّء البرنامج إلى أكبر قدر ممكن بحيث
يصبح البرنامج حلقات متكاملة يمكن استخدام أي حلقة بغنى عن الحلقات
األخرى في أي برنامج آخر ،األسطر السابقة هي باختصار الفكرة من
التوابع والتي سنتناولها بالتفصيل في الفصل السادس إن شاء هللا.
قبل االنتقال إلى بنى جديدة البد من التنويه إلى أن C#يربط elseبآخر if
قبلها ،لذلك كوّن صداقة مع األقواس { }.
الحظ المثال:
;int x, y
;x = 6; y = 3
if (x > 4) //True
if (y > 4) //False
;)"Console.WriteLine ("x and y > 4
else
;)"Console.WriteLine ("x is <= 4
;)(Console.ReadKey
انسخ الكود السابق إلى فيجوال ستوديو وستالحظ أنه حاذى else
مستوى ifالفرعية ،ل ُتعتَبر حالة ثانية لها.
98
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
وعند تنفيذ البرنامج ،وطالما أن x > 4فالبنية الفرعية سوف تُعالَج ،وبما أن
yليست أكبر من 4فالشرط غير محقق وستتم تنفيذ أكواد elseوالتي
تقول أن xأصغر أو تساوي ،4وفي الواقع هي !!6
إن األمر 1ينفذ إذا كان الشرط محققا ،بمعنى أنه إذا كانت نتيجته ،True
بينما األمر 2فهو معاكس له.
99
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
-الدخول إلى البنية بمتغير معين (وليس بحالة معينة كما في الشرط ،إذ
إننا لن نقارن متغيرات مع بعضها البعض ،وإنما سنناقش قيمة متغير بعينه).
-عند تحقق إحدى القيم فإن مجموعة أكواد ستتنفذ ،ثم يتم الخروج من
بنية االختيار لوجود التعليمة .Break
مالحظة
عند عدم وجود التعليمة ،Breakفإن بنية االختيار لن يتم الخروج
منها مالم يتم المرور بجميع حاالت البنية أو المرور بتعليمة .Break
100
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
في أحد الفنادق تم إنشاء برنامج يقوم بإظهار أسعار الغرف من أجل يوم
واحد ،بحيث يختار الزبائن الغرف عبر الحواسيب مثال.
يقوم البرنامج بإظهار ثالثة خيارات على سبيل المثال ،وبحسب اختيار
الزبون يتم إظهار سعر الغرفة من أجل يوم واحد فقط.
;)"Console.WriteLine("Menu:\n
;)"Console.WriteLine("A) Room with one bed
;)"Console.WriteLine("B) Room with tow beds
;)"Console.WriteLine("C) Room with three beds
;)"begin: Console.Write("Choose A,B or C:
;))(char choise = Convert.ToChar(Console.ReadLine
{ )switch (choise
case 'a':
case 'A':
;)"Console.WriteLine ("Cost of this room is 25$/day
;break
case 'b':
case 'B':
;)"Console.WriteLine ("Cost of this room is 40$/day
;break
case 'c': case 'C':
;)"Console.WriteLine ("Cost of this room is 60$/day
;break
default:
;Console.WriteLine ("Choose A,B or C ONLY"); goto begin
}
;)(Console.ReadKey
-لوحة المفاتيح تُتدخل قيم من نوع نصي Stringلذلك يجب التحويل للنوع
الحرفي.
101
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
-قد يدخل الزبون حرف كبير أو حرف صغير لذلك يجب وضع القيمتين
بالحسبان ،إذ إن الكمبيوتر يميز بين األحرف الكبيرة واألحرف الصغيرة.
مالحظة
عند وضع حالة بدون أكواد ،فإن الحالة التالية ستنفذ!
الحظ الصور التالية ،األولى تم تنفيذ البرنامج دون أية أخطاء (في االختيار)،
الثانية والثالثة تم اختيار غرفة غير موجودة ضمن الخيارات ثم اختيار واحدة
موجودة.
102
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
قد تسألني عن إمكانية استخدام بنية اختيار Switchبدال من بنية شرط If
لتحديد ما إذا كان المقام معدوما أم ال ،سأجيبك بنعم تستطيع ذلك لكن
هناك احتمال كبير أن يكون المقام عددا عشريا ،وقد أشرت سابقا إال عدم
إمكانية مناقشة األعداد غير الصحيحة.
قد تتساءل لماذا ال يمكن القسمة على صفر؟! لماذا يمثل هذا العدد
كابوسا عند إجراء القسمة .جميع من مرّ على مسائل رياضية واكبَ
المسائل التي تفترض ،𝑥 ≠ 0لماذا هذا التمييز برأيك!؟
103
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
في الواقع وكما تعلم عزيزي فالمقام كلما صغر زادت قيمة الكسر ،وعند
الوصول لقيمة قريبة من الصفر ،فإن الكسر سيأخذ قيم كبيرة جداً قد ال
تتخيلها حتى.
20 − 5 = 15
15 − 5 = 10
10 − 5 = 5
5−5=0
20 − 0 = 20
20 − 0 = 20
20 − 0 = 20
⋮
20 − 0 = 20
ستبقى تنقص القيمة 0من العدد 20إلى أن يأخذ هللا أمانته منك ولن
20
التي علمونا إياها في المدارس، تنتهي .الموضوع أعقد من ∞ →
0
الموضوع منطق ومبدأ وليس فقط معادالت ومسلّمات ،وهذا المنطق سائد
في الرياضيات والفيزياء والبرمجة واللغات حتى.
104
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
أمثلة تطبيقية
، باإلضافة إلى جنسه، برنامج يطلب من المستخدم اسمه وعمره-1
وبعدها يقوم بطباعة رسالة ترحيبية مسبوقة بـ "أهال ً سيد فالن" إذا
مع إظهار. و"أهال ً سيدة فالنة" إذا كانت أنثى،كان المستخدم ذكرا
.الوقت الذي قام بتشغيل البرنامج فيه
// 1
string name;
int age;
char gender;
string time;
// 2
time = DateTime.Now.ToShortTimeString();
Console.Title = "Welcome to C# Program";
// 3
Console.Write("Enter Your Name : ");
name = Console.ReadLine();
Console.Title = "Logged in by " + name;
Console.Write("Enter Your Age : ");
age = Convert.ToInt16(Console.ReadLine());
Console.Write("Press [m] for Male, [f] for Female : ");
gender = Convert.ToChar(Console.ReadLine());
// 4
if (gender == 'm')
{
Console.WriteLine("Welcome Mr. " + name);
Console.WriteLine ("Your age is "+ age);
}
else if (gender == 'f')
{
Console.WriteLine ("Welcome Mrs. " + name);
Console.WriteLine ("Your age is " + age);
}
else
Console.WriteLine ("Error 101..");
// 5
Console.WriteLine("you started the program at " + time);
Console.ReadKey();
:شرح البرنامج
105
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
-إسناد قيمة الوقت الحالي للمتغير المخصص لحفظ قيمة الوقت بصيغة
الوقت القصير ##:##ص/م ،باإلضافة إلى تغيير عنوان البرنامج.
-مقارنة المتغير الحاوي على جنس المستخدم بقيم ثابتة مرجعية ،فإذا
كان " "mأظهر عبارة "أهال سيد فالن" ،وإذا كان " "fأظهر عبارة "أهال
سيدة فالنة" ،وإال أظهر عبارة خطأ.
-2برنامج ُيد ِ
خل درجة الحرارة مقدرة بالفهرنهايت ،يقوم بتحديد فيما إذا
كانت مناسبة للجو أم ال ،ثم يقوم بطباعة مايساويها في
الفهرنهايت .حيث أن سلم درجات الحرارة بالفهرنهايت يتراوح ضمن
المجال ( )-32 – 212ودرجة حرارة الغرفة النظامية هي ضمن
المجال ( )15 – 25درجة مئوية .والعالقة التي تربط بين مقياسي
درجات الحرارة هي:
(𝐹 − 32) ∙ 5
=𝐶
9
;int c, f
;)" Console.Write("Enter Temperature (F):
106
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
f = Convert.ToInt16(Console.ReadLine());
if (f < -32 || f > 212)
Console.WriteLine("Temperature is out of range!");
else
{
c = (f - 32) * 5 / 9;
if (c >= 15 && c <= 25)
Console.WriteLine("Temperature is good : " + c + " (C)");
else
Console.WriteLine("Temperature is bad : " + c + " (C)");
}
Console.ReadKey();
،ال أظن أنه من الضروري شرح األمثلة التطبيقية على غرار المثال األول
.فقد أصبحتم كبا ًرا اآلن بوصولكم لنهاية هذا البحث
107
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
108
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
c = Convert.ToInt16(Console.ReadLine());
// *
int temp;
if (a < b)
{
temp = a;
a = b;
b = temp;
}
if (a < c)
{
temp = a;
a = c;
c = temp;
}
if (a >= c + b)
Console.WriteLine("Triangle can't be formed!");
else if (a * a == b * b + c * c)
Console.WriteLine("Right Triangle can be formed!");
Else
Console.WriteLine("Triangle can be formed!");
Console.ReadKey() ;
مالحظة
يجب تحديد أكبر ضلع من أضالع المثلث لنطبق القاعدة المذكورة
.في نص المسألة
109
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
110
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
ً
مثاال بيانيا للقيم السابقة .مع العلم أن المستقيم والشكل التالي يوضح
منصف للربع األول أي أن معادلته 𝑥 = 𝑦 والتي يجب أن تكتب −𝑥 + 𝑦 = 0
لتصبح بالشكل المستخدم في الحل.
111
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
112
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
على غرار بنى الشرط ،فإن بنى التكرار لها أكثر من صيغة واحدة ،ولك ٍ ّ
ل
استعمال وتفضيل.
حلقة For
تعتبر من أشهر بنى التكرار والحاضي والماضي 1يعرفها ،وهي مشتركة
في كثير من لغات البرمجة على اختالف أساليب التصريح عنها من أجل
ذات المبدأ .الصيغة العامة لها:
113
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
إن الصيغة السابقة تعني – بلغة إنسانية أكثر منها برمجية – أنه من أجل
القيمة االبتدائية لعداد الحلقة سيتم تنفيذ أكواد الحلقة بشكل متكرر من
أجل شرط التكرار ،مع األخذ بعين االعتبار خطوة عداد الحلقة.
مالحظة
عند وجود أمر واحد ضمن أوامر حلقة التكرار ،C#'s Codesيمكن
االستغناء عن األقواس الكبيرة } {.
القيمة االبتدائية هي قيمة عداد الحلقة.
لنأخذ مثاال عن طباعة عبارة نصية خمسَ مرات باستخدام حلقة تكرار ودون
استخدام ،الحظ:
;)(n = DateTime.Now.ToShortTimeString
Console.WriteLine("Welcome Eng27 Time ;)is: " + n
;)(n = DateTime.Now.ToShortTimeString
Console.WriteLine("Welcome Eng27 Time ;)is: " + n
;)(n = DateTime.Now.ToShortTimeString
Console.WriteLine("Welcome Eng27 Time ;)is: " + n
;)(n = DateTime.Now.ToShortTimeString
Console.WriteLine("Welcome Eng27 Time ;)is: " + n
;)(n = DateTime.Now.ToShortTimeString
Console.WriteLine("Welcome Eng27 Time ;)is: " + n
;)(Console.ReadKey
114
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
فكر معي ،كم متغير لدينا؟؟؟؟؟ لدينا متغير واحد ،العدد الذي سنكتب
جدوله ثابت ،أما األعداد التي سنضربها به فهي متغيرة (من 1حتى .)10
إذا فكرت معي أكثر ستالحظ أنه باإلمكان االستفادة من عداد الحلقة في
إنشاء هذا الجدول ،وبالنسبة للشرط فهو بسيط جدا ،طالما عداد الحلقة
أصغر من 9استمر في العمل .الحظ:
)for (int i=1;i<=10;++i
;)Console.WriteLine("4 x " + i + " = " + 4 * i
;)(Console.ReadKey
بإمكانك تنفيذ هذا المثال على جميع لغات cبنفس األكواد حتى (مع تغيير
بسيط في أكواد اإلدخال واإلحراج و)..
115
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
ماذا تغير لدينا؟ لدينا متغيران ،األول هو العدد الذي سنحسب جدول الضرب
له ،اآلخر هو األعداد التي سنضربها بالعدد األول.
من البديهي من المناقشة السابقة أن نقول أنه لدينا حلقتا ،forلكل منها
عداد منفصل ،وبالتفكير مليا بالموضوع نالحظ أن عداد الحلقة األولى يزداد
عند تغير قيمة عداد الحلقة الثانية من القيمة 1وحتى ،10بمعنى آخر فإن
الحلقة الثانية يجب أال يتحقق شرطها حتى تزداد قيمة عداد الحلقة األولى
بمقدار خطوة واحدة.
عاد ًة في بعض كتب شرح لغات البرمجة أمثال c++وغيرها يتم إنشاء
فقرة كاملة محتواها "حلقات forالمتداخلة" ،ومفادها أن إحدى الحلقات
ستتكرر بشكل كامل من أجل خطوة واحد للحلقات األخرى ،لن أستخدم
هذا األسلوب وسأكتفي بمثال:
)for (int i = 1; i <= 10; ++i
{
)for (int j = 1; j <= 10; ++j
;)Console.WriteLine(i + " x " + j + " = " + i * j
;)"Console.Write("\n
}
;)(Console.ReadKey
ال داعي لتجربة كتابة األكواد يدويا أليس كذلك؟؟؟؟ وعلى غرار المثال
السابق بإمكانك تنفيذ هذا المثال على لغات cمختلفة.
116
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
Do
{
C#'s Codes
.
.
;)شرط التكرار( } While
كمثال ،لنطلب من المستخدم أن يدخل عددا ما ،فإذا كان موجبًا أعدنا
عليه الطلب:
;int a
;)" Console.Write("Enter Number:
;))(a = Convert.ToInt32(Console.ReadLine
do
{
;)" Console.Write("Enter Number:
;))(a = Convert.ToInt32(Console.ReadLine
;)} while (a > 0
;)"Console.WriteLine("Finish
;)(Console.ReadKey
حلقة while
تشابه حلقة forكثيرا وتختلف عنها بطريقة التنفيذ ،كما أنها تختلف عن
حلقة do – whileبأنها ال تنفذ التعليمات إال إذا تحقق الشرط ،ولها الصيغة:
117
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
هل الحظت الفرق بين الحلقتين؟ في المثالين تعمدت إسناد القيمة 0
للمتغير ،aفي األولى تم تنفيذ الكود رغم أن القيمة ليست موجبة تماما،
وفكرة البرنامج – أو الكود – كما الحظت هو إعادة طلب الرقم مادام موجبا،
وهذا مالم يؤخذ بعين االعتبار في الحلقة األولى لمرة واحدة فقط ،بينما تم
مراعاته في الثانية.
بمعنى آخر ،في بعض األحيان تحتاج لتنفيذ كود ما ،ثم تكراره عند تحقق
الشرط .عوضا عن كتابة الكواد خارج الحلقة ثم كتابته من جديد داخل
118
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
Label:
C#'s Codes
.
.
;Goto label
119
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
التحكم بالحلقات
توفر لك العديد من لغات البرمجة وسائل للمناورة في أكوادها ،ومن هذه
الوسائل هي المناورة أثناء تنفيذ الحلقات التكرارية ،قد تحتاج لتجاهل
إحدى التكرارات أو إيقاف الحلقة عند تكرار معين ،وسنناقش وسيلتين في
كتابنا هذا:
باستخدام continue
تستعمل لتجاهل التكرار الذي تحقق فيه شرط ما ،وهي موضحة بالمثال
التالي:
)for (int i = 1; i<=10; ++i
{
)if (i == 5
;continue
;)Console.WriteLine (i
}
;)(Console.ReadKey
باستخدام break
120
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
أمثلة تطبيقية
-1جمع األعداد داخل مجال معين.
ال تنسَ إضافة مكتبة نوافذ ويندوز كمرجع للبرنامج لتتمكن من عرض
صندوق الرسالة ،راجع الفصل صفر ضمن فقرة اإلخراج بصندوق رسائل.
حيث:
Qالقيمة األصلية.
121
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
double A, Q = 1000;
double rate = 0.05;
double DollarToSP;
string Result;
Console.Write("Enter how much dollars in S.P. : ");
DollarToSP = Convert.ToDouble(Console.ReadLine());
Result = "\ السنةt \ األسهم قيمةn";
for (int year = 1; year <= 10; year++)
{
A = DollarToSP * Q * Math.Pow(1 + rate, year);
Result += year + "\t" + String.Format("{0:c}", A) + "\n";
}
MessageBox.Show(Result, ";)"قيمة األسهم مع نهاية كل سنة
122
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
;)"Console.Write("x
;number /= d
}
;d++
}
;)Console.Write(1
;)(Console.ReadKey
معنى البرنامج السابق هو :لدينا عددان أحدهما العامل األولي ،2بعد
إدخال العدد المراد تحليله إلى جداء عوامل أولية وطالما أن العدد موجب
وطالما أنه ال يوجد باقي قسمة عند قسمة العدد على العدد األولي
فقسمه عليه ،عندما ال يتحقق الشرط الثاني زد العدد األولي بمقدار واحد
وجرب من جديد ،عندما ال يتحقق الشرط األول والخروج من الحلقة اكتب
العدد ( 1وذلك حتى ال يبقى آخر رمز ضمن الصيغة هي xجداء ،جرب عدم
استخدام ).) Console.Write(1
123
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
124
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
بإمكانك تطبيق هذا المثال بشكل احترافي أكثر فيما لو أمكنت المستخدم
وبإمكانك أيضا تطوير.من تحديد الفئات النقدية القياسية التي يملكها
الحظ.البرنامج ليعطيك عدد الوحدات النقدية القياسية بدال من تكرارها
:الكود
Console.Write("Enter a price : ");
int price = Convert.ToInt32(Console.ReadLine());
Console.Write("Enter what you paid : ");
int paid = Convert.ToInt32(Console.ReadLine());
int change = paid - price;
int c1000, c500, c200, c100, c50, c25, c10, c5;
c1000 = c500 = c200 = c100 = c50 = c25 = c10 = c5 = 0;
while (change >= 1000)
{ c1000 += 1; change -= 1000; }
while (change >= 500)
{ c500 += 1; change -= 500; }
while (change >= 200)
{ c200 += 1; change -= 200; }
while (change >= 100)
{ c100 += 1; change -= 100; }
while (change >= 50)
{ c50 += 1; change -= 50; }
while (change >= 25)
{ c25 += 1; change -= 25; }
while (change >= 10)
{ c10 += 1; change -= 10; }
while (change >= 5)
{ c5 += 1; change -= 5; }
if (c1000 == 1) Console.WriteLine("One 1000");
else if (c1000 > 1) Console.WriteLine(c1000 + " 1000");
125
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
126
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
َ
دون زيادة أو نقصان. بشحمها ولحمها :كامل ً
ة 1
127
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
if (line.Substring(i, 1) == letter)
count++;
}
} while (line != null);
file.Close(); Console.WriteLine("Count = {0}", count); Console.ReadKey();
128
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
من المحتمل وإذا لم يخب ظني – وإذا كنت تتأمل وتراجع هذا المثال أكثر
من مرة – فإنك طالب جامعي طُلِب منه كتابة برنامج يطبع مجموعة من
.النجوم وفق شكل ما باستخدام الحلقات
129
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
Console.WriteLine();
}
for (int i = n - 2; i >= 1; i -= 2)
{
for (int j = i; j <= n; j += 2)
Console.Write(" ");
for (int j = i; j > 0; --j)
Console.Write("*");
Console.WriteLine();
}
}
else
Console.WriteLine("Only odd numbers between 0 and 20 can be used");
Console.ReadKey();
.) هو فقط مثال، وأن يكون فرديا يمكن تغييره20 و0 الشرط (مابين
130
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
131
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
;double d = 0
{ do
;x[i] = d
;d+=h
;++i
;)} while (d <= a
;double L=0
)for (i = 0; i<=n;++i
{
)if (i == 0 | i == n
;)]L += 1/(1+x[i]*x[i
else
;)]L += 2*1/(1+x[i]*x[i
}
;L *= h / 2
;)Console.WriteLine("L = " + L
;)(Console.ReadKey
132
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
133
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
التصريح عن المصفوفات
الصيغة التالية تستخدم لتعريف المصفوفات أحادية البعد ،عدد عناصرها :n
مالحظة
أول عنصر في المصفوفات ترتيبه ،0وهذا شائع في جميع لغات
البرمجة ،هذا يعني أن آخر عنصر ترتيبه أقل من عدد عناصر
المصفوفة بمقدار واحد.
من الممكن في بعض لغات البرمجة تغيير ترتيب أول عنصر بجعله 1
بدال من .0
134
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
الحظ – عزيزي القارئ – أنني صرّحت عن مصفوفة عدد عناصرها 7من نوع
نصي ،اسمها ،dayعند التعامل مع عناصر المصفوفة نعتبر أول عنصر
ترتيبه ،0وعندما تتعامل مع المستخدم – الذي ال يفقه شيئا في
البرمجيات وترتيب العناصر والمصفوفات – فإنك ستناقشه على أساس
المنطق الواقعي المتمثل بأن أول عنصر ترتيبه .1حاول التفريق بين
المستخدم وبين الكمبيوتر ،بين أكوادك وبين القيم التي يعطيك إياها
المستخدم..
في حال كانت عناصر المصفوفة مكونة من سلسلة معروفة أو ناتجة عن
عمليات متالحقة أو ُمدخلة بالتتابع من قبل المستخدم ف ُتستخدم عاد ًة
حلقات التكرار.
;]double[] num = new double[10
)for (int i = 1; i <= 10; ++i
{
;num[i-1] = i * i
;)]Console.WriteLine(i + "^2 = " + num[i-1
}
;)(Console.ReadKey
ال تنسَ أن أول عنصر ترتيبه ،0وأن المستخدم لن يتعامل معك بالمنطق
البرمجي ،ال تنسَ هذا أب ًدا!
135
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
التعامل مع المصفوفات
مالحظة
في بنى الشرط ،وعند مقارنة متغيرات منطقية بالقيمة ،Trueال
داعي لذكر الشرط كامال ،بمعنى أن ) if (a = Trueتكافئ ) if (aألن
ناتج عملية المقارنة هو قيمة منطقية ،وهذا ما تسعى بنى الشرط
للتعامل معه.
في بنى الشرط من الممكن وضع تعليمة الشرط أمام جملة الشرط
في حال كانت تعليمة واحدة ،ويجب وضع أقواس في حال كانت أكثر
من تعليمة.
136
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
-للحصول على أول عنصر ضمن مصفوفة وآخر عنصر استخدم التابعين
Firstو:Last
;))(Console.WriteLine("First item is " + num.First
;))(Console.WriteLine("Last item is " + num.Last
استخدام Array
-لمسح عناصر محددة بد ًءا من عنصر فالني وحتى عنصر فالني آخر من
عناصر مصفوفة ما استخدم اإلجراء .Clearيجب تحديد اسم المصفوفة،
ترتيب عنصر البداية وعنصر النهاية بحيث ال يتجاوز عنصر النهاية عدد عناصر
المصفوفة:
;)Array.Clear(num, 2, 3
137
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
عند تنفيذ اإلجراء السابق فإنه سيتم استبدال ثالثة عناصر من المصفوفة
numبدءا من العنصر الثاني بالقيمة ،0ولو تم التعامل مع مصفوفة نصية
فإنه سيتم مسح العنصر (لن يتم إسناد القيمة 0له).
الحلقات في المصفوفات
جلنا إحدى البنى وهي بنيةفي الفصل الثالث تناولنا بنى تكرار متنوعة وأ ّ
،foreachوالتي تستخدم مع المصفوفات .الصيغة العامة لها:
حيث nمتغير من نوع بيانات المصفوفة (من نوع المصفوفة ذاتها) ،لتتضح
الفكرة عليك أكثر الحظ المثال التالي:
138
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
اللوائح Lists
ال تختلف اللوائح كثي ًرا عن المصفوفات ،فالمهمة المسندة إليهما ذاتُها وقد
تم توضيحها في بداية الفصل.
التصريح عن اللوائح
التعامل مع اللوائح
139
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
-إضافة عنصر
ً
شكال باألقواس ،وال نقوم بإسناد القيم تختلف اللوائح عن المصفوفات
للعناصر وإنما بإضافتها ألنها غير موجودة أصال ،حيث نضيف العنصر وقيمته.
المثال التالي يوضح عملية التعامل مع ستة مواد دراسية مدخلة مسبقا،
ويناقش البرنامج عدد المواد الراسبة ومعدل المواد معا:
;double Sum = 0
;)(>List<int> Marks = new List<int
;)Marks.Add(90
;)Marks.Add(80
;)Marks.Add(55
;)Marks.Add(90
;)Marks.Add(40
;)Marks.Add(66
)foreach (int m in Marks
)if (m < 60
;Sum = Sum + 1
;))Console.WriteLine("Average = " + Math.Round(Marks.Average(), 2
;)"!Console.WriteLine("Failed in " + Sum + " Subjects
;)(Console.ReadKey
النتيجة بالتأكيد ستكون راسب بمادتين ،والمثال سيكون واقعي أكثر فيما
لو تم إدخال المواد من قبل المستخدم أو من خالل استيراد القيم من ملف
خارجي أو قاعدة بيانات.
-حذف العناصر
140
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
مالحظة
أول عنصر في اللوائح ترتيبه .0
القواميس Dictionaries
قد تحتاج في كثير من األحيان إلى تخزين بيانات مشتركة بالنوع،
وفهرستها لتسهيل وتنظيم الوصول إليها .تعطيك المصفوفات واللوائح
فهارس تلقائية تتمثل بأعداد صحيحة تبدأ بالصفر ،أما القواميس فتعطيك
إمكانية فهرسة البيانات وفق أي نوع ترغب به.
التصريح عن القواميس
;)( >عنصر ,مفتاح< = new Dictionaryاسم_القاموس >عنصر ,مفتاح<Dictionary
141
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
;)"Names.Add(2, "Hasan
;)"Names.Add(3, "Khaled
;)"Names.Add(4, "Mahmoud
مالحظة
م أن > KeyValuePair<string, stringلم تعجبك ،لذلك سأخبرك أنه يمكنك أَعلَ ُ
استبدالها بـ ،varحيث أن varمتغير غير محدد .فالمترجم يقرر نوعه طبقا
للعملية الجارية والمتغيرات الممررة معه ..حيث إن األولى هي تركيب struct
خاص بالمجموعات.1
كما يمكن طباعة عنصر بمعرفة ترتيبه ضمن القاموس من خالل التابع
ElementAtوالذي يستقبل متغير رقمي صحيح:
]Console.WriteLine(Names.ElementAt(2)); //Prints [Name3, Hasan
المجموعات هي عبارة عن المصفوفات أو اللوائح أو ( . .إلخ من طرق تجميع البيانات المتشابهة معا). 1
142
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
المكدسات Stacks
دسات هي نوع من أنواع تجميع البيانات مثل المصفوفات واللوائح م َ
ك ِّ ال ُ
والقواميس ،إال أنها تختلف عنها بطريقة االستخدام أو الفكرة من وجودها.
عند إضافة العناصر للمكدسات فإن العنصر الجديد سيكون أمام أو أعلى من
العنصر القديم ،بمعنى أنه بإمكانك الوصول للعناصر األجدد أوال .هذا يعني
143
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
أن عملية طرح العناصر ستكون من العنصر األخير إلى العنصر األول .وهذا ما
يسمى بتقنية LIFOوهي اختصار لـ .Last Input First Output
التصريح عن المكدسات
myStack
Item5
Item4
Item3
Item2
Item1
طرح العناصر ال يعني التخلص منها وإنما إسنادها إلى متغير آخر .تتم
عملية طرح العناصر عن طريق التابع Popوالذي يقوم فعليا بحذف العنصر
من المكدس وإسناده إلى متغير ما .وكما اتفقنا فعملية الطرح تكون وفق
العنصر األخير.
string x = myStack.Pop().ToString(); //x = Item5
144
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
كما يمكنك طرح العناصر من المكدسات دون حذفها منها عن طريق التابع
:Peek
x = myStack.Peek().ToString(); //x = Item4
:والنتيجة ستكون
145
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
Clearing myStack...
ختا ًما ،ال تقتصر عملية تخزين المتغيرات المتشابهة على المصفوفات
واللوائح والقواميس ،هناك أي ً
ضا Collectionو ArrayListو SortedListوالكثير
ضا ،كما أن هناك نوع آخر هو ،Hashtableوالذي ال يختلف كثيرا عن أي ً
القواميس.
146
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
أمثلة تطبيقية
مالحظة
غير مطلوب منك فهم المعادالت الواردة في هذا الفصل – أو بقية
الفصول – وإنما عليك فهم كيفية استخدامها وكيفية تكويدها .هناك
أناس متخصصون في الرياضيات سيفهمون هذه المعادالت ،النقاش
واالستنتاجات موجهة لهم ..أنت عليك األكواد فقط.
توجه مباشرة للكود وخذ النتيجة النهائية من كل استنتاج.
فكرة الحل:
سبق واتفقنا على أنه لحل أي مسألة في البرمجة يجب تجريد المطلوب
والحصول على صيغة نهائية للمتغيرات المطلوبة ،بحيث يتم التعويض
مباشرة فيها للحصول على النتيجة.
حيث xو yمجهوالن ،والبقية ثوابت ..لنأخذ مثاال ونحله رياضيا التسنتاج
طريقة ألتمتته!
−5 𝑥 + 2 𝑦 = −5
{
1 𝑥 + 2 𝑦 = 13
لحل جملة المعادلتين السابقتين هناك ثالثة طرق ،إحداها طرح المعادلتين
من بعضهما ..الحظ:
147
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
Resault = BB – AA
بنا ًءا عليه يمكن حساب المتغير الثاني وذلك بعد قسمة مابعد المساواة
على أمثاله..
ثالثا :نعزل من Aأو Bأو AAأو BBعالقة لـ xونعوض فيها قيمة .y
148
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
149
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
مالحظة
ضتَ كان من الممكن أن يكون البرنامج السابق أفضل في حال ُع ِر
على كل حال هكذا.)B وA المعادلتين بعد إدخال أمثالهما (كل من
..برامج وأمثلة تطبيقية ُيستَفاد منها في النوافذ أكثر من هنا
150
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
1كثير الحدود هو تركيب جبري يتكون من واحد أو أكثر من المعامالت والمتغيرات ،يتم بناؤه باستخدام
عمليات الجمع والطرح والضرب واألسس الصحيحة غيرالسالبة( .المصدر :ويكيبيديا – متعدد الحدود).
151
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
حيث:
سأبسط لك الموضوع أكثر ..لدينا مسألة نعلم فيها نقاط فقط ،خذ المسألة
التالية:
لنقم بتعيين النقاط على جملة محاور إحداثية كما يفعل االقتصاديون:
152
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
والذي نريده هو رسم منحني بياني تقريبي يمر من كافة النقاط السابقة
ومعرفة تابعه الرياضي ،بحيث يمكن معرفة قيمة األرباح (المحور
الشاقولي) بمجرد معرفة أو توقع قيمة رأس المال (المحور األفقي) ،كما أن
التابع الرياضي يعطي توقعات أدق من الرسم البياني .وإحدى طرق معرفة
التابع الرياضي هي طريقة االستيفاء الداخلي لالغرانج ،والتي تعتمد على
نقاط يمر منها التابع الرياضي (جذور التابع الرياضي) ،وبكلمات أخرى:
النقاط التي تحقق معادلة التابع الرياضي.
المخططات على شكل أعمدة ال تعطيك مجاال لتوقع نقاط أخرى وإنما
تسمح لك بمقارنة النقاط المعلومة فقط.
بما أن الجدول يحوي أربعة قيم فهذا يعني أن تابع الغرانج له الشكل:
4
) (𝑥 − 𝑥0 ) ∙∙∙ (𝑥 − 𝑥𝑖−1 ) ∙ (𝑥 − 𝑥𝑖+1 ) ∙∙∙ (𝑥 − 𝑥3
𝑖𝑦 ∑ = )𝑥( 𝐿4
) (𝑥𝑖 − 𝑥0 ) ∙∙∙ (𝑥𝑖 − 𝑥𝑖−1 ) ∙ (𝑥𝑖 − 𝑥𝑖+1 ) ∙∙∙ (𝑥𝑖 − 𝑥3
𝑖=1
وبالتالي:
)(𝑥 − 2)(𝑥 − 3)(𝑥 − 5 )(𝑥 − 1)(𝑥 − 3)(𝑥 − 5
𝐿4 (𝑥) = 1 +5
)(1 − 2)(1 − 3)(1 − 5 )(2 − 1)(2 − 3)(2 − 5
)(𝑥 − 1)(𝑥 − 2)(𝑥 − 5 )(𝑥 − 1)(𝑥 − 2)(𝑥 − 3
+ 14 + 25
)(3 − 1)(3 − 2)(3 − 5 )(5 − 1)(5 − 2)(5 − 3
وبالتالي:
154
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
للتأكد من صحة الحل ،جرب عوض قيم xلتحصل على ،yوبالتأكيد ستكون
قيم تقريبية منها ألن التابع هو تابع تقريبي.
لكن لحظة ،كيف سنقوم بهذا بالبرمجة؟! الصفحات السابقة ليست إال
مقدمة ،اآلن بدأ العمل ..وأعيد تذكيرك إذا لم تكن مختصّا بالرياضيات أو من
ذب نفسك بقراءة المناقشة وكيفية االستنتاج ،ال أريد أن محبيها فال تع ّ
تخصص وق ًتا من أدعيتك للدعاء علي .
ما ،وتح ّ
ل ببعض الصبر، أما إذا كانت االستنتاجات تروق لك ،فأحضر ورقة وقل ً
وفكر معي:
في البداية لنستنتج ماهو ناتج نشر معادلة من الدرجة الثالثة (أي معلوم
منها ثالثة نقاط) ،وهي من الشكل(𝑥 − 𝑎)(𝑥 − 𝑏)(𝑥 − 𝑐) :
155
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
ألف مبروك لقد استنتجت منشور معادلة من الدرجة الثالثة بمعرفة ثالثة
جذور منها ،بغض النظر ما إذا كان هناك من سبقك في استنتاجه أو سجله
تحت اسمه ،انتقل للفيسبوك مباشر ًة وأنشئ صفحة باسم الباحث
والمفكر في الرياضيات وابدأ بنشر أفكارك ونظرياتك..
وبالعودة لصيغة الغرانج ،فإنك تحتاج لمصفوفة xللمجاهيل ،و yللتوابع ،وL
لكثير حدود الغرانج نضع فيها ثوابت المعادلة وبالتأكيد فإنك تحتاج لمصفوفة
تضع فيها نتيجة كثيرات الحدود الجزئية.
;int n = 4
;]int[] x = new int[n
;]int[] y = new int[n
;x[0] = 1; x[1] = 2; x[2] = 3; x[3] = 5
;y[0] = 1; y[1] = 5; y[2] = 14; y[3] = 25
أمثال كثير حدود الغرانجdouble[] L = new double[n]; //
أمثال المعادالت الجزئيةdouble[,] L1 = new double[n, n]; //
مقامات المعادالت الجزئيةdouble[] L2 = new double[n]; //
;double a = 0, b = 0, c = 0
)for (int i = 0; i < n; ++i
{
;L2[i] = 1
)for (int j = 0; j < n; ++j
{
حساب المقام//
)]if (x[i] != x[j
;)]L2[i] *= (x[i] - x[j
else
{
تحديد البسط//
)if (j == 0
} ;]{ a = x[1]; b = x[2]; c = x[3
)else if (j == 1
} ;]{ a = x[0]; b = x[2]; c = x[3
)else if (j == 2
} ;]{ a = x[0]; b = x[1]; c = x[3
else
} ;]{ a = x[0]; b = x[1]; c = x[2
;L1[i, 0] = 1
;L1[i, 1] = -a - b - c
;L1[i, 2] = (a + b) * c + a * b
;L1[i, 3] = -a * b * c
156
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
}
}
}
)for (int j = 0; j < n; ++j
)for (int i = 0; i < n; ++i
;]L[j] += y[i] * L1[i, j] / L2[i
;)"Console.WriteLine("L(x) = L1 x^3 + L2 x^2 + L3 x + L4
;int l = 0
)foreach (double d in L
;))Console.WriteLine("L{0} = {1}",++l,Math.Round(d, 1
;)(Console.ReadKey
وفي حالة المسائل التي علم فيها خمسة نقاط ،فإن نشر المعادلة يكون
بالشكل:
حيث mميل هذا المستقيم ،والذي يساوي إلى مشتق التابع المراد
حساب المماس له .أي أن𝑚 = 𝑦 ′ :
157
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
البرنامج التالي يقوم باشتقاق تابع صحيح معطى من قبل المستخدم ،ثم
يقوم بإيجاد المماس بعد أن يقوم المستخدم بإدخال نقطة التماس.
أن يدخل المستخدم درجة تابع كثير الحدود والذي سنوجد مماسا -
له في نقطة تماس يختارها المستخدم.
أن يدخل المستخدم ثوابت كثير الحدود ،ويحفظها ضمن مصفوفة. -
فإذا كانت درجة كثير الحدود 3مثال ،احتجنا أربعة ثوابت:
𝑑 𝑓(𝑥) = 𝑎𝑥 3 + 𝑏𝑥 2 + 𝑐𝑥 +
أن يدخل المستخدم نقطة التماس. -
أن يحدد البرنامج معادلة المشتق وذلك بضرب كل ثابت بأس -
المجهول الذي يجاوره ،ومن أجل معادلة من الدرجة الثالثة يكون
المشتق:
𝑓 ′(𝑥) = 3𝑎𝑥 2 + 2𝑏𝑥 + 1𝑐 + 0
بمعنى أن ثوابت المشتق هي نفسها ثوابت التابع مضروبة بأرقام
تبدأ بدرجة التابع ،وآخر عنصر فيها 0ألن آخر حد في التابع ثابت.
أن يحسب البرنامج قيمة المشتق عند نقطة التماس. -
إذا أدخل المستخدم إحداثي xفقط يقوم البرنامج بحساب اإلحداثي -
اآلخر من معادلة التابع .ولكن سأترك هذه الخطوة لك مع أنها ليست
صعبة.
أن يظهر البرنامج معادلة المماس بعد أن يختزلها لتصبح بالشكل: -
𝑐 𝑦 = 𝑚𝑥 +
حيث 𝑚 = 𝑦′و ،𝑐 = −𝑚𝑥1 + 𝑦1بنا ًءا على ماسبق.
158
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
لنجرب البرنامج السابق رياضيا ،وبموازاة ذلك جرب األرقام التي اخترناها
وتحقق من النتائج.
𝑦 = 𝑥 2 − 2𝑥 − 3
𝑦 ′ = 2𝑥 − 2
وبالتالي:
𝑦 = 4𝑥 − 12
159
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
160
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
التراكيب Struct
إلنشاء أنواع مركبة تحوي أنواع عديدة من المتغيرات نستخدم التراكيب،
والتي تغنيك عن استخدام متغيرات مختلفة الختزان بيانات متعلقة ببعضها،
كبيانات طالب في مدرسة ،اسمه وعمره وعالماته .نصرّح عن التركيب
كالتالي:
اسم_التركيب struct
{
;Public struct's Vars
.
.
}
مالحظة
يجب أن تكون متغيرات التركيب عامة حتى نستخدمها في كافة
توابع وإجراءات المشروع.
161
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
في الحالة العامة (اإلجراء )Mainلدينا كائن يسمى ،Aliهو طالب ،منزله
( ،Ali.Homeأو بلغة إنسانية )Ali's Homeهو ،Aleppoوعمره ( ،Ali.Ageأو
)Ali's Ageهو .27حيث أن الموطن Homeوالعمر Ageهي البيانات
المطلوب تعريفها عند إضافة كائن ما على أنه طالب.
مالحظة
عند تعريف متغير ما على أنه تركيب ،فإنه سيتم حجز مكان بالذاكرة
لجميع متغيرات التركيب على أنها خاصة بهذا المتغير.
162
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
بشكل عام فإن التراكيب ماهي إال كتل أو بنى برمجية مركبة من عدة
وفي بعض األحيان قد تربط عدة تراكيب ببعضها بحيث،متغيرات وطرق
: الحظ المثال.تجعل أحد التراكيب من مكونات تركيب ما
struct Student
{
public string Home;
public int Age;
public BirthDay Birth;
}
struct BirthDay
{
public int Day, Month, Year;
}
static void Main(string[] args)
{
Student Ali = new Student();
Ali.Home = "Aleppo";
Ali.Age = 27;
Ali.Birth.Day = 3;
Ali.Birth.Month = 5;
Ali.Birth.Year = 1992;
}
163
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
S[0].Birth.Year = int.Parse(Console.ReadLine());
}
return str;
}
}
struct BirthDay
{
public int Day, Month, Year;
}
static void Main(string[] args)
{
Student Ahmad = new Student();
Ahmad.Home = "Aleppo";
Ahmad.Age = 25;
Ahmad.Birth.Day = 22;
Ahmad.Birth.Month = 5;
Ahmad.Birth.Year = 1994;
Console.WriteLine(Ahmad.ToString());
Console.ReadKey();
}
عند تنفيذ البرنامج ستحصل على عبارة نصية محتواها محدد بالقيمة
الذي تراهToString (هكذا تم إنشاء التابع.ToString المعادة من التابع
.)في مختلف المتغيرات والتوابع واإلجراءات
164
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
المعددات Enum
تستخدم المعددات عند وجود مجموعة من القيم محددة ال تتغير وال تزداد
وال تنقص ،ومصرّح عنها ساب ًقا ،ومرتبة وفق ترتيب معين يبدأ من .0نصرّح
عن المعدد كما يلي:
مالحظة
نكتب كل من التراكيب والمعددات خارج الدالة ،Mainفالدوال ال
يمكن أن تحتوي على تراكيب ،في حين أن التراكيب من الممكن أن
تحتوي على دوال.
في الفصل األول أخذنا مثاال عن درجات الحرارة ،وقلنا أنه لو كانت لدينا
حالة ثابتة هي درجة التجمد بالفهرنهايت 32مثال ،وللتعامل معها فإننا
أنشأنا متغي ًرا ثاب ًتا يمثل هذه الدرجة (انتقل لهناك اقرأ الفقرة وتذكر فكرتها
وعد إلى هنا لتدخل بالجو أكثر).
165
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
}
وال تنسى أن نشر األكواد – الكبيرة منها خصوصا – يتم عاد ًة عبر مكتبات
dllوالتي سنناقشها في الفصل السابع ،أي أن صدي َقك ال يمكنه التبنؤ
بمحتويات الكود (هو فقط سيستطيع الوصول إلى بعض الخصائص والطرق
والتي ستختارها أنت برمجيا.)1
واألكثر من ذلك ،ماذا لو قمت بنشر الكود على نطاق واسع؟؟؟ مثال عبر
موقع ما أو مجموعة من مجموعات التواصل االجتماعي أو أي مجتمع
برمجي ،هل ستتصل بجميع المبرمجين وتخبرهم باإلمكانيات المتاحة
حتى ال يشتموك عندما يواجهون المشاكل واألخطاء! أم أنك ستترك لهم
مل ًفا نصيا باسم ReadMeبحيث يقرؤونه قبل استخدام الكود؟؟؟؟؟
1أصال لو كانت األسطر البرمجية متاحة بين يديه وقرأها لوجد اإلمكانيات المتاحة التي يمكن للمتغيرات
أن تأخذها وذلك عبر بنى الشرط التي تحكم وتدير البرنامج بنا ًءا على قيم المتغيرات (والتي قلنا أنها
محدودة).
166
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
الحظ معي أنه عند استخدام المعددات فإن C#ستحصر المتغير بقيم
محددة ،فهنا لدينا سبعة خيارات ال ثامن لها!
وهذا أفضل من استخدام متغيرات نصية مثال للداللة على أيام األسبوع
مثال:
عد إلى فصل األساسيات وتحدي ًدا في فقرة األكواد األساسية ثم فقرة
تغيير لون نافذة المشروع ،الحظ الكود الموجود ،فيه ثوابت هي األلوان ،هذا
يعني أن األلوان ماهي إال معددات.
167
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
في الواقع فإن المعددات ماهي إال متغيرات رقمية صحيحة ،تبدأ بالرقم :0
;Day d = Day.Sunday
;)Console.Write("ToDay is {0}", ++d
enum Grades
{
first = 1,
168
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
second, third
}
static void Main(string[] args)
{
Grades g;
g = (Grades)2;
Console.WriteLine(g); //Prints second
Console.ReadKey();
}
ستخزنsecond (أي أن1 مع العلم أن مقدار الزيادة لباقي العناصر ستكون
.)3 على أنهاthird و2 على أنها
169
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
أنواع البيانات التي يمكن للمعدات أن ترث منها هي التي من النوع الرقمي
بطبيعتها ،مثل byteو shortو intو.long
170
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
171
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
مرّ علينا ساب ًقا مجموعة من الطرق استخدمناها بكثرة مثل الطريقة
)( Console.ReadKeyأو )( Console.Writeأو )( Convert.ToInt32أو
) MessageBox.Show ( , , , , ,أو ) .Math.Round ( ,
172
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
1
حيث كل من ReadKeyو ToInt32و Writeهي طرق تابعة للفئة
،Consoleو Roundهي طريقة للفئة ،Mathو Showهي طريقة للفئة
.MessageBoxحيث إن الفواصل الموضحة مابين األقواس تمثل عدد
المتغيرات الالزمة إلعطاء النتيجة المطلوبة ،مع األخذ بعين االعتبار أنه من
الممكن تجاهل بعض المتغيرات أحيانا.
ضا التوابع واإلجراءات بأنها ليست إال قطعة من البرنامج ،تحتوي وتُع َرف أي ً
على مجموعة من األكواد ،بتنفيذها نحصل على نتيجة ما ،سوا ًءا أكانت
النتيجة ستعاد أم ال.
مالحظة
القيمة المعادة بعد كلمة returnهي عبارة عن متغير يحمل قيمة
نتيجة إجراء بعض العمليات ،ومن الممكن وضع عالقة بحيث ُيعاد
نتيجتها.
173
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
مالحظة
كما هو الحال في بنى التحكم وبعض حلقات التكرار ،فالطرق ال
تلحق بفاصلة منقوطة.
في اإلجراءات ال توجد الكلمة returnألنها ال تعيد أية قيمة.
174
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
كما أنه يوجد لدينا التابع ،Mainوالذي يحوي متغيرين صحيحين ،لهما
قيمتين صحيحتين ،تم فيه استدعاء طريقتين إحداهما إجرائية واألخرى
تعيد قيمة ،وذلك بالشكل التالي:
في السطر الثالث من التابع ،تم مناداة اإلجراء وإعطاءه ناتج جداء
المتغيرين ،ليقوم بما فيه من أكواد بغض النظر عنها ،وبغض النظر من أن
المتغيرات التي أرسلناها ستلزمه أم ال( .أعد قراءة الجملة األخيرة)
في السطر الذي يليه ،تم مناداة التابع وإعطاءه قيمة المتغيرين،
ليسندهما إلى متغيرات أخرى مناظرة لهذه المتغيرات ،ثم يعيد قيمة
نسندها إلى متغير من نفس نوع الدالة ،لنظهر النتيجة فيما بعد.
الزبدة:
-ال يلزمنا تعريف متغيرات الستقبال نتيجة اإلجراءات ،ألنها لن تعيد قيمة
أصال .وفي حال كانت النتيجة ستظهر في خرج البرنامج عندها يجب
إخراجها في اإلجراء نفسه أو إسناد النتيجة من داخل اإلجراء لمتغير يعمل
في كافة اإلجراءات ليتم إظهارها فيما بعد.
-يجب تعريف متغيرات الستقبال نتيجة الدوال ،أو استدعاء التابع كتمغير
لتوابع أخرى مثل استخدام الكود ))Console.WriteLine (funANS(a, b
والذي ُيغني عن الكود المستخدم في المثال.
175
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
تمرير المتغيرات
الستخدام إحدى الطرق – المتمثلة بالتوابع واإلجراءات – ال يكفي فقط ذكر
اسم الطريقة المطلوب استدعائها ،وإنما قد تحتاج لمتغيرات تمثل وسطاء
يتم استخدامها للحصول على نتيجة ما .عند استدعائك لتابع أو إجراء –
وذلك بذكر اسمه – سترسل معه المتغيرات التي ستمثل وسطاءه ،عملية
اإلرسال هذه تسمى تمريرًا.
التمرير بالقيمة
وهي أبسط أنواع التمرير .وفيها يتم إرسال قيمة المتغيرات إلى التابع أو
اإلجراء ،ليقوم ببعض العمليات باستخدام قيمها .ال تتغير قيمة هذه
المتغيرات عند استدعاء الطرق ،فمجال رؤيتها ال يتعدى مكان تمريرها.
التمرير بالمرجع
وفيه يتم تمرير مرجع المتغير وهو العنوان الموجود فيه المتغير في الذاكرة،
وعندها فإن أي تغيير في قيمة المتغير في الدالة أو اإلجراء المستدعى
يصحب معه تغير في قيمة المتغير الممرر مرجعه.
التمرير باإلخراج
وهو مماثل للتمرير بالمرجع ولكنه يختلف عنه في أن المتغير الممرر مرجعه
من الممكن أال يحوي على قيم أثناء التمرير ،في حين أن هذا األمر غير
متوفر عند استخدام أسلوبي التمرير السابقين.
176
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
;z=12
;)" Console.Write("in method:
;)Console.WriteLine (" z = " + z
}
)static void Main(string[] args
{
;int x
;)"Console.WriteLine("Before Passing:
;x = 10
;)Console.WriteLine("in Main: x = " + x
;)"Console.WriteLine("Passing with value:
;)valProc(x,2* x
//x = 10
;)Console.WriteLine("in Main: x = " + x
;)"Console.WriteLine("Passing with refrence:
!//Don't forget that x is 10 in Main Procedue
;)refProc(ref x
;)Console.WriteLine("in Main: x = " + x
//Now x is 11 Because we have changed it form the method
;)"Console.WriteLine("Passing with output:
int z; //There is no value to z
;)outProc(out z
//Now z has value
;)Console.WriteLine("in Main: z = " + z
;)(Console.ReadKey
}
ابتدأنا البرنامج على بركة هللا في اإلجراء ،Mainعرّفنا متغي ًرا عدديا صحي ً
حا
xثم أظهرنا قيمته قبل التمرير.
177
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
ً
مثاال آخر: إذا كانت األفكار السابقة صعبة عليك ،سأعطيك
)static void MyProc(int y
{
;y += 10
}
)static void Main(string[] args
{
;int x = 10
;)MyProc(x
Console.Write(x); //Prints 10
;)(Console.ReadKey
}
قيمة xستبقى 10سوا ًءا قبل استدعاء الطريقة MyProcأو بعدها ..أما
باستخدام المرجع:
)static void MyProc(ref int y
{
;y += 10
}
)static void Main(string[] args
{
178
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
;int x = 10
;)MyProc(ref x
Console.Write(x); //Prints 20
;)(Console.ReadKey
}
في الواقع فإن التوابع تعيد قيمة واحدة وهي القيمة المعادة بالكلمة
،returnفي حين أنه في بعض األحيان فإنك قد تحتاج إلرجاع أكثر من
قيمة من الطريقة .فمثال إذا أنشأت طريقة تعطيها قيمة زاوية xوترغب بأن
تعيد لك قيمة sinو cosو tanهذه الزاوية – وتفاصيل أخرى إذا رغبت – فإن
التوابع لن تشبع رغبتك .أنشئ إجرا ًءا يمكن استدعاؤه بالكود التالي:
;double sin, cos, tan
;)Math(x, out sin, out cos, out tan
179
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
لكن ماذا لو أردت تمرير أنواع أخرى من البيانات مع البيانات السابقة غير
محددة العدد؟؟
والنتيجة ستكون:
180
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
ناقشنا أيضا إمكانية تمرير عدد غير محدد من القيم على شكل مصفوفة
باستخدام البادئة ،paramsواآلن سنناقش كيفية إرجاع التوابع كمصفوفة،
أي أن القيمة المعادة من التابع هي مصفوفة!
181
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
182
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
في الحياة الحقيقية هناك كائنات مختلفة تتبع لفئات (أنواع) مثل أناس أو
سيارات أو آالت أو ..إلخ ،ولهذه الكائنات مجموعة من الصفات مثل االسم
والعمر ولون البشرة ولون الشعر وما إذا كان أيمن أو أيسر بالنسبة لألناس
مثال ،وبإمكان هؤالء الناس أن يقوموا بمجموعة من األفعال مثل الكتابة
والقراءة والكالم والسمع واالستيقاظ ،كما أنه تمر عليهم لحظات ومجريات
يشعرون فيها بالجوع أو اإلرهاق أو السعادة ..وبإسقاط هذا المفهوم على
مكونات البيئة البرمجية نحصل على مجموعة من الخصائص للكائنات التي
نتعامل معها مثل Titleو Nameو Textو ،Visibleومجموعة من األفعال مثل
ReadKeyو Writeو Clearومجموعة من األحداث التي تمر عليها مثل
Leaveو Enterو .KeyPressكما أنه بإمكانك إضافة خصائص أو أفعال خاصة
بك وفق حاجتك.
ً
مثاال لتقريب الفكرة :لدينا كائن اسمه حسن ،يتبع للفئة إنسان، لنأخذ
لديه خاصيتان االسم والعمر كمثال بسيط ،يقوم هذا الكائن بأخذ قيم
هاتين الخاصيتين وفق الطريقة Initializeوالتي تعني تحضير (بإمكانك
تغيير اسم هذه الطريقة إلى Setupمثال) ،ويقوم أيضا بعرض تفاصيله وفق
الطريقة .ShowDitails
183
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
على غير العادة – التي جرت في الفصول السابقة – لن أقوم بسرد صيغة
عامة للفئات وسأكتفي بمثال يوضح أبسط أشكالها لغاية في نفسي..
مالحظة
الكائن هو تعبير خاص بينما الفئة هي تعبير عام .فمثال الكتاب يعتبر
فئة ،لكن " C#من البداية حتى اإلتقان" يعتبر كائ ًنا.
تسمى عملية تعريف الكائنات باستنساخ الفئات.
يفضل دائما التفريق بين متغيرات الفئة نفسها ومتغيرات الفئات األخرى،
يمكن ذلك من خالل استخدام أحرف كبير أو صغيرة أو تسبيق أسماء
المتغيرات بلواحق تعتمد عليها دائما في برماجك .بالعودة لإلجراء ،Main
اكتب الكود التالي:
استنساخ الفئةHuman Hasan = new Human(); //
;int age = 22
;"string Name = "Hasan
184
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
;)Hasan.Initialize(Name, age
;)(Hasan.ShowDitails
;)(Console.ReadKey
بمعنى أنك ستحصل على جميع طرق الفئة المضافة عند استنساخها
إلى كائن جديد ،عملية استنساخ الفئة ليست إال السطر البرمجي األول
من الكود األخير .عند تحديد الطريقة المطلوبة فإنك ستحصل معها على
البارامترات المطلوبة كوسطاء الستدعاء هذه الطريقة.
مالحظة
بإمكانك كتابة الفئة داخل ملف مشروعك وذلك بجوار فئة البرنامج
الذي تعمل فيه.
أساسا حتى أنواع البيانات هي بالواقع كائنات ،وقد نوهنا إلى ذلك في ً
بداية الكتاب وقلنا أنه لنا وقفة مع أنواع البيانات عند الحديث عن الكائنات.
عند تعريف متغير فإنك بالواقع تستنسخ فئة تمثل نوع المتغير هذا ،أي أن
الكودين التاليين متكافئين:
;string s
;)(string s = new string
185
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
;int s
s.GetType(); //return System.Int32
s.ToString(); //return a string
!s.Equals(m); //return whether s and m are equals AS OBJECTS
المجمعات Assemblies
هو ملف يضم كل ما يوجد في برنامجك من ملفات وفئات وغيرها ،ويكون
امتداده exeأو dllوذلك تبعا لنوع المشروع الذي تتعامل معه .ويمكنك
عرض خصائص المجمع الخاص بمشروعك من Propertiesالخاص
بالمشروع ،وفيه بإمكانك ضبط الخصائص األساسية لمجمع مشروعك وما
إلى ذلك مثل نسخة المشروع .Version
تكلمنا بإيجاز في بداية هذا الكتاب عن مجاالت األسماء دون أن ننوه لها،
وقلنا أنه الستخدام الفئة Consoleيجب تضمين Systemفي مشروعك.
اآلن عد إلى ثاني صورة من الفصل صفر ولنتكلم عن الموضوع جز ًءا جز ًءا:
أوال :يعتبر Systemهو مجال أسماء ،و Consoleهو إحدى فئاته ،لذلك يجب
تضمين Systemفي مشروعك لتتمكن من استخدام طرق وخصائص
.Consoleويمكن تضمين أي مجال أسماء باستخدام الكلمة .using
ثالثا :من الممكن لمجال أسماء أي يحتوي على مجال أسماء آخر ،مثل
.System.Text
رابعا :هناك مجاالت أسماء أخرى ال ُتد َرج افتراضيا مع إنشاء مشروع جديد،
وال يمكنك استخدام بعض الكائنات والفئات لوالها ،في هذه الحالة عليك
إضافتها كـ .System.Windows.Forms
186
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
العناصر المكونة للسيارات ،فيمكن اعتبار السيارة مجال أسماء ألنه يحوي
مجموعة من الفئات تؤدي مع بعضها وظيفة معينة كما يمكن استخدام فئة
ل األسماء مجاالتِ أسماء أخرى ،فبدورهدون أخرى .كما يمكن أن يضم مجا ُ
الباب مثال مكون من فئة تمثل الزجاج وفئة تمثل المعدن وفئة تمثل المرآة
و ..إلخ من العناصر المكونة للباب .كما أن المرآة هي مجال أسماء يمكن
محاكاتها بذات الطريقة ،فمجاالت األسماء – كما هو حال الفئات – هي
تمثيل لكائنات الحياة الواقعية الحية منها وغير الحية ،الملموسة منها
والمعنوية ،على شكل كائنات برمجية.
عند إنشاء مشروع ما فإنه سيتم إنشاء مجال أسماء خاص بمشروعك
وباسم مشروعك أيضا ،قد تحتاج إلنشاء مجال أسماء تضع فيه بعض الفئات
الستخدامها في أكثر من برنامج ،وهي ذات الفكرة التي أنشؤوا من خاللها
مجاالت األسماء الجاهزة مثل ،IOفمن خالل استخدام فئاتها ستحصل
على نتائج أكواد موضوعة داخلها أنت بغنى عن الخوض في تفاصيلها
طالما أن النتيجة متاحة.
وعلى سبيل المثال ،بإمكانك إنشاء واستخدام مجاالت األسماء وفئاتها كما
يلي:
;using System
مجال أسماء خاص بناusing School; //
namespace ConsoleApplication11
{
class Program
{
)static void Main(string[] args
{
;)(Students Ali = new Students
;)(Teachers Khaled = new Teachers
;)(Subjects Math = new Subjects
}
}
}
187
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
namespace School
{
class Students
{
}
class Teachers
{
}
class Subjects
{
}
}
والفكرة من هكذا مجال أسماء ،هو إنشاء كتلة برمجية لمرة واحدة تتضمن
أفكا ًرا وتطبيقاتٍ عديدة ،واستخدامها برمجيا في أكثر من برنامج ،فعند
برمجة طرق وخصائص جميع فئات مجال األسماء هذا ،فإنه يصبح جاهزا
لالستخدام .وعند استنساخ هذه الفئات إلى كائنات في اإلجراء ،mainفإن
جميع الطرق التي ألّفتها ستصبح متاحة لهذه الكائنات ،مما يعطي برامج
قوية يسهل فيها إصالح األخطاء بعد اكتشافها.
مجال الرؤية
ويقصد بمجال الرؤية ،إمكانية الوصول إلى الفئات والكائنات ،الطرق
والخصائص والمتغيرات ،سوا ًءا من البرنامج أو الفئة أو الطريقة أو الحلقة
حتى.
كل متغير له مجال رؤية محدد ،أي إمكانية وصول محددة ،بمعنى آخر أنه
من خالل مجال الرؤية نحن نعطي الصالحيات للفئات والطرق األخرى من
البرنامج بالوصول لمتغيراتنا.
ويتم ضبط مجال الرؤية وذلك عند تعريف هذا الكائن أو الطريقة أو المتغير،
وذلك باألقسام التالية:
188
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
التعريف االفتراضي
ويحدث عند التعريف بالطريقة العادية ،وفيه تكون الكائنات معروفة فقط
على مستوى الوحدة البرمجية التي تنتمي إليها (الفئة أو الطريقة أو البنية
التي تم تعريف الكائنات فيها).
public
وهو أشمل أنواع التعريف ،وفيه تكون الكائنات معرفة في كافة فئات
البرنامج.
private
وهو نفسه التعريف االفتراضي ،الكائنات معروفة فقط على مستوى الوحدة
البرمجية التي تنتمي إليها.
protected
الكائنات معرفة على مستوى الفئات التي تنتمي إليها والفئات التي ترثها.
internal
الكلمة static
لهذه الكلمة دور هام في مجال رؤية الطرق والمتغيرات ،فالمتغير المعرف
بنوع ما ومسبوق بالكلمة staticيمكن رؤيته في جميع أجزاء البرنامج
والتي تحمل هذه الكلمة باإلضافة الستخدامه مباشرة دون استنساخ
الكائن الحاوي عليه.
189
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
بإمكانك الوصول لـ xمن خالل الحلقة ألنها تنتمي للطريقة التي تم تعريف
xفيها ،أما yفال يمكنك الوصول إليها إال من خالل الحلقة..
في بداية هذا الفصل وعند تعريفنا للفئات ناقشنا مثاال عن الفئات،
واستخدمنا إجرا ًءا لتعيين قيم اإلجراء ،وعند استخدام التابع البناء فال داعي
الستخدام أية طرق وسيطة.
كود البرنامج:
;int age = 22
;"string Name = "Hasan
استنساخ الفئةHuman Hasan = new Human(Name, age); //
;)(Hasan.ShowDitails
;)(Console.ReadKey
والنتيجة ذاتها..
190
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
عند استنساخ كائن ما من إحدى الفئات فإن التابع البنّاء ُينفذ فورًا دون أن
تناديه أصال ،لذلك ضع األكواد التي ترغب بتنفيذها عند استنساخ الكائن
في التابع البنّاء الـ .Constructor
}
الخصائص Properties
قد تحتاج في بعض األحيان للوصول إلى خاصية ما إلحدى كائنات
مشروعك ،وعلى اعتبار أن الكائن ما هو إال تصغير (أو تخصيص) لمفهوم
الفئة ،فجميع خصائص الفئة س ُت َ
نسخ للكائن.
بمعنى آخر ،عند استنساخ فئة (إنشاء كائن) ،فإن مكونات ومحتويات هذه
الفئة بما فيها الخصائص والتوابع واإلجراءات ستنسخ في ذاكرة الحاسوب
وتعطى للكائن المستنسخ .وبالعودة للمثال األول ضمن هذا الفصل
وتحدي ًدا في الصورة المرفقة رأينا أنه عند كتابة اسم الكائن ثم نقطة،
ستظهر قائمة منبثقة تحوي الطرق الممكن استخدامها ،ولكن ماذا عن
الخصائص؟؟؟؟ بالتأكيد عندما أنشأنا الفئة صرّحنا عن متغيرات تمثل
خصائص الفئة ،السؤال هو لماذا لم تظهر؟؟؟؟
في الواقع هذه المتغيرات ال تمثل خصائص الفئة وإنما تمثل متغيرات
تستخدم كوسطاء للحصول على نتائج معينة داخل الفئة وال يمكن للفئات
األخرى التعامل معها .وفي كثير من الفئات الجاهزة المتوفرة في C#عند
استنساخ كائنات منها ،وعند كتابة اسم الكائن ثم نقطة فإنك تحصل على
عدد من الطرق والخصائص ،هذه الخصائص هي تمثيل أكبر لبعض
المتغيرات داخل الفئة.
191
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
الخالصة :إذا كانت األسطر السابقة قد أربكتك فاقرأ ما يلي :في بعض
األحيان قد تحتاج للوصول لبعض متغيرات فئاتك وكائناتها ،ويمكن ذلك من
خالل استخدام مفهوم الخصائص المتمثل بـ setterو .getterوالموضحة
بالصيغة التالية:
مالحظة
تستخدم الكلمة thisفي C#للداللة على الفئة الحالية ،قد يكون
لديك متغيرات عامة تحمل ذات االسم في أكثر من فئة ،وحتى ال
تختلط عليك األمور بإمكانك كتابة اسم المتغير بعد هذه الكلمة
لتحصل على متغير هذه الفئة( .لمبرمجي ،VBهذه الكلمة مناظرة
للكلمة )Me
في أمثلة هذا الفصل استخدمنا الحرف cفي بداية متغيرات الفئة
للداللة على أنها تابعة لها ،مثل .cName
192
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
* مالحظة :جرت العادة عند إنشاء فئات ،أن يكون التابع البنّاء عديم األكواد
وال يحتاج بارامترات ،أي أنه يستخدم فقط الستنساخ الكائن .وفي الغالب
يتم وضع تابعين بنّائين – أو يمكن أكثر من ذلك – أحدهما خالي الوسطاء
واآلخر يحوي وسطاء وعمليات إسناد وذلك ليتمكن المبرمج الذي
سيستخدم الفئة من استعمال إحدى الطريقتين على راحته ووفقا للظروف
المارة بين يديه .أما الكود في التابع الرئيسي فهو:
استنساخ الفئةHuman Hasan = new Human(); //
إسناد القيم لمتغيرات الكائن//
;"Hasan.Name = "Hasan
;Hasan.Age = 22
إظهار كافة النتائجHasan.ShowDitails(); //
إظهار االسمConsole.WriteLine(Hasan.Name); //
إظهار العمرConsole.WriteLine(Hasan.Age); //
;)(Console.ReadKey
193
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
الوراثة Inheritance
هي أحد أهم تطبيقات مبدأ البرمجة كائنية التوجه ،OOPوتعني نقل
خصائص (صفات) ووظائف (طرق) كائن ما إلى كائن آخر ..ومن خاللها
تعطيك إمكانية التعامل مع الكائنات البرمجية كما نتعامل مع الكائنات في
الواقع ،أو بعبارة أخرى :أن تتعامل مع الكائنات من منطق إنساني أكثر من
المنطق البرمجي!
يختصر مبدأ الوراثة كتابة األكواد الكثيرة ،فيكفي كتابة أكواد الفئة
األساسية (وتسمى أيضا الفئة األم) ،ومنها نورث أكوادها للفئات األبناء.
لنأخذ المثال الذي ناقشناه على امتداد هذا الفصل ونطبق عليه مبدأ
الوراثة .لدينا فئة أساسية هي إنسان ،Humanولتكن لدينا ثالث فئات ُأ َ
خر
هي بعض مما يمكن أن يكونه هذا اإلنسان وهي موظف ،مدرس،
ومهندس على سبيل المثال ال الحصر.
في مثال هذا الفصل كان لدينا خاصيتان Nameو Ageوطريقة واحدة
،ShowDetailsوهي مكونات الفئة .Humanعند توريث الفئة Humanإلى
الفئات Employeeو Teacherو Engineerفإن هذه المكونات ستمتلكها
هذه الفئات أيضا دون الحاجة لكتابتها داخلها ،باإلضافة إلى أن لهذه الفئات
مكونات خاصة بها.
الحظ:
المكونات الفئة
هي فئة أساسية (ال ترث من أحد – فئة أم)
جميع الفئات التي سترث من هذه الفئة ستحصل على
الحقلين التاليين من الجدول ،باإلضافة إلى حقولها.
لها الخصائص
Human
Name
Age
لها الطرق
ShowDetails
ترث من الفئة Humanلذلك فلها خصائصها وطرقها.
لها الخصائص
Institution
Employee
StudyLevel
( Name من الفئة األم)
( Age من الفئة األم)
194
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
لها الطرق
Work
GetPromoted
):D (رشوةBribe
) (من الفئة األمShowDetails
. لذلك فلها خصائصها وطرقهاHuman ترث من الفئة
لها الخصائص
School
TeachLevel
) (من الفئة األمName
Teacher
) (من الفئة األمAge
لها الطرق
Teach
MakeTest
) (من الفئة األمShowDeatails
. لذلك فلها خصائصها وطرقهاHuman ترث من الفئة
لها الخصائص
Company
Specialty
) (من الفئة األمName Engineer
) (من الفئة األمAge
لها الطرق
Work
) (من الفئة األمShowDetails
195
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
}
class Teacher : Human
{
string cSchool, cTeachLevel;
public Teacher(string School, string TeachLevel)
{
//This is Constructor!
cSchool = School;
cTeachLevel = TeachLevel;
}
public void Teach()
{
//C#'s Codes!
}
public void MakeTest()
{
//C#'s Codes!
}
}
class Employee : Human
{
string cInstitution, cStudyLevel;
public Employee(string Institution, string StudyLevel)
{
//This is Constructor!
cInstitution = Institution;
cStudyLevel = StudyLevel;
}
public void Work()
{
//C#'s Codes!
}
public void Bribe()
{
//C#'s Codes!
}
public void GetPromoted()
{
//C#'s Codes!
}
}
class Engineer : Human
{
string cCompany, cSpecialty;
public Engineer()
{}
public Engineer(string Company, string Specialty)
196
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
{
!//This is Constructor
;cCompany = Company
;cSpecialty = Specialty
}
)(public void Work
{
!//C#'s Codes
}
}
class Program
{
)static void Main(string[] args
{
;"string Name = "Hasan
;int Age = 22
;"string Company = "None
;"string Speciality = "Mechanical
;)Engineer Hasan = new Engineer(Company, Speciality
;)Hasan.Initialize(Name, Age
;)(Hasan.ShowDitails
;)(Hasan.Work
;)(Console.ReadKey
}
}
لتوريث فئة لفئة أخرى نستخدم الرمز " ":للربط بين الفئة الوارثة والفئة
الموروث منها ،بحيث تكون الوارثة في البداية.
ال يتخلف إنشاء وتكوين الفئات العادية سوا ًءا أكانت سترث من فئات أخرى
أم ال ،الفارق ستجده عند استخدام هذه الفئات في فئات أخرى،
وسيتجلى هذا الفارق في أن محتويات الفئة ومكوناتها ستضم طرق
وخصائص أكثر.
يفضل دائما وضع أكثر من تابع بناء ،وذلك لنسمح للمبرمج الذي
سيستخدم فئتنا من إدخال وسطاء تعريف الفئة عند استنساخ كائن ،أو
استنساخ كائن فقط دون إدخال الوسطاء .الحظ الصورة التالية :عند
استنساخ كائن Hasanمن الفئة Engineerفإنه لديك خياران (الحظ
مكتوب ،)1 of 2ومن أجل ذلك أنشأنا تابعين بنائين .في بعض الفئات التي
تأتيك هدية مع لغة البرمجة – أقصد الفئات الجاهزة – قد تصل الخيارات
إلى العشرات!
197
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
قلنا أن البرمجة كائنية التوجه أتت لتجعل من مفهوم البرمجة أقرب مايكون
للحياة الواقعية ،والتي يعتبر كل مافيها كائنات .في الحياة الواقعية هناك
كائنات غير موجودة فعليا لكنها تعتبر نوعا لكائنات أخرى ،فوسائط النقل
هي كائن لكنه غير موجود ،أما السيارات والطائرات والسفن والقطارات
هي كائنات مشتقة من الكائن وسيطة نقل ولها مميزات خاصة بها تميزها
عن الكائنات األخرى من نفس النوع .بمعنى أنه ال يمكنك أن ترى وسيطة
نقل أو تستخدمها لكن بإمكانك استخدام ورؤية السيارات ،فوسيطة النقل
عبارة عن فكرة مجردة أما السيارة فهي كائن موجود!
198
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
class Program
{
)static void Main(string[] args
{
!خطأ ;)(//Transport Kia = new Transport
) :ممكنCar Kia = new Car(); //
}
}
199
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
class Program
{
static void Main(string[] args)
{
Human Ahmad = new Teacher();
Human Ali = new Employee();
Engineer Khaled = new Engineer();
Ahmad.Job();
Ali.Job();
Khaled.Job();
Console.ReadKey();
}
}
200
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
مالحظة
عند اشتقاق فئة من فئة أخرى (الوراثة منها) ،فإنه يمكن الوصول
للفئة الرئيسية عن طريق الكلمة .baseفكما أن الكلمة thisتمثل
الفئة الحالية ،فإن الكلمة baseتمثل الفئة الرئيسية.
الجيد في تعدد التعاريف أن المترجم يفهم الحالة التي تحتاج التعامل معها
من خالل نوع المتغيرات الذي ترسله عند نداء الطريقة ،وليس هناك حاجة
للتقليب بين الحاالت الـ 19السابقة الممكنة للوصول على الحالة
المطلوبة ،لذلك فأنت تدين للمترجم بالكثير .هل تذكر المترجم في بداياتك
مع الكتاب ؟
}
201
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
//Method overloading
public void AddFriend()
{
//C#'s Codes
}
public void AddFriend(int Age)
{
//C#'s Codes
}
public void AddFriend(string Name)
{
//C#'s Codes
}
}
class Program
{
static void Main(string[] args)
{
Human Ahmad = new Human("Ahmad alAari", 20);
Ahmad.AddFriend("Eng27");
Console.ReadKey();
}
}
202
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
class Human
{
)(public Human
{
//C#'s Codes
}
الواجهات Interfaces
تدعم بعض لغات البرمجة مبدأ الوراثة المتعددة ،أي إمكانية وراثة فئة ما
ألكثر من فئة أخرى .في C#ال يمكن للفئة أن ترث إال من فئة واحدة..
وبالتالي للوراثة من أكثر من فئة فنستخدم مفهوم الواجهات.
يشابه مفهوم الواجهات بشكل كبير مفهوم الفئات المجردة ،والتي ال يمكن
استساخ كائنات منها ،باإلضافة لعدم إمكانية كتابة أي كود عملي داخل
الواجهات وإنما فقط الوظائف والخصائص التي ستستعمل هذه الواجهة.
203
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
:الحظ المثال
interface Human
{
int Age { get; set; }
string Name { get; set; }
int BirthYear();
}
public Teacher()
{
}
class Teacher : Human
{
private string cNAME;
private int cAGE;
public Teacher(string Name, int Age)
{
cNAME = Name;
cAGE = Age;
}
int Human.Age
{
get { return cAGE; }
set { cAGE = value; }
}
string Human.Name
{
get { return cNAME; }
set { cNAME = value; }
}
int Human.BirthYear()
{
return DateTime.Now.Year - cAGE;
}
}
class Program
{
static void Main(string[] args)
{
204
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
Delegates المفوضات
ومن خاللها يمكن. والمندوب هو النائب أو الممثل،وتسمى لغ ًة بالمندوبات
بحيث يتعامل مع وظيفة ما من،أن ينوب عن فئة ما مفوّض أو مندوب
تستخدم المفوضات بشكل.وظائف الفئة شرط أن تكون من نفس نوعه
: الحظ المثال. وهو ماسنراه الحقا بإذن هللا،واسع للتعامل مع األحداث
class Numbers
{
public string isEven(int Number)
{
return ( Number % 2 == 0 ? "Even" : "Odd");
}
class Program
{
public delegate string NumCase(int Num); //التصريح عن مندوب
205
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
Console.ReadKey();
}
}
206
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
}
}
class Program
{
;)public delegate void NumCase(int Num
)static void Main(string[] args
{
;)(Numbers N = new Numbers
;)NumCase Num1 = new NumCase(N.isEven
;)NumCase Num2 = new NumCase(N.PrimeFactors
;)" Console.Write("Enter Number :
;))(int number = int.Parse(Console.ReadLine
;)Console.Write("{0} is ",number
;NumCase Multi = Num1 + Num2
;)Multi(number
;)(Console.ReadKey
}
}
األحداث Events
األحداث هي المجريات والمشاعر واألحاسيس التي تمر على برنامجك،
فضغط األزرار يفجر حدثًا ،واتصال جهاز بالكمبيوتر يفجر حدثًا ،ووصول التركيز
ألحد األدوات في النموذج يفجر حدثًا ،كما أن إدخال الحروف من لوحة
المفاتيح يفجر حدثًا ..وهناك الكثير والكثير من األحداث التي ستمر عليك
في حياتك البرمجية عند برمجتك للتطبيقات الحاوية على نوافذ..
مالحظة
مصطلح تفجير الحدث يقصد به حدوث الحدث ،وهي ترجمة حرفية
للمصطلح األجنبي ..فعندما نقول تم تفجير الحدث الفالني فإننا
نقصد أنه تم حدوثه.
إن مبدأ عمل األحداث هو استدعاء طريقة ما عند تفجير حدث ما ،لذلك
فتعاملنا سيكون مع الطرق في نهاية األمر وهذه الطرق الخاصة باألحداث
تسمى .Handlersكما أن لألحداث عالقة وطيدة مع المفوضات ،فكما قلنا
فالمفوضات تستعمل للتعامل مع األحداث ..لذلك فعليك إنشاء مفوضات
ستنوب األحداث وتتعامل معها.
الحظ المثال:
207
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
class Store
{
public event delegEvent Selling; //التصريح عن حدث جديد
class Program
{
static void Main(string[] args)
{
Store Product1 = new Store();
208
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
class Store
{
public event delegEvent Selling; //التصريح عن حدث جديد
209
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
class Program
{
static void Main(string[] args)
{
Store Product1 = new Store();
//ربط الحدث باإلجراء وذلك عن طريق المفوض
Product1.Selling += delegate()
{
Console.WriteLine("The quantity is not enough!");
};
210
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
class Store
{
public event delegEvent Selling; //التصريح عن حدث جديد
class Program
{
static void Main(string[] args)
{
Store Product1 = new Store();
//ربط الحدث باإلجراء وذلك عن طريق المفوض
Product1.Selling += () =>
{
Console.WriteLine("The quantity is not enough!");
};
211
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
وبالنسبة للوائح:
>List<string> Employees = new List<string
;}"{ "Ahmad","Ali","Khaled","Zaid
;)"Console.WriteLine("Employees are:
>= Employees.ForEach(name
{
;)Console.WriteLine("- {0}", name
;)}
;)(Console.ReadKey
212
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
لكن بالمقابل قد ال تشبع رغباتك الفئات الجاهزة ،لذلك فأنت مضطر إلنشاء
فئات خاصة بك كما تعلمتها في فقرات هذا الفصل .وعندما تكون هذه
الفئات مطلوبة في برامجك بشكل كبير فإنك تحتاج لنسخ الكود كامال من
أحد المشاريع القديمة والتي تحتوي عليه ووضعها في مشروع جديد لك.
وعوضا عن عملية نسخ الكود والعمل غير المنظم ،بإمكانك وضع هذه
الفئات في ملف ما يسمى مكتبة االرتباط الحيوي ،وإسناده لمراجع
مشاريعك في كل مشروع تحتاجه فيه ،وهكذا ففي حال تعديلك على
مكتبتك ،فإن جميع مشاريعك التي تعتمد على هذه المكتبة ستحصل
على التعديل الجديد.
213
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
ستحصل على هذه األكواد بشكل تلقائي (بتتذكر أيام الفصل صفر؟):
214
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
اآلن أنت أصبحت كبيرا وال داعي ألن أقول لك أن المشروع هنا عبارة عن
مجال أسماء خاص بمشروعك وأن القسم ُ قسمين ،األول مكتبات والثاني
األول ستضيف إليه مجاالت األسماء التي ستتعامل معها – وغير موجودة
ضمن مجاالت األسماء االفتراضية – وأن القسم الثاني سنضع فيه الفئات
الخاصة بنا وداخلها طرقها وخصائصها وأكوادها ،أليس كذلك؟؟؟
لننشئ مكتب ًة كمثال ،نقوم فيها بحل معادلة رياضية من الدرجة األولى:
𝐵−
= 𝑥. الحل فيها من الشكل
𝐴
using ;System
using ;System.Collections.Generic
using ;System.Linq
using ;System.Text
using ;System.Threading.Tasks
namespace ClassLibrary1
{
public class Equation1
{
;private double cA, cB
)(public Equation1
{
}
215
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
ومفادها أنه ال يمكن تنفيذ هذا المشروع إال من خالل إضافة مشروع
تنفيذي واستيراد هذا المشروع إلى قائمة المراجع الخاصة بالمشروع
التنفيذي..
216
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ClassLibrary1; //استيراد المكتبة برمجيا
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Equation1 Equ = new Equation1(5, 6); //Means 5x + 6 = 0
Console.WriteLine("x = " + Equ.Solve().ToString()); //Prints x = -1.2
Console.ReadKey();
}
}
}
217
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
مكتبات APIالجاهزة
من المحتمل أنك قد سمعت بهذا المصطلح بشكل واسع عند تسكّعك من
منتدى برمجي آلخر ومن موقع آلخر ،والسؤال هنا ماهي هذه المكتبات الـ
APIالجاهزة؟؟
في بداية الكتاب وعند سرد تاريخ البرمجة تم ذكر أن شركة ميكروسوفت
قد طرحت مكتبات APIمجانية لجميع المبرمجين لجذب انتباههم وكسب
والئهم ،فال أعتقد – وال هم يعتقدون – أن مبرمجا سيفوت عليه فرصة
الحصول على سر مصلحة شركة عريقة الستخدامه – سر المصلحة – في
برامجه كما يحلو له وبالشكل الذي يريد.
وتقوم الشركات عاد ًة بنشر مكتبات APIsخاصة بها كدعاية على منتجاتها،
وأنت باستخدامك لهذه المكتبات تستطيع تطوير برامجك بنا ًءا عليها
ً
بدال من بالشكل الذي ترغب به ،أي أنك تبدأ من حيث انتهى اآلخرون،
البدء بالبرمجة من الصفر.
218
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
219
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
الجزء الثاني
Windows Form
Applications
220
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
221
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
قد يتم إيجاز بعض األمور الهامة المتعلقة باألدوات المستخدمة في تصميم
مشاريع الكتاب والتي يجب اإللمام بها أو االطالع عليها بشكل جيد .ولمن
يحتاج المزيد من الشرح واإليضاح والتفصيل فهناك العديد من الكتب
والفيديوهات على االنترنت تهتم بهذا الموضوع ،وال أرى فائدة من إنشاء
كتابٍ يوجد ما يغني عنه ،وعوضا عن ذلك فمن الجيد – كفكرة – أن يتوفر
كتاب يشرح مشاريع تطبيقية ويحاول أن يكون مكتبة مقروءة لمشاريع
مفتوحة المصدر ،وهذا ما ينوي الكتاب أن يحويه.
وفيه يتم عرض جميع ملفات المشروع ومصادره وخصائصه ،ويمكّنك من
الوصول إلى جميع طرقه وكائناته.
1راجع كتاب "سبيلك المختصر إلى تعلم لغة ،C#.Netبرمجة الواجهات" لخالد السعداني .فقد ك ّفى
ح عن أكثر األدوات التي ستستخدمها في برامجك ،ليغطّي 36أداة شائعةووفّى ،في كتابه شر ٌ
االستخدام .جزاه خيرًا ♥.
222
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
وفيه توجد األدوات التي ستستخدمها لتصميم مشروعك ،وهي مرتبة وفق
مجموعات.
الخصائص Properties
النموذج Form
وهو عبارة عن إطار (أو نافذة) تضع عليه األدوات التي تختارها ألداء وظائف
معينة ،وفق ترتيب معين .وتسمى عملية انتقاء األدوات وترتيبها بتصميم
النافذة أو المشروع أو النموذج.
محرر األكود
223
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
مالحظة
عند الضغط على أداة ما وكانت تحوي كو ًدا تحت أحد إجراءاتها ،فإن
محرر األكواد سينتقل إليه مباشرة حتى لو لم يكن هذا اإلجراء هو
االفتراضي.
في الجزء األول عندما ناقشنا محتويات أول مشروع ،قلنا أنه مؤلف من
قسمين ،سأفترض أنك تعرف وتفهم كليهما ،لكن سأشرحهما باختصار
للتذكير:
في القسم العلوي هناك مجاالت أسماء (أسميناها مكتبات) ماهي إال
ملفات تحوي فئات تؤدي وظائف معينة عن طريق مجموعة من الطرق
والخصائص التابعة لها.
في القسم السفلي هناك مجال خاص بمشروعك ،وفيه ستكتب أكوادك.
قد يثير اهتمامك اإلجراء ،InitializeComponentال عليك صادقه في
برامجك وأعطه بعض االحترام ،هو إجراء يقوم بتهيئة أدوات مشروعك عند
1
بداية تنفيذ البرنامج .كيف عرفت أنه إجراء؟
إذا كنت قد أكملت الجزء األول من الكتاب بشكل جيد ،أعتقد أنك تعرف
معنى Form1 : Formو )( public Form1وتعرف وظائفهما ..أما إذا لم
،لم أكتبه لتقرأه جدتي . تكمله أو لم تبدأ به فأكمله أو ابدأ به
يعرف اإلجراء بأنه تابع أو طريقة ال تعيد قيمة ،لذلك ال نسنده لمتغير أو لوسطاء طريقة أخرى. 1
224
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
استيراد المراجع
أو بإمكانك إضافة مكتبة خاصة بك – أنت برمجتها أو غيرك ،المهم أنها على
– من :Browse قرصك الصلب ،قرص كمبيوترك الصلب أقصد
1تم شرح استيراد المراجع سابقا في الجزء األول من الكتاب باسم "إضافة المكتبة إلى مراجع
المشروع" ،وألهميته في هذا الجزء ،وألنه من المحتمل أن يكون بعض القراء قد انتقل تلقائيا إلى الجزء
الثاني تم إعادة التنويه لذلك.
225
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
الخصائص Properties
تتميز األدوات عن بعضها بالخصائص التي تتمتع بها واألحداث التي قد
تجري عليها .أما األحداث فهي ظروف برمجية تمر على األدوات
وسنناقشها الح ًقا إن شاء هللا ،وأما الخصائص فهي ماتميز كائن عن آخر،
وبهذه األداة – شريط الخصائص – بإمكانك إدارة أدوات مشروعك:
الوظيفة الخاصية
االسم البرمجي ،ويختلف عن االسم الظاهر
)(Name
للمستخدم المتمثل بالخاصية ،Textحاول التفريق!
226
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
1قد ُتحتوى األداة ضمن أداة أخرى مثل GroupBoxأو أي أداة من أدوات االحتواء ،أو من قبل النافذة
.Form
227
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
228
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
األحداث Events
األحداث ماهي إال إجراءات تُنفذ عند حدوث أمر ما ،وهي إحدى األمور التي
تتميز بها الكائنات ،فقد قلنا أن للكائن أفعال يقوم بها (أسميناها طرق)،
وسمات يتميز بها (أسميناها خصائص) ،وظروف تمر به (وهي األحداث).
إن كل حدث مرتبط بظرف معين يمر بالكائنات ،والكائنات التي سنتعامل مع
أحداثها هي أدوات التحكم ،مثل الزر وصندوق النص والالئحة وحتى
النموذج وغيرها من األدوات .تقع على هذه األدوات ظروف مثل مرور مؤشر
الماوس فوق األداة ،أو الضغط بأحد مفاتيح الكيبورد عندما يكون التركيز
عليها ،أو فقدان التركيز من األداة وغيرها الكثير من األحداث التي سأشرح
أكثرها تكرارا في مشاريع هذا الكتاب.
الوظيفة الحدث
يحدث عندما يتم الضغط بزر الفأرة األيسر (أو
Click
االفتراضي) على األداة.
يحدث عندما يتم الضغط مزدوجا على األداة. DoubleClick
يحدث عندما يقوم المستخدم بإغالق
FormClosed
النموذج.
يحدث أثناء عملية إغالق النموذج. FormClosing
InputLanguageChangedيحدث عند تغيير اللغة*.
يحدث عند بداية ضغط أحد مفاتيح الكيبورد**. KeyDown
يحدث عند استمرار الضغط على أحد مفاتيح
KeyPress
الكيبورد**.
يحدث عند نهاية ضغط أحد مفاتيح الكيبورد
KeyUp
(رفع اليد عن المفتاح)**.
يحدث عند النقر بالماوس ،ويمكن االستفادة
منه في معرفة الزر المضغوط (يمين أو يسار أو MouseClick
الوسط)**** .
يحدث عندما ُينقر على زر الماوس ،وأيضا
MouseDown
نستفاد منه في معرفة الزر المضغوط*** .
تحدث عندما تدخل الماوس المجال المرئي
MouseEnter
لألداة.
يحدث عند حركة مؤشر الماوس على إحدى
MouseMove
األدوات**** .
يحدث عند تغيير المحتوى النصي لألداة
TextChanged
(الخاصة بالنصوص).
229
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
230
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
231
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
هذا الكتاب وابتدا ًءا من هذا الفصل وحتى نهاية الكتاب سيعطي َ
ك أفكارًا
ن به ،وأثنا َء ذلك تحتاج بعض الصبر ،القليل من وأساليبَ للوصول لما ُع ِ
نو َ
الوقت ،ونت على مدار الساعة ،والكثير الكثير من المشاريع المتوفرة على
االنترنت ،المصورة منها والمكتوبة.
أمر أخير أود التنويه له ،مواضيع الجزء السابق مترابطة ومتتابعة و ُي َتوَقع منك
أن تكون قد تعلمتها – أو قرأتها – بشكل متسلسل ،أما محتويات هذا الجزء
صا هذا الفصل – فليست متعلقة ببعضها وقد تجد أكوا ًدا غير – وخصو ً
مذكورة أو مشروحة أو منوه عنها في الكتاب ،لذلك فعليك البحث والتحري.
232
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
مشروع TextToSpeech
System.Speech
System.Speech.Synthesis
أنشئ مشروعا جدي ًدا وأضف إلى مراجعه المجال السابق ،ثم صمم
النافذة وفق الشكل التالي:
233
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
مالحظة
MaximumSize اضبط الخصائص، لجعل النافذة بحجم واحد ال يتغير
علىMaximizeBox و، على نفس المقدارSize وMinimumSizeو
.False القيمة
234
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
namespace TextToSpeech
{
public partial class Form1 : Form
{
//استنساخ كائن جديد يمثل لسان الحاسوب
SpeechSynthesizer Reader = new SpeechSynthesizer();
//تهيئة مكونات النموذج
public Form1()
{
InitializeComponent();
}
//التأكد من أن صندوق النص يحوي عبارات نصية
//يحو على نصوص يجب عدم تمكين األزرار من العمل
ِ إذا لم
private void richTextBox1_TextChanged(object sender, EventArgs e)
{
if (richTextBox1.Text != "")
{
button1.Enabled = true;
button2.Enabled = true;
button3.Enabled = true;
button4.Enabled = true;
}
else
{
button1.Enabled = false;
button2.Enabled = false;
button3.Enabled = false;
button4.Enabled = false;
}
}
235
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
//تحدث
private void button1_Click(object sender, EventArgs e)
{
Reader.Dispose();
Reader = new SpeechSynthesizer();
Reader.SpeakAsync(richTextBox1.Text);
}
//إيقاف مؤقت
private void button2_Click(object sender, EventArgs e)
{
if (Reader != null)
{
if (Reader.State == SynthesizerState.Speaking)
Reader.Pause();
}
}
//استئناف
private void button3_Click(object sender, EventArgs e)
{
if (Reader != null)
{
if (Reader.State == SynthesizerState.Paused )
Reader.Resume ();
}
}
//إيقاف
private void button4_Click(object sender, EventArgs e)
{
if (Reader != null)
{
Reader.Dispose();
}
}
}
}
ثم ينشئ نفسه من،عند الضغط على زر البدء على الكائن أن يتوقف أوال
.جديد ويتحدث بمحتويات النص
236
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
عند الضغط على زر اإليقاف المؤقت ،وإذا لم يكن الكائن ال شيء (أي أنه
مازال على قيد الحياة) ،وإذا كانت حالة الكائن هي الكالم ،فعليه أن
يتوقف.
هل تذكر ماهية الطرق والخصائص؟؟ قلنا إنها أفعال يقوم بها الكائن وصفات
يتميز بها .إن الطريقة Disposeهي فعل يقوم به الكائن بإيقاف الكالم ،كما
أن الخاصية Stateهي صفة تميزه فيما إذا كان متوقفا عن الكالم أم
متحدثا.
مالحظة
ال يمكنك نسخ األكواد بالكامل ولصقها في الفيجوال ستوديو عندك
ألنها لن تعمل ..وذلك بسبب أن األحداث الناتجة عن األدوات مثل
حدث ضغط الزر أو تغيير النص أو غيرها من الخصائص ال يمكن أن
تُنشأ إال إذا قمت أنت بإنشاءها .طبعا ال أتحدث عن إنشاء األحداث
برمجيا والذي تكلمنا عنه في الجزء األول من الكتاب ،وإنما أقصد أن
تنشئ الحدث من خالل األداة ،فمثال بالضغط مرتين على الزر
button1يمكن أن ُينشأ حدث button1_Clickثم نضع بداخله الكود
المناظر له في هذا الكتاب .وهكذا بالنسبة لجميع األكواد...
237
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
مشروع EmailSender
System.Web
System.Net
System.Net.Mail
238
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
239
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
namespace EmailSender
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
//عند الضغط على زر اإلرسال
private void button1_Click(object sender, EventArgs e)
{
//إنشاء كائن إلرسال رسالة من خالله
MailMessage Mail = new MailMessage( from.Text,
to.Text,
subject.Text,
body.Text);
string SMTP;
//اختيار نوع السرفر بحسب شركة البريد
//مع إعطاء قيمة ابتدائية حتى ال يحصل أخطاء
SMTP = "smtp.gmail.com";
if (radioButton1.Checked)
SMTP = "smtp.gmail.com";
else if (radioButton2.Checked)
SMTP ="smtp.mail.yahoo.com";
else if (radioButton3.Checked)
SMTP = "smpt.live.com";
//إنشاء كائن يمثل الخادم ليتواصل مع البورت الخاص بالشركة
SmtpClient Client = new SmtpClient(SMTP,587);
Client.UseDefaultCredentials = false;
Client.Credentials = new NetworkCredential(from.Text,
password.Text);
Client.EnableSsl = true;
try
{
//محاولة إرسال البريد
Client.Send(Mail);
MessageBox.Show("Mail : " + subject.Text + " sent successfully!",
"Message Sent",
MessageBoxButtons.OK,
MessageBoxIcon.Information,
MessageBoxDefaultButton.Button1,
MessageBoxOptions.DefaultDesktopOnly);
body.Text = "";
}
catch (Exception ex)
{
//! أظهر رسالة بذلك،في حال وجود خطأ
240
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
MessageBox.Show(ex.Message,
"Message Cann't Sent",
MessageBoxButtons.OK,
MessageBoxIcon.Error,
MessageBoxDefaultButton.Button1,
MessageBoxOptions.DefaultDesktopOnly);
}
}
المرسل منه والمرسل إليه وموضوع الرسالة وجسمها .ثم يحدد نوع
السرفر وذلك بنا ًءا على نوع مخدم البريد الذي سترسل منه ويتمثل هذا
بعبارة نصية ،SMTPوبنا ًءا عليه يتم إنشاء كائن ليتواصل مع شركة البريد
بعد تحديد رقم البورت .وللقيام باإلرسال يجب تحديد بريد وكلمة سر
المرسل ،ثم محاولة اإلرسال وإعطاء رسالة للمستخدم بالفشل أو النجاح.
يجب عدم تفعيل زر اإلرسال مالم يتم التأكد من أن جميع البيانات قد تم
إدخالها ،ولذلك أنشأنا إجرا ًءا أسميناه ،CheckDATAوهو إجراء يقوم بالتأكد
من أن جميع الحقول ليست فارغة .نستدعي هذا اإلجراء في حدث تغيير
النص لكل من صناديق النصوص المستخدمة العادية منها والغنية.
يمكن معرفة تفصايل SMTPلكل شركة وذلك بالبحث باالنترنت عنها ،وعند
البحث ستحصل على مايلي:
242
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
في حال وجود أخطاء جرب أن تسمح بالتطبيقات قليلة األمان من استخدام
بريدك االكتروني وذلك من إعدادات حسابك .كما في الصورة:
243
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
مشروع WindowsExplorer
System.IO
System.Diagnostics
244
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
:يمكن ضبط خصائص أداة قائمة العرض بصورة سريعة ومختصرة كما يلي
245
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
كما يمكن ذلك من شريط الخصائص .إلضافة عناوين لألعمدة ادخل إلى
خصائص الخاصية Culomnsثم أضف خمسة قوائم ،واجعل خاصية النص
لها كما هو في جدول الخصائص في الصفحة السابقة.
246
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
//المكتبات المستخدمة
using System.IO; //للتعامل مع المجلدات والملفات
using System.Diagnostics; //للتعامل مع البرامج والعمليات
namespace WindowsExplorer
{
public partial class Form1 : Form
{
string SelectedDrive, SelectedPath;
public Form1()
{
InitializeComponent();
getDrives(); comboBox1.Text = "C:\\";
comboView(); comboBox2.Text = "Details";
}
247
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
// يجب الحصول على ملفاته،عند النقر على أحد عناصر شجرة العرض
private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
{
SelectedPath = e.Node.FullPath ;
248
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
getFiles(SelectedPath);
TreeNode node;
DirectoryInfo Dir = new DirectoryInfo(SelectedDrive + SelectedPath);
try
{
foreach (DirectoryInfo folder in Dir.GetDirectories())
{
node = new TreeNode(folder.Name, 0, 0);
e.Node.Nodes.Add(node);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
SelectedPath = SelectedDrive + SelectedPath;
}
249
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
عند تغيير المحتوى النصي لصندوق النص يتم البحث بشكل تلقائي//
هذا يضمن لك ديناميكية عمل األداة ،وهو أفضل من وضع زر للبحث//
)private void textBox1_TextChanged(object sender, EventArgs e
{
))if (File.Exists(SelectedPath + "\\" + textBox1.Text
;)"!MessageBox.Show("Exists
}
}
}
عرّفنا متغيرين سنضع فيهما القرص الذي اختاره المستخدم (من صندوق
االختيار) والمجلد الذي انتقل إليه المستخدم (في شجرة العرض).
عند تحميل النموذج (بداية تشغيله) وبعد تهيئة مكونات المشروع ،يجب
الحصول على جميع أقراص نظام التشغيل ،وذلك من خالل إجراء
،getDrivesثم نجعل النص المحدد في صندوق االختيار هو القرص "\"C:
على اعتبار أنه فعليا جميع أنظمة التشغيل أول قرص فيها هو القرص ،C
ثم نقوم بملئ عناصر صندوق االختيار الثاني بأشكال العرض الممكنة،
وذلك من خالل إجراء ،comboViewثم جعل النص المحدد قي صندوق
االختيار هذا هو " "Detailsعلى اعتبار أننا صممنا األداة على أن تعرض
الملفات بالشكل تفاصيل.
مالحظة
ال تنسَ أنه لكتابة الرمز \ في عبارة نصية يجب كتابته مكررا ألنه أحد
رموز تنسيق العبارات النصية.
يمكن استخدام @ في بداية العبارة النصية الممثلة للمسارات بدال
من تكرار \ التي تفصل بين المسارات.
250
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
مالحظة
قد تحصل على رسالة خطأ عند فتح أحد األقراص مفادها أن القرص
غير جاهز ،وسببها أن هذا القرص قد يكون قرص وهمي غير
مستخدم.
تستخدم األقراص الوهمية عادة عند تثبيت أو تشغيل بعض األلعاب
أو البرامج الضخمة والتي تحتاج لملفات خارجية يستصعب تواجدها
في األقراص العادية.
أما للحصول على ملفات المجلد المحدد – ووضعها في قائمة العرض – يتم
استدعاء اإلجراء getFilesوالذي له وسيط وحيد وهو مسار المجلد
المحدد ،وفيه يتم إنشاء كائن يمثل عنصر قائمة عرض lviللقيام بعمليات
على عناصر قائمة العرض بعد قليل دون تكرار وإكثار األكواد ،ثم أنشأنا كائنا
Dirوهو استنساخ للفئة مجلد ،وهذا الكائن هو عبارة عن مسار المجلد
المحدد لعرض ملفاته ،ثم تمسح مكونات قائمة العرض إلضافة عناصر
جديدة ،ثم تتم محاولة إضافة جميع الملفات الموجودة داخل المجلد Dir
إلى قائمة العرض وذلك من خالل حلقة foreachمتغيرها كائن filesمن
نوع ملف يمثل ملفات الكائن ،Dirومن أجل كل عنصر يجب إضافة اسمه
أوال ،ثم تفاصيل أخرى عبر .SubItemsوعند وجود خطأ يتم عرض رسالة ً
نصية تشرحه ثم يكمل البرنامج مسيرته للحصول على ملفات أخرى.
251
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
عندما تصبح أداة قائمة العرض هي األداة الفعالة (عندما تكسب التركيز
بلهجة الفيجوال بيسك) فإنه يتم تفعيل زر تشغيل العملية ،وهذا اإلجراء
وضعته لمحاولة إقالل عدد األخطاء ،تخيل لو أن المستخدم لم يحدد الملف
المراد تشغيله وضغط زر تشغيل العملية ماذا تعتقد أن يحدث؟ بالتأكيد
رسالة خطأ تودي بحياة برنامجك مالم تتحكم بها .ومع هذا فللخطأ نصيب
محتمل ولكن باحتمالية أقل.
عندما تصبح أداة شجرة العرض هي األداة الفعالة فإنه من البديهي أن أداة
قائمة العرض ليست األداة الفعالة في المشروع حاليا (وجميع األدوات
األخرى بطبيعة الحال) ،لذلك يجب عدم تفعيل زر تشغيل العملية ألنه ما
من ملف محدد ..هل فهمت الفكرة من آخر إجرائين؟؟؟!
مالحظة
إذا كانت المشاريع صعبة بالنسبة لك فال عليك هي ليست سهلة
بالتأكيد وال يمكن لمبتدئ أن يتقنها ،بإمكانك تطبيق الكود عدة مرات
أو سؤال أحد المختصين أو ذوي الخبرة ،أو العودة ألفكار الجزء األول
لمحاولة تعويض المعلومات المبهمة.
إذا كانت المشاريع سهلة بالنسبة لك فبإمكانك اإلنتقال لمشاريع
ذات تطبيقات أوسع وأكثر واقعية مثل تطبيقات إدارة المبيعات أو ما
شابهها ،كما أنه بإمكانك ومع بعض األفكار القيام بالكثير من
التطبيقات المفيدة.
252
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
مشروع NotePadDataBase
يمكنك هذا المشروع من اختزان قيم معينة في ملف ذو امتداد معين ،وهو
مشابه لفكرة قواعد البيانات ألنه يخزن مجموعة من البيانات في ملف
واحد .هذا المشروع يسمح للمستخدم بإدخال مجموعة من القيم النصية
دون تكرارها ،باإلضافة لحذف قيمة معينة أو حذف جميع القيم.
ال يضمن المشروع لك ارتباط العناصر وفق نسق معين ،مثل رقم idمثال
كما في قواعد البيانات العادية ،لكنه يسمح لك برتيب العناصر تصاعديا أو
تنازليا ،دون إمكانية العودة للترتيب القديم.
System.IO
253
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
namespace NotepadDatabase
{
public partial class Form1 : Form
{
//متغيرات ستلزمنا على امتداد المشروع
string Path = Application.StartupPath + @"\Data.dat";
string SelectedData;
254
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
int SelectedIndex;
List<string> Names = new List<string>();
public Form1()
{
InitializeComponent();
//إذا كان الملف موجودا
if (File.Exists (Path))
LoadData(); //حمل البيانات
else //وإن لم يكن موجودا
{
var file = File.Create(Path); // قم بإنشاءه:)
file.Close(); //ثم أغلقه حتى نستطيع فتحه للقراءة
//File.Create(Path).Close() is the same :)
LoadData(); //اآلن حمل البيانات بعد أن أنشأنا الملف
}
}
255
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
//إضافة اسم
private void button1_Click(object sender, EventArgs e)
{
//استدعاء إجراء التحقق من وجود االسم
bool CheckName = IsData(textBox1.Text);
if (!CheckName) //اذا كانت النتيجة سلبية هذا يعني أن االسم غير موجود
{
File.AppendAllText(Path, textBox1.Text + Environment.NewLine );
}
else //وإن لم تكن سلبية معناها أن االسم موجود ويجب إدخال اسم جديد
MessageBox.Show("Try another name!", "Name exists!");
LoadData(); //وعلى كل األحوال حمل البيانات من جديد
}
256
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
//ترتيب تصاعدي
private void button4_Click(object sender, EventArgs e)
{
File.Delete(Path);
Names.Sort();
foreach (string Name in Names)
File.AppendAllText(Path, Name + Environment.NewLine);
LoadData();
257
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
}
ترتيب تنازلي//
)private void button5_Click(object sender, EventArgs e
{
;)File.Delete(Path
;)(Names.Reverse
)foreach (string Name in Names
;)File.AppendAllText(Path, Name + Environment.NewLine
;)(LoadData
}
}
}
وفي الكود السابق ،عرّفنا عدة متغيرات ستلزمنا خالل المشروع ،وهي
كما يلي:
مسار الملف :Pathوهو متغير نصي ،سيأخذ قيمة مسار التطبيق ،ويتبعه
باسم للملف وليكن Dataذو الالحقة .dat
مالحظة
يمكن الحصول على متغيرات كثيرة تربط تطبيقك بالبيئة المحيطة به
وذلك من خالل الفئة ،Applicationومنها مسار تشغيل التطبيق.
لكتابة مسار ما في جملة نصية نستخدم الرمز @ ،وذلك عوضا عن
تكرار الرمز \\.
مع الملفات ومحتوياتها ،ينصح باستخدام الخاصية NewLineالتابعة
للفئة Environmentعوضا عن "."\n
258
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
مشروع SpeakToComputer
يقسم المشروع إلى جزئين :األول نطق الكالم وقد تم مناقشته في
مشروع سابق وما سيأتي هنا ماهو إال تتمة وتطوير له ،والثاني التعرف
على الكلمات وذلك من خالل حفظ بعض الكلمات واألفعال في ملفات
معينة يقوم التطبيق بفتحها عند بداية عمله ،ثم يتعرف على الكلمات
الموجودة في هذه الملفات فقط .باإلمكان استخدام معاجم وقواميس
جاهزة وتضمن جميع كلمات لغة معينة مثل اللغة اإلنكليزية لكن هذا
يتطلب مهارة ودقة في نطق األحرف ،وبدال من ذلك بإمكانك تضييق
الموضوع لتجعل التطبيق يتعرف على كلمات معينة ،األمر الذي ال يتطلب
دقة في نطق األحرف.
System.Speech
System.Speech.Synthesis
System.Speech.Recognition
System.IO
System.Diagnostics
259
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
260
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
261
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace SpeaktoComputer
{
public partial class Form1 : Form
{
//استنساخ فئات القراءة واالستماع
SpeechSynthesizer Reader = new SpeechSynthesizer();
SpeechRecognitionEngine Engine = new SpeechRecognitionEngine();
public Form1()
{
InitializeComponent();
comboBox1.SelectedIndex = 0;
comboBox1.SelectedIndex = 1;
Recognizing(); //بدء اإلصغاء
}
262
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
if (TextRecognized.Contains("run"))
{
try
{
TextReplaced= TextRecognized.Replace("run ", string.Empty);
Process.Start(TextReplaced + ".exe");
richTextBox1.Text = string.Empty;
richTextBox1.Text = "Ok I'll do sir!";
toolStripButton1_Click(sender, e)
}
catch
{
}
}
263
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
264
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
case 0:
Gender = System.Speech.Synthesis.VoiceGender.NotSet ;
break;
case 1:
Gender = System.Speech.Synthesis.VoiceGender.Male ;
break;
case 2:
Gender = System.Speech.Synthesis.VoiceGender.Female ;
break;
case 3:
Gender = System.Speech.Synthesis.VoiceGender.Neutral ;
break;
}
265
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
catch
{
var file = File.Create(Application.StartupPath +
@"/" +
266
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
comboBox1.Text +
".dat");
file.Close(); //بهذه الطريقة نغلق الملف بعد فتحه
File.WriteAllText(Application.StartupPath +
@"/" +
comboBox1.Text +
".dat",
"Write your " +
comboBox1.Text +
" here!");
}
}
private void richTextBox2_TextChanged(object sender, EventArgs e)
{
if (!richTextBox2.Lines.Contains (""))
File.WriteAllLines(Application.StartupPath +
@"/" +
comboBox1.Text +
".dat",
richTextBox2.Lines);
}
private void button1_Click(object sender, EventArgs e)
{
MessageBox.Show("The Application will restart to save changes!",
"Save to dictionary!",
MessageBoxButtons.OK ,
MessageBoxIcon.Information ); Application.Restart();
}
private void Form1_Load(object sender, EventArgs e)
{
if (DateTime.Now.Hour <= 12 && DateTime.Now.Hour >= 6)
richTextBox1.Text = "Good morning sir!";
else if (DateTime.Now.Hour >= 12 && DateTime.Now.Hour <= 14)
richTextBox1.Text = "Good afternoon sir!";
else if (DateTime.Now.Hour >= 17 && DateTime.Now.Hour <= 19)
richTextBox1.Text = "Good evening sir!";
else
richTextBox1.Text = "How are you sir!";
toolStripButton1_Click(sender, e);
}
}
}
267
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
مشروع TabbedNotePad
ابتدا ًءا من هذا المشروع ومرو ًرا بجميع المشاريع التي تليه لن يتم بيان
خصائص األدوات المستخدمة كما في المشاريع السابقة ،وذلك ألنك
أصبحت كبيرًا اآلن – أكثر من كل مرة قلت لك بأنك صرت كبيرًا فيها – وبات
بإمكانك اكتشاف خصائص األدوات المستخدمة لوحدك ..ولكن في بعض
األحيان قد يتم توضيح بعض الخصائص ألهميتها أو ألنها غير واضحة بشكل
مباشر.
هذا وسيتم استخدام هذا األسلوب مع األكواد كذلك األمر ،فلن يتم شرح
إال الشيء الهام والحيوي في المشروع (كما الحظت في آخر مشروع)،
وسيترك لك مهمة اكتشاف جميع وظائف ومهام األكواد المستخدمة ،حيث
أن شرح األكواد كان عن كل شاردة وواردة في بداية الكتاب – وتحدي ًدا في
بداية هذا الفصل – ألنه تم افتراض أنك جديد على المشاريع ،وإلعطاءك
268
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
ُ
الكتاب المسائلَ .واآلن عليك التفكير في األسلوب الذي يناقِش ويحلِ ّل فيه
المسائل باألسلوب الذي ترتاح له واألقرب لتفكيرك واهتمامك.
269
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
مالحظة
يمكن ضبط صورة للعنصر في شريط األدوات ToolStripبالضغط عليه
باليمين ثم .Set Image
يمكن تهيئة العنصر من نوع Buttonفي شريط األدوات من خالل
.DesplayStyle
مالحظة
يتم عادة إضافة ثالثة نقاط أمام األوامر أو القوائم التي س ُتظهر نوافذ
جديدة.
270
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
271
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
272
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
Cut.Enabled = false;
tsCopy.Enabled = false; //األمر الموجود في شريط األدوات
tsCut.Enabled = false; //األمر الموجود في شريط األدوات
}
else
{
Copy.Enabled = true;
Cut.Enabled = true;
tsCopy.Enabled = true;
tsCut.Enabled = true;
}
if (Clipboard.ContainsText())
{
//إذا كان هناك نص في حافظة النظام يمكن اللصق
Paste.Enabled = true;
tsPaste.Enabled = true;
}
else
{
Paste.Enabled = false;
tsPaste.Enabled = false;
}
//األوامر األساسية
private void Copy_Click(object sender, EventArgs e)
{
GetRichTextBox().Copy(); //الحظ للوصول إلى النص الحالي نستدعي التابع
}
273
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
274
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
275
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
276
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
277
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
278
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
هناك بعض األوامر واألكواد لم يتم وضعها في الكود مثل أكواد الطباعة أو
ألن...فتح وحفظ الملفات أو المساعدة أو االستبدال أو شريط الحالة
المشروع يركز على أوامر تعديل النصوص فقط وكيفية التعامل مع محرر
.TabbedNotepad نصوص مبوب
279
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
مشروع WebBrowser
طبعا المشروع يحتاج الكثير والكثير من العناية والتحديث والتطوير ل ُيستفا َد
منه ،كإمكانية حفظ سجل النشاط أو تنزيل الملفات أو غيرها من الميزات
حا مطلوبًا أو مفيدا على أقل تقدير!
التي تجعل من متصفحك متصف ً
280
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
public Form1()
{
InitializeComponent();
}
281
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
282
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
283
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
PopupMessage مشروع
إمكانية عرض تلميحات عند مرور مؤشر الفأرة على أحدC# توفر لك
: كما يليToolTip مكونات نافذة برنامجك وذلك عبر األداة
وفي هذا المشروع سنقوم بإنشاء رسالة منبثقة مع تفاصيل إضافية مثل
.إمكانية إضافة صور أو غيرها من التفاصيل
284
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
{
get { return cPicture; }
set { cPicture = value; }
}
//التوابع البناءة للفئة
public Popup()
{}
public Popup(Panel Panel, Label Label, PictureBox Picture)
{
cPanel = Panel;
cLabel = Label;
cPicture = Picture;
}
//إجراءات الفئة
public void Load()
{
cPanel.BringToFront();
cPanel.BorderStyle = BorderStyle.FixedSingle;
cLabel.AutoSize = true;
cLabel.AutoEllipsis = true;
cPicture.Left = cPicture.Top = 3;
cPicture.SizeMode = PictureBoxSizeMode.StretchImage;
cPicture.Height = cPicture.Width = 45;
cPanel.Visible = false;
}
public void MouseMove(Control Control, int x, int y, string Text)
{
cPanel.Visible = true;
cPanel.Left = Control.Left + x + 15;
cPanel.Top = Control.Top + y + 15;
cPanel.Width = cLabel.Width + 60;
int H;
if (cPicture.Height < cLabel.Height) H = cLabel.Height;
else H = cPicture.Height;
cPanel.Height = H + 10;
cLabel.Text = Text;
cLabel.Top = 0; cLabel.Left = 55;
Control.MouseLeave += Control_MouseLeave;
}
void Control_MouseLeave(object sender, EventArgs e)
{
cPanel.Visible = false;
cPicture.Image = null;
}
}
}
285
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
ً
وصمم النافذة،WindowsFormApplications مشروعا من نوع ثم أنشئ
:التالية
واكتب في محرر األكواد ما،View Code اضغط باليمين على النموذج ثم
:يلي
using System;
using System.Windows.Forms;
using PopupDLL;
namespace Popup_test
{
public partial class Form1 : Form
{
Popup p = new Popup();
public Form1()
{
InitializeComponent();
}
286
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
طبعا بإمكانك تغيير لون الخط أو الخلفية أو إضافة مكونات أو إزالتها من
الرسالة كإدراج الصور أو الجداول أو الفيديوهات أو أية تفاصيل أخرى،
وستستفيد من هكذا فكرة في البرامج التي تحوي قواعد بيانات ضخمة
بحيث تحصل على تفاصيل المكونات الحالية بمجرد مرور مؤشر الفأرة على
أحد عناصر قاعدة البيانات.
287
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
MP3Reader مشروع
288
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
try
{
FileStream file = File.Open(name, FileMode.Open);
data = new byte[size];
file.Seek(-128, SeekOrigin.End);
file.Read(data, 0, size);
file.Close();
byte b1 = data[0];
byte b2 = data[1];
byte b3 = data[2];
int i = 3;
string title = "";
for (; i < 33; i++)
{
if (data[i] != 0)
title += Convert.ToChar(data[i]);
}
289
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
year += Convert.ToChar(data[i]);
}
290
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
كخاتمة لهذا الكتاب أحببت أن أنهيه بهذا المشروع ،والذي يستخدم بكثرة
في برامج المحاسبة والبرامج األدارية.
مالحظة
الرقم هو حرف أو رمز يعبر عن مجموعة من األعداد وفق نظام عد
ما ،وهي 8 ،7 ،6 ،5 ،4 ،3 ،2 ،1 ،0و 9في نظام العد العشري.
وهي عبارة عن أبجدية األعداد.
العدد هو مجموعة أرقام تكتب مع بعضها لتدل على قيمة ما ،مثل
1000 ،600 ،10وغيرها الكثير الكثير من األعداد .فاألعداد أشبه
بالكلمات إذا ما اعتبرنا األرقام حروف.
مشروعنا هذا يأخذ العدد ويحلله ألرقامه التي شكلته ثم يدرس
قيمة كل خانة مع أخرى ،ويدرس كيفية تسميتها مع بعضها.
ويعتمد هذا المشروع على تحليل العدد المدخل إلى أرقامه األولية ،ثم
معرفة اسم الخانة الموافقة لكل رقم وفق الخانة التي يشغلها.
291
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
namespace MoneyToWords
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
292
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
R = MoneyTens(cMoney) + ";"ة
if (cMoney[0] == char.Parse("1") &
cMoney[1] == char.Parse("1"))
R = ";"عشر أحد
if (cMoney[0] == char.Parse("2") &
cMoney[1] == char.Parse("1"))
R = ";"عشر اثنا
if (cMoney[0] > char.Parse("2") &
cMoney[1] == char.Parse("1"))
R = MoneyOnes(cMoney) + " " + MoneyTens(cMoney);
if (cMoney[0] == char.Parse("0") &
cMoney[1] != char.Parse("0") ) // أصفار آحاد
R = MoneyTens(cMoney);
}
if (i == 3)
{
if (MoneyHundreds(cMoney) != "")
{
if (cMoney[0] != char.Parse("0") &
cMoney[1] != char.Parse("0"))
R = MoneyHundreds(cMoney) + " "و+ R;
if (cMoney[0] == char.Parse("0") &
cMoney[1] != char.Parse("0"))
R = MoneyHundreds(cMoney) +
" "و+ MoneyTens(cMoney);
if (cMoney[0] != char.Parse("0") &
cMoney[1] == char.Parse("0"))
R = MoneyHundreds(cMoney) +
" "و+ MoneyOnes(cMoney);
if (cMoney[0] == char.Parse("0") &
cMoney[1] == char.Parse("0"))
R = MoneyHundreds(cMoney);
}
}
if (i == 4)
{
if (MoneyThousands(cMoney) != "")
{
if (SConvertCurrency(OtherUnits(cMoney)) != "")
R = MoneyThousands(cMoney) +
" "و+ SConvertCurrency(OtherUnits(cMoney));
else
R = MoneyThousands(cMoney);
}
}
if (i == 5)
{
293
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
if (SConvertCurrency(OtherUnits3(cMoney)) != "")
R = HundredThousands +
" "و+ SConvertCurrency(OtherUnits3(cMoney));
else
R = HundredThousands;
}
}
if (i == 7)
{
if (MoneyMillions(cMoney) != "")
{
if (SConvertCurrency(OtherUnits(cMoney)) != "")
R = MoneyMillions(cMoney) +
" "و+ SConvertCurrency(OtherUnits(cMoney));
294
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
else
R = MoneyMillions(cMoney);
}
}
if (i ==8)
{
string TenMillions = SConvertCurrency(
double.Parse(cMoney[7].ToString() + cMoney[6].ToString()));
if (TenMillions != "")
{
if (TenMillions == " )"عشرTenMillions += ";"ماليين ة
else TenMillions += " ;"مليون
if (SConvertCurrency(OtherUnits2(cMoney)) != "")
R = TenMillions +
" "و+ SConvertCurrency(OtherUnits2(cMoney));
else R = TenMillions;
}
}
if (i == 9)
{
string HundredMillions = SConvertCurrency(
double.Parse(cMoney[8].ToString() + cMoney[7].ToString() +
cMoney[6].ToString())) + " ;"مليون
if (HundredMillions != "")
{
if (cMoney[7] == '0' & cMoney[6] != '0')
{
if (cMoney[6] == '1')
HundredMillions =
SConvertCurrency((double.Parse(cMoney[8].ToString() + "00"))) + " ;"ومليون
else if (cMoney[6] == '2')
HundredMillions =
SConvertCurrency((double.Parse(cMoney[8].ToString() + "00"))) + "
;"ومليونان
else
HundredMillions =
SConvertCurrency((double.Parse(cMoney[8].ToString() + "00"))) + " "و+
SConvertCurrency(double.Parse(cMoney[6].ToString())) + " ;"ماليين
}
if (SConvertCurrency(OtherUnits3(cMoney)) != "")
R = HundredMillions +
" "و+ SConvertCurrency(OtherUnits3(cMoney));
else
R = HundredMillions;
}
}
295
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
if (i == 10)
{
if (MoneyBillions(cMoney) != "")
{
if (SConvertCurrency(OtherUnits(cMoney)) != "")
R = MoneyBillions(cMoney) +
" "و+ SConvertCurrency(OtherUnits(cMoney));
else
R = MoneyBillions(cMoney);
}
}
if (i == 11)
{
string TenBillions = SConvertCurrency(
double.Parse(cMoney[10].ToString() + cMoney[9].ToString()));
if (TenBillions != "")
{
if (TenBillions == " )"عشرTenBillions += ";"مليارات ة
else TenBillions += " ;"مليار
if (SConvertCurrency(OtherUnits2(cMoney)) != "")
R = TenBillions +
" "و+ SConvertCurrency(OtherUnits2(cMoney));
else R = TenBillions;
}
}
if (i > 11)
{
R = "";
}
}
return R;
}
case 1:
return ";"واحد
case 2:
return ";"اثنان
case 3:
return ";"ثالث
case 4:
return ";"أربع
296
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
case 5:
return ";"خمس
case 6:
return ";"ست
case 7:
return ";"سبع
case 8:
return ";"ثمان
case 9:
return ";"تسع
default:
return "";
}
}
static string MoneyOnes(int Ones) //اآلحاد بطريقة أخرى
{
switch (Ones)
{
case 1:
return ";"واحد
case 2:
return ";"اثنان
case 3:
return ";"ثالث
case 4:
return ";"أربع
case 5:
return ";"خمس
case 6:
return ";"ست
case 7:
return ";"سبع
case 8:
return ";"ثمان
case 9:
return ";"تسع
default:
return "";
}
}
static string MoneyTens(params char[] c) //العشرات
{
switch (int.Parse(c[1].ToString())) //ثاني خانة
{
case 1:
return ";"عشر
297
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
case 2:
return ";"عشرون
case 3:
return ";"ثالثون
case 4:
return ";"أربعون
case 5:
return ";"خمسون
case 6:
return ";"ستون
case 7:
return ";"سبعون
case 8:
return ";"ثمانون
case 9:
return ";"تسعون
default:
return "";
}
}
static string MoneyHundreds(params char[] c) //المئات
{
switch (int.Parse(c[2].ToString())) //ثالث خانة
{
case 1:
return ";"مئة
case 2:
return ";"مئتان
//جميع الحاالت التالية لها نفس النتيجة
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
case 9:
{
return MoneyOnes(int.Parse(c[2].ToString())) + " ; "مئة
}
default:
return "";
}
}
static string MoneyThousands(params char[] c) //اآلالف
{
switch (int.Parse(c[3].ToString())) //رابع خانة
{
298
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
case 1:
return ";"ألف
case 2:
return ";"ألفان
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
case 9:
{
return MoneyOnes(int.Parse(c[3].ToString())) + " ;"آالف
}
default:
return "";
}
}
static string MoneyMillions(params char[] c) //الماليين
{
switch (int.Parse(c[6].ToString())) //سابع خانة
{
case 1:
return ";"مليون
case 2:
return ";"مليونان
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
case 9:
{
return MoneyOnes(int.Parse(c[6].ToString())) + " ;"ماليين
}
default:
return "";
}
}
static string MoneyBillions(params char[] c) //المليارات
{
switch (int.Parse(c[9].ToString())) //عاشر خانة
{
case 1:
return ";"مليار
case 2:
299
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
return ";"ملياران
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
case 9:
{
return MoneyOnes(int.Parse(c[9].ToString())) + " ;"مليارات
}
default:
return "";
}
}
static double OtherUnits(params char [] c) //الخانات التالية لأللف والمليون
{
string t = "";
for (int j = c.Length; j > 1; --j)
t += c[j - 2].ToString(); //#$$$ >> $ is needed (or #$$$$$$)
return double.Parse(t);
}
static double OtherUnits2(params char[] c) //الخانات التالية لعشرات اآلالف
{
string t = "";
for (int j = c.Length; j > 2; --j) //##$$$ >> $ is needed
t += c[j - 3].ToString();
return double.Parse(t);
}
static double OtherUnits3(params char[] c) //الخانات التالية لمئات اآلالف
{
string t = "";
for (int j = c.Length; j > 3; --j) //###$$$ >> $ is needed
t += c[j - 4].ToString();
return double.Parse(t);
}
وكبداية أعتذر منك ج ًدا ج ًدا ج ًدا عن رداءة الكود ألن عرض الصفحة ال
فبعض األكود وزعتها على سطرين بحيث يتم،يكفي ليظهر الكود كامال
300
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
وبعدها سنقوم بدراسة كل رقم برقمه ،وذلك عبر حلقة تكرار تبدأ من
القيمة ( 1أول خانة) وتنتهي بقيمة تمثل عدد أرقام العدد ،وفي حالتنا 7
أرقام ،أي أن الحلقة ستتكرر 7مرات ،من 1وحتى .7
إذا كان عداد الحلقة iيساوي ،1أي أننا ندرس أول خانة ،فإننا سنستدعي
التابع MoneyOnesوالذي يقوم بتحويل اآلحاد إلى أرقام ،وبدوره التابع
MoneyOnesيقوم باستقبال عدد غير محدد من الوسطاء كمصفوفة
حرفية ،ليقوم باختبار قيمة العنصر األول ذي الترتيب ،0فإذا كانت 1يعيد
القيمة "واحد" ،وإذا كانت 2يعيد القيمة "اثنان" ،وهكذا حتى .9وفي مثالنا
ومن أجل قيمة اآلحاد 4سيعيد التابع القيمة "أربع" .وبالعودة للتابع الذي
استدعى MoneyOnesفإن Rستصبح قيمتها "أربع".
ينتقل الكود سطرًا سطرًا وال ينفذ أي سطر بعد بنية الشرط األولى ألن
جميع الشروط التالية غير محققة .ليزداد عداد الحلقة بمقدار 1ويعيد تنفيذ
محتواها من جديد.
اآلن عداد الحلقة له القيمة ،2لذلك فالشرط الذي ينص على أن i == 2
سيتم تنفيذه ،وفيه سنالحظ الحاالت التالية (وهي حاالت وضعتها بنفسي
ومن المحتمل أن توجد حاالت أخرى لم تخطر على بالي ،والموضوع مماثل
لبنى الشرط األخرى):
301
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
-أن يكون اآلحاد معدوم والعشرات تساوي 1وهو حالة العدد 10فقط،
وعندها Rتساوي "عشرة".
-أن يكون اآلحاد معدوم والعشرات ال يساوي ،1مثل 20أو 30أو ،40
فتكون Rهي ناتج تنفيذ التابع MoneyTensفقط.
عندما يصبح عداد الحلقة ،3وفي حالة لم تكن خانة المئات معدومة ،تكون
لدينا الحاالت التالية:
302
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
-أن يكون اآلحاد معدوم والعشرات غير معدوم مثل العدد 720وعندها
Rستكون سبع مئة وعشرون ،الحظ قيمة 7باآلحاد ثم "مئة" ثم "
و" ثم قيمة 2بالعشرات.
-أن يكون اآلحاد غير معدوم والعشرات معدوم مثل 702وعندها R
ستكون سبع مئة واثنان ،الحظ قيمة 7باآلحاد ثم "مئة" ثم " و" ثم
قيمة 2باآلحاد.
عندما يصبح عداد الحلقة ،4أي عند دراسة اآلالف فإنه ومن أجل قيمة
لآلالف غير معدومة تكون لدينا الحاالت التالية:
-إذا كان ما أمام خانة اآلالف (خانة اآلحاد والعشرات والمئات) غير
معدوم – ويمكن ذلك عن طريق استدعاء التابع SConvertCurrency
ليعيد فقط القيمة المقابلة لألرقام المكونة من اآلحاد والعشرات
والمئات وهذه القيمة نحصل عليها من التابع OtherUnitsوالذي
يقوم بتكون عبارة نصية مكونة من الخانات الثالث فقط – فعندها
ُيستدعى تابع اآلالف ويضاف للقيمة المعادة من تابع اآلالف القيمة "
و" ثم ناتج استدعاء SConvertCurrencyمن أجل ناتج .OtherUnits
ً
نوعا ما لذلك تأمل األمثلة التالية: أعلم أن الموضوع مربك
العدد 1250يكتب ألف ومئتان وخمسون ،الحظ ألف ثم " و" ثم ناتج
تحويل القيمة 250إلى كلمات وذلك باتباع الخطوات عندما عداد
الحلقة يأخذ القيم 1و 2و.3
ُيكتب ألفان – ناتج استدعاء تابع األلوف – ثم " و" ثم يستدعى تابع
تحويل العدد لكلمات من أجل العدد 501ليكون الناتج خمس مئة
وواحد .ليصبح الناتج النهاية ألفان وخمس مئة وواحد.
استغرقت في برمجة هذا المشروع ثالثة أيام – بمعدل أربع ساعات يوم ًيا
– ألحصل على هذا التطبيق ،وقد ابتدأت بأمل %0.00أن أصل لنهايته،
ألثبت لنفسي ولك عزيزي القارئ أنه ال صعبَ مع المحاولة واإلصرار
والرغبة بوجودة المعرفة والتوكل على هللا.
ما علينا ،1قررت في النهاية وضع المشروع في نهاية هذا الفصل كهدية
للقارئ – ألنه بنظري من أكثر المشاريع قيم ًة وتطبي ًقا واقعيا – وكدعاية
وأهداف شخصية أخرى .لكني صدمت مرة أخرى عندما حاولت االنتقال من
أسلوب األكواد اإلجرائي الذي تتعامل معه VBإلى أسلوب أكواد بيئة دوت
نت ،ومع بعض التجارب الفاشلة حصلت على هذا التطبيق الناجح!! ولمن
يرغب باالطالع أو االستفادة فهذا هو الكود بلغة :Visual Basic 6
_ Public Function ConvertCurrency(Money, FullCurrency, _ PartCurrency As
)String
On Error GoTo 1
Ma = " " & FullCurrency
304
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
305
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
ومع األسف وبعد ماانتهيت من التطبيق اكتشفت أن هناك من صمم واح ًدا
وهو من نجوم البرمجة العربية مثل،وهو المهندس محمد حمدي غانم
.تركي العسيري وأحمد جمال خليفة
306
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
ً
مثال ،كما أنه يشتمل على مجال مثل إحصاء الناس أو األدوات أو القطع
أوسع من األعداد..
307
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
308
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
في هذا الفصل سنتحدث عن أكثر األوامر شيوعا في نظام الدوس والتي
سنستخدم بعضها في برامجنا.
309
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
طيب لماذا تناولناه في هذا الكتاب؟؟؟ ألن هناك الكثير من األمور التي
بإمكاننا القيام بها في C#بمساعدة موجه األوامر ،توجد أكثر من فكرة
بإمكاننا االستعانة بموجه األوامر ألداءها في ،C#والفقرات التالية ستوضح
ذلك .وعلى اعتبار أنه من المحتمل أنك – عزيزي القارئ – ال تعلم كثيرًا
عن موجه األوامر ،فكان من الجيد شرحه لك بشيء من اإليجاز ألكثر من
غاية ،األولى هي تحضيرك وتدريبك على كيفية عمل موجه األوامر
لتستطيع فهم األفكار التي قلنا إنها تعتمد عليه ،الثانية هي إطالعك على
بيئة الدوس والتي قد تفيدك في تطبيقات خاصة بك ،الثالثة هي إكسابك
مرجعا صغيرًا مختصرًا عن موجه األوامر إن كان أحد اهتماماتك.2
والكتاب هذا يحاول قدر اإلمكان احتواء أكبر عدد من المواضيع الممكنة
المتعلقة بـ ،C#فقد تحدثنا عن المفاهيم األساسية والمتقدمة ،وناقشنا
بعض المشاريع التطبيقية ،وسنناقش اآلن كيفية التعامل مع موجه األوامر
من خالل ،C#والح ًقا كيفية التعامل مع الرجستري من خالل ،C#كما
وسنتحدث عن قواعد البيانات أيضا إن شاء هللا.
إذا لم تكن ترغب بتعلم نظام الدوس فانتقل مباشرة لفقرة حماية الملفات والبيانات هناك ستجد .C# 2
310
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
أوامر دوس
كما هو الحال في أي بيئة برمجية – أو بكالم أدق بيئة تتعامل مع أوامر
برمجية – فإنه عليك كمستثمر لهذه البيئة سوا ًءا أكانت برنام ً
جا أو لغة
برمجة أو غيرها من البرمجيات أن تعرف الكلمات الخاصة بهذه البيئة وأن
تفهم طريقة تطبيقها ..وفهم طريقة تطبيق هذه الكلمات أهم من معرفتها
ً
أساسا ..هذه الكلمات هي نفسها الكلمات المحجوزة في لغات البرمجة.
موجه األوامر يتعامل مع أوامر محددة ،بمتغيرات محددة ،وأي خلل في
األمر أو المتغيرات يعرضك لخطأ أنت بغنى عنه .فال تتوقع مثال أن تكتب له
مثال ) Hello bro :فيجيب تحيتك! بالعكس تماما ستظهر لك عبارة ستمر
معك طيلة فترة حياتك وستكره عمرك منها ،هذه العبارة مفادها:
"ياحبيبي 'Hello' ،ال يعتبر من األوامر الداخلية أو الخارجية ،وليس برنامجا
قابال للفتح أو ملفا دفعيا" ،ال تأخذ مني إال الكالم ،افتح موجه األوامر وجرب
الكود السابق:
مالحظة
عليك االنتقال لفهرس المجلدات أو الملفات التي ستتعامل معها
وذلك باستخدام أمر معين سنراه الحقا ،وإال فعليك كتابة مسار هذه
الملفات أو المجلدات بشكل كامل.
فهرس يعني مجلد أو مسار ( فاجأتك صحيح ؟).
في حال وجود فراغات في مسارات أو أسماء المجلدات أو الملفات
التي ستتعامل معها عليك إحاطتها بإشارة ".
المحرف \ يستخدم مع المسارات أما /فيستخدم مع خيارات
ومتغيرات األوامر.
311
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
افتح موجه األوامر لتالحظ وجود ثالثة أسطر بها كلمات ،أول سطرين يصفان
لك نسخة موجه األوامر المثبتة على جهازك .السطر الثالث فارغ ،السطر
الرابع مكتوب فيه مسار مستخدمك الشخصي في كمبيوترك ثم إشارة >،
وأمامها مؤشر يظهر ويختفي كل أقل من ثانية ..سنقوم اآلن ببعض
العمليات األساسية والتي ال غنى عنها عند التعامل مع .cmd
مالحظة
موجه األوامر ليس حساسا لحالة األحرف ،فـ gamesنفسها
.Gamesوكذلك الحال بالنسبة لألوامر cdنفسها CDنفسها .Cd
وصفه األمر
عرض أو إضافة اسم مشغل ملف معين في
الرجستري.
لمعرفة جميع المشغالت في الكمبيوتر:
assoc Assoc
لمعرفة مشغل الملفات النصية مثال:
Assoc .txt
والنتيجة ستكون ،.txt = txtfileولمعرفة مسار هذه
312
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
313
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
314
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
0وحتى .9999
CSالخيارات حساسة لحالة األحرف.
الخياران Tو Dيأتيان معا.
الحظ األمثلة:
"CHOICE /C YN /M "Press Y for Yes, N for No.
CHOICE /T 10 /C ync /CS /D y
CHOICE /C ab /M "Select a for option 1 and b
"for option 2.
بعد إدخال أحد الخيارات فإن هناك متغير افتراضي
في موجه األوامر يسمى errorlevelيأخذ قي ً
ما
عددية ..هذا المتغير سنستخدمه لتحديد ما يجب
على موجه األوامر تنفيذه وذلك من خالل األمر .if
إذا لم يتم إدخال أحد الخيارات الموضوعة من خالل
الخيار cفإن موجه األوامر لن يسمح لك بالتقدم
لألوامر التالية (مثال لديك الخيارات 123وقمت
بالضغط على .)4
لمسح محتويات الشاشة. Cls
نسخ ناتج تنفيذ أمر ما إلى الحافظة .مثال:
Clip
Dir | clip
تغيير لون شاشة او خط موجه األوامر ،ويأخذ أحد
القيم:
Color
315
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
316
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
317
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
318
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
319
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
( ) ELSE
echo d:\file.txt missing.
)
كما يمكن استخدام الخيار iمع األمر ifلتصبح
بالشكل:
IF [/I] string1 compare-op string2 command
IF CMDEXTVERSION number command
IF DEFINED variable command
حيث compare-opيأخذ إحدى القيم التالية:
Equمساوي.
Neqليس مساوي.
Lssأقل.
Leqأقل أو يساوي.
Gtrأكبر.
Geqأكبر أو يساوي.
الحظ المثال:
IF %ERRORLEVEL% LEQ 2 goto okay
والذي يعني إذا كانت القيمة المختارة أكبر أو تساوي
2انتقل للسطر المعنون بـ .okay
عرض وتعديل اسم محركات األقراص.
لعرض اسم القرص :d
Label d:
لضبط اسم جديد للقرص :d
Label
Label d: MyDisk
إلزالة اسم القرص (استعادة االفتراضيات) ،قم بعرض
اسم القرص من خالل األمر األول ،ثم اضغط Enter
ثم .y
إنشاء مجلد .وهو نفسه .mkdir
في حال كنت في مسار المجلد الذي ترغب بإنشاء Md
مجلد فيه يكفي كتابة اسمه.
تنسيق موجه األوامر ،من حيث األبعاد.
لتغيير أبعاد نافذة موجه األوامر: Mode
Mode 50,30
نقل الملفات وإعادة تسمية الملفات أو المجلدات.
ويأخذ الخيارات التالية:
Move
Yعدم إظهار رسالة تأكيد عند وجود نفس الملف.
-yإظهار رسالة تأكيد عند وجود نفس الملف.
التحكم بالشبكة المحلية ،وهو ضخم جدا يحتاج
لكتاب لشرحه.. Net
لعرض األقسام التي يتعامل معها األمر:
320
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
Net
لعرض معلومات عن األمر:
Net help
لعرض معلومات عن قسم معين مثال :user
Net help user
عرض قائمة بأسماء األجهزة المتصلة بالشبكة
وأسماء مستخدمي الكمبيوتر:
Net user
إضافة مستخدم:
Net user Name /add
حذف مستخدم:
Net user Name /delete
تغيير كلمة سر المستخدم:
Net user Name Pass
حيث Nameاسم المستخدم و Passكلمة السر.
أمر مخصص بالشبكات ،وهو أضخم من القبله.
عرض أسماء الشبكات المحفوظة في الكمبيوتر:
Netsh wlan show profiles
Netsh
عرض معلومات عن شبكة معينة اسمها :WL
Netsh wlan show profiles WL
كما أنه لعرض كلمة السر يكتب .key = clear
إيقاف موجه األوامر بشكل مؤقت وإظهار العبارة:
إضغط أي مفتاح لالستمرار ،...وذلك في الملفات Pause
الدفعية.
تغيير العبارة التي تظهر في كل سطر قبل األوامر
والتي قلنا أن اسمها المحث ،وافتراضيا هي مسار
الفهرس الحالي.
يمكن للمحث أن يأخذ القيم التالية:
$aإشارة &
$bإشارة |
$cقوس مفتوح )
$dالتاريخ الحالي
Prompt
$eمفتاح الهروب (مفتاح أسكي له )27
$fقوس مغلق (
$gإشارة أكبر >
$hمسح حرف للخلف
$lإشارة أصغر <
$nالقرص الحالي
$pالمسار الحالي (بما فيه القرص الحالي)
$qإشارة مساواة =
321
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
$sفراغ
$tالوقت الحالي
$vإصدار ويندوز
_ $سطر جديد
$$إشارة الدوالر $
لجعل المحث عبارة نصية وليكن :Eng27
Prompt Eng27
كما يمكن استخدام أكثر من قيمة م ًعا:
Prompt Eng27$g
وإلعادته لوضعه االفتراضي وهو $P$Gاكتب
.prompt
حذف المجلدات. Rd
نفسه .rd Rmdir
ترك مالحظة في الملفات الدفعية ،وهو مكافئ
للمحرف \\ المستخدم في C#لترك المالحظات.
والمالحظات هي أسطر ال يقرؤها المترجم ،وكما هو Rem
معروف فإن المالحظات تستخدم لعنونة األكواد ولترك
تلميحات ومذكرات يعاد إليها عند الحاجة.
إعادة تسمية الملفات .حيث يوضع مسار الملف
المراد إعادة تسميته ثم االسم الجديد.
ren e:\Folder\File1.txt File.txt
حيث تم تغيير اسم الملف الواقع في المجلد Folder
Ren
ضمن القرص eمن االسم File1.txtإلى .File.txt
كما يمكنك عدم كتابة مسار الملف كامال إذا كنت
في فهرسه.
كما يمكن استخدام األمر moveإلعادة التسمية.
نفسه .ren Rename
التحكم بالمتغيرات الخاصة ببيئة دوس وإظهارها.
وهو أحد األوامر التي من الممكن أن تستفيد منها
خالل حياتك .وذلك بالشكل التالي:
إظهار المتغيرات الموجودة في نظام :dos
Set
عرض المتغيرات التي تبدأ بحرف ما أو مجموعة من
الحروف وليكن :an Set
Set an
إنشاء متغير وإسناد قيمة له:
Set a = 5
استقبال قيمة من المستخدم وتخزينها في متغير:
Set /p a = Enter a:
والناتج سيكون عبارة نصية تطالبك بإدخال فيمة لـ .a
322
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
323
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
وحتى .32727
الملف الدفعي يتمثل كمسار بمتغير باسم ،0حيث
يمكن استخدامه بكتابة إشارة %واحدة قبله ،الحظ:
Copy %0 d:\Hasan%random%.txt
والكود السابق يأمر الملف الدفعي أن ينسخ نفسه
إلى القرص dويغير اسمه إلى Hasanويليه رقم
عشوائي ويجعل صيغته .txt
خيارات الطاقة في ويندوز .ويأخذ المتغيرات التالية:
Sإيقاف تشغيل الكمبيوتر.
Rإعادة تشغيل الكمبيوتر.
Lتسجيل الخروج (ال يمكن استخدامه مع cأو.)t
Iعرض مربع حوار خيارات الطاقة للشبكات.
Tإجراء العملية بعد زمن ما (مقدرا بالثانية). Shutdown
Cترك تعليق للمستخدم.
Aإحباط العملية في حالة كانت مجدولة.
Fإيقاف قسري لجميع البرامج قيد العمل.
والجدير بالذكر أن الزمن في حال لم يتم تحديده من
خالل المتغير tهو 60ثانية.
تشغيل برنامج في نافذة جديدة .وله الخيارات:
Minتشغيل البرنامج في وضع التصغير.
Maxتشغيل البرنامج في وضع التكبير.
Lowالتشغيل بأولوية ضعيفة.
BelowNormalالتشغيل أقل من عادية.
Normalالتشغيل بأولوية عادية.
AboveNormalالتشغيل بأولوية أكثر من عادية.
Highالتشغيل بأولوية عالية. Start
RealHighالتشغيل بأولوية أعلى من العالية.
Waitتشغيل البرنامج بعد إصدار أمر جديد.
" "Titleإظهار عنوان لبعض البرامج.
يمكن تشغيل البرامج التالية من خالل هذا األمر:
-البرامج العادية (بكتابة مسارها).
-البرامج الموجودة داخل ،System32مثل calc
و notepadو cmdو explorerو controlوغيرها.
معلومات عامة عن الكمبيوتر. Systeminfo
قائمة بالبرامج قيد العمل. Tasklist
إيقاف العمليات الجارية ..هذا األمر والذي سبقه معا
Taskkill
يشكالن .Alt + Ctrl + Del
تغيير اسم الملف الدفعي أو موجه األوامر الحالي. Title
عرض أو تعديل الوقت الحالي .لعرض الوقت فقط
Time
اضغط Enterبعد استخدام األمر.
324
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
جرب جميع األوامر السابقة لتأخذ فكرة عنها وأي أمر يستعصي عليك
اكتب اسمه ثم ? ،/لتحصل على شرح مفصل عنه.
325
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
مالحظة
قد تحتاج لتشغيل موجه األوامر كمسؤول لتتمكن من تنفيذ بعض
األوامر.
في بعض األحيان قد تحتاج لحفظ ناتج أحد أوامرك في ملف خارجي
تستفيد منه كتقرير لعملية ما ،خصوصا عند أتمتة برامجك ،أو قد ال تتمكن
من عرض ناتج تنفيذ أحد األوامر في cmdلضخامته فتضطر لحفظ الناتج
في ملف خارجي وقراءته هناك ،أو قد ترغب باستعراض عضالتك في نظام
الدوس أمام أحد معارفك .أيا كان هدفك فبإمكانك القيام بهذه العملية
بالصيغة التالية:
فمثال انتقل للقرص eعبر األمر e:ثم اكتب ،dir > c:\EFiles.txtليتم
إنشاء ملف نصي في القرص cباسم EFilesمكتوب فيه محتويات .e
لكن انتبه ،ففي حال وجود الملف سيتم استبداله عند استخدام هذا
األمر ،أي أن بياناتك ستحذف ،لذلك فكن حذرا مع هذا األمر .وعوضا عن
ذلك إذا أردت الكتابة إلى نهاية ملف موجود مسبقا فاستخدم اإلشارة >>،
وفي كال الحالتين سيتم إنشاء ملف جديد في حال عدم وجوده.
مالحظة
عند حفظ ناتج تنفيذ أمر ما في ملف خارجي فالناتج لن يعرض في
شاشة موجه األوامر ،لذلك عند استخدامك إياه يجب أن تكون قد
درست ناتج األمر أوال بتطبيقه دون استخدام هذه العملية.
عندما ال يكون األمر الذي تستخدمه من األوامر التي يتعارف عليها
نظام الدوس – على األقل على كمبيوترك – فإنه سيتم كتابة عبارة
وجود خطأ في الملف الخارجي ،مع تطبيق البند األول من هذه
المالحظة.
يوفر لك موجه األوامر إمكانية تنفيذ أكثر من كود في سطر واحد وذلك من
خالل الربط بين األوامر بإشارة & ،حيث بإمكانك تنفيذ العديد والعديد من
326
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
األوامر بوجود هذا الرمز .لكن انتبه ،عند وجود خطأ ما (أمر ال يعرفه نظام
التشغيل) ،فإن األوامر ما بعد األمر الخاطئ لن تنفذ ،أما األوامر التي قبله
فستنفذ بسالسة.
هذا يعني أن األمر الخاطئ إذا كان أوال ً لن يتم تنفيذ شيء ،وإذا كان آخر
أمر ضمن سطرك المدمج فسيتم تنفيذ جميع األوامر إال واحداً.
المفتاح :F1يقوم بكتابة آخر أمر تم استخدامه ،وذلك بمعدل حرف واحد
من اليسار إلى اليمين من أجل كل ضغطة للمفتاح .F1
المفتاح :F2يعطيك مربع حوار يطلب منك إدخال حرف ،فيقوم بنسخ جميع
أحرف األمر السابق حتى الحرف السابق للحرف الذي أدخلته.
المفتاح :F7يعرض األوامر في ذاكرة موجه األوامر ،هل سألت نفسك كيف
األوامر األوام َر السابقة؟! بالتأكيد هناك ذاكرة وهنا باإلمكان
ِ يتذكر موجه
التعامل معها .عند اختيار أحد األوامر المحفوظة في الذاكرة فإنه سينفذ
فورا.
327
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
المفتاح :F9يقوم بتنفيذ أحد األوامر الموجودة في الذاكرة بناء على رقم
األمر (الحظ أن أول عنصر رقمه .)0
بقية األزرار ال وظيف َ
ة لهم (على حد علمي).
جميع األوامر التي تعرفت عليها كانت تتعامل مع ملف واحد بعينه ،قد
تحتاج للتعامل مع عدد كبير من الملفات أو نوعية معينة من الملفات،
الحظ:
328
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
في المثالين األخيرين ،سيتم التعامل مع جميع الملفات التي عدد أحرف
اسمها ثالثة ،ومن نوع نصي أو من أجل جميع أنواع الملفات.
أخطاء قد تواجهك
329
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
يفضل دائما االبتداء باألمر @Echo offفي الملفات الدفعية إلخفاء المحث،
حيث يقوم األمر Echo offبإلغاء ظهور المحث لألوامر التالية أما الرمز @
فيلغيه لألمر الحالي ..هذه الحركة تعطيك شاشة فارغة محتوياتها فقط
ستكون نواتج تنفيذ األوامر.
في حال كان ملفك الدفعي سيجري محادثة مع المستخدم ،يجب إنهاء
ملفك الدفعي باألمر pauseوالذي يوقف شاشة موجه األوامر ريثما يقوم
المستخدم بإدخال أحد المفاتيح (مناظر لـ )( Console.ReadKeyفي .)C#
330
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
وماسيحدث هو أن مل ًفا نصيًا س ُيب َتدَأ بعبارة نصية ،ثم ُيكتب بعدها
مشغالت ملفات كمبيوترك ،ثم خطوط ثم عبارة تقول للمستخدم أنه تم
تنفيذ األمر في الوقت الفالني.
الحظ أنه استخدمنا إشارة > مرة واحدة عند أول أمر وإشارتين عند بقية
األوامر ،والسبب في ذلك أن األولى تقوم باستبدال الملف في حال وجوده،
أما الثانية فتكتب في نهاية الملف في حال وجوده.
قد تقول لي :أين األمر pause؟! وسأجيبك أنه ال يهمني أن تظهر شاشة
موجه األوامر للمستخدم ..أنا فقط تهمني النتائج التي ستحفظ في ملف
نصي.
-إخفاء جميع الملفات النصية والتي عدد األحرف المكونة السمها هو
،3اإلخفاء سيكون بشكل متقدم بحيث ال يمكن عرض الملفات
بتفعيل خيار عرض الملفات والمجلدات المخفية:
@echo off
attrib ???.txt +h +s
-قد تتحول جميع ملفات أحد األقراص إلى ملفات نظام مخفية (كما
في المثال السابق لكن على مستوى القرص ككل) ،ويكون ذلك
غالبا بفعل فيروس مايع (ساذج بلغة أفالم الكرتون) ،والستعادتها
إلى وضعها األصلي يمكنك استخدام الكود التالي:
@echo off
attrib /s -h –s
'REM Don't forget to use parameter 's' with 'h
331
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
color 02
:start
echo
%random%%random%%random%%random%%random%%random%%ran
dom%%random%%random%%random%%random%
goto start
332
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
:d
color 2
pause
سيتم إجراء العمليات السابقة إما مباشرة أو بعد 11ثانية ،يمكن تغيير
الموضوع حسب الحاجة .كما يمكن إحباط العملية من خالل األمر
،shutdown –aيمكن إضافته إلى القائمة السابقة بنفس الملف الدفعي
ويمكن تنفيذه عن طريق Runأو من خالل موجه األوامر.
كما يمكن إنشاء اختصار يقوم بإيقاف التشغيل (أو أي مهمة أخرى)،
الجميل فيه هو إمكانية تغيير أيقونته إلى أي أيقونة تريد ألنه اختصار:
وبالمناسبة فإن هذه الحركة (تغيير األيقونة) بإمكانك القيام بها على
الملفات الدفعية عموما بشكل غير مباشر ،أنشئ ملفا دفعيا واحفظه في
مكان ما مثال في القرص ،Eأرسله إلى سطح المكتب كاختصار ،ثم غير
اسم وأيقونة االختصار وفقا لحاجتك.
333
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
Cmd
Notepad
calc
أرسل الملف األول كاختصار لسطح المكتب وغير أيقونته لما يناسب عمله،
ثم جربه( .هل الحظت أن هذه العملية أشبه باإلجراءات والتوابع؟)
334
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
-نسخ أي ملف أو برنامج إلى بدء التشغيل ،وبالتالي فإنه يعمل عند
تشغيل المستخدم:
Copy e:\File.txt
"C:\Users\%username%\AppData\Roaming\Microsoft\Windows\Start
Menu\Programs\Startup
وهذا المسار توضع فيه البرامج التي من الممكن إرسال الملفات من
خاللها ،كما هو موضح بالصورة التالية:
335
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
كما الحظت فإن الملفات الدفعية يمكن اكتشاف محتوياتها بسهولة ،فهي
بسيطة ال يمكن المناورة بها ..ومع قليل من الخبرة ستتمكن من فهم
الغاية من أي ملف دفعي تصادفه أو على أقل تقدير ستتمكن من إيجاد
336
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
طريقة لفهم هذا الملف وذلك عبر البحث عبر االنترنت على بعض األسطر
الموجودة فيه أو االطالع على بعض المراجع وغيرها من األساليب..
-من خالل ضغط الملف الدفعي وتحويل الملف المضغوط الناتج إلى
ملف تنفيذي ،exeوذلك بتفعيل خيار .Create SFX archieve
-من خالل لغات البرمجة ،وذلك بإنشاء مشروع برمجي يقوم بإنشاء
ملف دفعي ُيكتب فيه األسطر البرمجية المطلوب تنفيذها ،ثم يقوم
المشروع بتشغيل هذا الملف عبر كائن مستنسخ من الفئة
Processفي C#مثال ،وذلك عبر الطريقة ..Startوفي نهاية العملية
يتم حذف الملف الدفعي عبر الطريقة ،File.Deleteويفضل انتظار
العملية ريثما تنتهي عبر الطريقة ( WaitForExitالتابعة للفئة
)Processوالتي تعطي أمرًا لبرنامجك ليتريث قليال حتى انتهاء
الملف الدفعي من تنفيذ أوامره ..وبعدها يقوم بحذفه.
طبعا عندما نقول حماية الملفات بإخفاءها فإننا ال نقصد إخفاءها بالطريقة
العادية بتاتًا بتاتًا ،وإنما نقصد إخفاءها بشكل كامل بحيث ال يمكن إظهارها
حتى لو تم تفعيل خيار "إظهار الملفات والمجلدات المخفية" (إال إذا كانت
الغاية من الحماية هي إبعاد الملفات عن متناول األطفال ففي هذه الحالة
ال بأس باستخدام الطريقة العادية ).
من الممكن أيضا حماية الملفات بتغيير صيغها ،فمثال بإمكانك إنشاء ملفات
تخزن فيها بيانات نصية وحفظها على أنها ملفات mp3مثال ،في الواقع
هذه الملفات ليست إال ملفات نصية لكن الظاهر (لنظام التشغيل
وللمستخدم) أن هذه الملفات هي ملفات mp3تالفة.
ً
طرقا عديدة لحماية الملفات والبيانات وذلك عبر عدة مشاريع، سنناقش
بعضها يعتمد على موجه األوامر وبعضها ال يعتمد..
337
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
تشفير النصوص
1هناك طرق جاهزة للتشفير ،إذا كانت هذه غايتك فأعتذر منك ربما قد غرّك عنوان الفقرة ،فما
سأناقشه هو كيفية إنشاء برنامج تشفير بسيط.
هناك طرق جاهزة للتشفير وأنا لن أناقشها. أكرر
338
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
والفكرة من الكود هو إسناد جميع أحرف عبارة نصية ما إلى الئحة أو
مصفوفة ثم الحصول على األحرف التالية لها وإظهارها في عبارة نصية
: الحظ المثال.جديدة
339
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
340
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
من الممكن استخدام هذا التطبيق لتشفير الرسائل أو البيانات النصية أو
غيرها ،فمثال بإمكانك تشفير البيانات المرسلة إلى قاعدة بيانات على
سبيل المثال وفك تشفير البيانات المستوردة منها ،كالبيانات الشخصية أو
اإلدارية مثال .صحيح أنه يمكن حماية وسائل التخزين كقواعد البيانات
بكلمات سر لكن ال يوجد شيء غير قابل لالختراق .
يجدر االنتباه إلى أن المحارف مرتبة وفق جدول معين يسمى جدول
،ASCII1فحرف Aمثال ال يليه aوإنما ،Bوهكذا .أو باألحرى فإن الرموز
والمحارف اليونانية مرتبة وفق هذا الجدول ،أما بقية اللغات فمرتبة وفق
جدول .Unicode2
إحدى تطبيقات نظام الدوس هي إخفاء الملفات داخل ملف صورة ،والذي
يتيح لك حماية ملفاتك من الغرباء سوا ًءا أأردت تخزين الملفات على
كمبيوترك وأنت مرتاح البال أنها لن يتم الوصول إليها ،أم أنك أرسلتها عبر
البريد أو أية وسيلة نقل إلى أحد أصدقاءك( ..أو جرب سلة المهمالت ).
وكما أسلفت فإن العملية تتم على نظام الدوس بشكل كامل ،أي في
موجه األوامر والملفات الدفعية .ستقول لي مادور C#هنا؟؟؟ في الواقع
دور C#هنا ثانوي ،فوظيفته إعطاء النوافذ لبرنامجك وتنظيم المدخالت
والمخرجات والتواسط بين المستخدم ونظام الدوس حتى تُكلل العملية
بالنجاح .فنظام الدوس و C#في هذا التطبيق كالعالقة بين htmlو cssفي
. تطبيقات ومواقع الويب! أو كالعالقة بين الفتاة والكوافيرة
341
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
342
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
أضف الملفات المطلوب إخفاءها إلى ملف مضغوط وسمه .RARأصبح لديك
الملفات التالية:
343
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
افتح الصورة File1لتجد الصورة البريئة التي اخترتها ولكن بحجم رهيب،
11.5ميغابايت!!
حيث تم تحويل الصورة File1إلى ملف مضغوط ،في الواقع تمت إعادة
تسميتها فقط تحت بيئة دوس..
شايف العمليات التي قمنا بها للتو؟؟ سنجعل C#ينظم ويدير هذه الملفات
للحصول على برنامج تفاعلي يعطي ذات النتيجة.
344
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
لكن قبل ذلك نحتاج لضغط الملفات قبل تشفيرها ،وال أعتقد أنه من كرم
ت تطبيقك – أن يقوم الضيافة أن تطلب من المستخدم – في حال نشر َ
بضغط الملفات ثم إعطاءك إياها ،وإنما من األنسب أن تقوم أنت – كمبرمج
– بضغطها ،وللقيام بذلك سنستعين بنظام الدوس مرة أخرى وسنضغط
الملفات من خالله ،أنشئ مل ًفا نصيّا جدي ًدا واكتب فيه:
Rar a RAR Files
لكن لحظة ،نظام الدوس ال يمكنه ضغط الملفات ،وإنما يقوم بتوجيه برنامج
ضغط الملفات لهذا األمر .لذلك فعليك الحصول على برنامج ضغط الملفات
مدعومة بمكتبة تحوي فئات خاصة بضغط الملفات .برأيك من هو أفضل من
يضغط الملفات؟؟؟ أعتقد أن WinRarيجول في خاطرك اآلن ..سنذهب إليه
ونستعير منه ملفين صغيرين وال أعتقد أنه سيمانع ألنه معطاء وجواد
وبإمكانك استخدام النسخة التجريبية منه مدى الحياة وبكافة اإلمكانيات.
المهم ،انتقل لمسار WinRarفي قرص نظام التشغيل واستعر منه
الملفين Rar.exeو ،RarExt.dllوضعهما في ذات مسار الملف .RarFiles
أصبح لديك الملفات التالية:
345
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
ثالثا :يتم ضغط الملفات الموجودة داخل المجلد Filesعبر تشغيل الملف
RarFiles.batوالذي يتعامل مع ملفي الضغط.
،لنبدأ باسم هللا ،أنشئ مشروعا هذا كله سنقوم به عن طريق C#
جديدا وصمم النافذة التالية:
346
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
مالحظة
عاد ًة ما توضع ثالث نقاط أمام أسماء األزرار والقوائم التي ستفتح
نوافذ جديدة ،لهذا فإن بعض أزرار المشروع تم تطبيق هذه الفكرة
عليها.
الزر JPG Fileسيفتح لك نافذة فتح الملفات لتختار الصورة التي سنخفي
فيها الملفات ،حيث يتم وضع مسارها في مربع النص المجاور ،ويمكن
لصق مسار الصورة مباشر ًة.
347
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
{
File.Delete(file.FullName); //حذف جميع الملفات القديمة
}
//حذف الملفات القديمة الموجودة بجوار البرنامج
File.Delete(Application.StartupPath + "\\image.jpg");
File.Delete(Application.StartupPath + "\\archive.rar");
File.Delete(Application.StartupPath + "\\DecryptedFiles.rar");
}
void CanEncrypt() //التحقق من إمكانية التشفير
{
//في حال كان هناك عناصر في أداة العرض
//وفي نفس الوقت الصورة التي سيتم التشفير فيها موجودة في الكمبيوتر
//فإنه من الممكن تشفير الملف
if (listView1.Items.Count > 0 & File.Exists(textBox1.Text))
Encrypt.Enabled = true;
else
Encrypt.Enabled = false;
Remove.Enabled = false; //إخفاء زر حذف العنصر
}
void RarFiles() //هذا اإلجراء يقوم بضغط الملفات
{
var f = File.Create(Application.StartupPath + "\\RarFiles.bat");
f.Close(); //إنشاء الملف الدفعي الذي سيضغط الملفات
StreamWriter FileW = File.AppendText(Application.StartupPath +
"\\RarFiles.bat");
FileW.WriteLine("Rar a Archive Files");
FileW.Close();
Process p = new Process();
ProcessStartInfo pInfo = new ProcessStartInfo(f.Name);
p.StartInfo = pInfo;
p.Start();
p.WaitForExit(); //بدون هذا الكود سيتم االنتقال للتعليمة التالية مباشرة
//دون انتظار الملفات ليكتمل ضغطها
//كما تعلم فإن ضغط الملفات يحتاج وقت خصوصا الكبيرة منها
}
void BatEncrypt()
{
var f = File.Create(Application.StartupPath + "\\Encrypt.bat");
f.Close();
StreamWriter FileW = File.AppendText(Application.StartupPath +
"\\Encrypt.bat");
FileW.WriteLine("copy /b image.jpg + archive.rar encrypted.jpg");
FileW.Close();
Process.Start(f.Name);
}
void BatDecrypt(string path)
{
348
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
349
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
}
private void Remove_Click(object sender, EventArgs e)
{
foreach (ListViewItem L in listView1.Items)
if (L.Selected)
L.Remove();
CanEncrypt();
}
private void Encrypt_Click(object sender, EventArgs e)
{
string fullpath;
foreach (ListViewItem Item in listView1.Items)
{
//نسخ جميع الملفات إلى مجلد التشفير
fullpath = Application.StartupPath + @"\Files\" +
Item.SubItems[0].Text;
File.Copy(Item.SubItems[2].Text, fullpath);
}
//نسخ الصورة التي سيتم التشفير فيها وتغيير اسمها
File.Copy(textBox1.Text, Application.StartupPath + "\\image.jpg");
RarFiles(); //ضغط الملفات
BatEncrypt(); //تشفير الملفات
MessageBox.Show("Files encrypted successfully!", "FilesToJPG By
Eng27");
//فتح الملف الحاوي على التطبيق وملفاته
Process.Start(Application.StartupPath);
}
private void JPGfile_Click(object sender, EventArgs e)
{
OpenFileDialog open = new OpenFileDialog();
open.Filter = "JPG File | *.jpg";
if (open.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
textBox1.Text = open.FileName;
}
}
private void Decrypt_Click(object sender, EventArgs e)
{
OpenFileDialog open = new OpenFileDialog();
open.Filter = "JPG File | *.jpg";
if (open.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
BatDecrypt(open.FileName);
MessageBox.Show("Files decrypted successfully!", "FilesToJPG By
Eng27");
Process.Start(open.FileName.Replace(open.SafeFileName,
"DecryptedFiles.rar"));
350
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
}
}
)private void textBox1_TextChanged(object sender, EventArgs e
{
;)(CanEncrypt
}
}
}
351
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
في حال وجود ملف ال ترغب بتشفيره مع الملفات أنقر عليه ثم اضغط إزالة
ملف:
352
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
الحظ الفرق بين الصورتين (محتواهما ذات الصورة ،على الثقة المحتوى
نفسه مافي داعي أعرضلك إياهما) .الحظ الفرق في حجوم الصور!
تتميز الطريقة األولى باألمان ،لكنها تتسبب بحجم كبير لقاعدة البيانات كما
أنها قد تسبب بطء في عمل البرنامج .أما الثانية فإنها أسرع وأقل حجما،
لكنها أقل أمانًا!
وعاد ًة ماتكون الملفات المخزنة هي صور سوا ًءا بالطريقة األولى أو الثانية.
وهذا ماسنتحدث عنه في الفصول األخيرة من هذا الكتاب.
353
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
يعتمد هذا النوع من الحماية على األمر ،attribفكما تعلم فإن هذا األمر
يقوم بضبط سمات الملفات والمجلدات .ومن السمات التي من الممكن
ضبطها هي سمة ملفات النظام.
وكما تعلم فإن سمة ملفات النظام المتمثلة بالمتغير sوسمة اإلخفاء
المتمثلة بالمتغير hيجب أن يضبطا م ًعا ..سوا ًءا للضبط أو اإلزالة( .لم تكن
ورأسا ومباشر ًة).
ً تعلم؟؟ انتقل لجدول أوامر cmdفورًا
354
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
355
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
من المحتمل أن تكون هذه أول مرة تسمع بها بالرجستري ،لذلك سأضع
شرحا موجزا عنه ،بما في ذلك التعامل معه واالستفادة منه وحتى التأثير
على نظام التشغيل من خالله ،ثم سأنتقل لكيفية التعامل معه من خالل
برامجك في .C#إذا لم تكن لك رغبة بتعلم الرجستري فانتقل مباشر ًة
لفقرة الرجستري من خالل .C#
356
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
من األدوات التي تأتي مع نظام التشغيل مثل اآللة الحاسبة والرسام
وموجه األوامر .cmd
مالحظة
يمكن الوصول لألمر تشغيل عن طريق .Win+R
HKEY_CLASSES_ROOT
وتحتوي على كل مايخص الملفات من معلومات ،مثل أنواع الملفات
ومشغالتها ،وأيقوناتها وتفاصيلها .فمن خالل هذه الخلية يعرف نظام
357
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
HKEY_CURRENT_USER
وفيها يتم حفظ معلومات وإعدادات المستخدم الحالي ،كشاشة
التوقف الحالية وإعدادات االنترنت وغيرها من اإلعدادات الشخصية.
HKEY_LOCAL_MACHINE
وتحتوي هذه الخلية على معلومات عن المكونات المادية والبرمجية
لحاسوبك.
HKEY_USERS
وتحتوي على معلومات عن المستخدمين لحاسوبك.
HKEY_CURRENT_CONFIG
وهي عبارة عن اختصار لـ ،HKCUإال أنها أكثر خصوصية .فالمعلومات
الموجودة في HKCCهي نفسها المعلومات الموجودة في ،HKCU
إال أن األخيرة أشمل وهي األساس.
عند التعديل على المعلومات في إحدى الخليتين فإن الخلية األخرى
ستتأثر.
مالحظة
تختصر الخاليا الرئيسية عادة وفق أوائل أحرف كلماتها ،فالخلية
HKEY_CLASSES_ROOTهي .HKCR
358
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
نظرة عامة
359
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
أما من أجل نوع محدد من الملفات ،مثل الملفات النصية على سبيل
المثال ،فإنه يتم إنشاء مفتاحين هما .txtو ،txtfileواألمر مماثل بالنسبة
لبقية أنواع الملفات ،الحظ إحدى القيم:
والقيمة األخرى:
بعد هذه الجولة السريعة في محرر التسجيل سنقوم ببعض األمور على
القيم التي تصفحناها منذ قليل ،لنفهم الرجستري والمنطق الذي يعمل
به ،وبعدها بإذن هللا سنتعامل معه من خالل .C#
مالحظة
كن حذرا عند تعاملك مع الرجستري ،أي خطأ من الممكن أن يكلفك
الكثير ،لذلك ينصح عادة بأخذ نسخة احتياطية قبل إجراء أي تعديل
عليه.
أنا ال أتحمل مسؤولية أي خطأ ناتج عن سوء استخدامك لمحرر
التسجيل اتفقنا ؟
اآلن تعال وفكّر معي ،نحتاج لفتح القائمة المنبثقة التي تظهر عند الضغط
على الملفات بالزر األيمن ،وبجوار األوامر فتح وضغط وإرسال إلى وفتح
باستخدام وبقية األوامر األخرى الشائعة نحتاج لوجود أمر يقوم بنسخ
محتوى الملف المحدد ،ال واألكثر من ذلك أن هذا األمر له صورة واسم
خاصان بك!
360
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
اآلن عدل القيمة االفتراضية للمفتاح األول كما هو موضح في الصورة أدناه،1
مها Iconواجعل قيمتها هو مسار أيقونة ثم قم بإضافة قيمة نصية وس ّ
برنامجك أو شركتك إذا أردت ذلك ،أو ال تضف هذه القيمة إذا لم ترغب
بوجود أيقونة بجانب األمر.
على اعتبار أن هذه هي القيمة االفتراضية للمفتاح الرئيس ،فستظهر للمستخدم.. 1
361
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
اآلن اذهب إلى أي ملف يخطر ببالك واضغط عليه بالزر األيمن وتفاجأ
،اضغط على األمر الذي أضفناه ثم وبسرعة اذهب إلى أي بالنتيجة
برنامج يستقبل النصوص والصق بداخله محتوى الحافظة النصي وستجد
مسار الملف .ولكن قبل ذلك ،ال تنسَ أن تضع األيقونة التي ستظهر بجانب
دل القيمة Iconإلى األمر في المسار الذي حددناه في القيمة !Iconأو ع ّ
المسار الذي وضعت به أيقونتك!!!
وكشرح بسيط عما حدث ،أضفنا مفتاحا أسميناه وضبطنا اسمه وأيقونته،
وجعلنا األمر الخاص به هو تشغيل موجه األوامر وكتابة المسار الذي تم
تنفيذه منه ،ثم نسخها للحافظة .Clipboard
مالحظة
إذا لم تضبط القيمة االفتراضية للمفتاح الرئيس ،فإن اسمه سيظهر
للمستخدم.
من الممكن أن تكون قيمة أيقونة األمر هي مسار ملف أيقونة أو
مسار برنامج ما ،حيث أن نظام التشغيل يأخذ أيقونة البرنامج.
األمر cmdهو في الواقع ،cmd.exeوعلى اعتبار أنه من عائلة نظام
التشغيل – أقصد أنه من البرامج االفتراضية والتي تجدها في مجلد
– System32فبإمكانك كتابة اسمه دون الحقة .وينطبق هذا على
جميع ملحقات نظام التشغيل مثل regeditو runو( cmdجرب افتح
موجه األوامر واكتب notepadأو ،notepad.exeالفرق).
في موجه األوامر األمر echoيستخدم لطباعة عبارة نصية ،وهو مناظر
لألمر Console.WriteLineفي .C#أما الخيار /cفيقوم بإيقاف موجه األوامر
عن العمل بعد تنفيذ الكود .وبالنسبة للمتغير %1 1فيحمل مسار الملف أو
362
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
مالحظة
لطباعة مسار المجلد األب .echo %w
لنسخ المسار مع تنصيص ،ضع التنصيص في األمر وذلك كما يلي:
.echo "%1" | clip
باتت الفكرة واضحة نوعا ما ومكشوفة وال داعي إلشارة تعجب في نهاية
العنوان حتى .في التطبيق السابق كنا نتعامل مع الملفات لذلك اتجهنا
للمفتاح * ،اآلن سنتعامل مع المجلدات فماهو المفتاح الذي سنتعامل معه
ياحذرك ؟؟؟
أعد الخطوات التي قمنا بها في التطبيق األول (القيمة االفتراضية ،األيقونة،
األمر).
بنفس المبدأ وباالعتماد على نظام الدوس المتمثل بموجه األوامر يمكن
معرفة محتويات مجلد ما بما فيها من ملفات ومجلدات ،وباإلمكان نسخ
363
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
المحتوى إلى الحافظة باستخدام | Clipبعد تنفيذ األمر أيضا .ولكن ليس
من المج ِد وال من المستخدَم وال من العادة أن يرغب المستخدم بنسخ
محتويات المجلدات ووضعها في الحافظة ،بينما قد تحتاج لوضع هذه
المحتويات في ملف ما بحيث يستفيد منها برنامجك ،أو أنت الحقا.
حيث إن cd %1هو أمر يقوم بنقل الدليل 1الحالي في نظام الدوس إلى
المسار ( %1وهذا المتغير كما تعلم يحوي مسار المجلد الذي تم تنفيذ
األمر منه ،على اعتبار صار عندك خبرة) ،أما اإلشارة && فتفيد في تنفيذ
أكثر من أمر في موجه األوامر (فـ cdأمر و dirأمر آخر ،في حين أن العبارة
echo %1 | Clipهي أمر واحد) .وبالنسبة لألمر dirفهو يعرض محتويات
الدليل الحالي ،أما إشارة > والمسار الذي يليها فهو يعني أن ناتج تنفيذ
األمر لن يظهر على شاشة موجه األوامر وإنما سيوضع في ملف ما ،وفي
حال قرأت الفقرات األُوَل من الفصل السابق فإنك تعلم أن إشارة > تعني
مسح الملف في حال وجوده وإنشاء آخر جديد ،أما عندما تكون مزدوجة
>> فإنها تعني الكتابة إلى نهاية الملف في حال وجوده.
1الدليل أو الفهرس هو مصطلح يعبر عن مسار المجلدات ،إذا كنت في القرص Dبداخل مجلد Games
فهذا يعني أن فهرسك الحالي هو .D:\Games
364
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
قد ال تكون قد استوعبت الفكرة بعد أو تخيلت العملية وال الحاجة من
ل فتح الملفإشارة التعجب ،تخيل المرور بجانب أحد الملفات النصية ،وبد َ
النصي وتحديد كامل النص بداخله ثم نسخه وإغالق الملف ،بإمكانك إضافة
أمر إلى القائمة المنبثقة ليقوم بنسخ محتوى أي ملف نصي تنفذه منه.
وعلى اعتبار أن العملية غير مجدية مع غير الملفات النصية تقريبا ،فلن
نضيف هذا األمر بالنسبة لجميع الملفات (أي بالمفتاح *) ،وإنما سنضيفه
للملفات النصية فقط (أي بالمفتاح .)txtfileأعتقد اآلن أنه باتت لديك فكرة
واضحة عن مبدأ عمل الرجستري وكيف يتعامل معه نظام التشغيل.
وأجر
ِ حا باسم ،copythecontent انتقل للمفتاح txtfileوأضف بداخله مفتا ً
التغييرات واإلضافات الالزمة كما سبق (ال داعي ألن أخبرك أن هذه
اإلضافات هي بين قوسين القيمة االفتراضية واأليقونة واألمر ،فقد أصبحت
خبيرا اآلن ماشاء هللا ).
365
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
،وصلنا لألمر الذي سنستخدمه في اآلن لنعد لموضوعنا ،أخذنا الحديث
هذا التطبيق ،الحظ:
واألمر السابق يعني أنه على موجه األوامر ( )cmdوبعد أن يغلق نفسه
( )/cأن ينسخ ( )clipمحتوى المسار الذي تم تنفيذه منه (" .)< "%1حاول
أنسنة جميع أعمالك حتى لو كانت برمجية بحتة.
لكن مشكلة نظام الدوس أنه ال يقبل المحارف العربية ،لذلك فالمحتوى
العربي سيكون مشوّها عند نسخه ألنه سيمرر إلى شاشة موجه األوامر
تماما كشاشة ،Consoleبينما ستدعم المحارف األجنبية بالكامل .ومن
هنا أتت الحاجة لتطوير برنامج بلغة برمجة عالية المستوى لتتعامل مع
جميع أنواع المحارف .لذلك فالتطبيق التالي سيكون باستخدام .C#
366
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
والكود رغم بساطته إال أنه يعني الكثير ،فالسطر األول يص ِرّح عن متغير
نصي س ُيسنَد إليه قيمة نصية هي مسار الملف الذي تم استدعاء
برنامجنا من خالله ،وهي تكافئ %1في نظام الدوس .أما السطر الثاني
فيقوم بقراءة محتويات الملف الذي مساره Pathبالترميز االفتراضي للنظام
(وهذه أهم خطوة في كامل التطبيق هذا) ،ثم يسند هذه المحتويات إلى
متغير نصي .ثم يضع قيمة المتغير النصي األخير في الذاكرة وذلك بعد
حذف محتواها ..وأخيرا وعلى اعتبار أن النافذة ال تهمنا فيجب إغالقها.
كل ماسبق هو خطوة أولى ،اآلن نريد أن نربط برنامجنا باألمر الموجود في
القائمة المنبثقة ،ألن اإلجراء GetCommandLineArgsسيعيد مصفوفة
نصية تحوي مسار البرنامج ومسار الملف الذي تم تنفيذ األمر منه .اآلن،
كيف عرف نظام التشغيل أن عليه تنفيذ برنامجنا وبدوره برنامجنا
وباستخدام هذا األمر سيتعامل مع الملف الذي نفذه؟؟؟ ببساطة علينا
الرجوع للرجستري وبدل تنفيذ cmdسننفذ برنامجنا.
367
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
مالحظة
عند تنفيذ المشروع في الفيجوال ستوديو ستحصل على خطأ ،ال
مشكلة فقط أغلق المشروع وانسخ البرنامج التنفيذي من
مشروعك إلى القرص ،dوجرب التطبيق.
الفكرة من هذا التطبيق مشابهة لسابقه ،إال أنه سيقوم بالحصول على
خصائص الملف وعرضها في صندوق رسالة بدال من نسخ محتويات الملف،
كما أن هذا التطبيق يمكن تنفيذه على جميع أنواع الملفات وعلى
المجلدات ،لذلك فأتوقع أن مايجول بخاطرك هو المفتاح * و.Directory
368
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
فإذا ظهر خطأ فهذا يعني،يقوم الكود بمحاولة أخذ تفاصيل المسار كملف
.أن المسار هو مجلد
369
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
قم بتصدير جميع أوامرك واجمعها في ملف تسجيل واحد ،كما في الصورة
التالية:
370
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
اذهب ألحد المجلدات وجرب القائمة المنبثقة عليه ..ثم قم بتسمية ملف
التسجيل باسم مثل ،Eng27Setupوهو جاهز للنشر والتوزيع اآلن.
371
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
يقوم األمر األول بعدم إظهار المسارات الحالية ،والثاني يقوم بنسخ جميع
الملفات التنفيذية exeحتى لو كانت مخفية أو ملفات نظام ،مع عدم انتظار
تأكيد النسخ من المستخدم ،وذلك إلى القرص .dأما الثالث قيقوم بإنشاء
مجلد جديد باسم REGفي القرص ،eثم ينسخ جميع األيقونات إليه.
372
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
مسح المفاتيح
يمكن مسح المفاتيح عن طريق ملفات التسجيل باستبدال إشارة @
باإلشارة -باإلضافة لوضعها في مسار المفتاح ،الحظ كود ملف uninstall
الموجود في الفقرة السابقة:
التسجيل الصامت!
يقصد بالتسجيل الصامت أو التنصيب الصامت بتسجيل المفاتيح برمجيّا،
ودون الحاجة لطلب إذن المستخدم في تشغيل ملف التسجيل والموافقة
على التسجيل..
373
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
المتغيرات ،أن تجعل للبرنامج ذاكرة يخزن فيها ما يجول بخاطره ويقرر
تصرفاته بنا ًءا عليها .ثم قيل لك أنه ال يكفي وجود المتغيرات في برنامجك
وإنما عليك اختزان قيمها في ملفات خارجية على القرص الصلب ،وقراءة
محتوياتها عند الحاجة ،فالمتغيرات تفنى عند الخروج من البرنامج!
قد تكون البيانات المختزنة ضمن المتغيرات حساسة أو هامة وال يجب
النفوذ إليها أو التعديل عليها ،أو حتى حذفها ،وقد ال تنفع وسائل التشفير
والقفل ،عندها بإمكانك استخدام الرجستري لتخزين قيم متغيراتك بحيث
ال أحد يعلم مكانها سواك..
بإمكانك القيام بكل ماسبق من خالل ،C#ال حاجة لفتح محرر التسجيل
إلضافة القيم والمفاتيح ،بإمكانك التصريح عن كائنات من نوع مفاتيح
الرجستري لتتحكم بالمفاتيح بإمكانيات كثيرة.
اآلن أصبح الكائن keyهو عبارة عن مفتاح وبإمكانك القيام من خالله على
كل العمليات الممكنة على المفاتيح والقيم.
374
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
الحظ ناتج تنفيذ الكود السابق فيما لو تم فتح أحد المفاتيح وإسناده لكائن:
مالحظة
للتعامل مع القيمة االفتراضية للمفتاح ،نضع اسم القيمة .null
وإلغالق المفتاح:
;)(key.Close
375
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
افتح الفيجوال ستوديو وأنشئ مشروعا جدي ًدا ،صمم الواجهة التالية
باألدوات الموضّحة أمامك:
ثم الواجهة:
376
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
377
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
378
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
}
private void newUser() //إجراء يقوم بتهيئة ىالبرنامج إلنشاء حساب جديد
{
button1.Text = "Sign Up";
key = Registry.CurrentUser.CreateSubKey("Software\\RegApp");
MessageBox.Show("New user?\nEnter a name and a password",
"NEW USER!",
MessageBoxButtons.OK,
MessageBoxIcon.Information);
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
buttonCheck();
}
private void textBox2_TextChanged(object sender, EventArgs e)
{
buttonCheck();
}
379
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
380
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
381
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
من األفكار التي يمكن تطبيقها على المفتاح الخاص ببرنامجك في
الرجستري هو تحديد عدد المرات التي يمكن للمستخدم استخدام
البرنامج خاللها ،وسنطور التطبيق 7ليصبح مشتمال على ذلك.
. توقّع بع َد فترة أن تجد في األسواق كراكا لتطبيقك بقيامك بهذه الحركة
382
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
أما بالنسبة لـ ،txtfileففيه يتم تخزين معلومات عن مشغل هذا النوع من
الملفات .وقيمته االفتراضية تحدد وصف الملف ،وداخل هذا المفتاح يتم
وضع االيقونة االفتراضية في مفتاح ،DefaultIconباإلضافة إلى األوامر التي
تظهر للمستخدم في القائمة المنبثقة ،مثل فتح أو تحرير أو أوامر خاصة
مثل التطبيقات األُوَل ضمن هذا الفصل وغيرها من األوامر.
383
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
ثم اضبط القيمة االفتراضية للمفتاح الرئيس على القيمة ""RegApp Files
وهو الوصف الذي سيظهر على ملفات هذا النوع.
كما أنه بضبط القيمة االفتراضية لـ shellعلى اسم أحد مفاتيحها الفرعية
سيجعله المفتاح االفتراضي ،لذلك اضبطها على القيمة .open
384
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
الحظ الفرق بين صيغتنا وصيغة موجودة في نظام التشغيل مثل icofile
(طبعا صيغتنا أحلى):
بقي لدينا فكرة أساسية وهي ربط برنامجنا بالصيغة الجديدة ،عندما نفتح
أي ملف يحمل الصيغة myraسيتم فتح البرنامج RegAppألننا وضعنا
مساره في المفتاح ،openلكنه سيفتح وهو فارغ تماما.
فكر معي ،عندما تفتح مستند وورد جديد ،أو برنامج الوورد من موقعه
األصلي فإنه ستظهر لك نافذة بيضاء ال غبار عليها ،صحيح؟؟؟ طيب عندما
نفتح مستن ًدا قديما يحوي بيانات ،كيف عرف نظام التشغيل أن هناك
بيانات ،وحتى كيف عرف مسارها؟؟؟؟
في الواقع فإننا تطرقنا إلى هذا الموضوع دون التنويه له وذلك ألن األفكار
والمعلومات فيما يخص التعامل مع الرجستري كثيرة ،وعندما تناولنا
التطبيق 5و 6فإننا تعاملنا مع الملفات التي قامت بتنفيذ أمر التشغيل،
ولكن بشكل سطحي ج ًدا..
أي أنه للحصول على متغير نصي وليس مصفوفة نصية تحوي المسار،
يكفي كتابة ] Environment.GetCommandLineArgs()[1مثال للحصول
على مسار الملف الذي أرسل أمر تنفيذ البرنامج .وبحصولنا على مسار
385
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
الملف الذي نفذ البرنامج بإمكاننا التعامل معه كيفما نشاء ،بدءا بالحصول
على تفاصيله كما رأينا في التطبيق 5و ،6وانتها ًءا بالتعديل والتحكم به.
اآلن عد للتطبيق 7وصرح متغيرًا نصيًا باسم pathفي المكان الذي صرحنا
فيه عن المتغيرات (ضمن الفئة Forms : Formتتذكرها؟).
ثم أضف الكود التالي إلى أكواد ( ،Form1_Loadال داعي ألن أخبرك أن هذا
اإلجراء موجود ضمن النافذة األولى صحيح؟ أصبحنا كبا ًرا اآلن وذوي خبرة
ماشاء هللا):
try
{
;]path = Environment.GetCommandLineArgs()[1
}
catch
{
}
386
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
ثم.. وهكذاOpenM وNewM ثم غير األسماء البرمجية لهذه القوائم لتصبح
:أضف األكواد للقوائم كما يلي
private void NewM_Click(object sender, EventArgs e)
{
if (path != null)
{
string content = File.ReadAllText(path, Encoding.Default);
if (textBox1.Text != string.Empty && textBox1.Text != content)
{
DialogResult resault;
resault = MessageBox.Show("Do you want to save changes to\n" +
path,
"Save changes?",
MessageBoxButtons.YesNoCancel,
MessageBoxIcon.Question);
if (resault == DialogResult.Yes)
{
SaveM_Click(sender, e);
Application.Exit();
Process.Start(Environment.GetCommandLineArgs()[0]);
}
else if (resault == DialogResult.No)
{
Application.Exit();
Process.Start(Environment.GetCommandLineArgs()[0]);
}
}
else
{
Application.Exit();
Process.Start(Environment.GetCommandLineArgs()[0]);
}
}
387
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
388
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
SaveM_Click(sender, e);
}
}
path = open.FileName;
textBox1.Text=File.ReadAllText (path, Encoding.Default);
}
}
389
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
{
DialogResult resault;
resault = MessageBox.Show("Do you want to save changes to
untiteled file?",
"Save changes?",
MessageBoxButtons.YesNoCancel,
MessageBoxIcon.Question);
if (resault == DialogResult.Yes)
{
SaveAsM_Click(sender, e);
}
}
}
else if (path != null)
{
string content = File.ReadAllText(path, Encoding.Default);
if (textBox1.Text !=content )
{
DialogResult resault;
resault = MessageBox.Show("Do you want to save changes to\n"
+ path,
"Save changes?",
MessageBoxButtons.YesNoCancel,
MessageBoxIcon.Question);
if (resault == DialogResult.Yes)
{ SaveM_Click(sender, e); }
}
}
Application.Exit();
}
}
390
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
ولذلك انتقل للمفتاح .myraثم أضف إليه مفتاحا فرعيا باسم ShellNew
أي المفتاح "جديد" في القائمة المنبثقة ،ثم أضف إليه قيمة باسم
NullFileواتركها فارغة:
391
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
كما يمكنك إضافة البرنامج لقائمة إرسالة إلى ،وذلك بوضع اختصار له في
المسار التالي:
C:\Users\Hp\AppData\Roaming\Microsoft\Windows\SendTo
وهذه بعض الصور عن التطبيق عند استخدامه ،إنشاء ملف من نوع الصيغة
): الخاصة بنا (من إنتاج شركتنا
على اعتبار هذه أول مرة نفتح بها البرنامج (على أساس) ،1فإنه سيتم
إنشاء مستخدم جديد:
سمه باالسم الذي ترغب به وضع له كلمة سر ،ثم اضغط تسجيل.
ستحصل على رسالة تأكيد:
392
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
مالحظة
لمحاذاة النص من اليمين إلى اليسار اضغط RCtrl+RShiftمعا .وهو
نفسه من أجل محررات النصوص العادية.
احفظ الملف أو اخرج من البرنامج ،ستحصل على رسالة تفيد بأن الملف
غير محفوظ إذا خرجت دون حفظ البيانات..
393
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
عدل على الملف ثم اختر جديد ،لتحصل على رسالة تسألك فيما إذا أردت
حفظ التغييرات أم ال:
394
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
في الملف الجديد أضف بعض البيانات ثم اضغط فتح ،لتحصل على رسالة
تطلب منك حفظ التغييرات إلى ملف غير محفوظ:
.. تهانينا
395
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
396
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
خذ مثال بياناتِ عيادة ما .لديك مجموعة من المرضى ،لكل مريض اسم
وعمر ،وحالة مرضية ،وهل هو ذكر أم أنثى ..إلخ من البيانات .كما أنه لديك
مجموعة من الموظفين في العيادة ،لكل موظف اسم وعمر ،ووظيفة،
ومستوى تعليمي ،وغيرها من البيانات الشخصية.
إن تنظيم هذه البيانات لكل مريض بمفرده أو لكل موظف بمفرده يجعل من
الصعب إجراء اإلحصائيات ومقارنة البيانات وتحليلها ..تخيل إجراء مقارنة بين
مئات الملفات – االلكترونية أو الورقية – لمعرفة عدد المرضى الذكور مثال،
أما لو كانت البيانات مرتبة وفق جداول معينة ،وبإلقاء نظرة على قيم عمود
ما بإمكانك الحصول على الكثير من التفاصيل .وعند حاجتك للحصول على
ملف شامل ألحد المرضى أو الموظفين ،بإمكانك جمع بيانات سطر واحد –
يمثل هذا الموظف أو المريض – ووضعها في ملف منفصل.
397
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
ويعتبر تنصيب برنامج إدارة قواعد البيانات حساسا للغاية وعليك اتباع
اإلرشادات بدقة ،ألن أي خطأ أثناء ضبط إعدادات برنامج التثبيت قد يؤدي
إلى مشاكل عديدة منها عدم إمكانية االتصال بالسرفر أو أن البرنامج غير
مثبت بشكل صحيح.
ومن المشاكل التي تظهر أيضا وجود نسخة سابقة من برنامج إدارة قواعد
البيانات حتى لو لم يكن موجو ًدا ،وسبب هذه المشكلة هو وجود برنامج
الفيجوال ستوديو والذي يتعامل مع قواعد البيانات ،لذلك قم بحذفه وثبت
برنامج SQLثم ثبت الفيجوال ستوديو من جديد.
398
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
399
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
ثم قم بتعريف أعمدة الجدول األول والممثل لبيانات مرضى العيادة كما
يلي:
مالحظة
لتستطيع التعامل مع قاعدة البيانات باألحرف العربية نضبط نوع
البيانات على nvarcharبدال من .text
400
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
ولجعل العمود primaryانقر باليمين على الحقل الصغير الموجود بجانبه ثم
، ،Set Primary Keyأو حدد العمود ثم من شريط األدوات اختر األمر
كما في الشكل:
401
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
،وتأكد أنك تنفذ األوامر على قاعدة أنشئ Queryجديد عبر األمر
البيانات التي أنشأتها:
402
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
مالحظة
يجب وضع إشارات ][ عند العبارات التي تحوي فراغات ،أو إحاطتها
بإشارة تنصيص واحدة كـ ' اسم المريض'
-لعرض السجل الثالث مثال نختار أكبر 3سجالت ونختار األصغر منها:
SELECT min(top 3 max(age)) from Patients
403
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
مالحظة
التابع STRيستخدم للتحويل للبيانات النصية ،إذ ال يجوز دمج بيانات
مختلفة األنواع.
سنرى التوابع بالتفصيل في فقرة الحقة.
ناتج العملية الحسابية لن يؤثر على البيانات ومحتواها وإنما يقتصر على ما
سيظهر للمستخدم فقط.
وين إدنك ياجحا :أن تسلك طريقا طويال على الرغم من وجود طريق قصير يوصلك لنفس النتيجة. 2
404
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
مالحظة
من الممكن التعامل مع كل من الروابط ><.>,<,=,>=,<=,
من الممكن التعامل مع كل من الروابط المنطقية .And, Or, Nor
عند التعامل مع مجاالت نستخدم الكلمة .between
عند اشتراط تشابه المعطيات بالسجالت نستخدم الكلمة .like
عند اشتراط وجود بيانات معينة (عدة خيارات) نستخدم الكلمة ،in
يعني هي اختصار الستخدام الكلمة .or
405
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
وكما قلنا فإن inهي اختصار لـ ،orتخيل كيف كانت ستكون حياتك لوال :in
'جلدية' = ' or Sickأسنان' = select * from Patients where Sick
406
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
كما يمكن استخدام betweenمع التواريخ ،وذلك عبر إحاطة التاريخ بـ #أو
تنصيص أحادي مثل النصوص العادية.
-عرض بيانات المرضى بإدخال الحروف التي تبدأ بالموقع الثاني من
بياناتهم:
'select * from Patients where Name like '_no%
-عرض بيانات المرضى بإدخال حروف معينة منها والباقي غير محدد:
'select * from Patients where Name like 's_m_r
407
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
أو
'select * from Patients where Name not like '[szt]%
مالحظة
في قواعد بيانات – MS ACCESSوالتي سنتناولها في الفصل التالي
1
– فإننا نستخدم * بدال من ،%و ؟ بدال من _.
408
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
كما يمكن كتابة األوامر بشكل مفصل وأعتقد أنك الحظت ذلك ،كل جملة
في سطر:
select name
from Patients
order by age desc
409
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
لو لم نضع شرطًا لتم تعديل جميع البيانات! ..كما يمكن تعديل أكثر من
عمود بوضع فاصلة بين أسماء األعمدة..
التوابع الجاهزة
تعطيك التوابع الجاهزة – كما في جميع لغات البرمجة – نتائج معينة بغض
النظر عن األكواد المستخدمة .كما يمكن استخدام الشروط والترتيب أيضا
عند التعامل مع التوابع ،األمثلة التالية تعطيك مجموعة من التوابع ومعناها:
مالحظة
بإمكانك تطبيق التوابع الجاهزة على السجالت غير المكررة ،قد ال
يختلف ناتج بعض التوابع مثل Maxو ،Minإال أن التوابع التي تجري
الحسابات تختلف نتيجتها بشكل كامل ،لذلك استخدم الكلمة
distinctكالكود التالي.select count(distinct age) from Patients :
كما يوجد دوال رياضية أخرى مثل Absو Sqrtوالتي تستخدم للحصول على
القيمة المطلقة والجذر ،ودوال نصية مثل Leftو Rightو UpperوLower
و Lenوهي معروفة لمبرمجي .C#
أما بالنسبة لدوال التاريخ والوقت فهي كثيرة وهامة ويجب اإللمام بها،
فالبرامج التي تتعامل مع قواعد البيانات غالبا ما يهمها التعامل مع بياناتها
بحسب التاريخ والوقت.
410
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
حيث التابع dateaddيأخذ ثالثة بارامترات أولها مقدار الزيادة ولها خيارات
كثيرة مثل dayو weekو monthو qو ،yearكما يمكن أن تكون second
و minuteو ..hourأما البارمتر الثاني فهو مقدار الزيادة ..والثالث هو التاريخ
والوقت.
كما يوجد )( DATEPARTوالذي يستخدم للحصول على جزء معين من
التاريخ أو الوقت.
باإلضافة للدوال السابقة لدينا دوال تحويل األنواع ،فللتحويل إلى العبارات
النصية كما رأينا نستخدم التابع )( ،STRولباقي األنواع )(.Convert
411
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
حيث يقوم األمر األخير بتجميع البيانات تبعا للعمود sickويعرض بجانبه
متوسط أعمار المرضى وذلك إذا كان عدد المرضى أكثر من .2أي سيعرض
عمودين األول فيه أسماء األمراض والتي عدد مرضاها أكثر من ،2والثاني
فيه متوسط أعمار مرضى هذا المرض.
مالحظة
العمليات اإلحصائية توضع في جملة havingإذا استخدمت كشرط،
غير ذلك توضع في جلمة select
النسخ االحتياطي
عند استعادة نسخة احتياطية يجب االتصال بقاعدة بيانات مغايرة للقاعدة
التي تستعيدها ،مثل ..MASTER
412
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
أو بالشكل:
;)( SqlConnection connection = new SqlConnection
;connection = new SqlConnection ("Server=Eng27; Datebase=New
;)"Integrated Security=true
وهذا الكائن نقوم بالتصريح عنه خارج إجراءات الفورم ،أي داخل فئة الفورم
مباشرة ،حيث إن Eng27هو اسم السرفر الذي تعمل عليه – في – SQL
و Newاسم قاعدة البيانات و trueتعني أنه ليس لقاعدة البيانات حماية .ثم
نستدعي اإلجراء Openللكائن connectionضمن اإلجراء الذي سيحدث
عنده االتصال بالسرفر:
;)(connection.Open
413
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
قمنا بالتصريح عن ثالثة كائنات ،األول إلنشاء االتصال والثاني للقيام بأوامر
SQL Serverوالثالث لقراءة نتائج كائن األوامر .ثم قمنا باالتصال بالسرفر.
صرحنا بعدها عن الئحة إلضافة عناصر قاعدة البيانات إليها ،فاللوائح تتميز
بكونها ديناميكية وال تتطلب عدد العناصر أثناء تعريفها .ثم أجرينا األمر "اختر
بيانات عمود األسماء من جدول المرضى" ،وذلك عبر االتصال connection
(هذا الكائن يحمل مواصفات السرفر وقاعدة البيانات ونوع االتصال) .ثم قرأنا
ناتج تنفيذ األمر كما سيظهر في بيئة ،SQL Serverوأضفنا هذه البيانات
إلى الالئحة التي صرحنا عنها في بداية الكود.
1عندما نقول أحد إجراءات النموذج أو الفورم فإننا نقصد اإلجراءات مثل button1_Clickأو Form1_Loadأو
textBox1_ChangeTextأو غيرها من اإلجراءات..
414
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
415
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
مالحظة
عندما ال نحتاج إلرجاع بيانات عند تنفيذ كود SQLمثل أوامر الحذف
واإلضافة نستخدم الطريقة .ExecuteNonQuery
كما في إضافة وحذف البيانات ،فإننا عند تعديل البيانات ننفذ أمرا من أوامر
SQL Serverوالتي ننفذها داخل استعالم ،Queryولالستغناء عن
االستعالمات من أجل تنفيذ الكود من خارج SQL Serverفإننا نتعامل مع
اإلجراء ..ExecuteNonQuery
صمم نافذة مشابهة للنافذة التالية ،اضبط خاصية التفعيل لصندوق التجميع
الثاني على :false
416
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
417
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
}
catch (Exception ex)
{
groupBox2.Enabled = false;
groupBox2.Text = ex.Message;
}
reader.Close();
connection.Close();
}
private void button2_Click(object sender, EventArgs e)
{
connection.Open();
string update = string.Format("update Patients set id = {0}, name = '{1}',
age = {2}, sick = '{3}', gender = '{4}' where Name = '{1}'",
textBox2.Text,
textBox3.Text,
textBox4.Text,
textBox5.Text,
textBox6.Text);
try
{
command = new SqlCommand(update, connection);
command.ExecuteNonQuery();
MessageBox.Show("Updated succesfully!");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
reader.Close();
connection.Close();
}
SqlParameter استخدام
418
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
;)(command.ExecuteNonQuery
}
هناك أكثر من نوع لالتصال بقواعد البيانات ،متصل ومنفصل .األول يتم فيه
التعامل مع قاعدة البيانات مباشرة وذلك من خالل كائن مستنسخ عن
الفئة ،SqlCommandوالثاني فيتم من خالل كائن مستنسخ من الفئة
،SqlDataAdapterوكال الكائنين يؤ ِ ّمنان لك قراءة وعرض وتعديل وحذف
البيانات ،والفارق أن الكائن الذي يعمل في الوضع المتصل يقوم بتعديل
البيانات مباشرة وال يحتاج لتخزينها في الذاكرة أما الثاني فيقوم بحجز
أماكن في الذاكرة لوضع البيانات فيها.
1التعفيش :النهب والسرقة في غياب الحكومة ،وهي كلمة مشتقة من كلمة َعفش وقد ظهرت أثناء
الحرب السوريّة .والعفش :بفتح العين وسكون الفاء ،هو األثاث.
419
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
سنعطي المستخدم إمكانية التنقل بين القيم من خالل أزرار تنقل ،كما
سيستطيع إضافة البيانات والتعديل عليها والبحث عنها ..في الواقع
فمكونات هذه الفقرة توجز جميع ماسبقها في هذا الفصل.
420
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
لجميع األزرار إلى القيمةName وغير التسمية البرمجية،Add ألغِ تفعيل زر
. الظاهرة عليها لتسهيل األكوادText النصية
SqlConnection connection; //كائن يقوم باالتصال بالسرفر
SqlDataAdapter adapter; //كائن يقوم بتنفيذ األوامر بالوضع المنفصل
SqlDataReader reader; //كائن يقوم بقراءة البيانات من كائن األوامر
SqlCommand command; //كائن يقوم بتنفيذ األوامر بالوضع المتصل
DataTable data; //كائن يقوم بحفظ جداول البيانات
CurrencyManager manager; //كائن يقوم بإدارة كائنات قواعد البيانات
SqlCommandBuilder commandbuilder;
public Form1()
{
InitializeComponent();
//إنشاء اتصال
connection = new SqlConnection("server=Eng27; database=ClinicDB;
Integrated Security=true");
adapter = new SqlDataAdapter("select * from patients", connection);
//استنساخ جدول
data = new DataTable();
adapter.Fill(data); //ملئ الجدول
dataGridView1.DataSource = data; //عرض الجدول في أداة جدول العرض
//إعطاء أسماء الكائنات واألدوات التي سيديرها كائن اإلدارة
manager = (CurrencyManager)this.BindingContext[data];
textBox2.DataBindings.Add("Text", data, "id");
textBox3.DataBindings.Add("Text", data, "name");
textBox4.DataBindings.Add("Text", data, "age");
textBox5.DataBindings.Add("Text", data, "sick");
textBox6.DataBindings.Add("Text", data, "gender");
}
private void New_Click(object sender, EventArgs e)
{
manager.AddNew();
Add.Enabled = true;
New.Enabled = false;
textBox2.Focus();
}
private void Add_Click(object sender, EventArgs e)
{
manager.EndCurrentEdit();
commandbuilder = new SqlCommandBuilder(adapter );
adapter.Update(data);
manager.Refresh();
MessageBox.Show("Added successfully!");
label6.Text = manager.Position + 1 + " of " + data.Rows.Count;
Add.Enabled = false;
New.Enabled = true;
}
421
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
//manager.EndCurrentEdit();
//commandbuilder = new SqlCommandBuilder(adapter);
//adapter.Update(data);
//manager.Refresh();
//MessageBox.Show("Edited successfully!");
//label6.Text = manager.Position + 1 + " of " + data.Rows.Count;
//Way2
connection.Open();
string update = string.Format("update Patients set id = {0}, name = '{1}',
age = {2}, sick = '{3}', gender = '{4}' where Name = '{1}'",
textBox2.Text,
422
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
textBox3.Text,
textBox4.Text,
textBox5.Text,
textBox6.Text);
try
{
command = new SqlCommand(update, connection);
command.ExecuteNonQuery();
MessageBox.Show("Updated succesfully!");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
connection.Close();
manager.Refresh();
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
DataView dv = new DataView(data);
dv.RowFilter = string.Format("Name LIKE '%{0}%'", textBox1.Text);
dataGridView1.DataSource = dv;
manager.Refresh();
connection.Open();
command = new SqlCommand("select id,name,age,sick,gender from
patients where name = '" + textBox1.Text + "'", connection);
reader = command.ExecuteReader();
reader.Read();
try
{
textBox2.Text = reader["id"].ToString();
textBox3.Text = reader["name"].ToString();
textBox4.Text = reader["age"].ToString();
textBox5.Text = reader["sick"].ToString();
textBox6.Text = reader["gender"].ToString();
}
catch
{
}
reader.Close();
connection.Close();
}
423
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
اإلجراءات المخزنة
كما في مشاريع ،C#بإمكانك إنشاء إجراءات خاصة بك في ،SQL Server
ف ً
بدال من تمرير أوامر SQL Serverكوسطاء في كائنات ،C#بإمكانك كتابة
هذه األوامر في إجراءات معينة تخزنها في استعالم ما ثم تستدعيها عند
الحاجة في مشروعك.
سنأخذ مثاال بسيطا فيه أداة جدول عرض وبعض األزرار مثل حذف وإضافة
بيانات وغيرها..
ثم حدد األسطر الثالثة التي كتبتها واضغط تنفيذ كما هو موضح بالصورة:
424
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
:ثم اذهب إلى الفيجوال ستوديو واكتب الكود التالي لالتصال بالقاعدة
public Form1()
{
InitializeComponent();
connection = new SqlConnection("server=Eng27; database=ClinicDB;
Integrated Security=true");
GetStart();
}
void GetStart()
{
command = new SqlCommand("GetPatients", connection); //اسم اإلجراء
//يجب ضبط كائن األوامر على أنه يتعامل مع اإلجراءات المخزنة
command.CommandType = CommandType.StoredProcedure;
adapter = new SqlDataAdapter(command);
data = new DataTable(); adapter.Fill(data); //ملء الجدول
dataGridView1.DataSource = data; //عرض الجدول في أداة جدول العرض
manager = (CurrencyManager)this.BindingContext[data];
}
وقارن النتائج فيما لو، وناقش الفوارق، قارن بين الطريقتين،جرب الكود
وليسcommand اتصلنا بقاعدة البيانات بالوضع المتصل (باستخدام
مع تمريرadapter وبرأيك لماذا قمنا باستنساخ الكائن.)adapter
كوسيط له؟؟ (أعتقد أنه يخطر على بالك أننا نود االتصالcommand
..)بالوضع المنفصل
425
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
مالحظة
فإنهSQL Server عند تعريف المتغيرات في استعالم من استعالمات
.يجب إضافة رمز @ إلى بداية اسم المتغير
بين األحرف الكبير واألحرف الصغيرة فهو ليسSQL Server ال يفرّق
.حساسا لحالة الحروف
في بداية الجملة-- نضع إشارةSQL Server لترك مالحظات في
.المراد جعلها مالحظة
command.Parameters.AddRange(p);
connection.Open();
command.ExecuteNonQuery();
connection.Close();
MessageBox.Show("Added successfully!");
Add.Enabled = false;
New.Enabled = true;
data.Clear();
GetStart();
}
426
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
command.Parameters.Add(p);
connection.Open(); command.ExecuteNonQuery(); connection.Close();
427
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
GetStart();
MessageBox.Show("Deleted successfully!");
}
:ولتعديل البيانات
create proc EditPatient
@id int, @name nvarchar(50), @age int, @sick nvarchar(50),
@gender nvarchar(50)
as
update Patients
set id = @id,
Name=@name,
Age=@age,
Sick=@sick,
Gender=@gender
where id=@id
command.Parameters.AddRange(p);
connection.Open();
command.ExecuteNonQuery();
connection.Close();
MessageBox.Show("Edited successfully!");
428
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
;)(data.Clear
;)(GetStart
}
)private void dataGridView1_Click(object sender, EventArgs e
{
;int i = dataGridView1.CurrentRow.Index
;)(textBox2.Text = dataGridView1.Rows[i].Cells["id"].Value.ToString
;)(textBox3.Text = dataGridView1.Rows[i].Cells["name"].Value.ToString
;)(textBox4.Text = dataGridView1.Rows[i].Cells["age"].Value.ToString
;)(textBox5.Text = dataGridView1.Rows[i].Cells["sick"].Value.ToString
;)(textBox6.Text = dataGridView1.Rows[i].Cells["gender"].Value.ToString
}
SQL Injection
والموضوع بهذا البساطة :لديك صندو َقي نصوص أحدهما يستقبل اسم
ً
وبدال من أن تُدخل المستخدم واآلخر يستقبل كلمة السر الخاصة به،
البيانات الصحيحة – االسم وكلمة السر – فإنك تُدخل كو َد SQLلتحقيق
أغراض معينة.
429
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
والموظف .ولكن بإضافة جدول ثالث يحوي أسماء األمراض مثال يصبح هناك
رابط بين الموظفين والمرضى وهو وجود األمراض ..فالمريض القادم
للمستوصف معه مرض معين ،وأحد موظفي المستوصف هو طبيب يعالج
هذا المرض ،لذلك يوجد رابط بين هذا الموظف وذاك المريض وهو وجود
مرض ما يعاني منه المريض ويعالجه الموظف.
لذلك قم بإنشاء جدول جديد يمثل بيانات األمراض ،وعلى سبيل المثال
ووصف له فقط .ونحتاج أيضا لجدول
ٍ سيحتوي هذا الجدول على رقم للمرض
آخر يربط بين جدول األمراض وجدول المرضى وجدول الموظفين ،باإلضافة
إلى احتواءه على تاريخ زيارة المريض ومقدار فاتورته مثال( .هذا يعني أنه ال
حاجة لعمود المرض sickفي جدول المرضى ألننا سننشئ جدوال خا ً
صا
باألمراض).
430
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
431
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
432
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
433
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
حيث أننا قد أضفنا زيارة واحدة فيها :رقم الزيارة هو ،1ورقم المريض هو 1
(يعني علي) ،والموظف رقمه ( 4يعني محمود طبيب الجلدية) ،ورقم
المرض هو ( 2يعني مرض الجلدية) ،والمبلغ المدفوع هو ،1500وتاريخ
الزيارة .18:22:33.190 28-09-2018ركز في المحتويات جيدا وافهمها..
بإمكانك إضافة الزيارة من خالل محرر الجدول كما في الجداول السابقة أو
من خالل األمر الذي ستضيف الزيارات والمرضى والموظفين واألمراض من
خالله:
)insert into Visits (id,PatientID,EmployeeID,SickID,Cost,Date
))(values(1,1,4,2,1500,GETDATE
434
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
بنفس الطريقة قم بإضافة زيارات مختلفة (ال تنس إدخال الطبيب المناسب
لمرض المريض):
وبالمثل يمكن الحصول على أسماء المرضى الذين لهم أسماء ضمن جدول
الزيارات .والتي سنستعرضها بصيغة أخرى:
* select
from Patients
)where exists (select id from Visits where id = Visits.id
435
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
الحظ أنه عليك وضع شروط إضافية عند التعامل مع جداول جديدة ،وذلك
حتى ال يتم عرض جميع بيانات الجدول.
من جهة أخرى ،فإن استخدام الفئات – أو الطرق بشكل خاص – يجعل من
صيانة البرنامج أمرًا أسهل وأكثر كفاءة ،فكما رأيت في أمثلة هذا الفصل
436
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
قمنا بكتابة أكواد بشكل متكرر أكثر من مرة في الكود ذاته مثل كود االتصال
بقاعدة البيانات أو قطع االتصال .أما عند استخدام الطرق فإن حدوث خطأ
برمجي يصبح من السهل اقتناصه وإصالحه فيما لو لم تستخدم الطرق
فعليك تعديل جميع األكواد التي من المحتمل أن يظهر فيها ذات الخطأ
الذي ظهر في أحد األكواد.
حذف البيانات
عملية الحذف من الممكن أن تكون من خالل حذف المريض بمعرفة رقم id
الخاص به أو اسمه أو عمره مع تفاصيل أخرى مثل عمره وجنسه أو عمره
ومرضه أو جميع األعمار األكبر من أو األصغر من أو التي تساوي عمر معين،
أو معلومات أخرى بإمكانك إضافتها بنفس المبدأ.
حذف بحسب الرقم الشخصي//
)public void DeletePatient(int id
{
;)string sql = string.Format("Delete from Patients where ID = {0}",id
))using (SqlCommand command = new SqlCommand(sql, connection
{
{try
;)(command.ExecuteNonQuery
437
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
}
catch (SqlException ex) {
Exception error = new Exception("some error occures: ", ex);
throw error;
}
}
}
//حذف بحسب االسم
public void DeletePatient(string name)
{
string sql = string.Format("Delete from Patients where [Name] =
'{0}'", name);
using (command = new SqlCommand(sql, connection))
{
try{
command.ExecuteNonQuery();
}
catch (SqlException ex) {
Exception error = new Exception("some error occures: ", ex);
throw error;
}
}
}
//ضبط حاالت العمر
enum deletecondition
{
morethan,
lessthan,
equal
}
//حذف بحسب العمر
public void DeletePatient(int age, deletecondition delcondition)
{
string sql = "";
if (delcondition == deletecondition.morethan)
sql = string.Format("Delete from Patients where age > {0}", age);
else if (delcondition == deletecondition.lessthan)
sql = string.Format("Delete from Patients where age < {0}", age);
else
sql = string.Format("Delete from Patients where age = {0}", age);
using (command = new SqlCommand(sql, connection))
{
try
{
command.ExecuteNonQuery();
}
catch (SqlException ex)
438
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
{
Exception error = new Exception("some error occures: ", ex);
throw error;
}
}
}
//حذف بحسب العمر والمرض
public void DeletePatient(int age, deletecondition delcondition, string sick)
{
string sql = "";
if (delcondition == deletecondition.morethan)
sql = string.Format("Delete from Patients where age > {0}", age);
else if (delcondition == deletecondition.lessthan)
sql = string.Format("Delete from Patients where age < {0}", age);
else
sql = string.Format("Delete from Patients where age = {0}", age);
sql += string.Format(" and sick = '{0}'", sick);
using (command = new SqlCommand(sql, connection))
{
try
{
command.ExecuteNonQuery();
}
catch (SqlException ex)
{
Exception error = new Exception("some error occures: ", ex);
throw error;
}
}
}
//حذف بحسب العمر والجنس
public void DeletePatient(int age, deletecondition delcondition, string gender)
{
string sql = "";
if (delcondition == deletecondition.morethan)
sql = string.Format("Delete from Patients where age > {0}", age);
else if (delcondition == deletecondition.lessthan)
sql = string.Format("Delete from Patients where age < {0}", age);
else
sql = string.Format("Delete from Patients where age = {0}", age);
sql += string.Format(" and gender = '{0}'", gender);
using (command = new SqlCommand(sql, connection))
{
try
{
command.ExecuteNonQuery();
}
439
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
.طب ًعا يجب أن تفتح االتصال قبل استدعاء إحدى هذه اإلجراءات
440
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
441
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
442
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
احفظ الجدول ثم احفظ قاعدة البيانات .اضغط حفظ باسم لتحفظ قاعدة
البيانات باالمتداد القديم:
443
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
444
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
ومن أجل ضمان بقاء األدوات في أماكنها عند تغيير حجم النافذة اضبط
الخاصية Anchorلجميع العناصر الواقعة في الالئحة العليا على Top,
،Rightعدا صندوق التجميع.
445
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
تهيئة البرنامج :وفيه يتم تهيئة المكونات ضمن التابع البنّاء للنافذة ثم إجراء
االتصال مع قاعدة البيانات الموَصفة بالمتغير النصي accessDBثم تحميل
بيانات قاعدة البيانات إلى أداة عرض البيانات.
)(public Form1
{
;)(InitializeComponent
;)connection = new OleDbConnection(accessDB
;)(dataGridView1.DataSource = LoadData
}
تحميل البيانات إلى أداة عرض البيانات :وفيه يتم فتح االتصال مع قاعدة
ً
جدوال ،وتنفيذ أمر تحميل جميع البيانات ثم استنساخ كائن جديد يمثل
حقول قاعدة البيانات عبر االتصال ،connectionثم الربط بين كائن األمر
وكائن الجدول عبر الكائن ،adapterوأخي ًرا إغالق االتصال وإرجاع الجدول
كقيمة للطريقة .LoadData
)(public DataTable LoadData
تحميل البيانات إلى أداة عرض البيانات{ //
;)(connection.Open
;)(data = new DataTable
;"string load = "select * from students
;)command = new OleDbCommand(load, connection
;)adapter = new OleDbDataAdapter(command
;adapter.Fill(data); connection.Close(); return data
}
446
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
ولضمان عدم تكرار األرقام الشخصية idاستخدم الكود التالي والذي يقوم
بفتح االتصال بقاعدة البيانات وإنشاء أمر يقوم باستدعاء جميع عناصر
الحقل ،idثم قراءتها عبر الكائن ،readerثم إضافة جميع محتويات الحقل
إلى الئحة بعد التصريح عنها .وأخيرًا نغلق االتصال والقارئ ،ونتحقق من
قيمة الرقم الممرر كوسيط للتابع isIDوذلك عبر بنية شرط ،فإذا كان
موجودا أعاد القيمة trueوإال .false1
)private bool isID(int n
{
;)(connection.Open
;)command = new OleDbCommand("select id from students", connection
;)(reader = command.ExecuteReader
;)(>List<string> id = new List<string
))(while (reader.Read
;))(id.Add(reader["id"].ToString
;)(reader.Close
;)(connection.Close
)))(if (id.Contains(n.ToString
;return true
else
;return false
}
1الغاية من التابع isIDهو معرفة هل العدد صالح ألن يكون رقم idأم ال .فكما هو معرف فرقم idيجب أال
يتكرر على اإلطالق في قاعدة البيانات وذلك ألنه يميز عناصر السجالت عن بعضها في قاعدة البيانات.
عند حذف أحد السجالت وفي حال لم يكن آخر سجل ،سيبقى رقمه idخاليا ال يحمله أي سجل ،وقد
يسبب لك هذا بعض المشاكل ،لذلك وعند إنشاء سجالت جديدة سنضعها مكان السجالت القديمة إن
أمكن.
447
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
command.ExecuteNonQuery();
connection.Close();
dataGridView1.DataSource = LoadData();
Add.Enabled = true ;
Save.Enabled = false ;
}
448
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
catch
{
// رسالة أو غيرها،هنا ضح شيئا ما يستقبل الخطأ
}
finally
{
//عند تنفيذ الكود أو وجود خطأ يجب إغالق االتصال في النهاية
if (connection.State.ToString() == "Open")
connection.Close();
}
}
مالحظة
كأسماء حقولMS Access عند استخدام كلمات محجوزة في
هذا إن استطعت استخدامها، أو غيرهاname أوcount كالكلمة
ضعها مابين قوسين متوسطين ] [ لتتمكن من استخدامها،أصال
.[count] مثال.بشكل طبيعي
والمسبقة بإشارة @ ليسValues القيم التي تعوضها بعد الكلمة
من الضروري أن تكون مماثلة ألسماء الحقول التي تمثلها ولكن يجب
.أن تكون مماثلة للكلمات التي ستوضع باألسطر التالية
حذف السجالت
:ويكون بالكود التالي
private void Delete_Click(object sender, EventArgs e)
{
DialogResult M = MessageBox.Show(" " حذف تريد هل+ textBox2.Text +
"?", ""تأكيد الحذف, MessageBoxButtons.YesNo, MessageBoxIcon.Question,
MessageBoxDefaultButton.Button1, MessageBoxOptions.RightAlign);
if (M == System.Windows.Forms.DialogResult.Yes)
try
{
connection.Open();
string delete = "delete from students where id = " +
dataGridView1.CurrentRow.Cells[0].Value.ToString() + "";
command = new OleDbCommand(delete, connection);
command.ExecuteNonQuery(); connection.Close();
dataGridView1.DataSource = LoadData();
}
449
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
finally
{
if (connection.State.ToString() == "Open") connection.Close();
}
}
تعديل السجالت
ً لتعديل سجل ما يجب أن نتأكد
أوال أن عمر الطالب – في مثالنا – أكبر من
وهذا ما كان علينا إضافته إلى كود إضافة طالب جديد إلى سجالت،الصفر
وال أرغب بتعديل الصفحات السابقة،قاعدة البيانات ولكني نسيت ذلك
وإعادة تنسيق الصفحات مع بعضها لذلك عدل الكود عندك ليشمل التحقق
.مدخل موجب تماما ُ من أن عمر الطالب ال
مالحظة
في الواقع هناك الكثير من األفكار الممكن تطبيقها على غرار التأكد
فمثال بإمكانك تخمين السنة الدراسية للطالب،من أن العمر موجب
سنوات يكون الطالب في6 اعتمادا على العمر (مثال من أجل عمر
.) وهكذا لبقية األعمار،الصف األول
(لذلك-_- سنة مثال30 من غير المنطقي أن يكون الطالب عمره
.)من الممكن قبول أعمار محددة
command.ExecuteNonQuery();
connection.Close();
dataGridView1.DataSource = LoadData();
}
450
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
ولجعل التركيز على صندوق النص الممثل للخلية المحددة (االسم األول أو
:)األخير أو العمر أو الصف
private void dataGridView1_CellEnter(object sender,
DataGridViewCellEventArgs e)
{
switch (e.ColumnIndex )
{
case 0:
textBox1.Focus();
451
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
break;
case 1:
textBox2.Focus();
break;
case 2:
textBox3.Focus();
break;
case 3:
textBox4.Focus();
break;
case 4:
textBox5.Focus();
break;
}
}
452
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
البحث عن السجالت
سنقوم بالبحث عن السجالت في صندوق اإلدخال المخصص للبحث
وللحصول على جودة في األداء سننفذ عملية،Search والمسمى برمجيا
. بحيث يتم جلب القيم المشابهة،TextChanged البحث عند تفجير حدث
private void Search_TextChanged(object sender, EventArgs e)
{
connection.Open();
DataTable data = new DataTable();
string load = "select * from students where firstname+lastname+class like
453
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
تجميع البيانات
يتم عادة تجميع البيانات إلجراء مقارنات وإحصائيات معينة حيث يتم عرض
ففي مثالنا يمكن عرض عدد الطالب.السجالت منسوبة لبيانات حقل ما
أو،المسجلين بالصفوف حيث يتم عرض عدد الطالب من أجل كل صف
أو غيرها وغيرها من،عرض عدد الطالب الذين لهم االسم الفالني
.التطبيقات حسب الحاجة
قم بإضافة زر لتجميع البيانات وزر إلعادة تحميل البيانات كامل ًة واستخدم
:الكود التالي
private void Group_Click(object sender, EventArgs e)
{
data = new DataTable();
string load;
load = "select count(age) as Age, class from students group by class";
command = new OleDbCommand(load, connection);
adapter = new OleDbDataAdapter(command);
adapter.Fill(data);
connection.Close();
dataGridView1.DataSource = data;
panel1.Enabled = false; panel2.Enabled = false;
//ال تنسى أنه علينا إلغاء تمكين المستخدم من تعديل السجالت أثناء التجميع
}
454
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
:فالنتيجة ستكون
، ً
خطأ Age [ لكني سيمتهcount] مي العمود األول ّ كان يجب أن أس
. طب ًعا ال تنسَ تغييره عندك. من فضلكcount لذلك تخيّله باالسم
455
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
الحظ أنه باستخدام التصميم السابق باتت النافذة مريحة أكثر للمستخدم،
إذا رغب بإضافة طالب جديد ينتقل للتبويبة ،Newوإال فإنه يبقى في
التبويبة Operationsإلجراء بعض العمليات الممكنة .بإمكانه البحث أيضا
ضمن صندوق النص الموضح بالشكل السابق .كما أن عملية ترتيب
البيانات ممكنة بسهولة بالنسبة له .إليك بعض األكواد التي ستحتاجها
إلحياء النافذة السابقة:
;using System
;using System.Windows.Forms
;using System.Data.OleDb
namespace ListViewDB
{
public partial class Form1 : Form
{
static string accessDB = @"Provider=Microsoft.jet.OLEDB.4.0;Data
;";Source = " + Application.StartupPath + "\\MyDB.mdb
456
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
OleDbConnection connection;
OleDbCommand command;
OleDbDataReader reader;
static ListViewItem L;
public Form1()
{
InitializeComponent();
connection = new OleDbConnection(accessDB);
}
while (reader.Read())
{
L = listView1.Items.Add(reader["id"].ToString());
L.SubItems.Add(reader["firstname"].ToString());
L.SubItems.Add(reader["lastname"].ToString());
L.SubItems.Add(reader["age"].ToString());
L.SubItems.Add(reader["class"].ToString());
}
connection.Close();
}
void ShowData()
{
listView1.Items.Clear();
connection.Open();
command = new OleDbCommand("select * from students order by "
+ OrderBy, connection);
reader = command.ExecuteReader();
while (reader.Read())
{
457
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
L = listView1.Items.Add(reader["id"].ToString());
L.SubItems.Add(reader["firstname"].ToString());
L.SubItems.Add(reader["lastname"].ToString());
L.SubItems.Add(reader["age"].ToString());
L.SubItems.Add(reader["class"].ToString());
}
connection.Close();
}
458
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
459
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
:أو بالشكل
chart1.Series["Ser"].ChartType =
System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Column;
460
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
..وغيرها الكثير
chart1.Series.Add(";)"عدد الطالب
chart1.Series["]"عدد الطالب.ChartType =
System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Column;
chart1.Series["]"عدد الطالب.XValueMember = data.Columns[2].ToString();
chart1.Series["]"عدد الطالب.YValueMembers = data.Columns[0].ToString();
.ويمكن أيضا إظهار أكثر من سلسلة على ذات المخطط بالطريقة ذاتها
461
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
وكمثال بسيط على الطريقة األولى أنشئ مشروعا جدي ًدا وصمم النافذة
التالية له:
هل تذكر مصطلح التعفيش؟؟ السرقة في وضح النهار وخارج عن سيطرة الحكومة. 1
462
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
namespace SaveImagesDB
{
public partial class Form1 : Form
463
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
{
static string accessDB = @"Provider=Microsoft.jet.OLEDB.4.0;Data
Source = " + Application.StartupPath + "\\LoginDB.mdb;";
public Form1()
{
InitializeComponent();
connection = new OleDbConnection(accessDB);
textBox2.PasswordChar = '\u25cf'; //PassChar: ••••
linkLabel1.Enabled = false;
}
464
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
;)(connection.Open
= ]command = new OleDbCommand("update users set [image
;)@image where id = " + id + "", connection
;)command.Parameters.AddWithValue("@image",open.FileName
;)(command.ExecuteNonQuery
;)pictureBox1.Image = Image.FromFile(open.FileName
;)(connection.Close
}
}
}
}
عند الضغط على زر تسجيل الدخول فإن جميع بيانات قاعدة البيانات سيتم
معالجتها وقارنتها مع صناديق نصوص اسم المستخدم وكلمة مروره ،في
حال تطابق إحدى البيانات يتم تسجيل الدخول وتحميل الصورة وذلك
باالعتماد على مسارها في قاعدة البيانات ثم جعل قيمة متغير منطقي
مساوية لـ ،1والتي تعني تم تسجيل الدخول.
وبعدها تتم مقارنة قيمة هذا المتغير فإذا كان 0يظهر رسالة خطأ.
عند الضغط على رابط تغيير الصورة يتم إظهار كائن استعراض الملفات..
يمكن تطوير المثال ليتم نسخ الصورة إلى جوار البرنامج مثال أو لحفظها
في مكان ما .في هذا المثال تم اإلبقاء على الصورة في مكانها ،أي أنه أي
فقد في الصورة من الممكن أن يسبب خطأ في عمل البرنامج.
465
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
466
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
هل الحظت كيف اختلفت األكواد بشكل كبير بين هذه الطريقة وتلك؟؟ ال
الفارق هو عند،يوجد اختالف بأكواد االتصال واالستعالم والتعديل وغيرها
467
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
النسخ االحتياطي
إلجراء النسخ االحتياطي هنا يكفي نسخ قاعدة البيانات واستعادتها في
وقت الحق وذلك عبر أكواد نسخ الملفات:
أزرار النسخ االحتياطي غير موجودة في المشروع ،تكرّم وأضفها ^_^//
)private void Backup_Click(object sender, EventArgs e
{
;)(SaveFileDialog save = new SaveFileDialog
;"|*.mdbقاعدة بيانات" = save.Filter
)if (save.ShowDialog() == DialogResult.OK
{
try
{
;)File.Delete(save.FileName
}
} { catch
try
{
;"string path = Application.StartupPath + @"\MyDB.mdb
;)File.Copy(path, save.FileName, true
;(" تم تصدير نسخة احتياطية بنجاح!"(MessageBox.Show
}
catch
{
;(" ال يمكن إجراء نسخة احتياطية!"(MessageBox.Show
}
}
}
)private void Restore_Click(object sender, EventArgs e
{
هل تود بالتأكيد استعادة نسخة احتياطية "(DialogResult M = MessageBox.Show
",استعادة نسخة احتياطية"",سابقة؟ ستفقد جميع المعلومات التي لم يتم حفظها!
468
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
MessageBoxButtons.YesNo, MessageBoxIcon.Question,
MessageBoxDefaultButton.Button1, MessageBoxOptions.RightAlign);
if (M == System.Windows.Forms.DialogResult.Yes)
{
OpenFileDialog open = new OpenFileDialog();
open.Filter = "*|بيانات قاعدة.mdb";
if (open.ShowDialog() == DialogResult.OK)
{
try
{
string path = Application.StartupPath + @"\MyDB.mdb";
File.Copy(open.FileName, path, true);
dataGridView1.DataSource = LoadData();
MessageBox.Show("!;(" تم استعادة نسخة احتياطية بنجاح
}
catch
{
MessageBox.Show("!;(" ال يمكن استعادة نسخة احتياطية
}
}
}
}
469
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
وبطبيعة الحال فإن كود االتصال بقاعدة البيانات سيكون بفرض كلمة السر
:111 هي
//في مكان ما تصل إليه جميع اإلجراءات
static string sql = @"Provider=Microsoft.jet.OLEDB.4.0; Data Source =
C:\MyDB.mdb; Jet OLEDB:Database Password='111'; Persist Security
Info=True;";
OleDbConnection connection;
//في أحد إجراءات النموذج وليكن إجراء تحميل النموذج
connection = new OleDbConnection(sql);
470
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
إلعادة ضبط كلمة السر عليك إزالتها أوال ثم ضبطها من جديد ،ويمكن ذلك
عن طريق فتح قاعدة البيانات في Accessبالوضع الخاص.
471
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
472
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
كبداية ،صمم نافذ ًة جديد ًة لعرض التقرير عليها ،أضف نافذة جديدة
لمشروعك وأضف إليها األداة :ReportViewer
473
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
تصميم التقرير
انقر على السهم أعلى أداة عارض التقارير ثم :Design a new report
سيظهر معالج تهيئة مصدر البيانات ،اختر قاعدة بيانات ،ثم اختر قاعدة
البيانات من نوع .Datasetأنشئ بعدها اتصال جديد ،ثم ابحث عن قاعدة
البيانات المطلوبة.
اضغط على زر تجربة االتصال كما جرت العادات والتقاليد ،ثم موافق.
اضغط التالي فتحصل على رسالة مفادها أن قاعدة البيانات ستنسخ إلى
موقع المشروع ،اضغط موافق.
ستظهر نافذة جديدة حدد ضمنها جميع الجداول المطلوبة ،ثم إنهاء.
474
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
475
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
األمر الثاني يعرض لك مسطرة كما لو أنك في برنامج وورد ،ويعرض لك
المجوعات لديك.
األمر الثالث إلضافة رأس للتقرير ،وهو نفسه المنطقة المكتوب عليها اسم
كتابي واسمي في أعلى أوراق كتابي هذا.
لنعد للتقرير وتصميمه ،أضف إلى رأس التقرير أداة صورة وأدوات نصوص أو
ماتراه مناسبا ،واضبط الصورة على الوضع :Stretch
أما التذييل (في أسفل الصفحة) ،فضع فيه أي عبارة أخرى على كيفك.
ليصبح التقرير بالشكل:
476
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
أيا كانت الطريقة التي أنشأت التقرير من خاللها – سوا ًءا بالطريقة المذكورة
بالفقرة السابقة أو يدويا أو بغيرها – فإنه عليك ربط التقرير بأداة عرض
التقارير ،ReportViewerوالعملية بسيطة للغاية ،عد إلى النافذة التي
تحتوي على التقرير ومن السهم في أعلى األداة:
لكن انتقل إلى كود نافذة التقرير واسمح األكواد التالية أو حولها لمالحظة
برمجية:
477
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
كما يمكنك عرض معاينة للصفحة التي ستظهر عند الطباعة ،بالضغط على
زر معاينة الطباعة ،Print Layoutالواقع بجانب زر الطباعة:
478
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
طبعا idيحوي قيمة السجل المحدد والذي يمكنك الحصول عليه من أجل
ListViewبالكود التالي:
)private void listView1_SelectedIndexChanged(object sender, EventArgs e
{
)foreach (ListViewItem L in listView1.Items
)if (L.Selected
{
;id = L.SubItems[0].Text
}
}
ولتجنب حدوث خطأ ،أنشئ حدثا يراقب تغييرات ،idفإذا لم تكن تحوي
بيانات يجب عدم تفعيل الزر الذي سينشئ تقريرًا بالسجل المحدد.
479
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
كما يمكنك عرض السجل المحدد بشكل عامودي وذلك بتصميم التقرير
:بالشكل التالي
.هل تذكر مصطلح تفجير؟؟ قلنا أن تفجير الحدث يعني حدوث الحدث 1
480
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
الحقيقة أن الكائن األول يقوم بربط الكائنات مع بعضها ،مثل ربط ناتج أمر
من أوامر قاعدة البيانات مع جداول عرض أو تقارير أو غيرها ،أما الثاني فمن
خالله بإمكانك قراءة نتائج تنفيذ أوامر قاعدة البيانات مباشرة .الحظ أننا
استخدمنا األول عند قراءة البيانات – إلظهارها على – ListViewوالثاني
استخدمناه عند إرسال النتائج إلى التقرير (الربط بين نتيجة األمر والـ
DataSetتبع التقرير).
481
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
482
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
في البداية سأعرفك على الرموز التي يمكن لويندوز التعرف عليها .افتح
قائمة ابدأ واكتب ،Character Mapلتحصل على برنامج يحوي العديد من
الرموز والتي ألول مرة قد تراها.
بإمكانك من خالل هذا البرنامج البحث عن الرموز أيضا بمعرفة شيفرة الرمز
بتشفير ،Unicodeوهو ماسنتعامل معه في برامجنا.
483
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
بإمكانك استخدام رموز برنامج خريطة المحارف وذلك بإسناد قيمة الرمز
المطلوب عرضه إلى متغير نصي الستخدامه عند الحاجة ،أو استخدم كود
المحرف ،والذي تجده أسفل نافذة البرنامج.
484
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
فمثال لعرض عبارة نصية مع رمز درجة مئوية ،ابحث أوال عن المحرف ،خذ
كوده ،ثم أسنده للمتغير:
خذ شيفرة المحرف المتمثلة برمز الـ Unicodeالخاص به ،ثم اكتبها داخل
عبارة نصية بعد \uمباشرة.
;int i = 25
;string temp
;"temp = i + " C\u00b0
كما يمكنك كتابة المحرف باستخدام لوحة المفاتيح وذلك من خالل أكواد
المفتاح ،Altوالتي يمكنك إيجادها بنفس البرنامج السابق وذلك أمام
.Keystrokeفلكتابة °استمر بالضغط على Altواضغط بالتتالي على
485
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
486
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
فمثال صناديق النصوص التي تستقبل أرقام الهواتف يجب أن تكون أرقاما
فقط ،أو تلك التي تستقبل معطيات رقمية مثل األعمار والعالمات والقراءات
الرقمية وغيرها.
وفي حال أردت السماح بإدخال الفاصلة " ،".فكرر أحد أجزاء الشرط
ليحتوي الفاصلة ،أو أرح رأسك واستخدم أداة .UpDownTextBox
487
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
قد ال يكون هذا الكود بهذه األهمية لدرجة أن يوضع ضمن التقنيات المفيدة
لكن ال بأس بسرده هنا ،قد تحتاجه إلظهار رسالة تطلب من المستخدم
حفظ التغييرات أو ماشابه ذلك.
ضع الكود في حدث//
//Form_Closing
?",هل أنت متأكد من أنك ترغب بالخروج"(DialogResult result = MessageBox.Show
;)", MessageBoxButtons.YesNo, MessageBoxIcon.Questionتأكيد الخروج"
)if (result == DialogResult.No
{
;e.Cancel = true
}
488
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
أضف خمسة عناصر لصندوق الالئحة األول ،واترك الصندوق اآلخر خاليا أو
امأله إن شئت .ثم استخدم الكود التالي:
سنخزن هنا صندوق الالئحة الف ّعال حاليًاListBox Selected; //
نقل عنصر واحد//
)private void listBox1_MouseDoubleClick(object sender, MouseEventArgs e
{
)if (listBox1.SelectedIndex >= 0
{
;)]listBox2.Items.Add(listBox1.Items[listBox1.SelectedIndex
;)listBox1.Items.RemoveAt(listBox1.SelectedIndex
}}
489
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
490
من البداية حتى اإلتقانC#
Hasan M. al-Fahl – Eng27
{
temp = Selected.Items[Selected.SelectedIndex].ToString();
Selected.Items[Selected.SelectedIndex] =
Selected.Items[Selected.SelectedIndex - 1];
Selected.Items[Selected.SelectedIndex - 1] = temp;
Selected.SelectedIndex -= 1;
}
}
}
،لذلك فسأعطيك تطبي ًقا يحوي آالف األيقونات تشبع تعطشك للتصميم
:Icon8 وهو تطبيق
491
C#من البداية حتى اإلتقان
Hasan M. al-Fahl – Eng27
وإلى هنا ،نكون قد أنهينا جز ًءا يسيرًا مما يجب عليك معرفته لتتقن ،C#
وعلى أمل أن يحقق الكتاب الفائدة المرجوة منه أتمنى منك – عزيزي
القارئ/المبرمج – نش َر الكتاب ومعلوماته ،وأن تدعو لي وللمسلمين بظهر
الغيب ،عسى أن تكون ساعة استجابة أو أن تكون – أنت – ممن يحبهم
هللا ،فإن هلل خواص ،في األمكنة واألزمنة واألشخاص..
ٌ
توفيق من هللا وحده ،وإنني وإذ وختا ًما ،فإن هذا العمل لم يكن ليكتمل لوال
حاولت تنقيحه وتدقيقه إال أن احتمال وجود أخطاء علمية أو نحوية وار ٌد بال
شك ،لذلك فيسعدني أن تقدم لي أخطائي أو أيّة نصائح أو اقتراحات
ألخذها بعين االعتبار في النسخ القادمة من هذا الكتاب – إن قدر هللا لهذا
الكتاب أن يكون له نسخ أخرى – على وسائل التواصل الموجودة أول
الكتاب .والسالم عليكم ورحمة هللا وبركاته .
492
ملحقات ومراجع كتاب C#من البداية حتى اإلتقان
الملحقات والمراجع
493
ملحقات ومراجع كتاب C#من البداية حتى اإلتقان
494
ملحقات ومراجع كتاب C#من البداية حتى اإلتقان
495
ملحقات ومراجع كتاب C#من البداية حتى اإلتقان
496
ملحقات ومراجع كتاب C#من البداية حتى اإلتقان
أكواد العمالت:
497
ملحقات ومراجع كتاب C#من البداية حتى اإلتقان
498
ملحقات ومراجع كتاب C#من البداية حتى اإلتقان
الرياضيات:
499
ملحقات ومراجع كتاب C#من البداية حتى اإلتقان
500
ملحقات ومراجع كتاب C#من البداية حتى اإلتقان
501
ملحقات ومراجع كتاب C#من البداية حتى اإلتقان
502
ملحقات ومراجع كتاب C#من البداية حتى اإلتقان
503
ملحقات ومراجع كتاب C#من البداية حتى اإلتقان
504
ملحقات ومراجع كتاب C#من البداية حتى اإلتقان
505
ملحقات ومراجع كتاب C#من البداية حتى اإلتقان
506
ملحقات ومراجع كتاب C#من البداية حتى اإلتقان
المراجع
المؤلف أو المصدر المرجع
كتاب ""C# Keywords
م .أحمد جمال خليفة كتاب "خطوة بخطوة مع فيجوال ستوديو "2008
كتاب "سبيلك إلى تعلم لغة "C#.Net
كتاب "سبيلك المختصر إلى تعلم لغة C#برمجة
الواجهات"
خالد السعداني
كتاب "دليلك المختصر -الهجرة من الفيجوال بسيك إلى
الفيجوال سي شارب والعكس".
كتاب "الشرح الوافي لتعلم لغة SQLمن نبعها الصافي"
KSA كتاب غير معنون فيه أساسيات SQL
زايد السعيدي كتاب غير معنون فيه سلسلة أساسيات C#
كتاب "برمجة ( ،)1لغة بيزيك المرئية للمهندسين"
م .أمل منا
كتاب "لغات برمجة"C++ ،
د .محمد دباس الحميد كتاب "البرمجة ( ،)1أساسيات البرمجة بلغة "C++
د .م .عمر قطاية كتاب ""Programming with C#
طه سوفت كتاب "دورة الملفات الدفعية"
OMS كتاب "الكامل في السي شارب"
م .محمد كمال أحمد و
كتاب "دورة كن خبيرًا في لغة "C#
م .شريف محمد رضا
م .حسام الدين الرز كتاب "اإلبحار في لغة – C#.Netج"2
قناة خالد السعداني قائمة تشغيل " دورة السي شارب كاملة" على يوتيوب
قناة Foxlearn قائمة تشغيل " "C# Toturialsعلى يوتيوب
قائمة تشغيل " " C# Tutorials From Lynda.comعلى
Sachin Paul
يوتيوب
قناة Darren Lee فيديوهات مختلفة
C# Examples أمثلة من تطبيق أندرويد
موقع https://www.w3schools.com/sql/
موقع https://ss64.com/
507
ملحقات ومراجع كتاب C#من البداية حتى اإلتقان
508
من البداية حتى اإلتقانC# ملحقات ومراجع كتاب
:رسالة الكتاب
C#Book book = new C#Book();
book = this.Book;
If(book.IsHelpful)
{
YouTube youtube = new Youtube("Hasan M. al-Fahl");
FaceBook facebook = new FaceBook("Eng27 – Programming");
Telegram telegram = new Telegram("@Eng27Channel");
telegram.Join();
facebook.Like();
facebook.SeeFirst = true;
youtube.Subscribe();
youtube.GetNotifications = true;
for (int i = 0; i < youtube.Videos.Count; i++)
{
youtube.Videos[i].Like();
youtube.Videos[i].Comment();
youtube.Videos[i].Share();
}
}
//By Eng27 – Hasan M. al-Fahl
509
ملحقات ومراجع كتاب C#من البداية حتى اإلتقان
.
خصص دعوة يومية للناس ،اترك بصمة خير في حياة بعضهم ،ساعد من غير انتظار
مقابل ،كن عونًا للناس..
م معلومة واحدة فقط يعني أنني يقول أحد دكاترتي في الجامعةْ :
أن أتعلم كل يو ٍ
سأتعلم 365معلومة خالل عام!
صا واح ًدا فقط يعني أنني ْ
"ألن أساعد كل يوم شخ ً عدل المقولة السابقة لتجعلها:
سأساعد 365شخص خالل عام"!
510