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

كلاس جاهز لعمل شاشة افتتاحية احترافية

بدأه Moudey في 31 يناير 2008 · 14 رد · 6,204 مشاهدة · في Microsoft Visual C#.NET
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

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

اقدم لكم كلاس SplashScreen يقوم بعمل شاشة افتتاحية للبرنامج.

نتعلم في هذا الكلاس عدة امور منها:

- كيفية استخدام دوال API

- كيفية انشاء struct وتعاملها مع دوال API

- كيفية التعامل مع الكلمة المفتاحية static

- كيفية استخدام المكتبة System.Drawing

- كيفية عمل ظهور "FadeIn" وتلاشي "FadeOut" بطريقة جديدة

- كيفية استخدام Command Line مع البرنامج والتحكم بها

واترككم مع الشيفرة

// SplashScreen.cs

using System;
using System.Drawing;
using System.Threading;
using System.Windows.Forms;
using System.Runtime.InteropServices;

public class SplashScreen
{
#region ' Win32 API '

[StructLayout(LayoutKind.Sequential)]
class BlendFunction
{
		public byte BlendOp;
		public byte BlendFlags;
		public byte SourceConstantAlpha;
		public byte AlphaFormat;

		public static BlendFunction Initialize(byte alpha)
		{
		const byte AC_SRC_OVER  = 0x00;
		const byte AC_SRC_ALPHA = 0x01;

		BlendFunction blendFun  = new BlendFunction();
		blendFun.BlendOp   = AC_SRC_OVER;
		blendFun.BlendFlags  = 0;  // Must be zero.
		blendFun.SourceConstantAlpha = alpha;
		blendFun.AlphaFormat  = AC_SRC_ALPHA;
		return blendFun;
		}
}

enum ULW : uint
{
		ColorKey = 1,
		Alpha		 = 2,
		Opaque   = 4
}

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)]
private static extern Boolean UpdateLayeredWindow(
		IntPtr hwnd, IntPtr hdcDst, ref Point pptDst, ref Size psize, IntPtr hdcSrc, ref Point pprSrc, int crKey, BlendFunction pblend, ULW dwFlags);

