الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

دروس في البرمجه بلغة C#2005, تعلم خطوة بخطوة , مع الإجابة عن أي سؤال

مغلقرائج
بدأه حماة النهضة في 19 أبريل 2007 · 208 رد · 80,594 مشاهدة · في Microsoft Visual C#.NET
مشاركة: واتساب X فيسبوك تيليجرام
#26

الواجب الرابع مرفق

ولكن احيانا يعلق اثناء الاستخدام , واذا اخترت صوره أيضاً يعلق( علماً اني وضعت له تراي وكاتش ) !!

WindowsApplication9.rar

تم تعديل هذه المشاركة بواسطة Pro_S00 في 29 أبريل 2007 في 18:22

#27

السلام عليكم ورحمه الله وبركاته

إن شاء الله هذا هو واجب الدرس الرابع أرجو ان ينال رضاكم

MyMediaPlayer4.rar

#28

وعليكم السلام ورحمة الله وبركاته

Pro_S00

اقتباس
الواجب الرابع مرفق

ولكن احيانا يعلق اثناء الاستخدام , واذا اخترت صوره أيضاً يعلق( علماً اني وضعت له تراي وكاتش ) !!

تأكد أخي انك وضعت جملة try في دالة تشغيل الملف أيضاً

ghubein

اقتباس
بارك الله فيكم على المجهود وجعله الله في ميزان حسناتكم ونفع بكم الامة

ارجوا ان تستمروا

وبارك لك أخي

بإذن الله مستمرين للنهاية

عمرو الحمصى

اقتباس
إن شاء الله هذا هو واجب الدرس الرابع أرجو ان ينال رضاكم

تمام أخي , أكيد نال رضانا , خصوصاً رسالة تأكيد الخروج..

أن شاء الله تستمر معنا بنفس النشاط

..

7oma

حماة النهضة

إعذرونا , سنضطر للغياب فترة كبيرة

الأمر ليس بيدنا ...... فسامحونا

#29

جزاك الله خيرا أخي "حماة النهضة", ان شاء الله سأضع الموضوع في المواضيع المتميزة.

اقتباس
ولكن احيانا يعلق اثناء الاستخدام , واذا اخترت صوره أيضاً يعلق( علماً اني وضعت له تراي وكاتش ) !!

Try & Catch بطيئة. ويجب استخدامها بحرص وفي الأخطاء التي يصعب عليك اصطيادها فقط, هي والأخطاء الغير متوقعة. مثلا يجب استخدامها في Play لأن العديد من المشاكل محتملة الحدوث ويصعب علينا حصرها جميعا. أما في اختيار ملف ليس WAV ولا MP3 فهذا يمكن اصطياده بمعرفة امتداد الملف. مثلا :

if (FO.ShowDialog() == DialogResult.OK)
{
System.IO.FileInfo selectedFileInfo = new System.IO.FileInfo(FO.FileName);

if (selectedFileInfo.Extension == ".wav" || selectedFileInfo.Extension == ".mp3")
{
try
{
//call Play()
}
catch (Exception exp)
{
MessageBox.Show("حدثت مشكلة أثناء تشغيل الملف " + selectedFileInfo.Name);
MessageBox.Show(exp.Message);
}
}
else
{
MessageBox.Show("البرنامج لا يدعم هذا النوع من الملفات");
}
}

ان اختار المستخدم ملف بامتداد ليس MP3 ولا WAV فستظهر رسالة تخبره بأن الملف الذي اختاره ليس مدعوم. وان اختار ملفات مدعومة ولكن حدثت مشكلة ما في تشغيلها ستظهر رسالة تخبره بهذا.

يمكن أيضا شبه-اجبار المستخدم على اختيار ملفات ذات امتداد معين في الـ OpenFileDialog, وذلك بتحديد خاصية الـ Filter. مثلا :

FO.Filter = "ملفات ام بي ثري|*.mp3|ملفات واف|*.wav";

#Read

http://MoutazShams.blogspot.com

projects003.gif

أعتذر عن التغيب هذه الأيام نظرا للانشغال المريب

#30

السلام عليكم ورحمة الله وبركاته

الدرس الخامس

تشغيل ملف فيديو

دوال تشغيل الفيديو موجودة في ملف Microsoft.DirectX.AudioVideoPlayback.dll

الذي أضفناه إلى التطبيق في الدرس السابق

دوال الفيديو تشبه إلى حد كبير دوال الصوت عدى عن إختلافات بسيطة

من اهم هذه الإختلافات أنه يمكنك أن تحدد كائن حاضن Owner Control لشاشة الفيديو

معنى كائن حاضن اي كائن يعمل كشاشة فيديو

أما إذا لم تحدد كائن حاضن فان التطبيق سيفتح نافذه جديدة لتكون شاشة الفيديو

قراءة أحداث المفاتيح

كل كائن له صفات و دوال كما عرفنا سابقاً , والكائنات تحتوي أيضاً على أحداث Events

مثلاً الزر له عدة أحداث منها عند الضغط عليه Click وعند الضغط المزدوج DoubleClick

و عند مرور مؤشر الماوس به MouseOver

وفي الدروس السابقة إستخدمنا حدث Click فقط

للتصفح بين أحداث الكائن , إختر الكائن ثم أفتح نافذة الصفات "الخواص" واختر زر الأحداث:

image5-1.jpg

ستظهر لك قائمة بجميع الأحداث للكائن المحدد

ولكي تضيف تعليمات عند حدوث حدث معين اضغط مزدوجاً على أسم الحدث في القائمة

ستتنتقل إلى الشفرة لتكتب التعليمات التي تنفذ عن حدوث ذلك الحدث

ومن الأحداث المهة حدث KeyPress وينطلق هذا الحدث عند الضغط على أي مفتاح

في لوحة المفاتيح .

التطبيق

إفتح تطبيق الدرس السابق وعدل النص في زر فتح ملف الصوت إلى "فتح ملف ميديا"

وفي زر تشغيل ملف الصوت إلى "تشغيل ملف ميديا"

أضف زراً جديداً وغير النص فيه إلى "ملئ الشاشة"

قبل تشغيل ملف الفيديو يجب أن نحدد له كائن حاضن ليعمل كشاشة

افتح التصميم وأضف أدات البانيل إلى الفورم:

image5-3.jpg

تأكد من إختيار البانيل و غير صفة الإسم إلى p1

غير صفة العرض Width إلى 400 وصفة الإرتفاع Height إلى 300

image5-4.jpg

من خلال صفة BackgroundImage إختر اي صورة لتكون خلفية الشاشة

ليصبح شكل النافذة هكذا:

image5-5.jpg

أضغط مزدوجاً على أي زر للذهاب إلى الشفرة ,

نحتاج إلى تعريف كائن عام Global من نوع فيديو ولأننا سنستخدمة في أكثر من إجراء

سنعرفه خارج جميع الإجراءات والدوال , إذهب إلى الشفرة حيث عرفنا متغير الصوت في الدرس السابق

وأكتب تعريف كا ئن الفيديو :

private Video vp;

تحت تعريف كائن الصوت من الدرس السابق :

image5-2.jpg

سنجعل التطبيق يفتح ملفات صوت أو ملفات فيديو , لكن المشكلة أن للصوت كائن

وللفيديو كائن آخر , وبالتالي يجب أن نعرف نوع الملف حتى نستخدم الكائن المحدد

وبما أن أنواع الفيديو كثيرة جداً فلا يمكننا فحص نوع الملف لتأكد من نوعه

وبالتالي فالحل الوحيد هو أن نحاول أولا تشغيل الملف بكائن الفيديو

فإن ظهر لنا خطأ فنحاول نشغلة بكائن الصوت , وأن ظهر لنا خطأ للمرة الثانية فالملف غير صالح

قد يسأل البعض لماذا بدأنا بتجربة كائن الفيديو مع أن معظم الملفات ستكوت صوت

والإجابة أن كائن الصوت ممكن أن يشغل ملفات فيديو بدون صورة , يعني انه يفتح ملف الفيديو

ويشغل الصوت الذي فيه , وبالتالي فربما يكون الملف فيديو ويتم تشغيله كملف صوت

لذلك يجب أولاً تجربة كائن الفيديو حتى إذا كان ملف فيديو يشغل الصوت مع الصورة

وإذا كان ملف صوت نجرب كائن الصوت ..

لعمل ذلك نحتاج إلى تنفيذ جملة تعقب الإخطاء try مرتين متداخلتين:

try
 {
 //شغل ملف الفيديو
 }
 catch
 {
	 try
	   {
	   //شغل ملف الصوت
	  }
	  catch
	   {
 		//الملف غير صالح
		 }
 }

أولا سنجرب فتح ملف فيديو فإذا حدث خطأ فإن المترجم ينتقل لتنفيذ التعليمات داخل جملة catch

والتي هي باللون الأزرق , وهناك جملة tryأخرى نقوم من خلالها بتجربة فتح ملف صوت

فإذا حدث أي خطأ فان المترجم ينتقل لتنفيذ تعليمات catch التي تحتها خط

في زر فتح ملف الميديا أمسح الكود السابق وأكتب بدلاً عنه :

			 OF.ShowDialog();
			 try
			 {
				 vp = Video.FromFile(OF.FileName);
				 vp.Owner = p1;
				 p1.Width = 400;
				 p1.Height = 300;
			 }
			 catch
			 {
				 try
				 {
				 ap = Audio.FromFile(OF.FileName);
				 }
				 catch
				 {
				 MessageBox.Show("الرجاء إختيار ملف صالح");
				 }			

			 }

التعليمة OF.ShowDialog تفتح نافذة فتح ملف ميديا

عند إختيار الملف نجرب تشغيل الفيديو عبر هذه التعليمات:

vp = Video.FromFile(OF.FileName);
  vp.Owner = p1;
  p1.Width = 400;
  p1.Height = 300;

في السطر الأول نحمل الملف الموجود في كائن فتح الملف إلى كائن الفيديو

في السطر الثاني نحدد الكائن الحاضن Owner لكائن الفيديو

في السطر الثالث والرابع , نعيد تحديد حجم الكائن الحاضن إلى الحجم الأصلي

لأن ملفات الفيديو لها أحجام مختلفة وحجم الكائن الحاضن قد يختلف على حسب حجم الصورة

في ملف الفيديو لذلك من الأفضل إعادة تحجيم الكائن الحاضن

عند حدوث أي خطأ سينتقل المترجم لتنفيذ الكود باللون الأزرق وتعليمة تحميل ملف الصوت إلى كائن الصوت:

ap = Audio.FromFile(OF.FileName);

عند حدوث خطأ آخر هنا سينتقل المترجم إلى تنفيذ تعليمة catch الداخلية وهي إظهار رسالة الخطأ

سنستخدم نفس الطريقة في إجراء الضغط على زر تشغيل ملف الميديا

إفتح التصميم وأضغط علية مزدوجاً للإنتقال للشفرة أمسح الشفرة الموجودة وأكتب بدلاً منها:

			 try
			 {
			 vp.Play();
			 }
			 catch
			 {
				 try
				 {
				 ap.Play();
				 }
				 catch
				 {
 				MessageBox.Show("حدث خطأ اثناء محاولة تشغيل الملف");
				 }
			 }

نجرب تشغيل ملف الفيديو وإذا حدث خطا نجرب تشغيل ملف الصوت وإذا حدث خطأ آخر نظهر رسالة.

افتح التصميم واضغط مزدوجاً على زر ملئ الشاشة وأكتب تعليمة ملئ الشاشة لكائن الفيديو:

vp.Fullscreen = true;

