الواجب الرابع مرفق
ولكن احيانا يعلق اثناء الاستخدام , واذا اخترت صوره أيضاً يعلق( علماً اني وضعت له تراي وكاتش ) !!
تم تعديل هذه المشاركة بواسطة Pro_S00 في 29 أبريل 2007 في 18:22
الواجب الرابع مرفق
ولكن احيانا يعلق اثناء الاستخدام , واذا اخترت صوره أيضاً يعلق( علماً اني وضعت له تراي وكاتش ) !!
تم تعديل هذه المشاركة بواسطة Pro_S00 في 29 أبريل 2007 في 18:22
السلام عليكم ورحمه الله وبركاته
إن شاء الله هذا هو واجب الدرس الرابع أرجو ان ينال رضاكم
وعليكم السلام ورحمة الله وبركاته
Pro_S00
اقتباسالواجب الرابع مرفقولكن احيانا يعلق اثناء الاستخدام , واذا اخترت صوره أيضاً يعلق( علماً اني وضعت له تراي وكاتش ) !!
تأكد أخي انك وضعت جملة try في دالة تشغيل الملف أيضاً
ghubein
اقتباسبارك الله فيكم على المجهود وجعله الله في ميزان حسناتكم ونفع بكم الامةارجوا ان تستمروا
وبارك لك أخي
بإذن الله مستمرين للنهاية
عمرو الحمصى
اقتباسإن شاء الله هذا هو واجب الدرس الرابع أرجو ان ينال رضاكم
تمام أخي , أكيد نال رضانا , خصوصاً رسالة تأكيد الخروج..
أن شاء الله تستمر معنا بنفس النشاط
..
7oma
حماة النهضة
إعذرونا , سنضطر للغياب فترة كبيرة
الأمر ليس بيدنا ...... فسامحونا
جزاك الله خيرا أخي "حماة النهضة", ان شاء الله سأضع الموضوع في المواضيع المتميزة.
اقتباسولكن احيانا يعلق اثناء الاستخدام , واذا اخترت صوره أيضاً يعلق( علماً اني وضعت له تراي وكاتش ) !!
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";
السلام عليكم ورحمة الله وبركاته
الدرس الخامس
تشغيل ملف فيديو
دوال تشغيل الفيديو موجودة في ملف Microsoft.DirectX.AudioVideoPlayback.dll
الذي أضفناه إلى التطبيق في الدرس السابق
دوال الفيديو تشبه إلى حد كبير دوال الصوت عدى عن إختلافات بسيطة
من اهم هذه الإختلافات أنه يمكنك أن تحدد كائن حاضن Owner Control لشاشة الفيديو
معنى كائن حاضن اي كائن يعمل كشاشة فيديو
أما إذا لم تحدد كائن حاضن فان التطبيق سيفتح نافذه جديدة لتكون شاشة الفيديو
قراءة أحداث المفاتيح
كل كائن له صفات و دوال كما عرفنا سابقاً , والكائنات تحتوي أيضاً على أحداث Events
مثلاً الزر له عدة أحداث منها عند الضغط عليه Click وعند الضغط المزدوج DoubleClick
و عند مرور مؤشر الماوس به MouseOver
وفي الدروس السابقة إستخدمنا حدث Click فقط
للتصفح بين أحداث الكائن , إختر الكائن ثم أفتح نافذة الصفات "الخواص" واختر زر الأحداث:

ستظهر لك قائمة بجميع الأحداث للكائن المحدد
ولكي تضيف تعليمات عند حدوث حدث معين اضغط مزدوجاً على أسم الحدث في القائمة
ستتنتقل إلى الشفرة لتكتب التعليمات التي تنفذ عن حدوث ذلك الحدث
ومن الأحداث المهة حدث KeyPress وينطلق هذا الحدث عند الضغط على أي مفتاح
في لوحة المفاتيح .
التطبيق
إفتح تطبيق الدرس السابق وعدل النص في زر فتح ملف الصوت إلى "فتح ملف ميديا"
وفي زر تشغيل ملف الصوت إلى "تشغيل ملف ميديا"
أضف زراً جديداً وغير النص فيه إلى "ملئ الشاشة"
قبل تشغيل ملف الفيديو يجب أن نحدد له كائن حاضن ليعمل كشاشة
افتح التصميم وأضف أدات البانيل إلى الفورم:

تأكد من إختيار البانيل و غير صفة الإسم إلى p1
غير صفة العرض Width إلى 400 وصفة الإرتفاع Height إلى 300

من خلال صفة BackgroundImage إختر اي صورة لتكون خلفية الشاشة
ليصبح شكل النافذة هكذا:

أضغط مزدوجاً على أي زر للذهاب إلى الشفرة ,
نحتاج إلى تعريف كائن عام Global من نوع فيديو ولأننا سنستخدمة في أكثر من إجراء
سنعرفه خارج جميع الإجراءات والدوال , إذهب إلى الشفرة حيث عرفنا متغير الصوت في الدرس السابق
وأكتب تعريف كا ئن الفيديو :
private Video vp;
تحت تعريف كائن الصوت من الدرس السابق :

سنجعل التطبيق يفتح ملفات صوت أو ملفات فيديو , لكن المشكلة أن للصوت كائن
وللفيديو كائن آخر , وبالتالي يجب أن نعرف نوع الملف حتى نستخدم الكائن المحدد
وبما أن أنواع الفيديو كثيرة جداً فلا يمكننا فحص نوع الملف لتأكد من نوعه
وبالتالي فالحل الوحيد هو أن نحاول أولا تشغيل الملف بكائن الفيديو
فإن ظهر لنا خطأ فنحاول نشغلة بكائن الصوت , وأن ظهر لنا خطأ للمرة الثانية فالملف غير صالح
قد يسأل البعض لماذا بدأنا بتجربة كائن الفيديو مع أن معظم الملفات ستكوت صوت
والإجابة أن كائن الصوت ممكن أن يشغل ملفات فيديو بدون صورة , يعني انه يفتح ملف الفيديو
ويشغل الصوت الذي فيه , وبالتالي فربما يكون الملف فيديو ويتم تشغيله كملف صوت
لذلك يجب أولاً تجربة كائن الفيديو حتى إذا كان ملف فيديو يشغل الصوت مع الصورة
وإذا كان ملف صوت نجرب كائن الصوت ..
لعمل ذلك نحتاج إلى تنفيذ جملة تعقب الإخطاء 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

ستنتقل إلى شفرة الحدث , أكتب تعليمة إعادة صورة الفيديو إلى الكائن الحاضن :
vp.Fullscreen = false;
هناك مشكلة ستواجهنا هنا وهي في حالة إذا كان تركيز لوحة المفاتيح على زر محدد
فلن ينطلق حدث الضغط على النافذة , سينطلق الحدث على الزر المحدد فقط
والشفرة السابقة على النافذه الأساسية ,,,
الحل أن هناك صفة في النافذة تمكنها من إطلاق الحدث حتى ولو حصل في أي كائن من الكائنات
هذه الخاصية هي KeyPreview عدلها من False إلى True لتصبح كما في الصورة

الآن شغل البرنامج وجرب تشغيل ملف صوت أو فيديو او ملف نصي
تلميحات الأدوات
أحيانا تحتاج إلى إظهار ملا حظة بسيطة للمستخدم عن وظيفة زر في التطبيق مثلاً
وتظهر هذا الملاحظات في مستطيل أصفر يظهر بمجرد مرور الماوس من فوق الزر
مثلاً لو تمرر الماوس فوق زر Start في شريط المهام ستظهر هذه الملاحظة
Click here to begin
لعمل مثل هذه الملاحظات في تطبيقنا نحتاج لإضافة كائن جديد
افتح التصميم واسحب كائن تلميحات الأدوات ToolTip

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

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