[DllImport("gdi32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)]
private static extern IntPtr CreateCompatibleDC(IntPtr hDC);

[DllImport("gdi32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)]
private static extern bool DeleteDC(IntPtr hdc);

[DllImport("gdi32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)]
private static extern IntPtr SelectObject(IntPtr hDC, IntPtr hObject);

[DllImport("gdi32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)]
private static extern bool DeleteObject(IntPtr hObject);

#endregion

#region ' SplashForm '

private class SplashForm : Form
{		public SplashForm()
		{
				base.ShowInTaskbar   = false;
				base.FormBorderStyle = FormBorderStyle.None;
				base.StartPosition   = FormStartPosition.CenterScreen;
		}
		protected override CreateParams CreateParams
		{		get
				{		CreateParams cp = base.CreateParams;
						cp.ExStyle |= 0x80000;
						return cp;
				}
		}
}

#endregion

public static bool Show(Image image)
{
		return Show(image, 5000);
}

public static bool Show(Image image, int timer)
{
		//if(image == null) return false;

		SplashForm frm   = null;
		Bitmap  bitmap  = null;
		Graphics graphics = null;
		IntPtr  screenDc  = IntPtr.Zero;
		IntPtr  memDc   = IntPtr.Zero;
		IntPtr  hBitmap  = IntPtr.Zero;
		IntPtr  oldBitmap  = IntPtr.Zero;

		try {
		frm   = new SplashForm();
		frm.Size = image.Size;
		bitmap  = new Bitmap(image);
		graphics = frm.CreateGraphics();
		screenDc = graphics.GetHdc();
		memDc  = CreateCompatibleDC(screenDc);
		hBitmap  = bitmap.GetHbitmap(Color.FromArgb(0));
		oldBitmap = SelectObject(memDc, hBitmap);
		Size pSize = new Size(bitmap.Width, bitmap.Height);
		Point pSrc = new Point(0, 0);
		Point pDst = new Point(
		((Screen.PrimaryScreen.WorkingArea.Width - bitmap.Width) / 2),
		((Screen.PrimaryScreen.WorkingArea.Height - bitmap.Height) / 2));

		frm.Show();

		for(int i = 0; i < 255; i += 5) {
				UpdateLayeredWindow(
						frm.Handle, screenDc, ref pDst, ref pSize, memDc, ref pSrc, 0, BlendFunction.Initialize((byte)i), ULW.Alpha);
				Thread.Sleep(5);
		}

   Thread.Sleep(timer);

		for(byte i = 255; i > 0; i -= 5) {
				UpdateLayeredWindow(
						frm.Handle, screenDc, ref pDst, ref pSize, memDc, ref pSrc, 0, BlendFunction.Initialize(i), ULW.Alpha);
				Thread.Sleep(5);
		}
		frm.Close();
		return true;
		} catch {
				return false;
		} finally {
				if(image != null){
						graphics.ReleaseHdc(screenDc);
						if(!((hBitmap == IntPtr.Zero))) {
								SelectObject(memDc, oldBitmap);
								DeleteObject(hBitmap);
						} else {
								DeleteDC(memDc);
						}
				}
		}
}
}

طريقة الاستدعاء

SplashScreen.Show(Bitmap);
SplashScreen.Show(Bitmap, int);

مثال

// SplashScreenDemo.cs
namespace SplashScreenDemo {

using System;
using System.Drawing;
using System.IO;
using System.Windows.Forms;

class frmMain : Form 
{
		public frmMain() {
				// btnCancel
				Button btnCancel = new Button();
				btnCancel.Location  = new Point(255, 281);
				btnCancel.Text  = "&Cancel";
				btnCancel.Click  += new EventHandler(Cancel);
				// frmMain
				this.Name		= "frmMain"; 
				this.Text   = "SplashScreen Demo";
				this.StartPosition = FormStartPosition.CenterScreen;
				this.ClientSize  = new Size(342, 316);
				this.Controls.Add(btnCancel);
		}

		private void Cancel(object o, EventArgs e){
				Application.Exit();
		}

		[STAThread]
		static void Main(string[] args) {
				Application.EnableVisualStyles();
				try {
						if(args.Length > 0){
								bool splashLoaded = false;
								if(File.Exists(args[0])){ 
										switch(args.Length)
										{
												case 1:
														splashLoaded = SplashScreen.Show(Bitmap.FromFile(args[0]));
														break;

												case 2:
														splashLoaded = SplashScreen.Show(Bitmap.FromFile(args[0]), int.Parse(args[1]));
												break;
										}

										if(!splashLoaded) 
												MessageBox.Show(string.Format("Can not load SplashScreen form '{0}'", args[0]));
								} 
						} else {
								if(!SplashScreen.Show(Bitmap.FromFile(@".\SplashScreen.png"), 5000))
										MessageBox.Show("Can not load SplashScreen");
						}
				} catch(Exception ex){
						MessageBox.Show(ex.Message);
				}
				Application.Run(new frmMain());
		}
}
}

SplashScreen.zip

بالتوفيق ان شاء الله

تم تعديل هذه المشاركة بواسطة Moudey في 2 فبراير 2008 في 10:25

مواضيع متنوعة

#2

شكرا جزيلا لك

ولكن لدي سؤال ألا يمكن أن نجري كل ما سبق بالاعتماد عى الدوت نيت فقط دون الاستعانة بدوال API

وشكرا،،

#3

مرحبأ اخي عبد الكريم

لايوجد مقابل لدوال الـ API المستخدمة في هذا الكلاس في dot net freamwork علي ماعتقد

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

حاولت كثيراً في جعل الخلفية شفافة بدون API ولكن دون جدوي

اخي "عبد الكريم" حاول تفعيل خاصية TransparencyKey هكذا this.TransparencyKey = this.BackColor;

ثم اجعل الصورة المرفقة في الموضوع خلفية للنموذج ثم اضغط F5 وانتظر منك الرد.

مواضيع متنوعة

#4

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

اشكرا اخي علي الموضوع

ولكن انا شايفة انه صعب اوي نكتب كل الكود ده عشان نعمل splash screen في حين انه من السهل جدا عملها بواسطة #C

اولا لو كنت تريد عمل splash screen هتجدها في المثال ده

splash.zip

ياريت تلاحظ ان في الفورمة اللي عاوزها تكون splash كتبت الكود ده

this.TransparencyKey =Color.Black

لان اللون الاسود هو خلفية الصورة او بمعني اصح هو اللون اللي انا مش عوزاه يظهر

لكن لو كتبت this.TransparencyKey =this.BackColor

هتظهر الفورمة بالفعل splashعلي الكمبيوتر بتاعي لكن لو اخذت البرنامج لكمبيوتر تاني سوف تظهر الفورمة كلها

انا مش عارفة ليه ولكن ده اللي بيحصل معايا دائما

ولو كنت عاوز تخلي الفورمة نفسها شفافة : في الخصائص بتاعت الفورمة خاصية اسمها opacity

سوف تجد القيمة الموجودة 100% ده معناه ان الفورمة مش شفافة يعني كل ماتقلل القيمة كلاما زادت شفافية الفورمة

ياريت ترد عليا هل هذا يغني عن دوال API

#5

السلام عليكم

هذة تجربة بدون دوال API اي dot net 100% لكن ليس بقوة الشيفرة السابقة

SplashScreen.2.zip

// SplashScreen.cs
using System;
using System.Drawing;
using System.Windows.Forms;

public static class SplashScreen
{
		static Form frm;
		static Bitmap bitmap;

		public static bool Show(Image image)
		{
				return Show(image, 5000, 255);
		}

		public static bool Show(Image image, byte opacity)
		{
				return Show(image, 5000, opacity);
		}

		public static bool Show(Image image, int timer)
		{
				return Show(image, timer, 255);
		}

		public static bool Show(Image image, int timer, byte opacity)
		{
				try
				{
					using(frm = new Form()) {
								bitmap		   = new Bitmap(image);
								frm.Size		   = bitmap.Size;
								frm.BackgroundImageLayout = ImageLayout.Center;
								frm.StartPosition		  = FormStartPosition.CenterScreen;
								frm.ShowInTaskbar		  = false;
								frm.FormBorderStyle		= FormBorderStyle.None;
								frm.BackgroundImage		= image;
								frm.Opacity				= Math.Round(((double)opacity / (double)255), 2);
								frm.HandleCreated		 += new EventHandler(OnHandleCreated);
								frm.Show();

								// Simulate a slow start, do something lengthy
								System.Threading.Thread.Sleep(timer);
						}
				} catch {
						return false;
				}
				return true; 
		}
		private static void OnHandleCreated(object sender, EventArgs e)
		{
				if(bitmap == null) 
					 bitmap = new Bitmap(frm.Width, frm.Height);

				// Create a bitmap buffer to draw things into
				Bitmap bufferBitmap = new Bitmap(frm.Size.Width, frm.Size.Height);
				Graphics bufferGraphics = Graphics.FromImage(bufferBitmap);

				// Get a screenshot of the desktop area where the splash form will show
				bufferGraphics.CopyFromScreen(frm.Left, frm.Top, 0, 0, frm.Size, CopyPixelOperation.SourceCopy);
				bufferGraphics.ReleaseHdc(bufferGraphics.GetHdc());

				// Draw the PNG image over the desktop screenshot
				bufferGraphics.DrawImage(bitmap, 0, 0, bitmap.Width, bitmap.Height);

				// Put the final result into the Form Background Image which will cover the entire splash form
				frm.BackgroundImage = bufferBitmap;
		}
}

اقتباس
ولكن انا شايفة انه صعب اوي نكتب كل الكود ده عشان نعمل splash screen في حين انه من السهل جدا عملها بواسطة #C

اولا لو كنت تريد عمل splash screen هتجدها في المثال ده

zip.gif splash.zip ( 138.75k ) عدد مرات التحميل: 1

ياريت تلاحظ ان في الفورمة اللي عاوزها تكون splash كتبت الكود ده

this.TransparencyKey =Color.Black

لان اللون الاسود هو خلفية الصورة او بمعني اصح هو اللون اللي انا مش عوزاه يظهر

لكن لو كتبت this.TransparencyKey =this.BackColor

هتظهر الفورمة بالفعل splashعلي الكمبيوتر بتاعي لكن لو اخذت البرنامج لكمبيوتر تاني سوف تظهر الفورمة كلها

انا مش عارفة ليه ولكن ده اللي بيحصل معايا دائما

ولو كنت عاوز تخلي الفورمة نفسها شفافة : في الخصائص بتاعت الفورمة خاصية اسمها opacity

سوف تجد القيمة الموجودة 100% ده معناه ان الفورمة مش شفافة يعني كل ماتقلل القيمة كلاما زادت شفافية الفورمة

ياريت ترد عليا هل هذا يغني عن دوال API

ارجو مراجعة هذا التعقيب

جربي وضع صورة من نوع PNG تحتوي علي شفافية "Alpah Blend" مع تلك الاعدادات this.TransparencyKey =Color.Black

الصورة ستظهر بشكل غير مناسب حيث شفافية الصورة لاتظهر بل يظهر لون الخلفية في موضع الشفافية

فالحل هو بأستدعاء دوال API

تم تعديل هذه المشاركة بواسطة Moudey في 2 فبراير 2008 في 10:31

مواضيع متنوعة

#6

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

شكرررررررا جزيلا

فعلا انا حاولت مع الصورة PNG فشلت محاولتي

المثال المرفق جميل جدا انا لم استطيع تحميل المثال الموجود في اول مشاركة مش عارفة ايه السبب بس (اكيد طبعا بسب النت اللي بايظ طول اليوم)

انا لم ادرس الكود الموجود في splashscreen2 بس عملتله رن وكان الناتج حلو اوي

ليه سؤال : الصورة اللي انت استخدمتها جايبها منين ؟؟؟؟؟؟؟

انا عاوزة صور مماثلة عشان استخدمها في شغلي لان شكلها جميل مع splash

#7

شكرا لك أخ Moudey جربت وضعت TransparencyKey = Color.Control

مشي الحال ولكن ليس بجمال مثالك الأول

أما طريقتك الثانية فهي مكشوفة إذا حاولت تغير مكان النوافذ.

وشكرا لك مجددا

#8
دعاء مختار كتب:
ليه سؤال : الصورة اللي انت استخدمتها جايبها منين ؟؟؟؟؟؟؟

انا عاوزة صور مماثلة عشان استخدمها في شغلي لان شكلها جميل مع splash

حملتها من موقع لااذكر اسمة!

في المرفقات بعض الصور التي يمكن استخدامها في عمل شاشة افتتاحية ويمكن التعديل عليها كما تريد.

images.zip

مواضيع متنوعة

#9

جزاك الله خيرا اخي Moudey

#10

ألف شكر ليك يابشمهندس

أنا كنت محتاجة الكلاس دى جددا

إن شاء الله أجربها وأقولك لو لى تعقيب

#11

تسلم ايديك اخ Moudey والله يبارك فيك وفى رجاله المنتدى كله

#12

شكرا يا عزيزي . . . .

في البداية يسخرون منك . . . ثم يهملونك . . . ثم يحاربونك . . . ثم تنتصر

#13

اخي محمد

ممكن تشرح لنا بعض اجزاء الكود التي ترى انها تحتاج الى شرح ؟ وشكرا جزيلا على البرنامج :)

#14

سأقوم بشرحة ان شاء الله

مواضيع متنوعة

#15

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

up

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