كائن الفيديو يحتوي على صفة Fullscreen من نوع قيمة بوليانية اما صح أو خطأ

فإذا حددنا الصفة بقية true فأن تشغيل الفيديو سيكون ملى الشاشة

و إذا حددناها false سيرجع تشغيل الفيديو إلى الكائن الحاضن

عرفنا كيف نجعل التشغيل ملئ الشاشة لكن المشكل كيف نرجعه للكائن الحاضن

لأنه في وضع ملى الشاشة لن نستطيع أن نرى أي شيئ في شاشة الكمبويتر سوى الفيديو

يأتي هنا دور حدث الضغط على أي من مفاتيح لوحة المفاتيح حيث سنجعل الفيديو

يرجع إلى الكائن الحاضن بمجرد الضغط على أي من مفاتيح لوحة المفاتيح

إفتح التصميم وإختر النافذة الأساسية "لا تختر أي زر أو كائن تأكد من إختيار النافذه كلها"

إذهب إلى قائمة الإحداث وأضغط مزردوجاً على الحدث KeyPress

image5-6.jpg

ستنتقل إلى شفرة الحدث , أكتب تعليمة إعادة صورة الفيديو إلى الكائن الحاضن :

vp.Fullscreen = false;

هناك مشكلة ستواجهنا هنا وهي في حالة إذا كان تركيز لوحة المفاتيح على زر محدد

فلن ينطلق حدث الضغط على النافذة , سينطلق الحدث على الزر المحدد فقط

والشفرة السابقة على النافذه الأساسية ,,,

الحل أن هناك صفة في النافذة تمكنها من إطلاق الحدث حتى ولو حصل في أي كائن من الكائنات

هذه الخاصية هي KeyPreview عدلها من False إلى True لتصبح كما في الصورة

image5-7.jpg

الآن شغل البرنامج وجرب تشغيل ملف صوت أو فيديو او ملف نصي

تلميحات الأدوات

أحيانا تحتاج إلى إظهار ملا حظة بسيطة للمستخدم عن وظيفة زر في التطبيق مثلاً

وتظهر هذا الملاحظات في مستطيل أصفر يظهر بمجرد مرور الماوس من فوق الزر

مثلاً لو تمرر الماوس فوق زر Start في شريط المهام ستظهر هذه الملاحظة

Click here to begin

لعمل مثل هذه الملاحظات في تطبيقنا نحتاج لإضافة كائن جديد

افتح التصميم واسحب كائن تلميحات الأدوات ToolTip

image5-8.jpg

الآن في أي كائن تختارة ستجد صفة جديدة إسمها ToolTip on toolTip1

أكتب فيها أي تلميح نصي للكائن :

image5-9.jpg

عند تشغيل البرنامج وتمرير الماوس من فوق الزر ستظهر الملاحظة هكذا:

image5-10.jpg

الواجب

أرسل التطبيق.

.نهاية الدرس الخامس.

..

7oma

حماة النهضة

إعذرونا , سنضطر للغياب فترة كبيرة

الأمر ليس بيدنا ...... فسامحونا

#31

معتز شمس

أهلا بك مشرفنا العزيز

نورت موضوعنا بإطلالتك العطرة

أشكرك كثيراً على الشرح المفصل للأخ Pro_S00

وعندك حق المفروض نراقب إستخدام جملة try

وإن كان إستخدامنا لها هنا هو من باب التبسيط على المبتدئ لا غير

كما أن بعض ملفات الصوتيات قد لا تحتوي على إمتداد نتيجة خطأ في التسمية

لكنها تظل ملفات صوتيه يمكن تشغيلها بالبرنامج

بعد إذنك أخي , ممكن أضيف تعديل بسيط جداً على كودك وهو إضافة العبارة ToLower بعد إمتداد الملف

حتى لا يتأثر البرنامج بحالة أحرف الإمتداد كبيرة أم صغيرة , فتصبح جملة الشرط هكذا :

if (selectedFileInfo.Extension.ToLower() == ".wav" || selectedFileInfo.Extension.ToLower() == ".mp3")

كما أود أن أنبه مشرفنا العزيز إلى أن كوده يحتوي على خطأ إملائي بسيط

إسم كائن OpenFileDialog هو OF وليس FO

شرفتنا بزيارتك اخي العزيز وبارك الله فيك

..

7oma

حماة النهضة

إعذرونا , سنضطر للغياب فترة كبيرة

الأمر ليس بيدنا ...... فسامحونا

#32

السلام عليكم ورحمه الله وبركاته

هذا هو الواجب اخى وأرجو أن يكون كما طلب منا

ولكن الجزء الأخير من الدرس السابق الخاص بال Full Screen لم أفهمه جيدا أنا فعلت كما قلت ولكنى لم أضع له زرار لأنى لم أفهم ما سوف يوضع من كود داخل هذا الزرار فأرجو الأفادة وهذا هو الواجب بدون هذا الزرار

MyMediaPlayer5.rar

#33

وعليكم السلام ورحمة الله وبركاته

عمرو الحمصى

اقتباس
هذا هو الواجب اخى وأرجو أن يكون كما طلب منا

الفيديو لا يظهر !! في خصائص الفورم هناك خاصية إسمها TransparencyKey

صفّر قيمتها بالنقر على اللون المختار ثم مفتاح Delete

اقتباس
ولكن الجزء الأخير من الدرس السابق الخاص بال Full Screen لم أفهمه جيدا أنا فعلت كما قلت ولكنى لم أضع له زرار لأنى لم أفهم ما سوف يوضع من كود داخل هذا الزرار فأرجو الأفادة وهذا هو الواجب بدون هذا الزرار

الكود في زر ملئ الشاشة هو السطر التالي :

 vp.Fullscreen = true;

..

7oma

حماة النهضة

إعذرونا , سنضطر للغياب فترة كبيرة

الأمر ليس بيدنا ...... فسامحونا

#34

الواجب الخامس بالمرفقات

ويعطيك العافيه على الشرح الجميل

WindowsApplication12.rar

#36

السلام عليكم ورحمة الله وبركاته

Pro_S00 , عمرو الحمصى

تطبيقاتكما صحيحة

ربنا يوفقكم

..

7oma

حماة النهضة

إعذرونا , سنضطر للغياب فترة كبيرة

الأمر ليس بيدنا ...... فسامحونا

#37

الدرس السادس

تشغيل ملفات الريل بلاير Playing RM Files

سنستخدم في هذا الدرس الإجراءات كثيراً , ولمزيد من التوضيح عنها أرجع إلى الدرس الرابع

تقنية rm تم تصميمها بواسطة شركة .Real Networks Inc حيث أن لهذه التقنية

مزايا كثيرة من أهمها حجم الملفات الصغير الذي يتيح تداول الملفات عبر الوب بسهولة

في الدروس السابقة تعاملنا مع ملفات الميديا بأي تقنية ما عدا هذه التقنية

ولأن هذه التقنية تختلف تماماً عن التقنيات الأخرى خصصنا لها هذا الدرس.

لتشغيل ملفات rm نحتاج لملفات dll تحتوي على دوال تشغيل rm

الملفات موجودة للتحميل من هنا

وهي من شركة Real تم تحويرة قليلاً ليتعامل مع بيئة الدوت نت

في التطبيق سنجد إختلاف بين أوامر rm والأوامر الأخرى لأن شركة Real تحتكر هذه التقنية

ولا تقبل بتوزيعها على الشركات الأخرى لذلك فميكروسوفت لا تدعم تشغيل ملفات rm

فمثلاً كما رأينا في الدرس السابق فان أمر تشغيل ملف صوت أو فيديو عادي هو:

Play();

أما لتشغيل ملف rm فيكون الأمر هكذا

DoPlay();

هذه مقارنه بسيطة بين أوامر ميكروسوفت وأوامر Real

AVI----------------Real 
 1-FromFile---------SetSource 
 2-Play-------------DoPlay
  3-Stop-------------DoStop
  4-Pause------------DoPause 
 5-Duration---------GetLength 
 6-CurrentPosition----GetPosition/SetPosition

الأمر الأول يستخدم لتحميل الملف

الأمر رقم 2 يستخدم لتشغيل الملف

الأمر 3 لإيقاف تشغيل الملف نهائياً

الأمر 4 لإيقاف تشغيل الملف مؤقتاً

الأمر 5 لإيجاد طول الملف بالثواني

الأمر 6 لإيجاد مكان التشغيل , أي إيجاد الموقع في الملف الذي يتم تشغيله

مثلاً إذا أنتجت الدالة 60 معنى ذلك أنه يتم الآن تشغيل الثانية رقم 60 من الملف

في أوامر Real هناك أمرين أحدهما لقرائة الموقع والآخر لضبط الموقع

أما في أوامر ميكروسوفت فالقراءة والضبط تستخدم نفس الأمر

سنستخدم في هذا الدرس جميع الأوامر السابقة

يتبع التطبيق في الرد التالي

إعذرونا , سنضطر للغياب فترة كبيرة

الأمر ليس بيدنا ...... فسامحونا

#38

التطبيق

إفتح تطبيق الدرس السابق

أضف الملف AxInterop.RealAudioObjects.dll الذي قمت بتحميلة إلى المراجع References كما فعلنا في الدرس الرابع

سنضيف في هذا التطبيق كائن عام جديد من نوع مشغل rm

وليكون إسم هذا الكائن rp إختصار لـ Real Player

سنقوم بتعريف هذا الكائن تحت تعريفات كائنات الصوت والصورة في الدرس السابق هكذا:

   private AxRealAudioObjects.AxRealAudio rp=new AxRealAudioObjects.AxRealAudio();

لاحظ أن كود تعريف الكائن يختلف قليلاً عن تعريف كائنات ميكروسوفت

بعد تعريف كائن مشغل rm أصبح لدينا ثلاثة كائنات رئيسية

مشغل صوت و مشغل فيديو ومشغل rm وعند فتح ملف جديد

سنبدأ بإختبار هل هو ملف فيديو ثم هل هو ملف صوت ثم هل هوملف rm

وبالتالي سنستخدم جملة try ثلاث مرات متداخلة عند فتح الملف وعند تشغيل الملف

وعند إيقاف تشغيل الملف أو عند تقديم أو تأخير المف ..

وإذا أردنا أختصار الكود لنستخدم جملة try المتداخلة فقط عند فتح الملف

سنستخدمها فقط عند فتح "تحميل الملف" ومنها سنعرف نوع المف , ونقوم بخزن نوع المف

في متغير عام من نوع نص , وعند تشغيل الملف بدلاً من إستخدام try المتداخله كما فعلنا في الدرس السابق

سنفحص نوع الملف من خلال المتغير من نوع نص الذي خزنا فيه نوع الملف عند الفتح

دون إستخدام جملة try وذلك سيسهل كثيرا ويسرع عملية تشغيل الملف والتعامل معه

إذاً سنعرف متغير عام من نوع نص لخزن نوع الملف وليكون إسمه type

نعرف هذا المتغير تحت تعريفات كائن الصوت والفيديو و مشغل rm هكذا:

private string type;

بحيث تصبح المتغيرات العامة هكذا :

image6-1.jpg

اذهب إلى التصميم

أضف للنافذة الأساسية زرين زر للإيقاف و زر للإيقاف المؤقت

إذهب إلى كرد البرنامج ..

سنقوم بكتابة إجراء مستقل لتحميل ملف الميديا إلى أحد الكائنات الثلاثة

إجراء تحميل الملف

وهذه الإجراء سيكون مستقله لكي نستطيع إستخدامه في أكثر من مكان