الواجب
أرسل التطبيق.
.نهاية الدرس الخامس.
..
7oma
حماة النهضة
إعذرونا , سنضطر للغياب فترة كبيرة
الأمر ليس بيدنا ...... فسامحونا
معتز شمس
أهلا بك مشرفنا العزيز
نورت موضوعنا بإطلالتك العطرة
أشكرك كثيراً على الشرح المفصل للأخ Pro_S00
وعندك حق المفروض نراقب إستخدام جملة try
وإن كان إستخدامنا لها هنا هو من باب التبسيط على المبتدئ لا غير
كما أن بعض ملفات الصوتيات قد لا تحتوي على إمتداد نتيجة خطأ في التسمية
لكنها تظل ملفات صوتيه يمكن تشغيلها بالبرنامج
بعد إذنك أخي , ممكن أضيف تعديل بسيط جداً على كودك وهو إضافة العبارة ToLower بعد إمتداد الملف
حتى لا يتأثر البرنامج بحالة أحرف الإمتداد كبيرة أم صغيرة , فتصبح جملة الشرط هكذا :
if (selectedFileInfo.Extension.ToLower() == ".wav" || selectedFileInfo.Extension.ToLower() == ".mp3")
كما أود أن أنبه مشرفنا العزيز إلى أن كوده يحتوي على خطأ إملائي بسيط
إسم كائن OpenFileDialog هو OF وليس FO
شرفتنا بزيارتك اخي العزيز وبارك الله فيك
..
7oma
حماة النهضة
إعذرونا , سنضطر للغياب فترة كبيرة
الأمر ليس بيدنا ...... فسامحونا
السلام عليكم ورحمه الله وبركاته
هذا هو الواجب اخى وأرجو أن يكون كما طلب منا
ولكن الجزء الأخير من الدرس السابق الخاص بال Full Screen لم أفهمه جيدا أنا فعلت كما قلت ولكنى لم أضع له زرار لأنى لم أفهم ما سوف يوضع من كود داخل هذا الزرار فأرجو الأفادة وهذا هو الواجب بدون هذا الزرار
وعليكم السلام ورحمة الله وبركاته
عمرو الحمصى
اقتباسهذا هو الواجب اخى وأرجو أن يكون كما طلب منا
الفيديو لا يظهر !! في خصائص الفورم هناك خاصية إسمها TransparencyKey
صفّر قيمتها بالنقر على اللون المختار ثم مفتاح Delete
اقتباسولكن الجزء الأخير من الدرس السابق الخاص بال Full Screen لم أفهمه جيدا أنا فعلت كما قلت ولكنى لم أضع له زرار لأنى لم أفهم ما سوف يوضع من كود داخل هذا الزرار فأرجو الأفادة وهذا هو الواجب بدون هذا الزرار
الكود في زر ملئ الشاشة هو السطر التالي :
vp.Fullscreen = true;
..
7oma
حماة النهضة
إعذرونا , سنضطر للغياب فترة كبيرة
الأمر ليس بيدنا ...... فسامحونا
السلام عليكم ورحمة الله وبركاته
Pro_S00 , عمرو الحمصى
تطبيقاتكما صحيحة
ربنا يوفقكم
..
7oma
حماة النهضة
إعذرونا , سنضطر للغياب فترة كبيرة
الأمر ليس بيدنا ...... فسامحونا
الدرس السادس
تشغيل ملفات الريل بلاير 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 هناك أمرين أحدهما لقرائة الموقع والآخر لضبط الموقع
أما في أوامر ميكروسوفت فالقراءة والضبط تستخدم نفس الأمر
سنستخدم في هذا الدرس جميع الأوامر السابقة
يتبع التطبيق في الرد التالي
إعذرونا , سنضطر للغياب فترة كبيرة
الأمر ليس بيدنا ...... فسامحونا
التطبيق
إفتح تطبيق الدرس السابق
أضف الملف 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;
بحيث تصبح المتغيرات العامة هكذا :

اذهب إلى التصميم
أضف للنافذة الأساسية زرين زر للإيقاف و زر للإيقاف المؤقت
إذهب إلى كرد البرنامج ..
سنقوم بكتابة إجراء مستقل لتحميل ملف الميديا إلى أحد الكائنات الثلاثة
إجراء تحميل الملف
وهذه الإجراء سيكون مستقله لكي نستطيع إستخدامه في أكثر من مكان
لنسمي هذه الإجراء 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";
}
}
}
}الكود السابق يمثل إجراء فحص الملف وتحملية إلى أحد الكائنات
الإجراء هو جزء من الشفرة يمكن إستخدامه أكثر من مرة من خلال إستدعائه بإسمه فقط
وبما أنه إجراء مستقلة يجب ان تكون خارج أي إجراء أخر:

الإجراء يتكون من مدخل واحد 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
حماة النهضة
إعذرونا , سنضطر للغياب فترة كبيرة
الأمر ليس بيدنا ...... فسامحونا
السلام عليكم ورحمة الله وبركاته
الدرس السابع
التنقل في الملف
ملف الصوت أو الفيديو يحتوي على خاصية طول الملف أي أن كل ملف له طول زمني
ويتم قياس الطول في مشغلات ميكروسوفت بالثانية , وفي مشغلات 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 ثوان

يتم تحديد طول الفترة الزمنية من خلال تعديل الخاصية "الصفة" Interval
حيث أن هذه الخاصية تأخذ الزمن بالملي ثانية أي أنه إذا أردنا أن تكون الفتره ثانية واحدة
فإن الخاصية Interval يجب ان تكون قيمتها 1000 , وإذا أردنا ثانيتين تكون 2000
ويتم كتابة الكود المراد تنفيذه من خلال الضغط مزدوجاً على المؤقت
في هذا الدرس سنستخدم الموقت ليفحص موقع تشغيل الملف كل ثانية
التطبيق في الرد التالي :
..
إعذرونا , سنضطر للغياب فترة كبيرة
الأمر ليس بيدنا ...... فسامحونا
التطبيق
إفتح تطبيق الدرس السابق , وأضف زرين للتقديم والتأخير
أضف مؤقت Timer , ستلاحظ انه سيضاف إلى الشريط الأصفر تحت نافذة التصميم

إختر المؤقت وقم بتعديل خاصية Interval إلى 1000 ,"ثانية واحدة"
وعدل قيمة الخاصية Enabled إلى True , هذه الخاصية تقوم بتشغيل أو تعطيل عمل الموقت
فإذا كانت القمية True فالمؤقت مفعل , أما إذا كانت False فهو معطل ولن يعمل

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

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

كائن التنقل يرجع قيمة بين الخاصيتين Minimum و Maximum
فمثلاً إذا كان Minimum = 0 و Maximum=50 فإن الخاصية Value سترجع قيمة بين 0 و 50
تمثل مكان المؤشر بالنسبة للكائن فمثلاً إذا كان المؤشر في منتصف الكائن فإن Value سترجع الرقم 25
وبما اننا نحتاج للتنقل عبر الملف فالمفروض أن نعدل الخاصية Minimum إلى 0
ونعدل الخاصية Maximum إلى طول الملف حتى ترجع القمية Value رقم بين 0 وطول الملف
وبما أن طول كل ملف يختلف عن الملف الآخر , فإننا سنعدل الخاصية Maximum عند تحميل أي ملف
ولن نحتاج لتعديل الخاصية Minimum لأن قيمتها الإفتراضية هي 0
سيصبح شكل النافذه هكذا:

إجراء ضبط كائن التنقل
إنقل هذا الكود إلى شفرة البرنامج مع مراعات أن يكون خارج أي إجراء آخر
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

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

* للأسف ليست كل الكائنات تدعم الخلفية الشفافة , فكائن التنقل مثلاً لا يدعمها ..
ملاحظة لمستخدمي بيئة Sharp Developer:
إحياناً عند الضغط المزدوج على المؤقت يحصل خطأ وتغلق بيئة التطوير
ولكتابة كود المؤقت إذا حدث هذا الخطأ دون الضغط مزدوجاً على المؤقت:
افتح شفرة التصميم من خلال فتح مستعرض الملفات ثم فتح MainForm.Designer.cs
و ابحث عن كود تعريف المؤقت وأضف بعده هذا السطر:
this.timer1.Tick+=new System.EventHandler(this.Timer1Tick);
كما في الصورة :

ثم إفتح شفرة البرنامج عند الإجراءات من خلال إختيار 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
حماة النهضة
إعذرونا , سنضطر للغياب فترة كبيرة
الأمر ليس بيدنا ...... فسامحونا
الدرس الثامن
المصفوفات:
المصفوفات هي عبارة عن مجموعة متغيرات من نفس النوع متراصة ومترابطة داخل كائن 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]
الكود السابق ينتج هذه الرسالة :

يمكن أيضاً تعديل أي عنصر من عناصر المصفوفة من خلال ترتيبة في المصفوفة :
string[] days= new string[]{"السبت","الأحد","الإثنين","الثلاثاء","الأربعاء","الخميس","الجمعة"};
days[4]="الأربعاء بعد التعديل";
MessageBox.Show(days[4]);في السطر الثاني غيرنا قيمة العنصر الذي ترتيبة 4 إلى "الأربعاء بعد التعديل"
الكود السابق ينتج الرسالة التالية :

