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

اضف إلى معلوماتك : تلميحات و خدع

مثبّترائج
بدأه محمد رضى في 12 سبتمبر 2009 · 69 رد · 30,544 مشاهدة · في قسم الدروس والمواضيع المتميزة
مشاركة: واتساب X فيسبوك تيليجرام
#26

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

شكرا لك أخي محمد علاء على مرورك و تفاعلك...

أبسط طريقة لضغط محتوى مجلد إلى ملف ZIP؟

post-207152-1255609509_thumb.jpg

منذ إصدارة ME, أصبح بمقدور ويندوز التعامل مع ملفات ZIP و كأنها مجلدات شبه عادية. في هذه التلميحة سنستعمل خدعة بسيطة لتسهيل ضغط محتوى مجلد نحو ملف من نوع ZIP. الخدعة تتمحور في إنشاء ملف جديد و كتابة رأس ملف ZIP فيه. رأس ملف ZIP مكون من 21 بايت. أول و ثاني بايت تكون توقيع ملفات ZIP الذي هو PK. ثالث و رابع بايت تكون معرفا بأن الملف المضغوط هو مجلد و تأخذ القيمتين 5 و 6.

أولا نقوم بإنشاء ملف ZIP فارغ :

		  ' إنشاء و كتابة ملف زيب فارغ
		  Dim B(21) As Byte
		  B(0) = 80 : B(1) = 75 : B(2) = 5 : B(3) = 6
		  IO.File.WriteAllBytes("file.zip", B)

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

		  ' نقل الملفات إلى ملف زيب الفارغ
		  Dim sh As New Shell32.Shell
		  Dim sf As Shell32.Folder = sh.NameSpace("path") ' مسار المجلد المراد ضغطه
		  Dim df As Shell32.Folder = sh.NameSpace("file.zip") ' اسم و مسار ملف زيب الذي سيستقبل محتوى المجلد
		  ' إبتداءا من إصدارة ME أصبح بمقدور ويندوز التعامل مع ملفات زيب و كأنها مجلدات "تقريبا" عادية
		  sf.CopyHere(df)

قبل الإنتهاء و جب الإعلام بضرورة استعمال إجراءات Shell في عملية نسخ المعلومات إلى ملف ZIP لتتم العملية كما يجب. في الكود أعلاه استعملنا مكتبة Microsoft Shell Controls And Automation التي نحتاج إلى زيادة Reference لها على المشروع و ذلك بفتح نافذة تكوين و تهيئة المشروع باختيار Project من القائمة الرئيسية ثم Properties لاسم المشروع و عند ظهور النافذة نختار صفحة References ثم نضغط على الزر Add.

تحياتي...

Folder2Zip.zip

تم تعديل هذه المشاركة بواسطة محمد رضى في 15 أكتوبر 2009 في 15:29

1
#27

الله ينور عليك يابو حميد

ياريت تشرح طريقة الضغط باستخدام مجال الأسماء System.IO.Compression لتكون الفائدة أكبر :blush:

وربنا يكرمك على الموضوع الجميل ده

خمس نجوم

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

feed.1.gif

#28

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

منور الموضوع و المنتدى أخي العزيز محمد و مازلت أنتظر ردك بخصوص درس ضغط و فك ضغط الملفات باستخدام فضاء الأسماء System.IO.Compression...

كيف تربط Enum بمربعات من نوع Combo box أو ListBox؟

قبل اكتشاف هذه التلميحة, كنت أربط مربعات Combo box أو ListBox التي لا تحتاج إلى عدد كبير من البيانات باستعمال مصفوفة من كائنات فئة بها على الأقل عضوين ID و Name أو غيرها. في هذه الحالة, ربط مربعات اللوائح مع Enum يكون أحسن لسهولة استعمال هذه الأخيرة و فعاليتها. و هذه طريقة الربط :

لنفترض أننا نريد ربط Enum تحوي أسماء أيام الأسبوع مع مربع لائحة من نوع Combo box. Enum معرفة كالتالي :

	Private Enum DayNames
		الإثنين = 1
		الثلاثاء = 2
		الأربعاء = 3
		الخميس = 4
		الجمعة = 5
		السبت = 6
		الأحد = 7
	End Enum

بعد ذلك, ربط Enum بمربع اللائحة يتم في سطر واحد في الحدث Load مثلا :

 ComboBox1.DataSource = [Enum].GetValues(GetType(DayNames))

للحصول على كائن من نوع Enum المرتبط بمربع اللائحة الذي هو في حالتنا هذه DayNames نقوم بتحويل قيمة الخاصية SelectedValue لمربع اللائحة إلى نوع Enum المرتبط بالمربع :

 Dim dn As DayNames = CType(ComboBox1.SelectedValue, DayNames)

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

	Private Sub ComboBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ComboBox1.SelectedIndexChanged
		Dim dn As DayNames = CType(ComboBox1.SelectedValue, DayNames)
		TextBox1.Text = "Day name : " + dn.ToString() + vbCrLf
		TextBox1.Text = TextBox1.Text + "Day number : " + CType(dn, Integer).ToString()
	End Sub

تحياتي...

#29

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

كيف تظهر الصور المتحركة على مشاريع الدوت نت؟

post-207152-1255810073_thumb.jpg

عذرا أخي محمد لاستعمال صورتك الافتراضية بدون أخد إذنك...

في هذه الإضافة سنتكلم, إن شاء الله, عن كيفية تحريك صور متحركة من نوع GIF و غيرها. لتسهيل فهم هذه التلميحة, سنبسط الأشياء إلى أبعد حد. سنحتاج في البداية إلى كائن من نوع Image الذي سنقوم بتحميل الصورة المتحركة عليه :

	  ' الكائن الذي سيحوي الصورة
	  Private img As Image