لنسمي هذه الإجراء LoadFile وستكون وظيفته إختبار نوع الملف ثم ضبط قيمة المتغير type

ليحمل حرف يرمز إلى نوع الملف و ايضاً هذالإجراء ستقوم بتحميل الملف للكائن المناسب من الكائنات الثلاثة

الأحرف التي سيحملها المتغير type هي A إذا كان ملف صوت و V إذا كان ملف فيديو وR إذا كان ملف rm

أي أن الإجراء سيفحص نوع الملف فإذا كان ملف صوت سيحمل type الحرف A ويحمل الملف إلى كائن الصوت ap

أما إذا كان فيديو فيحمل type الحرف V ويحمل الملف لكائن الفيديو vp

أما إذا كان الملف rm فيحمل type الحرف R ويحمل الملف لكائن الريل rp

فحص نوع الملف سيكون بنفس الطريقة في الدرس السابق ولكنا سنستخدم try ثلاث مرات متداخلة

أنسخ هذا الكود إلى الشفرة وتأكد أن يكون هذا الكود خارج أي دالة أخرى:

void LoadFile(string Path)
   {
		   StopFile();
		   ap=null;//تصفير الصوت
		   vp=null;//تصفير الفيديو
		   this.Controls.Add(rp);//تصفير الريل
				   rp.Visible=false;//أخفاء مظهر الريل
		   try
				   {
   				vp = Video.FromFile(Path);
				   vp.Owner = this.panel1;
				   panel1.Width = 400;
				   panel1.Height = 300;
				   type="V";
				   }
				   catch
				   {
						try
						{
						ap = Audio.FromFile(Path);
						type="A";
						}
						catch
						{
						   try
						   {
						   rp.SetSource(Path);	
						   type="R";
						   }
						   catch
						   {
   							MessageBox.Show("الرجاء إختيار ملف صالح");
							   type="N";
						   }		
						}

				   }
   }

الكود السابق يمثل إجراء فحص الملف وتحملية إلى أحد الكائنات

الإجراء هو جزء من الشفرة يمكن إستخدامه أكثر من مرة من خلال إستدعائه بإسمه فقط

وبما أنه إجراء مستقلة يجب ان تكون خارج أي إجراء أخر:

image6-2.jpg

الإجراء يتكون من مدخل واحد Path من نوع نص ويمثل مسار الملف الذي سيتم تحميلة

أي أننا عندما نستدعي الإجراء سنكتب إسمه ونعطيه مدخل من نوع نص مثلاً:

LoadFile("C://s.mp3");

الكود السابق سيقوم بإستدعاء الإجراء و الإجراء سيقوم بفحص وتحميل الملف s.mp3 الموجود في القرص c

ملاحظة: في لغة السي شارب يعتبر حرف \ حرفاً غير مسموح به

لذلك عند كتابة مسار الملف يتم إستبدالة بـ //

في السطر الأول من الإجراء تعلمية StopFile وهي إستدعاء لإجراء أخر سنشرحه فيما بعد

يقوم إجراء StopFile بإيقاف تشغيل أي ملف لكي يتم تحميل ملف جديد بدلاً منه وإذا لم نوقف تشغيل

الملف السابق وقمنا بتحميل ملف آخر سيحدث تداخل في الملفات ويتم تشغيل أكثر من ملف في آن واحد

في السطور 2 و3 و4 و5 كما هو مشروح في الكود يتم تصفير الكائنات

ومعنى التصفير هو إلغاء تحميل الملفات السابقة لكي يتم تحميل ملفات جديدة

بعدها جملة try الأولى تقوم بتحميل كائن الفيديو الملف المدخل من خلال المتغير Path

فإذا تم التحميل بنجاح فإن التعليمة type="V" تقوم بتحميل الحرف V إلى المتغير type

دلالة على أن نوع الملف هو فيديو , أما إذا حدث إي خطأ في التحميل فسوف يقفز المعالج إلى تنفيذ الكود باللون الأخظر

ويتم فيها تحميل الملف لكائن الصوت فإذا تم التحميل بنجاح يتم تحميل المتغير type الحرف A

دلالة على أن نوع الملف هو صوت , أما إذا حدث خطأ في التحميل فالمعالج سيقفز إلى تنفيذ الكود باللون الأحر

ويتم فيه تحميل الملف إلى كائن rm "لاحظ الأختلاف في الأمر عن أوامر الصوت والفيديو"

فإذا تم التحميل بنجاح يتم تحميل المتغير type الحرف R دلالة على أن نوع الملف هو ريل

وإذا حدث خطأ في التحميل يقفز المعالج لتنفيذ الكود باللون البرتقالي حيث يظهر رسالة خطأ

ويحمل المتغير الحرف N دلالة على أن نوع الملف غير معروف .

إجراء تشغيل الملف

سنقوم بكتابة إجراء مستقل أخر لتشغيل الملف , إجراء التشغيل سيكون أسهل بكثير من إجراء تحميل الملف

لان لدينا نوع الملف مخزن في المتغير type ولن نقوم بفحص نوع الملف مرة أخرى

حيث سنقوم بإستخدام تعليمة if لنعرف الحرف الموجود في type ومن خلالة نعرف نوع الملف فنشغل الكائن المطلوب

لنسمي هذا الإجراء PlayFile ولن تكون لهذا الإجراء أي مدخلات

أنسخ هذا الكود إلى الشفرة وتأكد أن يكون خارج أي إجراء أخر :

		   void PlayFile()
		   {
			   if(type=="V")
			   {
			   vp.Play();
			   }
			   else if(type=="A")
			   {
				ap.Play();	
			   }
			   else if(type=="R")
			   {
			   rp.DoPlay();
			   }
		   }

في المقارنة الأولى إذا كان المتغير يحمل الحرف V فهذا يعني أن نوع الملف هو فيديو كما في إجراء التحميل

ولذلك سيتم تشغيل كائن الفيديو vp , إما إذا لم يكن V فينتقل المعالج للمقارنة الثانية وإلا للثالثة

إجراء الإيقاف المؤقت

في هذا الإجراء أيضاً سنستفيد من محتويات المتغير type لتحديد نوع الملف والتعامل مع الكائن المحدد

أنسخ هذا الكود إلى الشفرة وتأكد أن يكون خارج أي إجراء أخر :

		   void PauseFile()
		   {
			   if (type=="V")
			   {
			   vp.Pause();
			   }
			   else if (type=="A")
			   {
				ap.Pause();	
			   }
			   else if (type=="R")
			   {
			   rp.DoPause();
			   }
		   }

لا أظن أنها تحتاج إلى شرح..

إجراء إيقاف التشغيل

أنسخ هذا الكود إلى الشفرة وتأكد أن يكون خارج أي إجراء أخر:

		void StopFile()
		   {
		   if (type=="V")
			   {
			   vp.Stop();
			   }
			   else if (type=="A")
			   {
				ap.Stop();	
			   }
			   else if (type=="R")
			   {
			   rp.DoStop();
			   }	
		   }

هذا هو الإجراء الذي إستدعيناه في إجراء تحميل الملف

لو قمت بتشغيل البرنامج الآن لن يتم تشغيل أي إجراء لأننا لم نستدعي أي منها

إفتح التصميم وإضغط مزدوجاً على زر فتح ملف ميديا , إمسح الكود السابق وأكتب بدلاً عنه:

OF.ShowDialog();
	LoadFile(OF.FileName);
	PlayFile();

في السطر الأول إستدعينا نافذة فتح الملف

في السطر الثاني إستدعينا إجراء تحميل الملف و حملنا المدخل بناتج كائن فتح الملف

أي أنه في شفرة إجراء التحميل ستكون قيمة المدخل Path هي قيمة OF.FileName

بعد إستدعاء إجراء تحميل الملف استدعينا إجراء تشغيل الملف , أي أنه سيتم تشغيل الملف بمجرد إختياره

إذهب إلى التصميم مجددا واضغط مزدوجاً على زر التشغيل, أمسح الكود السابق وأكتب بدلاً عنه:

PlayFile();

إستدعاء لإجراء التشغيل لا غير

نلاحظ كيف أستدعينا إجراء التشغيل في زر فتح الملف وفي زر التشغيل

اذهب للتصميم واضغط مزدوجاً على زر الإيقاف المؤقت وأكتب فيه هذا الكود:

PauseFile();

اذهب الي التصميم واضغط مزدوجاً على زر الإيقاف وأكتب هذا الكود:

StopFile();

نستطيع الآن أن نقول أن التطبيق يشغل جميع أنواع الملفات

ملاحظة:

عند أستيراد ملف دوال الريل بلاير AxInterop.RealAudioObjects.dll

تقوم بيئة التطوير بإنشاء الملف الآخر كربط بين التطبيق والملف

حيث يتكون الملف Interop.RealAudioObjects.dll

بجانب التطبيق بمجرد تشغيل التطبيق من بيئة التطوير

وهذا الملف ضروري لأنه يعمل كوسيط بين التطبيق وملف دوال الريل

إذا لم تستطيع البيئة تكوين هذا الملف لسبب أو لآخر

يجب ان يوضع بجانب التطبيق

أي أن ملفات dll التي يحتاجها التطبيق أصبحت أربعة ملفات مع ملفات الدروس السابقة

الواجب

أرسل التطبيق..

.نهاية الدرس السادس.

..

7oma

حماة النهضة

إعذرونا , سنضطر للغياب فترة كبيرة

الأمر ليس بيدنا ...... فسامحونا

#40

السلام عليكم ورحمة الله وبركاته

الدرس السابع

التنقل في الملف

ملف الصوت أو الفيديو يحتوي على خاصية طول الملف أي أن كل ملف له طول زمني

ويتم قياس الطول في مشغلات ميكروسوفت بالثانية , وفي مشغلات rm بالملي ثانية

يتم إيجاد طول الملف من خلال الخاصية Duration في مشغلات ميكروسوفت

أو الخاصية GetLength في مشغلات rm

مثلا التعليمة التالية :

ap.Duration;

ستنتج رقم يحدد طول الملف بالثواني مثلاُ إذا أنتجت رقم 100 يعني هذا أن طول الملف 100 ثانية

أم التعليمة التالية:

rp.GetLength();

فهي تنتج رقم يحدد طول الملف بالملي ثانية مثلاً إذا أنتجت 50000 يعني أن طول الملف 50 ثانية

إذاً هناك فرق كبير بين قيمة طول الملف في مشغلات ميكروسوفت ومشغلات rm

من أهم الوظائف لأي مشغل ميديا هو إمكانية التنقل عبر الملف سوءاً تقديماً أو تأخيراً

ويتم التنقل عبر الملف من خلال تعديل خاصية من خصائص كائن التشغيل

الخاصية ترجع قيمة تحتوي على رقم يمثل موقع التشغيل الحالي

مثلاً إذا أرجعت الخاصية الرقم 50 في مشغل ميكروسوفت فهذا يعني أن تشغيل الملف وصل إلى الثانية رقم 50

أما إذا أرجعت 40000 في مشغلات rm فهذا يعني أن تشغيل الملف وصل إلى الثانية رقم 40

الخاصية في مشغلات ميكروسوفت هي CurrentPosition سواءاً لقراءة القمية أو لتعديلها

فمثلاً التعليمة التالية:

ap.CurrentPosition;

ترجع رقم يمثل رقم الثانية الذي وصل إليها التشغيل , فمثلاً لو كان طول الملف 100 ثانية

وأرجعت الرقم 50 فهذا يعني أن تشغيل الملف وصل إلى المنتصف

أما التعليمة التالية:

ap.CurrentPosition=60;