القوائم
مع أن المصفوفات تعتبر من أهم هياكل البيانات التي استخدمت في لغات البرمجه منذ نشأتها
إلا أن لها عدداً من العيوب التي سعت 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 إذا لم يوجد العنصر في القائمة
مما سبق نستنتج أن القائمة أفضل بكثير وأسهل في الإستخدام من المصفوفة
وهذا ما سنستخدمه في تطبيقنا
يتبع التطبيق في الرد التالي:
إعذرونا , سنضطر للغياب فترة كبيرة
الأمر ليس بيدنا ...... فسامحونا
التطبيق:
تشغيل أكثر من ملف
سنضيف خاصية جديدة للبرنامج وهي فتح أكثر من ملف وإضافتها إلى قائمة التشغيل
حيث سنستخدم قائمة عناصرها من نوع نص لتخزين مسارات الملفات في قائمة التشغيل
إفتح تطبيق الدرس السابق , ومن صندوق الأدوات قم بسحب أداة القائمة :

من خلال الخاصية (Name) في جدول الخصائص قم بتغيير إسم القائمة من ListBox1 إلى pl
ليسهل التعامل معها من الشفرة , هذه هي قائمة التشغيل
قم بإعادة ترتيب الأدوات في النافذة حتى يصبح شكلها هكذا :

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

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

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

الآن سنعرف متغير عام من نوع قائمة عناصرها نصوص لخزن مسارات الملفات المختارة بأداة إختيار الملفات
كائن القائمة موجود في فضاء الأسماء System.Collections.Generic لذلك يجب إضافة عبارة using لتضمين كائنات ودوال الفضاء
إذهب إلى شفرة النافذة وأضف عبارة using التالية تحت عبارات using الموجوده في رأس الصفحة :
using System.Collections.Generic;
إذهب إلى شفرة البرنامج وقم بكتابة الكود التالي تحت كود تعريف كائنات Audio و Vedio و type :
public List<string> albume=new List<string>();

تحميل قيم القائمة
أداة إختيار الملفات 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
..
عند تشغيل البرنامج حالياً وإختيار عدة ملفات ستنتقل جميع أسماء الملفات إلى قائمة التشغيل
ويبدأ البرنامج بتشغيل أول ملف في القائمة :