سنحتاج إلى كائن من نوع FrameDimension الذي سيمكننا من قراءة خصائص الصورة المتحركة و اختيار صورة من بين الصور الإجمالية التي تحويها :

	  ' خصائص الصور التي تحويها الصورة المتحركة
	  Private dims As FrameDimension

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

	  ' عدد الصور التي تحويها الصورة المتحركة
	  Private frames As Integer
	  ' رقم الصورة الحالية
	  Private current As Integer

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

	  Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
		  ' رقم صورة البداية
		  current = 0
		  ' تحميل الصورة المتحركة
		  img = Image.FromFile("MVQQ62R4.GIF")
		  ' الحصول على خصائص الصورة المتحركة
		  dims = New FrameDimension(img.FrameDimensionsList(0))
		  ' عدد الصور
		  frames = img.GetFrameCount(dims)
	  End Sub

ما يهمنا هنا هو فهم العملية و لهذا فلن نتطرق إلى الإستعمالات المتقدمة لهذه التقنية من دقة الوقت بين الصور و غيرها. سنستعمل كائن Timer ليعلمنا بحلول وقت عرض الصورة التالية التي سنحصل عليها بالكود التالي :

	  Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
		  ' تحديد الصورة الحالية من بين العدد الإجمالي للصور
		  img.SelectActiveFrame(dims, current)
		  ' تحديد رقم الصورة التالية
		  current = IIf(current < frames - 1, current + 1, 0)
		  ' طلب إعادة رسم محتوى الفورم رسم الصورة على الفورم
		  Me.Invalidate()
	  End Sub