هذه التعليمة تقوم بنقل التشغيل إلى الثانية رقم 60 , أي أن التشغيل يقفز من موقعه إلى الثانية رقم 60

وفي مشغلات rm هي GetPosition لقراءة القمية أو SetPosition لتعديل القيمة

فمثلاً التعليمة :

rp.GetPosition();

ترجع رقم يمثل رقم الملي ثانية الذي وصل إليها التشغيل فمثلاُ إذا كان طول الملف 10000 ملي ثانية

وأرجعت الرقم 5000 فهذا يعني أن التشغيل وصل إلى الثانية رقم 5 اي إلى منتصف الملف

أما التعليمة التالية:

rp.SetPosition(60000);

هذه التعليمة تقوم بنقل التشغيل إلى الثانية رقم 60 , لاحظ أن جميع تعاملات مشغل rm تكون بالملي ثانية

وليست بالثانية كما في مشغلات ميكروسوفت , والثانية الواحد = 1000 ملي ثانية

إذاً التنقل عبر الملف يتم من خلال تعديل خاصية موقع التشغيل

الموقت Timer

المؤقت هو عبارة عن كائن لضبط الوقت , ويستخدم لتكرار حدث معين خلال فترة زمنية محددة

مثلاً إظهار رسالة كل 50 ثانية , أو تنفيذ كود معين كل 10 ثوان

image7-1.jpg

يتم تحديد طول الفترة الزمنية من خلال تعديل الخاصية "الصفة" Interval

حيث أن هذه الخاصية تأخذ الزمن بالملي ثانية أي أنه إذا أردنا أن تكون الفتره ثانية واحدة

فإن الخاصية Interval يجب ان تكون قيمتها 1000 , وإذا أردنا ثانيتين تكون 2000

ويتم كتابة الكود المراد تنفيذه من خلال الضغط مزدوجاً على المؤقت

في هذا الدرس سنستخدم الموقت ليفحص موقع تشغيل الملف كل ثانية

التطبيق في الرد التالي :

..

إعذرونا , سنضطر للغياب فترة كبيرة

الأمر ليس بيدنا ...... فسامحونا

#41

التطبيق

إفتح تطبيق الدرس السابق , وأضف زرين للتقديم والتأخير

أضف مؤقت Timer , ستلاحظ انه سيضاف إلى الشريط الأصفر تحت نافذة التصميم

image7-3.jpg

إختر المؤقت وقم بتعديل خاصية Interval إلى 1000 ,"ثانية واحدة"

وعدل قيمة الخاصية Enabled إلى True , هذه الخاصية تقوم بتشغيل أو تعطيل عمل الموقت

فإذا كانت القمية True فالمؤقت مفعل , أما إذا كانت False فهو معطل ولن يعمل

image7-4.jpg

أضف كائن التنقل TrackBar ليستخدم كأداة تنقل عبر الملف

image7-2.jpg

إختر كائن التنقل و عدل الخاصية TickFrequency إلى 0 لكي تختفي خطول القياس

وعدل الخاصية TickStyle إلى Both إذا أردت

image7-5.jpg

كائن التنقل يرجع قيمة بين الخاصيتين Minimum و Maximum

فمثلاً إذا كان Minimum = 0 و Maximum=50 فإن الخاصية Value سترجع قيمة بين 0 و 50

تمثل مكان المؤشر بالنسبة للكائن فمثلاً إذا كان المؤشر في منتصف الكائن فإن Value سترجع الرقم 25

وبما اننا نحتاج للتنقل عبر الملف فالمفروض أن نعدل الخاصية Minimum إلى 0

ونعدل الخاصية Maximum إلى طول الملف حتى ترجع القمية Value رقم بين 0 وطول الملف

وبما أن طول كل ملف يختلف عن الملف الآخر , فإننا سنعدل الخاصية Maximum عند تحميل أي ملف

ولن نحتاج لتعديل الخاصية Minimum لأن قيمتها الإفتراضية هي 0

سيصبح شكل النافذه هكذا:

image7-6.jpg

إجراء ضبط كائن التنقل

إنقل هذا الكود إلى شفرة البرنامج مع مراعات أن يكون خارج أي إجراء آخر

 void SetTrackBar()
  {
  if (type=="V") 
 {
  trackBar1.Maximum=Convert.ToInt32(vp.Duration);
  }
  else if (type=="A")
  {
  trackBar1.Maximum=Convert.ToInt32(ap.Duration);
  }
  else if (type=="R")
  {
  trackBar1.Maximum=Convert.ToInt32(rp.GetLength()); 
 }
 }

إسم الإجراء هو SetTrackBar ونقوم فيه بفحص نوع الملف كما شرحنا في الدرس السابق

فإذا كان نوع الملف صوت أو فيديو فإنا نأخذ طول الملف عبر الخاصية Duration

ثم نحول الرقم إلى عدد صحيح عبر كائن التحويل Convert.ToInt32

والرقم الناتج نحملة لخاصية Maximum في كائن التنقل , وبهذا مهما تنقلنا في الكائن فأن القيمة الناتجة ستكون بين 0 و طول الملف

إما إذا كان نوع الملف rm فإنا نأخذ طول الملف عبر الخاصية GetLength ونحول الرقم إلى عدد صحيح ونحمله للخاصية Maximum

ذلك هو إجراء ضبط القيمة العظمى لكائن التنقل ,لكن أين نستدعي هذا الإجراء ؟؟؟

أفضل مكان لإستدعاء هذا الإجراء هو بعد تحميل الملف أي بعد إستدعاء إجراء التحميل LoadFile

إفتح كود زر فتح الملف وأضف تعليمة الإستدعاء بعد تعليمة إستدعاء إجراء تحميل الملف:

OF.ShowDialog();
  LoadFile(OF.FileName);
  SetTrackBar();
  PlayFile();

اللون الأزرق يمثل الزيادة التي أضفناها إلى الشفرة.

بعد أن قمنا بضبط القمية العظمى لكائن التنقل نحتاج لكود التنقل عبر الملف

إي أننا نحتاج لكود يقوم بالتنقل عبر الملف بمجرد تغيير مؤشر كائن التنقل

إضغط مزدوجا على كائن التنقل لتنتقل إلى الكود الذي يتنفذ بمجرد تغيير المؤشر TrackBar1Scroll

إنسخ الكود التالي :

if (type=="V") 
 {
  vp.CurrentPosition=trackBar1.Value;
  } 
 else if (type=="A") 
 {
  ap.CurrentPosition=trackBar1.Value; 
 }
  else if (type=="R")
  {
  rp.SetPosition(trackBar1.Value);
 }

عند تغيير مؤشر كائن التغيير سيقوم المعالج بتنفيذ الكود السابق

trackBar1.Value ترجع رقم بين 0 و طول الملف على حسب موقع المؤشر

حيث نقوم بفحص نوع الملف فإذا كان فيديو أو صوت نعدل موقع التشغيل عبر الخاصية CurrenPosition

أما إذا كان rm فنعدل موقع التشغيل عبر الخاصية SetPosition.

الآن نحتاج إلى كود لتحريك مؤشر كائن التنقل ليحدد الموقع الذي وصل إليه التشغيل

لعمل ذلك نحتاج لإستخدام المؤقت حيث نقوم كل ثانية بفحص موقع التشغيل ونعدل موقع المؤشر

إضغط مزدوجاً على كائن المؤقت لتنتقل إلى الكود الذي ينفذ كل ثانية وأنسخ الكود التالي :

 if (type=="V")
  {
  trackBar1.Value=Convert.ToInt32(vp.CurrentPosition);
  }
  else if (type=="A")
  { 
 trackBar1.Value= Convert.ToInt32(ap.CurrentPosition);
  }
  else if (type=="R") 
 {
  trackBar1.Value=Convert.ToInt32(rp.GetPosition()); 
 }

الكود السابق سينفذ كل ثانية لإننا حددنا خاصية Interval في المؤقت إلى 1000

يقم الكود السابق بفحص نوع الملف فإذا كان صوت أو فيديو نقوم بأخذ موقع التشغيل الحالي

عبر الخاصية CurrentPosition ونحولها إلى عدد صحيح ونحمل الرقم الناتج إلى الخاصية Value

حيث أن الخاصية Value تمثل موقع مؤشر كائن التنقل .

وإذا كان الملف rm نأخذ طول الملف عبر الخاصية GetPosition ونحولها إلى عدد صحيح

ونحملها في خاصية موقع المؤشر Value

الكود السابق يقوم بتغيير موقع مؤشر كائن التنقل على حسب موقع التشغيل الذي وصل إليه الملف.

بقي لنا كود زري التقديم والتأخير ..

إضغط مزدوجاً على زر التقديم وأنقل الكود التالي :

 if (type=="V") 
 {
  vp.CurrentPosition=vp.CurrentPosition+20;
  }
  else if (type=="A") 
 { 
 ap.CurrentPosition=ap.CurrentPosition+20;
  }
  else if (type=="R")
  {
  rp.SetPosition(rp.GetPosition()+20000); 
 }

في الكود السايق نقوم بتعديل موقع التشغيل ليكون موقع التشغيل الحالي + 20 ثانية

أي أننا إذا ضغطنا على زر التقديم فان التشغيل سيقفز 20 ثانية إلى الأمام

يمكن وضع عدد أكبر من العشرين ثانية إذا أردت أو أصغر ..

لاحظ أنه إذا كان نوع الملف rm فإننا إضفنا إلى الموقع الحالي 20000 لأن مشغل rm يتعامل بالملي ثانية

شغل البرنامج وإفتح ملف ميديا وجرب تحريك مؤشر كائن التنقل.

الواجب

* أكتب كود زر التأخير ..

* قد يحدث خطأ في زري التقديم والتأخير إذا تم التأخير لأقل من صفر أو التقديم لأكثر من طول الملف

لذلك يجب وضع كود الزرين داخل جملة try هكذا:

try
 {
 //كود التقديم أو التأخير
 }
 catch
 {
 }

عند حدوث خطأ لن يتم تنفيذ أي شيئ.

* أرسل التطبيق.

ملاحظات:

* تأكد من إتجاه مؤشر كائن التنقل من خلال الخاصية RightToLeft.

* لجعل خلفية الزر شفافة عدل خاصية FlatStyle إلى Popup

و خاصية BackColor إلى Transparent

image7-7.jpg

* يمكن تغيير الصور في الأزرار بواسطة الخاصية Image.

* يمكن تعديل لون خلفية الكائن الحاضن للفيديو إلى شفاف لتصبح كما في الصورة .

image7-8.jpg

* للأسف ليست كل الكائنات تدعم الخلفية الشفافة , فكائن التنقل مثلاً لا يدعمها ..

ملاحظة لمستخدمي بيئة Sharp Developer:

إحياناً عند الضغط المزدوج على المؤقت يحصل خطأ وتغلق بيئة التطوير

ولكتابة كود المؤقت إذا حدث هذا الخطأ دون الضغط مزدوجاً على المؤقت:

افتح شفرة التصميم من خلال فتح مستعرض الملفات ثم فتح MainForm.Designer.cs

و ابحث عن كود تعريف المؤقت وأضف بعده هذا السطر:

this.timer1.Tick+=new System.EventHandler(this.Timer1Tick);

كما في الصورة :

image7-9.jpg

ثم إفتح شفرة البرنامج عند الإجراءات من خلال إختيار MainForm.cs