إختيار الملف من قائمة التشغيل
إذهب إلى التصميم , وأنقر مزدوجاً على قائمة التشغيل , ستنتقل إلى شفرة البرنامج
أنسخ الكود التالي حيث مؤشر الفارة " بين حاصرتي إجراء 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
حماة النهضة
إعذرونا , سنضطر للغياب فترة كبيرة
الأمر ليس بيدنا ...... فسامحونا
دروس راااائعة, الله يوفقكم ويعينكم على هذا العمل الجبار
السؤالاول: حول عملية ال compilation هل C# يترجم الى البايت كود مثل java
السؤال الثاني: هل استطيع انشاء مساريح للمبايل أو ال pocket pc بال C#
و شكرا
السلام عليكم
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
حماة النهضة
إعذرونا , سنضطر للغياب فترة كبيرة
الأمر ليس بيدنا ...... فسامحونا
السلام عليكم ورحمه الله وبركاته
إن شاء الله فى الأسفل واجب الدرس السابع والثامن
وأسف على تأخير الواجب لظروف الأمتحانات
وليا سؤال تانى هو إزاى أخلى مثلا زرار play له شكل المثلث كما فى الميديا بلير مثلا
ومشكور أخى على المجهود الرائع MyMediaPlayer7___8.rar
وعليكم السلام ورحمة الله وبركاته
عمرو الحمصى
موفق أخي في الأمتحانات إن شاء الله :)
اقتباسوليا سؤال تانى هو إزاى أخلى مثلا زرار play له شكل المثلث كما فى الميديا بلير مثل
أي زر لازم يكون شكلة مربع , لكن يمكن خداع المستخدم بإستخدام صور gif
حيث يتخذ الزر شكل الصورة , وذلك من خلال إضافة الصورة إلى الخاصية BackgroundImage
من خصائص الزر
..
7oma
حماة النهضة
إعذرونا , سنضطر للغياب فترة كبيرة
الأمر ليس بيدنا ...... فسامحونا
الدرس التاسع
إنتاج أرقام عشوائية
ربما يتسائل البعض ما الذي يدعونا لإنتاج أرقام عشوائية وفي اي شيئ سنستخدمها
حسناً , يعتبر إنتاج الأرقام العشوائية من اهم الدعائم التي ترتكز عليها أنظمة الذكاء الإصطناعي والشبكات العصبية الإصطناعية
وإنتاج الأرقام العشوائية ليس بالسهولة التي تتصورها
حيث تستخدم خوارزمية شديدة التعقيد لغرض أنتاج أرقام لا معنى لها
تكمن الصعوبة في الخوارزمية أن أنظمة الحاسوب لاتستطيع أن تنتج أي شي لامعنى له
فلا يوجد شيئ "عشوائي" في أنظمة الحاسوب
ولكن خوارزميات إنتاج الأرقام العشوائية تستخدم الكثير من المدخلات من مصادر مختلفة لإنتاج الأرقام العشوائية
كأن تأخذ تاريخ ووقت النظام , وتجري عليه عددا من الدوال والحسابات
في برنامجنا سنضيف اليوم خاصية إختيار طريقة تشغيل الملفات , إما تتابعية أو عشوائية
تتابعية يعني أن يشغل البرنامج الملف الأول في قائمة التشغيل وعند الإنتهاء منه يشغل الملف الثاني وهكذا
أما الطريقة العشوائية فهي أن يقوم البرنامج بالحصول على رقم عشوائي بين الصفر و عدد الملفات في قائمة التشغيل ويبدأ بتشغيلة
وعند الإنتهاء منه يحصل على رقم عشوائي ويشغل ملف آخر وهكذا.
في لغة 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
إعذرونا , سنضطر للغياب فترة كبيرة
الأمر ليس بيدنا ...... فسامحونا
التطبيق
إفتح تصميم البرنامج , ومن صندوق الأدوات قم بسحب كائن صندوق المجموعة Group Box إلى الفورم الرئيسي:

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

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

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

إختر زر الإختيار المسمى radioButton1 وإذهب إلى جدول الخصائص
وغير الخاصية (Name) من radioButton1 إلى serbtn
وغير الخاصية Text من radioButton1 إلى تتابعي
وغير أيضاً الخاصية Checked إلى true
إختر زر الإختيار الأخر المسمى radioButton2 وإذهب إلى جدول الخصائص
وغير الخاصية (Name) من radioButton2 إلى rndbtn
وغير أيضاً الخاصية Text من radioButton2 إلى عشوائي
عدل ترتيب الأدوات في النافذه حتى يصبح شكلها هكذا :

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

إجراء تشغيل الملف الحالي
الإجراء 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
لكن هناك مشكلة , فالمؤقت يغير قيمة الشريط كل ثانية واحدة
إعذرونا , سنضطر للغياب فترة كبيرة
الأمر ليس بيدنا ...... فسامحونا
التطبيق
إفتح تصميم البرنامج , ومن صندوق الأدوات قم بسحب كائن صندوق المجموعة Group Box إلى الفورم الرئيسي:

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

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

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

إختر زر الإختيار المسمى radioButton1 وإذهب إلى جدول الخصائص
وغير الخاصية (Name) من radioButton1 إلى serbtn
وغير الخاصية Text من radioButton1 إلى تتابعي
وغير أيضاً الخاصية Checked إلى true
إختر زر الإختيار الأخر المسمى radioButton2 وإذهب إلى جدول الخصائص
وغير الخاصية (Name) من radioButton2 إلى rndbtn
وغير أيضاً الخاصية Text من radioButton2 إلى عشوائي
عدل ترتيب الأدوات في النافذه حتى يصبح شكلها هكذا :

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

إجراء تشغيل الملف الحالي
الإجراء 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:

ستنتقل إلى شفرة البرنامج إلى إجراء 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
حماة النهضة
إعذرونا , سنضطر للغياب فترة كبيرة
الأمر ليس بيدنا ...... فسامحونا
هذا الموضوع مغلق.
المتواجدون خلال آخر دقيقتين · يتحدّث كل ٣٠ ثانية
جارٍ التحقق من المتواجدين…