و أخيرا سنقوم برسم الصورة الحالية على الفورم عند الحدث Paint :

	  Private Sub Form1_Paint(ByVal sender As System.Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint
		  ' رسم الصورة الحالية على الفورم
		  e.Graphics.DrawImage(img, (ClientSize.Width - img.Width) / 2.0F, (ClientSize.Height - img.Height) / 2.0F)
	  End Sub

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

في الملف المرفق مشروع صغير به الكود الكامل مع التعليق.

تحياتي...

WindowsApplication5.rar

تم تعديل هذه المشاركة بواسطة محمد رضى في 17 أكتوبر 2009 في 23:13

#30

هل يمكن بإستخدام الـ FrameDimension تحميل و عرض صور من نوع MNG ؟ ام لابد من عمل فئه خاصه بهذا النوع من الصور ؟

و الله ولى التوفيق

مدونتي: C++ Tips and Tricks

#31

ماشاء الله عليك يابو حميد ,, جميل جدا الموضوع ده

اقتباس
منور الموضوع و المنتدى أخي العزيز محمد و مازلت أنتظر ردك بخصوص درس ضغط و فك ضغط الملفات باستخدام فضاء الأسماء System.IO.Compression...

هو انا مش رديت عليك وقتها ؟!! :huh:

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

feed.1.gif

#32
اقتباس
هو انا مش رديت عليك وقتها ؟!!

لا, لم يصلني الرد!

اقتباس
هل يمكن بإستخدام الـ FrameDimension تحميل و عرض صور من نوع MNG ؟ ام لابد من عمل فئه خاصه بهذا النوع من الصور ؟

FrameDimension لا تدعم Animated PNG و لا MNG حتي IE8 لا يعرضها بل فقط يظهر الصورة الأولى. FireFox يعرضها. على الموقع http://www.libmng.com/ الكثير من المكتبات و لكن و لا واحدة للدوت نت...

تحياتي...

#33

انا اقصد حيث انه يتم عرض الـ Frame الأول من الصوره فبهذا يتم التعامل معها على انها صورة png لذا يمكن فتحها بإستخدام الفئه image و بالتالى و بإستخدام الخصائص المتوفره داخل هذه الفئه يمكن الحصول على باقى الـ Frames.

و الله ولى التوفيق

مدونتي: C++ Tips and Tricks

#34
اقتباس
لا, لم يصلني الرد!

الرد:

يمكنك وضع رابط الموضوع الآخر هنا وتحويل الكود إلى VB أو تكتفى بالإشارة إلى الموضوع فقط كما تحب

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

feed.1.gif

#35
اقتباس
انا اقصد حيث انه يتم عرض الـ Frame الأول من الصوره فبهذا يتم التعامل معها على انها صورة png لذا يمكن فتحها بإستخدام الفئه image و بالتالى و بإستخدام الخصائص المتوفره داخل هذه الفئه يمكن الحصول على باقى الـ Frames.

الجملة :

		  ' عدد الصور
		  frames = img.GetFrameCount(dims)

ترجع دائما العدد 1 عندما تكون Image تحوي صورة متحركة من نوع PNG بالنسبة للنوع MNG فلم أجد أي صورة للتجريب و حتما ستعطي نفس النتيجة.

اقتباس
الرد:

يمكنك وضع رابط الموضوع الآخر هنا وتحويل الكود إلى VB أو تكتفى بالإشارة إلى الموضوع فقط كما تحب

سوف أحرر الرد المعني بالأمر لإضافة رابط الموضوع الذي يحوي كما قلت لك كود VB.NET و C#

تحياتي...

#36

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

التلميحة القديمة الجديدة : كيف تنشئ مجلدا مشخصا بأيقونة و وصف؟

post-207152-1255960088_thumb.jpg

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

1 : إنشاء المجلد الجديد و تحديد وسم النظام عليه.

2 : تجهيز سيناريو تشخيص المجلد. إنتظر قليلا...

3 : إنشاء ملف desktop.ini داخل المجلد الجديد, كتابة سيناريو التشخيص فيه ثم إخفاء الملف و تحديد وسم النظام عليه.

سيناريو تشخيص المجلد بأيقونة و النص الوصفي له يكون بالشكل التالي :

   
  [.ShellClassInfo]
  IconFile=file.ext
  IconIndex=number
  IconResource=file.ext, number
  ConfirmFileOp=0
  InfoTip=description

IconFile : يقبل اسم ملف يحوي الأيقونة التي نريد.

IconIndex : رقم الأيقونة بين الأيقونات التي يحويها الملف المحدد على IconFile.

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

ConfirmFileOp : حسب أهمية المجلد, إذا كان مجلد به بيانات حساسة نحدد 1 كي يظهر النظام مربع حوار تنبيهي عند محاولة المستخدم حذف المجلد. يحدد على صفر إفتراضيا.

InfoType : النص الوصفي للمجلد. على نسختي ويندوز فيستا لا يظهر هذا النص لكن أبقيت عليه في حالة دعم الإصدارات الأخرى لهذه الخاصية.

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

الكود معلق عليه بالتفصيل :

	  ''' <summary>
	  ''' تنشئ مجلدا جديدا مشخصا بأيقونة و وصف.
	  ''' </summary>
	  ''' <param name="DstFolder">مسار مجلد الوجهة.</param>
	  ''' <param name="FolderName">اسم المجلد الجديد.</param>
	  ''' <param name="IconFile">اسم و مسار الملف الذي يحوي الأيقونة.</param>
	  ''' <param name="IconNumber">رقم الأيقونة على الملف</param>
	  ''' <param name="FolderDesc">نص وصفي للمجلد الجديد.</param>
	  Public Function CreateUserDefinedFolder(ByVal DstFolder As String, ByVal FolderName As String, ByVal IconFile As String, ByVal IconNumber As Integer, ByVal FolderDesc As String) As Boolean
		  If Directory.Exists(DstFolder) Then ' إذا كان المجلد الوجهة موجودا
			  If FolderName <> "" Then ' إذا تم تحديد اسم المجلد الجديد
				  If File.Exists(IconFile) Then ' إذا كان ملف الأيقونة موجودا
					  If FolderDesc <> "" Then ' إذا كان وصف المجلد الجديد غير فارغ
						  Try
							  ' تحديد مسار المجلد الجديد
							  Dim path As String = DstFolder + "\" + FolderName
							  ' إنشاء المجلد الجديد
							  Directory.CreateDirectory(path)
							  ' مجلد مشخص يجب أن يكون له وسم النظام
							  File.SetAttributes(path, FileAttributes.System)
							  ' تحديد سيناريو تشخيص المجلد. أنظر التلميحة على المنتدى
							  Dim folder_ini As String = vbCrLf + "[.ShellClassInfo]" + vbCrLf + "IconFile=" + IconFile + _
															  vbCrLf + "IconIndex=" + IconNumber.ToString() + _
															  vbCrLf + "IconResource=" + IconFile + ", " + IconNumber.ToString() + _
															  vbCrLf + "ConfirmFileOp=0" + vbCrLf + "InfoTip=" + FolderDesc + vbCrLf
							  ' تحديد مسار ملف تهيئة المجلد
							  Dim desktop_ini As String = path + "\Desktop.ini"
							  ' إنشاء ملف تهيئة المجلد و كتابة السيناريو داخله
							  File.WriteAllText(desktop_ini, folder_ini)
							  ' ملف تهيئة المجلد يجب أن يكون مخفيا و له وسم النظام
							  File.SetAttributes(desktop_ini, FileAttributes.Hidden Or FileAttributes.System)
						  Catch ex As Exception
							  MsgBox("حدث خطأ أثناء عملية إنشاء و تشخيص المجلد الجديد..." + vbCrLf + ex.Message, MsgBoxStyle.Exclamation, "خطأ...") 
							  Return False
						  End Try
					  Else
						  MsgBox("المرجو إدخال وصف المجلد.", MsgBoxStyle.Exclamation, "خطأ...")
						  Return False
					  End If
				  Else
					  MsgBox("المرجو اختيار ملف الأيقونة المراد إضهارها على المجلد.", MsgBoxStyle.Exclamation, "خطأ...")
					  Return False
				  End If
			  Else
				  MsgBox("المرجو إدخال اسم صحيح للمجلد الجديد.", MsgBoxStyle.Exclamation, "خطأ...")
				  Return False
			  End If
		  Else
			  MsgBox("المرجو اختيار المجلد الذي سيتم بداخله انشاء المجلد الجديد.", MsgBoxStyle.Exclamation, "خطأ...")
			  Return False
		  End If
		  ' نجحت العملية
		  Return True
	  End Function

في الملف المرفق مشروع صغير به كل الكود الذي تتكلم عليه هذه التلميحة.

تحياتي...

UserDefinedFolder.rar

تم تعديل هذه المشاركة بواسطة محمد رضى في 19 أكتوبر 2009 في 16:54

#37

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

كيف تغير قيمة الخصائص و الحقول المقروءة فقط؟

سنتكلم في هذه الإضافة, إن شاء الله, عن خدعة تمكننا من الكتابة في حقل أو خاصية غير مقروءة (محمية بوسم ReadOnly).

من منا لم يفكر يوما في تغيير قيمة حقل مقروء فقط عندما تستنفذ كل طرق البحث عن خطأ ما؟!

الخدعة تتم بالمرور عبر Reflection للوصول إلى الكائن أو المتغير المقروء فقط بطريقة غير مباشرة.

ملاحظة : لتغيير قيمة خاصية موسومة بـ ReadOnly يجب البحث عن اسم الكائن أو المتغير الذي تحفظ فيه الخاصية قيمتها.

الكود بسيط و معلق عليه بالتفصيل :

Module Module1

	Sub Main()
		' الكائن الذي نريد كتابة خاصيته المقروءة فقط
		Dim tst As New Test()
		' للتجربة فقط
		Console.WriteLine(tst.ReadOnlyProperty)
		' الحصول على نوع الكائن
		Dim t As Type = tst.GetType()
		' الحصول على الكائن الذي يمثل الحقل الذي نريد
		Dim fi As Reflection.FieldInfo = t.GetField("ReadOnlyPropertyValue", Reflection.BindingFlags.NonPublic Or Reflection.BindingFlags.Instance)
		' تغيير القيمة
		fi.SetValue(tst, "I changed it!")
		' لمعرفة القيمة الجديدة للخاصية المقروءة فقط
		Console.WriteLine(tst.ReadOnlyProperty)
	End Sub

	' الفئة التي نريد تغيير قيمتها المقروءة فقط
	Public Class Test
		Sub New()
			' تحديد قيمة الخاصية المقروءة فقط
			ReadOnlyPropertyValue = "This must never change from out side!"
		End Sub

		' قيمة الخاصية المقروءة فقط
		Private ReadOnlyPropertyValue As String
		' الخاصية المقروءة فقط و التي نريد كتابة قيمة أخرى فيها
		Public ReadOnly Property ReadOnlyProperty() As String
			Get
				Return ReadOnlyPropertyValue
			End Get
		End Property
	End Class
End Module

تحياتي...

تم تعديل هذه المشاركة بواسطة محمد رضى في 20 أكتوبر 2009 في 16:56

#38

بســم الله الـرحمــن الرحيــم

التاليه هى تلميحه برمجيه كنت قد قرأتها داخل الـ MSDN يوما ما و هى خاصه بجملة If

لجملة if طريق عديده فى الكتابه و هى تأخذ الشكل التالى

If condition Then
   ...
   ...
End If


If condition Then
   ...
   ...
Else
   ...
   ...
End If

If condition Then
   ...
   ...
Elseif condition Then
   ...
   ...
End If

If condition Then
   ...
   ...
Elseif condition Then
   ...
   ...
Else
   ...
   ...
End If

ايضا توجد لدينا الداله IIF و التى عبارة عن compact if (هى فى الحقيقه triple operator فى عائلة الـ C) و تستخدم كالتالى

Dim ret As Object = IIF (condition, TruePart, FalsePart)

بالطبع السابق كله نعرفه و لكن التالى هو التالى هو الذى قد لا تعرفه.

يوجد داخل الـ VB.Net المعامل If، نعم لقد قرأت الجمله بشكل سليم المعامل If و هو نسخه مصغره من جملة If، هذا المعامل يمكن استخدامه بصورتين و يأخذوا الشكل التالى

Dim ret As Object = If (condition, TruePart, FalsePart)

السابقه هى مشابهه لـ IIF حيث اذا كان المعامل الأول True سيتم العوده بالمعامل الثانى، واذا كان المعامل الأول False يتم العوده بالمعامل الثالث.

Dim ret As Object = If (TruePart, FalsePart)

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

هذه النسخه يتم تمرير لها معاملان فإن كان الأول Nothing يتم العوده بالمعامل الثانى و غير ذلك يتم العوده بالمعامل الأول، بسيطه مش كده.

اذا كان لديك كائن X و لديك بديل لهذا الكائن و هو Y فى حالة ان الكائن X قد يكون Nothing فقط قم بتمريره كمعامل اول و مرر Y كمعامل ثانى و سيتم العوده بـ X إن كان صالحا او Y ان كان X غير صالح.

هذه النسخه قد تكون فعاله جدا كبديل لـ TryCast او يمكن دمج TryCast معها لحصول على كود صغير اسرع من اى كود اخر.

ارجو ان تكون هذه التلميحه مفيده، و شكرا للأخ محمد رضا لوضعه موضوع قيم و شيق كهذا.

و الله ولى التوفيق

تم تعديل هذه المشاركة بواسطة Muhammad alaa في 21 أكتوبر 2009 في 03:10

مدونتي: C++ Tips and Tricks

#39

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

أشكرك أخي محمد علاء على المشاركة القيمة و أتمنى أن ينظم باقي الأعضاء و يدلون بدلوهم في الموضوع حتى تعم الفائدة على الجميع...

كيف تعرف الدالة التي قامت بالنداء على الدالة الحالية؟

مباشرة مع الكود :

Module Module1

	Sub Main()
		JustASub()
	End Sub

	Sub JustASub()
		' إنشاء الكائن الذي سيملؤ بلائحة الدوال المنادى عليها حاليا في Stack
		Dim st As New StackTrace()
		' الوصول إلى الدالة الثانية التي قامت بالنداء على الدالة الحالية التي تأخد الرقم 0 في السلسلة
		Dim sf As StackFrame = st.GetFrame(1)
		' الحصول على الكائن الذي يحوي كل خصائص الدالة المنادية
		Dim mtd As Reflection.MethodInfo = sf.GetMethod()
		' كتابة اسم الدالة التي نادت على الدالة الحالية
		Console.WriteLine(mtd.Name) ' تكتب "Main"
	End Sub
End Module

نبدأ بالحصول على كائن من نوع StackTrace الذي عند إنشاءه يقرأ لائحة الدوال الحالية على Stack التي تنتظر إنتهاء تنفيذ الدوال المنادى عليها لتنهي تنفيذ كودها هي الأخرى.

بعدها نحصل على كائن من نوع StackFrame الذي يرجع لنا معلومات أي دالة في لائحة الدوال الحالية على Stack في كائن من نوع MethodInfo عن طريق المناداة على الدالة StackFrame.GetMethod()

الكائن من نوع MethodInfo به كل المعلومات اللازمة للتعرف على دالة ما.

الخاصية Name : ترجع لنا اسم الدالة

الخاصية Module : ترجع لنا معلومات الموديل الذي تم تعريف الدالة فيه.

الخصائص IsXXXXX : من بينها IsPublic, IsPrivate, IsStatic و غيرها.

الدالة GetParameters : ترجع لنا معلومات عن الوسائط المعرفة بها الدالة.

الدالة Invoke : للمناداة على الدالة.

الدالة GetMethodBody : ترجع لنا كائن من نوع MethodBody الذي يمكننا من الوصول إلى كود MSIL للدالة إضافة إلى المتغيرات الداخلية و الاستثناءات.

للمزيد من المعلومات الرجاء البحث على MSDN

تحياتي...

#40

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

كيف تتجاهل دوال محددة وقت تنفيذ الكود جملة جملة على Debugger؟

أنت الآن تنفذ الكود جملة جملة بالضغط على الزر F11 بحثا عن خطأ ما و لكن في كل مرة تكون مضطرا للدخول إلى دالة حيث أنت متأكد مائة بالمائة أن الخطأ لا يوجد فيها. هذه الدالة يمكن أن تكون حدث لـ Timer مثلا أو حدث تغيير محتوى خاصية أو غيرها. في كل مرة تكون مضطرا لاستعراض جملها وتنفيذها واحدة واحدة مع أنك تعرف أن الخطأ ليس فيها, فما هو الحل لتجاهلها؟!...

الحل يكمن في زيادة وسم عند رأس الدالة لإعلام VS Debugger بتجاهل الدالة و تنفيذ جملها مرة واحدة. الوسم :

 <System.Diagnostics.DebuggerStepThrough()>

لاحظ معي الكود التالي :

Module Module1

	' قم بتنفيذ البرنامج جملة جملة بالنقر المتتابع على الزر F11
	Sub Main()
		' النقر على الزر F11 هنا لن يدخلنا إلى محتوى الدالة. لاحظ كود الدالة و الوسم الموجود على رأسها
		StepThroughSub()
		' النقر على الزر F11 سينقلنا إلى أول جملة في الدالة.
		StepInSub()
	End Sub

	Sub StepInSub()
		Console.WriteLine("In StepInSub")
	End Sub

	''' <summary>
	''' هذه الدالة موسومة بوسم DebuggerStepThrow الذي سيؤدي إلى تجاهل الدخول إلى الدالة 
	''' Break points الموجودة داخلها.و كذلك تجاهل
	''' </summary>
	<System.Diagnostics.DebuggerStepThrough()> _
	Sub StepThroughSub()
		Console.WriteLine("In StepThroughSub")
	End Sub
End Module

عند أول ضغطة على الزر F11 سيتم التوقف على الجملة Sub Main() في انتظار ضغطة أخرى التي ستدخلنا داخل الدالة Main و تتوقف عند الجملة StepThroughSub(). ضغطة أخرى على الزر F11 ستنفذ الجمل داخل الدالة و تخرج منها تم تعود و تتوقف عند الجملة التالية StepInSub(). ضغطة أخرى للزر F11 ستدخلنا الدالة StepInSub و الضغطات التالية تنفذ جمل الدالة واحدة واحدة. الوسم <System.Diagnostics.DebuggerStepThrough()> الموجود على رأس الدالة StepThroughSub() هو الذي يؤدي إلى تجاهلها أثناء عملية تنفيذ الكود جملة جملة عبر الضغط على الزر F11. الوسم كذلك يسبب تجاهل Break points الموجود داخل الدالة.

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

هذه التلميحة ستساهم حتما في نقص عدد المبرمجين دوي الشعر الشايب في الوطن العربي :D

تحياتي...

#41

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

مربع بروجرس بار عمودي لمشاريعكم

post-207152-1256165221_thumb.jpg

لتغيير اتجاه مربع بروجرس بار من الإتجاه العادي له إلى الإتجاه العمودي من الأسفل صعودا نحو الأعلى, سنقوم بإنشاء فئة بسيطة جدا تقوم بتغيير معامل إنشاء المربع و تظمن له الثابت PBS_VERTICAL داخل الخاصية CreateParams. الفئة VerticalProgressBar سترث من الفئة الأصلية ProgressBar و لن يكون هناك أي تغيير آخر غير التعديل على الخاصية CreateParams.

الكود :

' مربع بروجرس بار عمودي
Public Class VerticalProgressBar
	' الفئة سترث من مربع بروجرس بار الأصلي
	Inherits ProgressBar

	' ثابت تغيير طريقة إنشاء المربع
	Private Const PBS_VERTICAL As Integer = &H4

	' تتم قراءة محتوى الخاصية عند إنشاء المربع
	Protected Overrides ReadOnly Property CreateParams() As System.Windows.Forms.CreateParams
		Get
			' تغيير قيمة صيغة الإنشاء الإفتراضية و تضمين معامل الإنشاء العمودي
			Dim cp As CreateParams = MyBase.CreateParams
			cp.Style = cp.Style Or PBS_VERTICAL
			Return cp
		End Get
	End Property
End Class

تحياتي...

#42

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

كيف تظهر الصور المتحركة على مشاريع الدوت نت؟ (طريقة أخرى)

post-207152-1255810073.jpg

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

أولا سنحتاج إلى تعريف كائن لتحميل الصورة المتحركة :

	' الكائن الذي سيحتوي على الصورة المتحركة
	Private AnImage As Image = Nothing

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

	Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
		' تحميل الصورة
		AnImage = Image.FromFile("MVQQ62R4.gif")
		' بدء عملية عرض الصورة المتحركة
		ImageAnimator.Animate(AnImage, AddressOf ImageAnimator_OnFrameChanged)
	End Sub

نلاحظ في السطر الثاني للكود أعلاه أن الدالة Animate تستقبل عنوان دالة للمناداة عليها في كل مرة يحين فيها وقت إضهار الصورة التالية من مجموع صور الصورة المتحركة. يمكن المناداة على الدالة CanAnimate التي ترجع لنا ما إذا كانت الصورة AnImage صورة متحركة أم لا. الكود التالي للدالة المذكورة سابقا و التي ستقوم بطلب رسم الصورة التالية على الفورم :

	' حدث يحدث في كل مرة يأتي دور صورة أخرى للعرض
	Private Sub ImageAnimator_OnFrameChanged(ByVal sender As Object, ByVal e As EventArgs)
		' طلب رسم الصورة التالية
		Me.Invalidate()
	End Sub

و أخيرا, سنقوم بالتقاط الحدث Paint للفورم لرسم الصورة التالية من العرض :

	Private Sub Form1_Paint(ByVal sender As System.Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint
		' تجهيز الصورة التالية للعرض
		ImageAnimator.UpdateFrames(AnImage)
		' رسم الصورة على الفورم
		e.Graphics.DrawImage(AnImage, (ClientSize.Width - AnImage.Width) / 2.0F, (ClientSize.Height - AnImage.Height) / 2.0F)
	End Sub

لوقف العرض, ننادي على الدالة StopAnimate. لبدء عملية العرض, ننادي على الدالة Animate.

بالرغم من بساطة كود هذه الطريقة إلا أنني لاحظت أن فعالية الطريقة الأولى أحسن. الفئة ImageAnimator لا تدعم هي الأخرى الصور المتحركة من نوع PNG و MNG.

في الملف المرفق مشروع كود هذه التلميحة.

تحياتي...

WindowsApplication5.rar

تم تعديل هذه المشاركة بواسطة محمد رضى في 22 أكتوبر 2009 في 20:15

1
#43

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

كيف تظهر محتوى البيانات المسحوبة أثناء عملية سحب و إفلات؟

post-207152-1256248905_thumb.jpg

هذه التلميحة تتحدث عن كيفية إظهار محتوى البيانات المسحوبة أثناء عملية سحب و إفلات (Drag And Drop) مكان الصورة الصغيرة التي يأخد شكلها مؤشر الفأرة. إذا كنت من مستعملي متصفح الأنترنت فايرفوكس, قم بسحب صورة أو محتوى ما و سترى أن مؤشر الفأرة يأخد شكل المحتوى الذي قمت بسحبه. هذا ما سنتكلم عنه في هذه التلميحة.

كل العمل يتم داخل دالة الحدث GivFeedback التي تتم المناداة عليها عند بدء عملية سحب محتوى مربع. أحد معاملات هذه الدالة هو e من نوع GiveFeedbackEventArgs الذي يحوي الخاصية UseDefautCursors من نوع Boolean تأخد القيمة True في حالة ما أردنا من مسير واجهة المستخدم Shell أن يستعمل الصور الإفتراضية لمؤشر الفأرة. و تأخد القيمة False إذا ما أردنا تحديد صورة مشخصة لمؤشر الفأرة عن طريق إحالة الصورة إلى الكائن Cursor.Current

الكود :

	' يحدث في بداية عملية السحب لإعطاء الفرصة للكائن الذي بدأ عملية السحب
	' لتغيير صورة مؤشر الفأرة لإعطاء صورة مفهومة لعملية السحب و الإفلات
	Private Sub PictureBox1_GiveFeedback(ByVal sender As System.Object, ByVal e As System.Windows.Forms.GiveFeedbackEventArgs) Handles PictureBox1.GiveFeedback
		If e.Effect = DragDropEffects.All Then
			' إلغاء خاصية الصور الإفتراضية لمؤشر الفأرة لشيل
			e.UseDefaultCursors = False
			' تحديد محتوى صورة مؤشر الفأرة لعملية السحب و الإفلات
			Cursor.Current = New Cursor(CType(PictureBox1.Image, Bitmap).GetHicon())
		End If
	End Sub

تحدثنا في هذه التلميحة عن محتوى من نوع صورة و لكن يمكننا كذلك تحويل أي محتوى معروف إلى صورة كمثال إذا تم سحب نص من برنامج إلى مربع من نوع RichTextBox يمكننا كتابة النص المسحوب على صورة من نوع Bitmap و من تمة إضهار صورة النص كمؤشر للفأرة عندما يدخل إلى مربع النص. ربما أخصص تلميحة لهذه الحالة...

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

تحياتي...

TestLab.rar

#44

تم تثبيت الموضوع لأهميته وفوائده الكثيرة

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

feed.1.gif

#45

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

شكرا أخي محمد :)

كيف تتحكم في وقت تنفيذ Blocking Methods؟

Blocking Methods هي إجراءات تأخد وقتا طويلا لتنفيذ عملها مما يؤدي إلى توقف مؤقت (تهنيج) للبرنامج و تجمد واجهة المستخدم. هذه المدة حتى لو تم قياسها بثواني معدودة, تمر على المستخدم و كأنها سنوات! مما قد يؤدي به إلى الإنفعال و صب جام غضبه على الفأرة و لوحة المفاتيح بالضرب خصوصا المفتاحين ESC و Return...

نعود لموضوعنا, كمثال لهذه التلميحة سنتكلم عن الكائن TcpClient الذي بالطبع يأخد وقتا "طويلا" لربط الإتصال بالخادم خصوصا إذا كان الخادم أو الشبكة مشغولين كثيرا أو كان هناك خطأ في معلومات الربط... في هذه الحالة, كود ربط الإتصال بـ Blocking Method Connect يأخد تقريبا (على حاسوبي) 20 ثانية ليرفع استثناء بفشل عملية ربط الإتصال. الكود :

		' حفظ وقت بدء العملية
		Dim dt As DateTime = DateTime.Now
		' كائن العميل لربط الإتصال بالخادم
		Dim clt As New System.Net.Sockets.TcpClient()
		Try
			' ربط الإتصال
			clt.Connect("www.arabteam2000-forum.com", 6879)
		Catch
		End Try
		' حساب وقت عملية ربط الإتصال
		Dim ts As TimeSpan = DateTime.Now - dt
		Console.WriteLine(ts.ToString())
		' قطع الإتصال في حالة نجاحه
		If Not clt Is Nothing Then If clt.Connected Then clt.Close()

لتفادي هذه المشكلة سنقوم بتحديد مدة (Time out) عمل الدالة. سنستعمل هنا مقابل الدالة Connect التي هي الدالة BeginConnect. هذه الدالة ترجع لنا كائن من نوع الواجهة IAsyncResult الذي يمكننا من التحكم في مدة عملها و حتى إنهائها/إلغائها في أي لحظة. ملخص القول.. عموما, هناك دائما Non-Blocking Methods مقابلة للـ Blocking Methods في فئات الدوت نت و تكون مبتدئة بـ BeginXXXXXXX...

الكود :

		' تحديد مدة عملية ربط الإتصال
		Dim timeout As Integer = 2000
		' حفظ وقت بدء العملية
		Dim dt As DateTime = DateTime.Now
		' كائن العميل لربط الإتصال بالخادم
		Dim clt As New System.Net.Sockets.TcpClient()
		' بدء عملية الربط
		Dim iar As IAsyncResult = clt.BeginConnect("www.arabteam2000-

forum.com", 6879, Nothing, Nothing)
		' تحديد مدة عملية الربط و التوقف حتى انتهائها
		Dim success As Boolean = iar.AsyncWaitHandle.WaitOne(timeout, True)
		' عرض مدة عملية الربط
		Dim ts As TimeSpan = DateTime.Now - dt
		Console.WriteLine(ts.ToString())
		' التحقق من نجاح العملية
		If Not success Then
			' كود حالة الخطأ
		Else
			' كود نجاح العملية
			clt.EndConnect(iar)
			clt.Close()
		End If

الكود أعلاه يأخد مدة ثانيتين (2000 milliseconds) لتنفيذ كود ربط الإتصال. يحترم المدة المحددة سواء أتم العملية أم لم يتمها و لكنه يبقى Blocking على أي حال...

الحل الأمثل يكمن في تغيير الجملة التي تنادي على الدالة WaitOne إلى loop تنتظر انتهاء العملية و تمكن التطبيق من التقاط الرسائل و الأحداث و تنفيذها عن طريق المناداة على الدالة Application.DoEvents() حتى لا يتوقف البرنامج و لا تتجمد واجهة المستخدم.

		' حفظ وقت بدء العملية
		Dim dt As DateTime = DateTime.Now
		' كائن العميل لربط الإتصال بالخادم
		Dim clt As New System.Net.Sockets.TcpClient()
		' بدء عملية ربط الإتصال
		Dim iar As IAsyncResult = clt.BeginConnect("www.arabteam2000-

forum.com", 6879, Nothing, Nothing)
		' إنتظار انتهاء عملية ربط الإتصال
		While Not iar.IsCompleted()
			' إعطاء الفرصة لأحداث التطبيق حتى تأخد مجراها الطبيعي و منها 

تحديث واجهة المستخدم
			Application.DoEvents()
		End While
		' إضهار مدة عملية ربط الإتصال
		Dim ts As TimeSpan = DateTime.Now - dt
		Console.WriteLine(ts.ToString())
		' إنهاء عملية الإتصال
		clt.EndConnect(iar)
		' قطع الإتصال
		clt.Close()

قد يقول البعض أن تخصيص مسلك خاص للمناداة على الدالة Connect هو الحل لهذه المشكلة, لكن ما العمل إذا أراد المستخدم غلق البرنامج مباشرة بعد بدء عملية الربط. البرنامج سيتوقف و واجهة المستخدم ستجمد في انتظار انتهاء المسلك الخاص بعملية ربط الإتصال. لذا, فبنظري, أحد هاتين الطريقتين هو الأحسن في هذه الحالة. و أنا شخصيا أفضل الحل الأول في تطبيقات Console و الحل الثاني في تطبيقات Windows Forms Applications.

تحياتي...

#46

و الله اخى محمد إن اللسان يعجز عن وصف ما تفعله هنا فى هذا الموضوع، افكار متنوعه بشرح بسيط و فائده كبيره

حقيقى هذا الموضوع من اقيم المواضيع فى هذا المنتدى و فعلا جزاك الله خيرا على مجهودك به و زادك علما و نفعك به

و فقك الله اخى.

مدونتي: C++ Tips and Tricks

#47

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

شكرا أخي محمد و وفقني الله و إياك و جميع المسلمين لما يحب و يرضى.

كيف تصل إلى دالة محمية (Private و Protected) و تنادي عليها؟

كنا في خدعة سابقة قد تعلمنا كيفية تغيير محتوى الخصائص المقروءة فقط. في هذه التلميحة سنستعمل نفس التقنية للوصول إلى الدوال المحمية (Private و Protected) داخل الكائنات و المناداة عليها و استعمالها كما نريد. هذه الخدعة كذلك تتم بالمرور عبر Reflection و الوصول إلى الدالة بطريقة غير مباشرة. الكود :

Module Module1

	Sub Main()
		' إنشاء الكائن الذي يحوي الدالة الخاصة المحمية
		Dim tst As New Test()
		' الوصول إلى نوع الكائن الحاوي للدالة المحمية
		Dim t As Type = tst.GetType()
		' الحصول على الكائن الذي يحتوي على معلومات و بيانات الدالة
		Dim mtd As Reflection.MethodInfo = t.GetMethod("PrivateSub", Reflection.BindingFlags.Instance Or Reflection.BindingFlags.InvokeMethod Or Reflection.BindingFlags.NonPublic)
		' المناداة على الدالة التي لا يمكن الوصول إليها بالطرق العادية
		mtd.Invoke(tst, Nothing)
	End Sub

	' فئة للتجربة
	Class Test
		' عموما هذه الدالة لا يمكن المناداة عليها من خارج الفئة "تست" و حتى من فئة ترث منها...
		Private Sub PrivateSub()
			Console.WriteLine("PrivateSub reached from out side!")
		End Sub
	End Class
End Module

تحياتي...

تم تعديل هذه المشاركة بواسطة محمد رضى في 24 أكتوبر 2009 في 16:33

#48

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

أبسط طريقة لفك ضغط ملف مضغوط من نوع ZIP؟

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

كما ذكرت سابقا أنه بدءا من الإصدارة ME لويندوز, أصبح بمقدور هذا الأخير التعامل مع ملفات ZIP و كأنها مجلدات شبه عادية يمكن النسخ منها و إليها. نبدأ بتجهيز الكائنات التي ستمتل Shell و ملف ZIP و مجلد الوجهة :

		' إنشاء كائن من نوع Shell
		Dim shl As New Shell32.Shell()
		' إنشاء الكائن الممثل للمجلد من نوع ZIP
		Dim src As Shell32.Folder = shl.NameSpace("file.zip")
		' إنشاء الكائن الممثل للمجلد العادي الذي سيستقبل الملفات التي تم فك ضغطها
		Dim dst As Shell32.Folder = shl.NameSpace("path")

التغيير الوحيد بين الضغط و فك الضغط هو في جملة بدء العملية. ضغط المجلد نمرر فقط كائن من نوع Folder يمثل مجلد المصدر للدالة CopyHere بينما عملية فك الضغط تحتاج الدالة إلى كائن يمثل لائحة الملفات التي نريد فك ضغطها من الملف المضغوط :

		' بدء عملية النسخ مع فك الضغط
		dst.CopyHere(src.Items)

للحصول على لائحة الملفات المضغوطة داخل الملف المضغوط ZIP :

		' استعراض الملفات المضغوطة داخل ملف من نوع ZIP
		For i As Integer = 0 To src.Items.Count - 1
			Console.WriteLine(src.Items.Item(i).Path.ToString())
		Next

قبل الإنتهاء و جب الإعلام بضرورة استعمال إجراءات Shell في عملية نسخ المعلومات من و إلى ملف ZIP لتتم العملية كما يجب. في الكود أعلاه استعملنا مكتبة Microsoft Shell Controls And Automation التي نحتاج إلى زيادة Reference لها على المشروع و ذلك بفتح نافذة تكوين و تهيئة المشروع باختيار Project من القائمة الرئيسية ثم Properties لاسم المشروع و عند ظهور النافذة نختار صفحة References ثم نضغط على الزر Add.

تطوير برنامج ضاغط الملفات من نوع ZIP أصبح أمرا سهلا للغاية!

تحياتي...

تم تعديل هذه المشاركة بواسطة محمد رضى في 25 أكتوبر 2009 في 17:33

#49

سلام عليكم

اخي العزيز محمد رضى ابدعت في هذا الموضوع الاكثر من رائع

لا املك لك سوى الدعاء بارك الله فيك وجزاك الله كل خير

#50

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

شكرا لك أخي الكريم Palestine48 :)

كيف تحصل على صورة صفحة ويب؟

post-207152-1256560111_thumb.jpg

صراحة, ترددت كثيرا قبل كتابة هذه التلميحة نظرا لوجود رد لأخي محمد علاء عن كيفية استخلاص محتوى صفحة ويب على شكل نص مقروء بدون كود HTML و موضوع آخر في منتدى ASP.NET

المهم, هذه التلميحة تتكلم عن كيفية أخد صورة لصفحة ويب. سنستعمل مربع متصفح أنترنت WebBrowser لتحميل الصفحة و بعد ذلك نقوم بأخد صورة لمحتوى مربع المتصفح و نظهره على مربع صورة كما هو مبين على الصورة أعلاه. سنستفيذ مما سنتعلم هنا في مثلا حفظ (cache) صور مصغرة لمواقع انترنت لاستعمالها في برامجنا...

سنبدأ أولا بتعريف مربع متصفح انترنت الذي سيعمل في الخفاء لتحميل الصفحات من المواقع :

	' مربع التصفح الذي سنستعمل للحصول على الصورة
	Private wBrowser As WebBrowser

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

	' تجهيز مربع التصفح
	Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
		' كائن جديد
		wBrowser = New WebBrowser()
		' High def
		wBrowser.Size = Screen.PrimaryScreen.Bounds.Size
		' عند اكتمال تحميل الصفحة نحولها إلى صورة
		AddHandler wBrowser.DocumentCompleted, AddressOf wBrowser_DocumentCompleted
	End Sub

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

	' يحدث عند اكتمال تحميل الصفحة
	Private Sub wBrowser_DocumentCompleted(ByVal sender As Object, ByVal e As WebBrowserDocumentCompletedEventArgs)
		' إنشاء كائن الصورة الذي سيستقبل الصورة المصغرة
		Dim img As New Bitmap(wBrowser.ClientSize.Width, wBrowser.ClientSize.Height, Imaging.PixelFormat.Format24bppRgb)
		' رسم محتوى مربع التصفح على الصورة
		wBrowser.DrawToBitmap(img, New Rectangle(0, 0, wBrowser.Width, wBrowser.Height))
		' إظهار الصورة
		PictureBox1.Image = img
		PictureBox1.Invalidate()
		' عملية جديدة
		Button1.Enabled = True
	End Sub

كما نعرف جميعا فكل مربع يرث من الفئة Control يمكن له رسم محتواه على صورة من نوع Bitmap عن طريق الدالة الموروثة DrawToBitmap.

و أخيرا, ننادي على الدالة Navigate لمتصفح الانترنت لتحميل الصفحة :

	' عند الضغط على الزر GO
	Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
		If TextBox1.Text <> "" Then
			Button1.Enabled = False
			' تحميل الصفحة
			wBrowser.Navigate(TextBox1.Text)
		End If
	End Sub

في الملف المرفق مشروع صغير به الكود كاملا مع التعليق.

تحياتي...

TestLab.rar

تم تعديل هذه المشاركة بواسطة محمد رضى في 26 أكتوبر 2009 في 15:39

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