وأضف هذا الإجراء وتأكد أنه خارج أي إجراء:

 void Timer1Tick(object sender, System.EventArgs e)
  {
  if (type=="V") 
 {
  trackBar1.Value=Convert.ToInt32(vp.CurrentPosition); 
 }
  else if (type=="A")
  { 
 trackBar1.Value= Convert.ToInt32(ap.CurrentPosition); 
 }
  else if (type=="R") 
 {
  trackBar1.Value=Convert.ToInt32(rp.GetPosition()); 
 } 
 }

.نهاية الدرس السابع.

..

7oma

حماة النهضة

إعذرونا , سنضطر للغياب فترة كبيرة

الأمر ليس بيدنا ...... فسامحونا

#42

الدرس الثامن

المصفوفات:

المصفوفات هي عبارة عن مجموعة متغيرات من نفس النوع متراصة ومترابطة داخل كائن Array

ويتم الوصول لأي عنصر في هذه المجموعة من خلال ترتيبة في المجموعة Index

مثلاً : مصفوفة أيام الأسبوع تعتبر مجموعة متغيرات من نوع نص

و مصفوفة أيام الشهر تعتبر مجموعة متغيرات من نوع رقم ..

يتم تعريف المصفوفة بإحدى ثلاث طرق :

1-طريقة تعريف إسم المصفوفة فقط

التعريف بهذه الطريقة نادراً ما يستخدم , ويحدد فقط إسم لكائن المصفوفة بدون أن يقوم بإنشاءة:

string[] days;

الكود السابق يعرف إسم days لمصفوفة عناصرها من نوع نص

لاحظ القوسين المربعين بعد كلة string دلالة على أن days تمثل مصفوفة نصوص وليس نص

2-طريقة تعريف المصفوفة وتحديد عدد عناصرها

طريقة التعريف هذه تعرف و تنشئ كائن مصفوفة وتحدد عدد عناصر هذه المصفوفة:

string[] days= new string[7];

لأن المصفوفة هي كائن وجب علينا تعريفه بإستخدام عبارة new

والرقم 7 بين قوسي تعريف الكائن هو عدد عناصر المصفوفة

أي أن الكود السابق عرف مصفوفة إسمها days تحتوي على 7 عناصر من نوع نص

لكن هذه الطريقة لا تحمل قيم لعناصرها , أي أنها تحتوي على 7 نصوص فارغة

3-طريقة تعريف المصفوفة وتحميل قيم لعناصرها

هذه الطريقة تعرف وتنشئ كائن المصفوفة وتحمل قيم لجميع عناصر المصفوفة:

string[] days= new string[]{"السبت","الأحد","الإثنين","الثلاثاء","الأربعاء","الخميس","الجمعة"};

في الكود السابق قمنا بتعريف كائن المصفوفة وقمنا بتحميل القيم لجميع عناصره

بإدخالها كمجموعة نصوص بين حاصرتين تفصل بين كل نص وآخر علامة ,

لاحظ أنا لم نحدد عدد عناصر المصفوفة حيث سيقوم المعالج بتحديدها آلياً من خلال عد النصوص المدخلة بين الحاصرتين

ملاحظة : العناصر المدخلة بين حاصرتين يجب أن تكون من نفس نوع عناصر المصفوفة

الوصول إلى عناصر المصفوفة:

كما قلنا سابقاً يتم الوصول إلى عناصر المصفوفة من خلال ترتيب العنصر المراد الوصول إليه

والترتيب في المصفوفات يبدأ من الصفر , أي أن أول عنصر في المصفوفة ترتيبة صفر

فمثلاً في مصفوفة الأيام , يوم السبت ترتيبة صفر و الأحد ترتيبة 1 ... والجمعة ترتيبة 6

ويتم الوصول إلى العنصر المحدد بكتابة إسم المصفوفة الموجود بها متبوعا بقوسين مربعين بينهما ترتيب العنصر

ماذا لو أردنا إظهار رسالة تخبرنا بالعنصر الذي ترتيبة 4 في مصفوفة الأيام :

string[] days= new string[]{"السبت","الأحد","الإثنين","الثلاثاء","الأربعاء","الخميس","الجمعة"};
 MessageBox.Show(days[4]);

لاحظ كيف تم الوصول إلى العنصر الرابع في مصفوفة days من خلال العبارة days[4]

الكود السابق ينتج هذه الرسالة :

image8-1.jpg

يمكن أيضاً تعديل أي عنصر من عناصر المصفوفة من خلال ترتيبة في المصفوفة :

string[] days= new string[]{"السبت","الأحد","الإثنين","الثلاثاء","الأربعاء","الخميس","الجمعة"};
 days[4]="الأربعاء بعد التعديل";
 MessageBox.Show(days[4]);

في السطر الثاني غيرنا قيمة العنصر الذي ترتيبة 4 إلى "الأربعاء بعد التعديل"

الكود السابق ينتج الرسالة التالية :

image8-2.jpg

القوائم

مع أن المصفوفات تعتبر من أهم هياكل البيانات التي استخدمت في لغات البرمجه منذ نشأتها

إلا أن لها عدداً من العيوب التي سعت C#2005 لحلها من خلال إدخال نوع جديد من هياكل البيانات

اهم العيوب هو حجم المصفوفة الثابت , فعند تعريف مصفوفة وإسناد قيم لها أو تعريف حجمها

لن تستطيع أن تزيد من حجمها أو تنقص منه , وأيضاً لا توجد طريقة فعالة للبحث بين العناصر

مثلاً في مصفوفة أيام الأسبوع لا يوجد طريقة للبحث عن يوم السبت مثلاً إلى باستخدام دوارة تمر بجميع عناصر المصفوفة:

for(int i=0;i<days.Lehgth;i++)
 {
 if (days=="السبت")
 {
 MessageBox.Show("هذا يوم السبت");
 }
 }

هيكل البيانات الجديد الذي تفادى عيوب المصفوفات هو القائمة

حيث يتم تعريف القائمة وتعريف أنواع عناصرها هكذا:

List<string> dayslist;

ولأن القائمة كائن وليست متغير , فيجب إستخدام عبارة new ليصبح التعريف الصحيح هكذا:

List<string> dayslist=new List<string>();

لاحظ أننا لم نحدد لها حجم أو عدد لعناصر لأن حجمها متغير , حيث تستطيع أن تضيف لها عنصر هذا:

dayslist.Add("السبت");

كما أنك تستطيع أن تضيف لها عناصر مصفوفة كاملة:

dayslist.AddRange(days);

الكود السابق يضيف عناصر المصفوفة days إلى القائمة dayslist

وتستطيع أن تحذف منها عنصر هكذا :

dayslist[5].Remove();

الكود السابق يحذف العنصر الذي ترتيبة 5 من القائمة

كما أنك تستطيع البحث عن عنصر ما هكذا :

dayslist.Contains("السبت");

الدالة السابقة سترجع القيمة true إذا كان العنصر موجود في القائمة

أو ترجع القيمة false إذا لم يوجد العنصر في القائمة

مما سبق نستنتج أن القائمة أفضل بكثير وأسهل في الإستخدام من المصفوفة

وهذا ما سنستخدمه في تطبيقنا

يتبع التطبيق في الرد التالي:

إعذرونا , سنضطر للغياب فترة كبيرة

الأمر ليس بيدنا ...... فسامحونا

#43

التطبيق:

تشغيل أكثر من ملف

سنضيف خاصية جديدة للبرنامج وهي فتح أكثر من ملف وإضافتها إلى قائمة التشغيل

حيث سنستخدم قائمة عناصرها من نوع نص لتخزين مسارات الملفات في قائمة التشغيل

إفتح تطبيق الدرس السابق , ومن صندوق الأدوات قم بسحب أداة القائمة :

image3-1.jpg

من خلال الخاصية (Name) في جدول الخصائص قم بتغيير إسم القائمة من ListBox1 إلى pl

ليسهل التعامل معها من الشفرة , هذه هي قائمة التشغيل

قم بإعادة ترتيب الأدوات في النافذة حتى يصبح شكلها هكذا :

image8-3.jpg

قم بتحديد إداة OF في الشريط الأصفر تحت النافذة:

image8-4.jpg

وإذهب إلى جدول الخصائص وقم بتغيير خاصية Multiselect إلى True

image8-5.jpg

عند إسناد قيمة True إلى هذه الخاصية فإنها تسمح لأداة إختيار الملفات بإختيار أكثر من ملف واحد كل مرة:

image8-6.jpg

الآن سنعرف متغير عام من نوع قائمة عناصرها نصوص لخزن مسارات الملفات المختارة بأداة إختيار الملفات

كائن القائمة موجود في فضاء الأسماء System.Collections.Generic لذلك يجب إضافة عبارة using لتضمين كائنات ودوال الفضاء

إذهب إلى شفرة النافذة وأضف عبارة using التالية تحت عبارات using الموجوده في رأس الصفحة :

 using System.Collections.Generic;

إذهب إلى شفرة البرنامج وقم بكتابة الكود التالي تحت كود تعريف كائنات Audio و Vedio و type :

 public List<string> albume=new List<string>();

image8-7.jpg

تحميل قيم القائمة

أداة إختيار الملفات OF تحتوي على خاصية إستخدمناها في الدروس السابقة

وهي خاصية FileName , وهذه الخاصية تحمل قيمة من نوع نص للملف الذي قام المستخدم بإختياره

لكن ماذا لو إختيار المستخدم أكثر من ملف واحد ؟

لحسن الحظ يوجد خاصية أخرى إسمها FileNames "بزيادة حرف s عن الخاصية الأخرى"

والخاصية FileNames تحمل مصفوفة جميع الملفات الذي قام المستخدم بإختيارها

وعناصر المصفوفة من نوع نص لخزن مسارات الملفات المختارة

فمثلاً لو إختار المستخدم 3 ملفات سيكون عدد عناصر هذه المصفوفة 3

إذهب إلى التصميم وإضغط مزدوجاً على زر فتح ملف ستجد الكود التالي :

 OF.ShowDialog();
  LoadFile(OF.FileName);
  SetTrackBar();
  PlayFile();

وغيره إلى الكود إلى التالي :

 OF.ShowDialog();
 albume.AddRange(OF.FileNames);
  LoadFile(albume[0]);
 FillList();
  SetTrackBar();
  PlayFile();

في السطر الثاني قمنا بتحميل جميع عناصر المصفوفة OF.FileNames إلى القائمة albume

والمصفوفة OF.FileNames كما شرحنا سابقاً تحتوي على عناصر تحمل مسارات الملفات المختارة

وقمنا بإضافة عناصرها إلى القائمة albume والتي سنستخدمها في أنحاء البرنامج

في السطر الثالث قمنا بتحميل العنصر الذي ترتيبة صفر من قائمة albume حتى يتم تشغيله

وفي السطر الرابع إستدعينا إجراء FillList الذي يقوم بملئ قائمة التشغيل بأسماء الملفات في عناصر القائمة albume كما سنشرح في الفقرة التالية

إجراء FillList

هذا الإجراء سيقوم بنقل جميع عناصر القائمة albume إلى قائمة التشغيل

حتى يسهل الوصول للمقطع الصوتي المراد تشغيلة ,

لكن , القائمة albume تحتوي على مسارات الملفات كاملة , وقائمة التشغيل لا تتسع لكتابة مسار الملف كاملاً

نريد فقط أسماء الملفات في قائمة التشغيل

لحسن الحظ يوجد كائن في إطار العمل داخل الفضاء System.IO يقوم بهذا العمل

الكائن Path يحتوي على دالة GetFileName تقوم بأخذ مسار الملف كاملاً وتنتج لنا إسم الملف فقط

إذا كان مسار الملف هو :

c:\sounds\s1\track.mp3

فالدالة GetFileName تأخذ المسار كامل وترجع القيمة التالية :

track.mp3

يتم إستدعاء الكائن Path من خلال كتابة عنوناه الكامل :

			string FileName;
			 FileName=System.IO.Path.GetFileName("c://sounds//s1//track.mp3");
			 MessageBox.Show(FileName);

في السطر الأول عرفنا متغير من نوع نص ليحمل نتيجة الدالة GetFileName

في السطر الثاني قمنا بإستدعاء الدالة GetFileName من خلال كتابة عنوانها كاملاً

وأسندنا ناتج الدالة للمتغير FileName

السطر الثالث سينتج رسالة مكتوب عليها :

track.mp3

بعد أن شرحنا عمل الدالة GetFileName سنحتاج في هذا الإجراء أيضاً لدوارة تقوم بالمرور على كافة عناصر القائمة albume

يمكنك الرجوع للدرس الثالث ومراجعة الدوارات

تبدأ الدوارة من 0 إلى عدد عناصر القائمة , حيث يمكن معرفة عدد عناصر القائمة من خلال الخاصية Count :

albume.Count;

إفتح شفرة البرنامج , وأنسخ الكود التالي وتأكد أن يكون خارج أي إجراء آخر :

		 void FillList()
		 {
 pl.Items.Clear();
			 for(int i=0;i<albume.Count;i++)
			 {
			 string FileName;
			 FileName=System.IO.Path.GetFileName(albume);
			 pl.Items.Add(FileName);
			 }
		 }

الأمر pl.Items.Clear يقوم بتنظيف القائمة من أي عناصر موجوده مسبقاً حتى تستعد لإدخال العناصر الجديدة

الكود داخل حاصرتي for سيتم تنفيذه بعدد عناصر القائمة albume

في السطر الأول من الكود داخل حاصرتي for , قمنا بتعريف الكائن الذي سيحمل نتيجة الدالة GetFileName

وفي السطر الثاني إستدعينا الدالة GetFileName ومررنا لها العنصر الذي ترتيبة i من قائمة albume

طبعاً في أول مرة يتم تنفيذ الكود سيكون i يساوي صفر , والمرة الثانية 1 والثالثة 2

وهكذا فإن قيمة i متغيرة من مرة لأخرى

في السطر الثالث أضفنا إسم المكلف الناتج إلى قائمة التشغيل pl

..

عند تشغيل البرنامج حالياً وإختيار عدة ملفات ستنتقل جميع أسماء الملفات إلى قائمة التشغيل

ويبدأ البرنامج بتشغيل أول ملف في القائمة :

image8-8.jpg

إختيار الملف من قائمة التشغيل

إذهب إلى التصميم , وأنقر مزدوجاً على قائمة التشغيل , ستنتقل إلى شفرة البرنامج

أنسخ الكود التالي حيث مؤشر الفارة " بين حاصرتي إجراء plSelectedIndexChanged

			StopFile();
			 LoadFile(albume[pl.SelectedIndex]);
			 SetTrackBar();
			 PlayFile();

حيث يتم تنفيذ الكود السابق كل مرة تقوم بها بإختيار عنصر من قائمة التشغيل.

عند إختيار عنصر من قائمة التشغيل , فإن السطر الأول يقوم بإيقاف تشغيل الملف الحالي

والسطر الثاني يأخذ ترتيب العنصر المختار من قائمة التشغيل من خلال الخاصيةSelectedIndex

ويقوم بتحميل الملف من قائمة albume الذي ترتيبة هو نفس ترتيب العنصر المختار في قائمة التشغيل

السطر الثالث والرابع تم شرحهما سابقاً ..

الآن قم بتشغيل البرنامج وإختر أكثر من ملف , سيتم نقل إسماء الملفات لقائمة التشغيل

ثم تشغيل أول ملف في القائمة , وعند إختيار ملف آخر من قائمة التشغيل سيتوقف تشغيل الملف الحالي

ويبدأ تشغيل الملف المختار

خطأ شائع:

أحيانا يقم المؤقت بتغيير قيمة شريك التنقل قبل أن يتم تحميل الملف

وهذا يسبب خطأ لأن قيم شريط التنقل الكبرى والصغرى لم يتم ضبتها بعد

ولا يجوز تغيير قيمة شريك التنقل قبل ضبط قيمه الصغرى والكبرى

لمعالجة الخطأ إذهب إلى شفرة إجراء المؤقت Timer1Tick :

		void Timer1Tick(object sender, System.EventArgs e)
		 {

			 if (type=="V")
			 {
				trackBar1.Value=Convert.ToInt32(vp.CurrentPosition);
			 }
			 else if (type=="A")
			 {
				 trackBar1.Value= Convert.ToInt32(ap.CurrentPosition);
			 }
			 else if (type=="R")
			 {
				 trackBar1.Value=Convert.ToInt32(rp.GetPosition());
			 }
		 }

وأضف إلى بدايتها الكود التالي:

			if (trackBar1.Maximum == 0)
			 {
				 SetTrackBar();
			 }

وهذا الكود يفحص ما إذا كانت قيمة شريط التنقل الكبرى قد تم ضبطها

فإن كانت قيمتها 0 يعني أنه لم يتم ضبطها بعد وبالتالي يستدعي إجراء ضبطها مرة أخرى

حيث يصبح شكل الإجراء هكذا بعد وضعه داخل عبارة try لتفادي الأخطاء الأخرى :

		void Timer1Tick(object sender, System.EventArgs e)
		 {
		 try
		 {
			 if (trackBar1.Maximum == 0)
			 {
				 SetTrackBar();
			 }
			 if (type=="V")
			 {
				trackBar1.Value=Convert.ToInt32(vp.CurrentPosition);
			 }
			 else if (type=="A")
			 {
				 trackBar1.Value= Convert.ToInt32(ap.CurrentPosition);
			 }
			 else if (type=="R")
			 {
				 trackBar1.Value=Convert.ToInt32(rp.GetPosition());
			 }
		 }
		 catch
		 {
		 }
		 }

الواجب

أرسل التطبيق.

.نهاية الدرس الثامن.

..

7oma

حماة النهضة

إعذرونا , سنضطر للغياب فترة كبيرة

الأمر ليس بيدنا ...... فسامحونا

#44

دروس راااائعة, الله يوفقكم ويعينكم على هذا العمل الجبار

السؤالاول: حول عملية ال compilation هل C# يترجم الى البايت كود مثل java

السؤال الثاني: هل استطيع انشاء مساريح للمبايل أو ال pocket pc بال C#

و شكرا

#45

السلام عليكم

Anas_x

صحيح أنس المفروض أخي أن تضع الأسئلة الخارجة عن الدروس في مواضيع مستقلة

مع ذلك , بعد إذنك مشرفنا العزيز نجاوب أسئلة أخونا أنس

اقتباس
السؤالاول: حول عملية ال compilation هل C# يترجم الى البايت كود مثل java

لا , الأمر يختلف قليلاً , فجميع مترجماتع لغات إطار العمل .NET تنتج كود من نوع IL

Intemedial Language , وكود لغات ميكروسوفت يختلف قليلاً عن كود IL المتداول في اللغات الأخرى كالدلفي دوت نت

ويسمى MSIL حيث أن جمع اللغات تنتج نفس الكود تقريباً , والذي يتم ترجمته إلى لغة الآله عن طريق CLR

Common Language Runtime والذي يتعامل مع جميع اللغات التي تعمل بتقنية الدوت نت سواءاً لغات ميكروسوفت أو غيرها

كمثال , لو جربت عمل برنامج بالـ VB.NET و نفس البرنامج بالـ C# و نسخة ثالثة بالـ J# ثم تقوم بترجمة جميع الأسمبليز

ستلاحظ تشابة كبير جداً في كود الـ MSIL الناتج , على أن الكود الناتج من لغة C# يتميز عن الباقي بالوضوح وعدد السطور الأقل

مما يوفر الكثير من الوقت عند تنفيذ برامج السي شارب , وهذا ما يجعلنا نفضل السي شارب عن لغات الدوت نت الأخرى

يمكنك الإطلاع على كود أي برنامج دوت نت من خلال أداه مرفقة بالفيجوال ستوديو يمكن إيجادها في هذا المسار:

   C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin\ildasm.exe

اقتباس
السؤال الثاني: هل استطيع انشاء مساريح للمبايل أو ال pocket pc بال C#

نعم بإمكانك عمل ذلك , لكنك تحتاج إلى بيئة التطوير الكاملة وليس بيئة Express

ويمكنك عمل مشاريع Smart Phone و Smart Device و Pocket PC و Windows CE

من خلال إنشاء مشروع جديد وإختيار النوع الذي ترغب به ..

كما يمكنك تجربة مشاريعك بواسطة برامج المحاكاه المرفقة بالبيئة Simulators

حيث يمكنك تشغيلها من قائمة Tool ثم Connect To Device ثم تختر المحاكي التي ترغب بتشغيلة

..

7oma

حماة النهضة

إعذرونا , سنضطر للغياب فترة كبيرة

الأمر ليس بيدنا ...... فسامحونا

#46

السلام عليكم ورحمه الله وبركاته

إن شاء الله فى الأسفل واجب الدرس السابع والثامن

وأسف على تأخير الواجب لظروف الأمتحانات

وليا سؤال تانى هو إزاى أخلى مثلا زرار play له شكل المثلث كما فى الميديا بلير مثلا

ومشكور أخى على المجهود الرائع MyMediaPlayer7___8.rar

#47

وعليكم السلام ورحمة الله وبركاته

عمرو الحمصى

موفق أخي في الأمتحانات إن شاء الله :)

اقتباس
وليا سؤال تانى هو إزاى أخلى مثلا زرار play له شكل المثلث كما فى الميديا بلير مثل

أي زر لازم يكون شكلة مربع , لكن يمكن خداع المستخدم بإستخدام صور gif

حيث يتخذ الزر شكل الصورة , وذلك من خلال إضافة الصورة إلى الخاصية BackgroundImage

من خصائص الزر

..

7oma

حماة النهضة

إعذرونا , سنضطر للغياب فترة كبيرة

الأمر ليس بيدنا ...... فسامحونا

#48

الدرس التاسع

إنتاج أرقام عشوائية

ربما يتسائل البعض ما الذي يدعونا لإنتاج أرقام عشوائية وفي اي شيئ سنستخدمها

حسناً , يعتبر إنتاج الأرقام العشوائية من اهم الدعائم التي ترتكز عليها أنظمة الذكاء الإصطناعي والشبكات العصبية الإصطناعية

وإنتاج الأرقام العشوائية ليس بالسهولة التي تتصورها

حيث تستخدم خوارزمية شديدة التعقيد لغرض أنتاج أرقام لا معنى لها

تكمن الصعوبة في الخوارزمية أن أنظمة الحاسوب لاتستطيع أن تنتج أي شي لامعنى له

فلا يوجد شيئ "عشوائي" في أنظمة الحاسوب

ولكن خوارزميات إنتاج الأرقام العشوائية تستخدم الكثير من المدخلات من مصادر مختلفة لإنتاج الأرقام العشوائية

كأن تأخذ تاريخ ووقت النظام , وتجري عليه عددا من الدوال والحسابات

في برنامجنا سنضيف اليوم خاصية إختيار طريقة تشغيل الملفات , إما تتابعية أو عشوائية

تتابعية يعني أن يشغل البرنامج الملف الأول في قائمة التشغيل وعند الإنتهاء منه يشغل الملف الثاني وهكذا

أما الطريقة العشوائية فهي أن يقوم البرنامج بالحصول على رقم عشوائي بين الصفر و عدد الملفات في قائمة التشغيل ويبدأ بتشغيلة

وعند الإنتهاء منه يحصل على رقم عشوائي ويشغل ملف آخر وهكذا.

في لغة C# يوجد كائن مسئول عن إنتاج الأرقام العشوائية هو كائن Random

وعند تعريفة ولأنه كائن وليس متغير يجب إستخدام كلمة new هكذا :

Rabdom rnd=new Random();

في الكود السابق قمنا بتعريف كائن إسمه rnd من نوع Ranom

الدالة Next في هذا الكائن هي المسئولة عن إنتاج الأرقام العشوائية

وتستقبل هذه الدالة رقمين يمثلا الحد الأدنى والحد الأقصى للعدد العشوائي المراد إنتاجه

مثلاً لو أردنا إنتاج رقم عشوائي بين 0 و 10 :

rnd.Next(0,10);

حيث ستنتج هذه الدالة رقماً عشوائيا بين الصفر والعشرة

ولأن هذه الدالة تعيد قيمة فإن إستدعائها بالطريقة السابقة خاطئ , حيث يجب إسنادها لمتغير من نوع رقم:

int num;
 num=rnd.Next(0,10);

حيث أن المتغير num سيحمل القيمة الناتجة من الدالة .

يتبع التطبيق في الرد التالي..

تم تعديل هذه المشاركة بواسطة حماة النهضة في 15 مايو 2007 في 15:52

إعذرونا , سنضطر للغياب فترة كبيرة

الأمر ليس بيدنا ...... فسامحونا

#49

التطبيق

إفتح تصميم البرنامج , ومن صندوق الأدوات قم بسحب كائن صندوق المجموعة Group Box إلى الفورم الرئيسي:

image9-1.jpg

قم بإختيار صندوق المجموعة ومن جدول الخصائص إذهب إلى خاصية Text

وأكتب أمامها "طريقة التشغيل" , ستلاحظ أن عنوان صندوق المجموعة قد تغير :

image9-2.jpg

من صندوق الأدوات أيضاً قم بسحب كائن زر الإختيار Radio Button مرتين إلى صندوق المجموعة :

image9-3.jpg

تأكد من أن زري الإختيار قد تم وضعها داخل صندوق المجموعة :

image9-4.jpg

إختر زر الإختيار المسمى radioButton1 وإذهب إلى جدول الخصائص

وغير الخاصية (Name) من radioButton1 إلى serbtn

وغير الخاصية Text من radioButton1 إلى تتابعي

وغير أيضاً الخاصية Checked إلى true

إختر زر الإختيار الأخر المسمى radioButton2 وإذهب إلى جدول الخصائص

وغير الخاصية (Name) من radioButton2 إلى rndbtn

وغير أيضاً الخاصية Text من radioButton2 إلى عشوائي

عدل ترتيب الأدوات في النافذه حتى يصبح شكلها هكذا :

image9-5.jpg

سنحتاج إلى متغير عام من نوع رقم وليكن current حيث سيقوم بخزن ترتيب الملف الذي يتم تشغيله حالياً

قم بإضافة هذا المتغير أسفل المتغيرات العامة من الدروس السابقة :

image9-6.jpg

إجراء تشغيل الملف الحالي

الإجراء PlayCurrent وظيفته هي تشغيل الملف الذي ترتيبه هو قيمة current من القائمة albume

مثلاً إذا كانت قيمة current هي 3 فإن هذا الإجراء يشغل الملف من قائمة التشغيل والذي ترتيبه 3

إنسخ هذا الإجراء إلى شفرة البرنامج وتأكد أنه خارج أي إجراء آخر

		void PlayCurrent()
		{
			LoadFile(albume[current]);
			SetTrackBar();
			PlayFile();
		}

إجراء إختيار الملف التالي

وظيفة الإجراء SetNext هي إختيار الملف التالي لتشغيلة بعد الإنتهاء من تشغيل الملف الحالي

حيث يقوم هذا الإجراء بفحص طريقة التشغيل المختارة من قبل المستخدم ومن خلالها تقوم بإختيار الملف التالي بطريقتين مختلفتين:

if(rndbtn.Checked)
{
  //current إضافة 1 إلى المتغير 
}
else
{
  // current إختيار رقم عشوائي وتحميلة للمتغير 
}

إنسخ الإجراء التالي إلى شفرة البرنامج وتأكد أنه خارج أي إجراء آخر:

		void SetNext()
		{
			if(serbtn.Checked)
			{
				  current=current+1;
			}
			else
			{
						Random rnd=new Random();
					current=rnd.Next(0,albume.Count-1);
			}
				pl.SelectedIndex = current;
				PlayCurrent();
		}

في السطر الثالث من الكود السابق توجد عبارة if والتي تفحص زر الإختيار serbtn الذي خصصناه للتشغيل التتابعي

فإذا كانت حالة الزر Ckecked أي أن الإختيار عليه , أي أن نوع التشغيل المختار من قبل المستخدم هو التتابعي

عندها في السطر الخامس نقوم بإضافة 1 إلى قيمة current , فإذا كانت قيمته مثلاً 5 ستصبح قيمته 6

إما إذا كذا الإختيار على الزر الآخر وهو المخصص للتشغيل العشوائي

ففي السطر التاسع قمنا بتعريف كائن من نوع Random

وفي السطر العاشر إسندنا للمتغير current القيمة الناتجة من دالة إنتاج الأرقام العشوائية

حيث أن الدالة ستنتج رقماً عشوائيا بين الصفر و ترتيب آخر عنصر في قائمة التشغيل

ونعرف أن عدد عناصر قائمة التشغيل هو طول نفس عدد عناصر القائمةalbume

ولكن عدد عناصر القائمة يختلف عن الترتيب لأنه كما قلنا في الدرس السابق فإن الترتيب في المصفوفات والقوائم يبدأ من الصفر

فإذا كان طول القائمة 5 فإن أعلى ترتيب فيها هو 4 لذلك إضفنا -1 بعد طول المصفوفة

في السطر الثاني عشر قمنا بتغيير الإختيار في قائمة التشغيل من خلال الخاصية SelectedIndex

مثلاً لو أردنا أن نختار العنصر الثالث من قائمة التشغيل سنستخدم الكود التالي :

pl.SelectedIndex=2;

لاحظ 2 و ليست 3 لأن العنصر الثالث في القائمة ترتيبه 2 وليس 3 حيث ان العنصر الأول كما قلنا ترتيبه 0

والعنصر الثاني ترتيبه 1 والعنصر الثالث ترتيبه 2 و هكذا .

في السطر الثالث عشر قمنا بإستدعاء الإجراءPlayCurrent والذي يقوم بتشغيل الملف الذي ترتيبه هو قيمة current

هناك ملاحظة على الكود السابق

فإذا كانت طريقة التشغيل تتابعي , ووصل ترتيب الملف إلى آخر عنصر

عندها إذا أضفنا 1 إلى المتغير current فإنه سيحمل ترتيب أعلى من ترتيب آخر عنصر في القائمة وهذا سيسبب خطأ

عند محاولة تحميل ملف غير موجود اساساً في قائمة الملفات albume وقائمة التشغيل

لذلك يجب أن نفحص قيمة current أولاً فإذا كانت تساوي آخر ترتيب في القائمة فنقوم بأسناد الرقم 0 إلى المتغير current

حتى يرجع ترتيب المتغير لأول عنصر في القائمة , وبالتالي عند الإنتهاء من تشغيل جميع الملفات في القائمة فسيعود تشغيل الملفات من أول القائمة مرة أخرى

في كود إجراء إختيار الملف أحذف السطر التالي :

				  current=current+1;

وأكتب مكانه هذه الأسطر :

				if(current==albume.Count-1)
				{
					 current=0;
				}
				else
				{
					current=current+1;
				}

عبارة if في السطر الأول تقوم بفحص قيمة current فإذا كانت تساوي ترتيب آخر عنصر بالقائمة

ففي السطر الثالث تسند القيمة 0 إلى المتغير current

أما إذا كانت قيمة current لا تساوي ترتيب آخر عنصر

ففي السطر السابع تضيف 1 إلى قيمة current

بالتعديل السابق يصبح إجراء إختيار الملف التالي هكذا :

		void SetNext()
		{
			if(serbtn.Checked)
			{
				if(current==albume.Count-1)
				{
					 current=0;
				}
				else
				{
					current=current+1;
				}
			}
			else
			{
				Random rnd=new Random();
				current=rnd.Next(0,albume.Count-1);
			}
			pl.SelectedIndex = current;
			PlayCurrent();
		}

متى نستدعي إجراء إختيار الملف التالي ؟

إذا قمت بتشغيل البرنامج فلن يتم تشغيل الملفات لا عشوائيا و لا تتابعياً

لأننا قمنا بكتابة كود إجراء الأختيار ولكنا لم نستدعه في أي مكان في البرنامج

والمفروض أن نستدعي إجراء إختيار الملف التالي عند الإنتهاء من تشغيل الملف الحالي

ولكن كيف نعرف متى سيتم الإنتهاء من تشغيل الملف الحالي ؟

حسنا نعرف أن قيمة شريط التنقل عبر الملف تتغير كل ثانية بفعل المؤقت

سنستخدم هذه الميزة لنعرف وقت الإنتهاء من تشغيل الملف الحال ..

حيث أنه عند الإنتهاء من تشغيل الملف فإن قيمة شريط التنقل تصبح مساوية لطول الملف

إذا سنختبر قيمة شريط التنقل في كل مرة تتغير فيها فإذا أصبحت قيمته مسوية لطول الملف يعني أنه وصل إلي نهاية الملف الحالي

وبالتالي يجب إستدعاء إجراء SetNext

لكن هناك مشكلة , فالمؤقت يغير قيمة الشريط كل ثانية واحدة

إعذرونا , سنضطر للغياب فترة كبيرة

الأمر ليس بيدنا ...... فسامحونا

#50

التطبيق

إفتح تصميم البرنامج , ومن صندوق الأدوات قم بسحب كائن صندوق المجموعة Group Box إلى الفورم الرئيسي:

image9-1.jpg

قم بإختيار صندوق المجموعة ومن جدول الخصائص إذهب إلى خاصية Text

وأكتب أمامها "طريقة التشغيل" , ستلاحظ أن عنوان صندوق المجموعة قد تغير :

image9-2.jpg

من صندوق الأدوات أيضاً قم بسحب كائن زر الإختيار Radio Button مرتين إلى صندوق المجموعة :

image9-3.jpg

تأكد من أن زري الإختيار قد تم وضعها داخل صندوق المجموعة :

image9-4.jpg

إختر زر الإختيار المسمى radioButton1 وإذهب إلى جدول الخصائص

وغير الخاصية (Name) من radioButton1 إلى serbtn

وغير الخاصية Text من radioButton1 إلى تتابعي

وغير أيضاً الخاصية Checked إلى true

إختر زر الإختيار الأخر المسمى radioButton2 وإذهب إلى جدول الخصائص

وغير الخاصية (Name) من radioButton2 إلى rndbtn

وغير أيضاً الخاصية Text من radioButton2 إلى عشوائي

عدل ترتيب الأدوات في النافذه حتى يصبح شكلها هكذا :

image9-5.jpg

سنحتاج إلى متغير عام من نوع رقم وليكن current حيث سيقوم بخزن ترتيب الملف الذي يتم تشغيله حالياً

قم بإضافة هذا المتغير أسفل المتغيرات العامة من الدروس السابقة :

image9-6.jpg

إجراء تشغيل الملف الحالي

الإجراء PlayCurrent وظيفته هي تشغيل الملف الذي ترتيبه هو قيمة current من القائمة albume

مثلاً إذا كانت قيمة current هي 3 فإن هذا الإجراء يشغل الملف من قائمة التشغيل والذي ترتيبه 3

إنسخ هذا الإجراء إلى شفرة البرنامج وتأكد أنه خارج أي إجراء آخر

		void PlayCurrent()
		 {
			 LoadFile(albume[current]);
			 SetTrackBar();
			 PlayFile();
		 }

إجراء إختيار الملف التالي

وظيفة الإجراء SetNext هي إختيار الملف التالي لتشغيلة بعد الإنتهاء من تشغيل الملف الحالي

حيث يقوم هذا الإجراء بفحص طريقة التشغيل المختارة من قبل المستخدم ومن خلالها تقوم بإختيار الملف التالي بطريقتين مختلفتين:

if(rndbtn.Checked)
 {
   //current إضافة 1 إلى المتغير 
 }
 else
 {
   // current إختيار رقم عشوائي وتحميلة للمتغير 
 }

إنسخ الإجراء التالي إلى شفرة البرنامج وتأكد أنه خارج أي إجراء آخر:

		void SetNext()
		 {
			 if(serbtn.Checked)
			 {
				   current=current+1;
			 }
			 else
			 {
						 Random rnd=new Random();
					 current=rnd.Next(0,albume.Count-1);
			 }
				 pl.SelectedIndex = current;
				 PlayCurrent();
		 }

في السطر الثالث من الكود السابق توجد عبارة if والتي تفحص زر الإختيار serbtn الذي خصصناه للتشغيل التتابعي

فإذا كانت حالة الزر Ckecked أي أن الإختيار عليه , أي أن نوع التشغيل المختار من قبل المستخدم هو التتابعي

عندها في السطر الخامس نقوم بإضافة 1 إلى قيمة current , فإذا كانت قيمته مثلاً 5 ستصبح قيمته 6

إما إذا كذا الإختيار على الزر الآخر وهو المخصص للتشغيل العشوائي

ففي السطر التاسع قمنا بتعريف كائن من نوع Random

وفي السطر العاشر إسندنا للمتغير current القيمة الناتجة من دالة إنتاج الأرقام العشوائية

حيث أن الدالة ستنتج رقماً عشوائيا بين الصفر و ترتيب آخر عنصر في قائمة التشغيل

ونعرف أن عدد عناصر قائمة التشغيل هو طول نفس عدد عناصر القائمةalbume

ولكن عدد عناصر القائمة يختلف عن الترتيب لأنه كما قلنا في الدرس السابق فإن الترتيب في المصفوفات والقوائم يبدأ من الصفر

فإذا كان طول القائمة 5 فإن أعلى ترتيب فيها هو 4 لذلك إضفنا -1 بعد طول المصفوفة

في السطر الثاني عشر قمنا بتغيير الإختيار في قائمة التشغيل من خلال الخاصية SelectedIndex

مثلاً لو أردنا أن نختار العنصر الثالث من قائمة التشغيل سنستخدم الكود التالي :

pl.SelectedIndex=2;

لاحظ 2 و ليست 3 لأن العنصر الثالث في القائمة ترتيبه 2 وليس 3 حيث ان العنصر الأول كما قلنا ترتيبه 0

والعنصر الثاني ترتيبه 1 والعنصر الثالث ترتيبه 2 و هكذا .

في السطر الثالث عشر قمنا بإستدعاء الإجراءPlayCurrent والذي يقوم بتشغيل الملف الذي ترتيبه هو قيمة current

هناك ملاحظة على الكود السابق

فإذا كانت طريقة التشغيل تتابعي , ووصل ترتيب الملف إلى آخر عنصر

عندها إذا أضفنا 1 إلى المتغير current فإنه سيحمل ترتيب أعلى من ترتيب آخر عنصر في القائمة وهذا سيسبب خطأ

عند محاولة تحميل ملف غير موجود اساساً في قائمة الملفات albume وقائمة التشغيل

لذلك يجب أن نفحص قيمة current أولاً فإذا كانت تساوي آخر ترتيب في القائمة فنقوم بأسناد الرقم 0 إلى المتغير current

حتى يرجع ترتيب المتغير لأول عنصر في القائمة , وبالتالي عند الإنتهاء من تشغيل جميع الملفات في القائمة فسيعود تشغيل الملفات من أول القائمة مرة أخرى

في كود إجراء إختيار الملف أحذف السطر التالي :

				  current=current+1;

وأكتب مكانه هذه الأسطر :

				if(current==albume.Count-1)
				 {
					  current=0;
				 }
				 else
				 {
					 current=current+1;
				 }

عبارة if في السطر الأول تقوم بفحص قيمة current فإذا كانت تساوي ترتيب آخر عنصر بالقائمة

ففي السطر الثالث تسند القيمة 0 إلى المتغير current

أما إذا كانت قيمة current لا تساوي ترتيب آخر عنصر

ففي السطر السابع تضيف 1 إلى قيمة current

بالتعديل السابق يصبح إجراء إختيار الملف التالي هكذا :

		void SetNext()
		 {
			 if(serbtn.Checked)
			 {
				 if(current==albume.Count-1)
				 {
					  current=0;
				 }
				 else
				 {
					 current=current+1;
				 }
			 }
			 else
			 {
				 Random rnd=new Random();
				 current=rnd.Next(0,albume.Count-1);
			 }
			 pl.SelectedIndex = current;
			 PlayCurrent();
		 }

متى نستدعي إجراء إختيار الملف التالي ؟

إذا قمت بتشغيل البرنامج فلن يتم تشغيل الملفات لا عشوائيا و لا تتابعياً

لأننا قمنا بكتابة كود إجراء الأختيار ولكنا لم نستدعه في أي مكان في البرنامج

والمفروض أن نستدعي إجراء إختيار الملف التالي عند الإنتهاء من تشغيل الملف الحالي

ولكن كيف نعرف متى سيتم الإنتهاء من تشغيل الملف الحالي ؟

حسنا نعرف أن قيمة شريط التنقل عبر الملف تتغير كل ثانية بفعل المؤقت

سنستخدم هذه الميزة لنعرف وقت الإنتهاء من تشغيل الملف الحال ..

حيث أنه عند الإنتهاء من تشغيل الملف فإن قيمة شريط التنقل تصبح مساوية لطول الملف

إذا سنختبر قيمة شريط التنقل في كل مرة تتغير فيها فإذا أصبحت قيمته مسوية لطول الملف يعني أنه وصل إلي نهاية الملف الحالي

وبالتالي يجب إستدعاء إجراء SetNext

لكن هناك مشكلة , فالمؤقت يغير قيمة الشريط كل ثانية واحدة , وطول المف في ملفات الريل يقاس بالملي ثانية

أي انه عند وصول الملف لنهايته فهناك إحتمال كبير أن لا تكون قيمة الشريط هي طول الملف

لذلك يجب أن نجد طريقة أخر لفحص الصول إلى نهاية الملف

الطريقة هي أن نفحص نوع الملف الذي يتم تشغيله حالياً فإذا كان ملف ريل فالفحص يتم على آخر 1000 رقم

أما إذا كان ملف صوت عادي أو ملف فيديو فالفحص يتم على أخر رقم

أي أن شرط الوصول إلى نهاية ملف الريل يتحقق إذا كانت قيمة شريط التنقل أكبر من طول الملف ناقص 1000

وشرط الوصول إلى نهاية ملف الصوت العادي والفيديو يتحقق إذا كانت قيمة شريط التنقل أكبر من طول الملف ناقص واحد كما سنشرح في الفقرة التالية

إذهب إلى تصميم البرنامج وقم بإختيار كائن التنقل trackBar1

من نافذة الخصائص إختر خصائص الأحداث وانقر مزدوجاً أمام الحدث ValueChanged:

image9-7.jpg

ستنتقل إلى شفرة البرنامج إلى إجراء TrackBar1ValueChanged هذا الإجراء يتم تنفيذه في كل مرة تتغير فيها قيمة شريط التنقل

حيث من المفترض ان نستدعي إجراء إختيار الملف التالي هنا :

 void TrackBar1ValueChanged(object sender, EventArgs e)
 {
 //إستدعاء إجراء إختيار الملف التالي
 }

إنسخ الكود التالي إلى داخل الإجراء TrackBar1ValueChanged :

			int last;
			 if (type == "R")
			 {
				 last = trackBar1.Maximum - 1000;
			 }
			 else
			 {
				 last = trackBar1.Maximum - 1;
			 }
			 if (trackBar1.Value > last)
			 {
				 SetNext();
			 }

حيث يصبح الإجراء TrackBar1ValueChanged هكذا :

		void TrackBar1ValueChanged(object sender, EventArgs e)
		 {
			 int last;
			 if (type == "R")
			 {
				 last = trackBar1.Maximum - 1000;
			 }
			 else
			 {
				 last = trackBar1.Maximum - 1;
			 }
			 if (trackBar1.Value > last)
			 {
				 SetNext();
			 }
		 }

في هذا الإجراء عرفنا متغير إسمه last من نوع رقم يحمل قيمة تمثل أعلى قيمة لطول الملف الصوتي

وهي طول الملف الصوتي ناقص 1000 في ملفات الريل

وهي طول الملف الصوتي ناقص واحد في ملفات الصوت العادية والفيديو

في السطر الرابع عبارة if لفحص نوع الملف الذي يتم تشغيله حالياً من خلال المتغير type الذي شرحناه في دروس سابقة

فإذا كانت قيمة type هي R يعني هذا أنه ملف ريل , وبالتالي فإن أعلى قيمة لطول الملف الصوتي هي آخر ثانية في الملف

وهي طول الملف ناقص 1000 , وقد وضعنا بدل طول الملف trackBar1.Maximum لأنها يحملان نفس القيمة بفعل الإجراء SetTrackBar

أما إذا لم يكن الملف ملف ريل فإن أعلى قيمة لطول الملف هي آخر ثانية وهي طول الملف ناقص واحد

في السطر الثاني عشر عبارة if أخرى تقوم بفحص قيمة شريط التنقل فإذا كانت قيمته أكبر من أعلى قيمة لطول الملف

فهذا يعني أن البرنامج وصل إلى نهاية الملف الصوتي , ويجب إستدعاء دالة إختيار الملف التالي وتشغيلة

..

إذهب إلى إجراء plSelectedIndexChanged من الدرس السابق وغير شفرته حتى يصبح هكذا :

		void plSelectedIndexChanged(object sender, EventArgs e)
		 {
			 current=pl.SelectedIndex;
			 PlayCurrent();
		 }

عرفنا أن الإجراء plSelectedIndexChanged ينفذ في كل مرة تقوم بإختيار ملف من قائمة التشغيل

والكود السابق يقوم يتحميل المتغير current ترتيب الملف الذي إخترته ثم يستدعي إجراء تشغيله

الآن قم بتشغيل البرنامج وإختر عدة ملفات و جرب طرق التشغيل

الواجب

أرسل التطبيق

.نهاية الدرس التاسع.

..

7oma

حماة النهضة

إعذرونا , سنضطر للغياب فترة كبيرة

الأمر ليس بيدنا ...... فسامحونا

هذا الموضوع مغلق.

مواضيع مشابهة

عدد الزوار حالياً

المتواجدون خلال آخر دقيقتين · يتحدّث كل ٣٠ ثانية

—الإجمالي—أعضاء مسجّلون—زوار بدون تسجيل

جارٍ التحقق من المتواجدين…