PDA

View Full Version : سوال: فرم شفاف(Transparency Key)



blake_daniel
شنبه 08 خرداد 1395, 11:07 صبح
درود خدمت دوستان گرامی
مدتی هست که من با C# آشنا شدم و دارم برنامه نویسی میکنم(قبلا .Net کار میکردم)
برای ساخت یه پروژه(فرم لاگین)مشکل دارم
از دوستان حرفه ای کسی میدونه توابعی چیزی هست برا رسیدن به فرمی شبیه به این عکس(این عکس رو خودم با فوتوشاپ گذاشتم روی دسکتاپ) (http://uupload.ir/files/52ip_1.jpg)
در اصل میخام بجای بکگراند فرم یه عکس PNG نمایش بدم که فقط دوتا تکست توش دیده بشه
من دقیقا همین کار رو قبلا با .Net انجام میدادم ولی بعد از جستجو در مورد C# متوجه شدم برا این کار فقط میشه از Transparency Key استفاده کرد
که میتونم بگم این تابع از مزخرف هم مزخرف تره!!!(به علت محدودیت در تعریف یک رنگ برای شفاف شدن و ...)
توی جستجوها یه DLL هم پیدا کردم برا اینکار ولی ترجیح میدم بدون استفاده از منبع خارجی این کار رو انجام بدم
دوستان حرفه ای و حرفه ای تر کسی نظری داره!!! :لبخند:
با سپاس

محمد آشتیانی
شنبه 08 خرداد 1395, 11:50 صبح
سلام
مبحثی هست به اسم Alpha Blend ، مطالعه لینک های زیر میتونه کمکتون کنه

http://www.codeproject.com/Articles/20758/Alpha-Blended-Windows-Forms

http://www.codeproject.com/Articles/1822/Per-Pixel-Alpha-Blend-in-C




موفق باشید.

blake_daniel
یک شنبه 09 خرداد 1395, 11:58 صبح
سلام
مبحثی هست به اسم Alpha Blend ، مطالعه لینک های زیر میتونه کمکتون کنه

http://www.codeproject.com/Articles/20758/Alpha-Blended-Windows-Forms

http://www.codeproject.com/Articles/1822/Per-Pixel-Alpha-Blend-in-C




موفق باشید.

ممنونم بابت پاسخ
من یکی از پروژه ها رو دانلود کردم ولی راستش از ساختارش سر در نیاوردم(البته کاری که میخام رو انجام داد)
تو این پروژه ای که دانلود کردم یه فایل Build هست که وقتی اجرا میشه یه نرم افزار میسازه که یه فرم داره
داخل این فرم یه عکس PNG رو Drag & Drop میکنی دقیقا نمایش میده و همون چیزی هست که میخام
ولی این پروژه Solution نداره فقط دوتا فایل cs داره که کدش رو اینجا میذارم اگر امکانش هست یه نگاه بندازین و یه توضیح بدین که من برا
فرم لاگین به اون شکلی که نمایش دادم نیاز به کدوم قسمتها دارم
ممنونم
البته به غیر از این کدی که قرار دادم(کدهای یکی از فایلها)یه فایل دیگه هم هست به نام Main.cs :متفکر:



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



// class that exposes needed win32 gdi functions.
class Win32
{
public enum Bool
{
False= 0,
True
};


[StructLayout(LayoutKind.Sequential)]
public struct Point
{
public Int32 x;
public Int32 y;

public Point(Int32 x, Int32 y) { this.x= x; this.y= y; }
}


[StructLayout(LayoutKind.Sequential)]
public struct Size {
public Int32 cx;
public Int32 cy;

public Size(Int32 cx, Int32 cy) { this.cx= cx; this.cy= cy; }
}


[StructLayout(LayoutKind.Sequential, Pack=1)]
struct ARGB
{
public byte Blue;
public byte Green;
public byte Red;
public byte Alpha;
}


[StructLayout(LayoutKind.Sequential, Pack=1)]
public struct BLENDFUNCTION
{
public byte BlendOp;
public byte BlendFlags;
public byte SourceConstantAlpha;
public byte AlphaFormat;
}


public const Int32 ULW_COLORKEY = 0x00000001;
public const Int32 ULW_ALPHA = 0x00000002;
public const Int32 ULW_OPAQUE = 0x00000004;

public const byte AC_SRC_OVER = 0x00;
public const byte AC_SRC_ALPHA = 0x01;


[DllImport("user32.dll", ExactSpelling=true, SetLastError=true)]
public static extern Bool UpdateLayeredWindow(IntPtr hwnd, IntPtr hdcDst, ref Point pptDst, ref Size psize, IntPtr hdcSrc, ref Point pprSrc, Int32 crKey, ref BLENDFUNCTION pblend, Int32 dwFlags);

[DllImport("user32.dll", ExactSpelling=true, SetLastError=true)]
public static extern IntPtr GetDC(IntPtr hWnd);

[DllImport("user32.dll", ExactSpelling=true)]
public static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);

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

[DllImport("gdi32.dll", ExactSpelling=true, SetLastError=true)]
public static extern Bool DeleteDC(IntPtr hdc);

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

[DllImport("gdi32.dll", ExactSpelling=true, SetLastError=true)]
public static extern Bool DeleteObject(IntPtr hObject);
}



/// <para>Your PerPixel form should inherit this class</para>
/// <author><name>Rui Godinho Lopes</name><email>rui@ruilopes.com</email></author>
class PerPixelAlphaForm : Form
{
public PerPixelAlphaForm()
{
// This form should not have a border or else Windows will clip it.
FormBorderStyle = FormBorderStyle.None;
}


/// <para>Changes the current bitmap.</para>
public void SetBitmap(Bitmap bitmap)
{
SetBitmap(bitmap, 255);
}


/// <para>Changes the current bitmap with a custom opacity level. Here is where all happens!</para>
public void SetBitmap(Bitmap bitmap, byte opacity)
{
if (bitmap.PixelFormat != PixelFormat.Format32bppArgb)
throw new ApplicationException("The bitmap must be 32ppp with alpha-channel.");

// The ideia of this is very simple,
// 1. Create a compatible DC with screen;
// 2. Select the bitmap with 32bpp with alpha-channel in the compatible DC;
// 3. Call the UpdateLayeredWindow.

IntPtr screenDc = Win32.GetDC(IntPtr.Zero);
IntPtr memDc = Win32.CreateCompatibleDC(screenDc);
IntPtr hBitmap = IntPtr.Zero;
IntPtr oldBitmap = IntPtr.Zero;

try {
hBitmap = bitmap.GetHbitmap(Color.FromArgb(0)); // grab a GDI handle from this GDI+ bitmap
oldBitmap = Win32.SelectObject(memDc, hBitmap);

Win32.Size size = new Win32.Size(bitmap.Width, bitmap.Height);
Win32.Point pointSource = new Win32.Point(0, 0);
Win32.Point topPos = new Win32.Point(Left, Top);
Win32.BLENDFUNCTION blend = new Win32.BLENDFUNCTION();
blend.BlendOp = Win32.AC_SRC_OVER;
blend.BlendFlags = 0;
blend.SourceConstantAlpha = opacity;
blend.AlphaFormat = Win32.AC_SRC_ALPHA;

Win32.UpdateLayeredWindow(Handle, screenDc, ref topPos, ref size, memDc, ref pointSource, 0, ref blend, Win32.ULW_ALPHA);
}
finally {
Win32.ReleaseDC(IntPtr.Zero, screenDc);
if (hBitmap != IntPtr.Zero) {
Win32.SelectObject(memDc, oldBitmap);
//Windows.DeleteObject(hBitmap); // The documentation says that we have to use the Windows.DeleteObject... but since there is no such method I use the normal DeleteObject from Win32 GDI and it's working fine without any resource leak.
Win32.DeleteObject(hBitmap);
}
Win32.DeleteDC(memDc);
}
}


protected override CreateParams CreateParams
{
get {
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x00080000; // This form has to have the WS_EX_LAYERED extended style
return cp;
}
}
}

blake_daniel
یک شنبه 09 خرداد 1395, 12:05 عصر
اینم کدهای فایل Main.cs



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



/// <para>Our test form for this sample application. The bitmap will be displayed in this window.</para>
class MyPerPixelAlphaForm : PerPixelAlphaForm
{
public MyPerPixelAlphaForm()
{
TopMost = true;
ShowInTaskbar = false;
}


// Let Windows drag this form for us
protected override void WndProc(ref Message m)
{
if (m.Msg == 0x0084 /*WM_NCHITTEST*/) {
m.Result= (IntPtr)2; // HTCLIENT
return;
}
base.WndProc(ref m);
}
}



///<para>The "controller" dialog box.</para>
class MyForm : Form
{
public MyForm()
{
Font= new Font("tahoma", 8);
Text= "perpixelalpha# - Sample application";
FormBorderStyle = FormBorderStyle.FixedDialog;
MinimizeBox = false;
MaximizeBox = false;
ClientSize = new Size(350, 160);
StartPosition = FormStartPosition.CenterScreen;

AllowDrop = true; // Because we want to be a drop target of windows explorer files.

InitializeComponent();
}


///<para>Constructs and initializes all child controls of this dialog box.</para>
private void InitializeComponent()
{
// Label with to display current opacity level
Label Label1 = new Label();
Label1.AutoSize = true;
Label1.Location = new System.Drawing.Point(4, 8);
Label1.Text = "1. Drag&&Drop an image file from windows explorer into this window.";
Controls.Add(Label1);

Label Label2 = new Label();
Label2.AutoSize = true;
Label2.Location = new System.Drawing.Point(4, 38);
Label2.Text = "2. Play with the opacity level [0..255]:";
Controls.Add(Label2);

// Label with to display current opacity level
LabelValue = new Label();
LabelValue.AutoSize = true;
LabelValue.Location = new System.Drawing.Point(195, 38);
LabelValue.Text = "255";

Controls.Add(LabelValue);


// Trackbar to change opacity level
Track = new TrackBar();

Track.Location = new System.Drawing.Point(18, 58);
Track.Size = new System.Drawing.Size(310, 0);
Track.BeginInit();
Track.Maximum = 255;
Track.TickFrequency = 5;
Track.TickStyle = TickStyle.TopLeft;
Track.Value = 255;
Track.EndInit();

Track.ValueChanged += new EventHandler(Track_ValueChanged);

Controls.Add(Track);


Label Label3 = new Label();
Label3.AutoSize = true;
Label3.Location = new System.Drawing.Point(4, 108);
Label3.Text = "3. Drag the layered window arround you desktop!";
Controls.Add(Label3);


// Label with two links to me! :)
LinkLabel Link = new LinkLabel();

Link.Location = new System.Drawing.Point(4, 140);
Link.Size = new System.Drawing.Size(250, 80);
Link.Text = "by Rui Lopes <rui@ruilopes.com>";
Link.Links.Add(3, 9, "http://www.ruilopes.com");
Link.Links.Add(14, 16, "mailto:rui@ruilopes.com");

Link.LinkClicked += new LinkLabelLinkClickedEventHandler(Link_LinkClicked) ;

Controls.Add(Link);


// TestForm will containt the per-pixel-alpha dib
TestForm = new MyPerPixelAlphaForm();
TestForm.Show();
}


///<para>Frees our bitmap.</para>
protected override void Dispose(bool disposing)
{
try {
if (disposing && bitmap != null) {
bitmap.Dispose();
bitmap = null;
}
}
finally {
base.Dispose(disposing);
}
}


///<para>Accepts only Drops of windows explorer files.</para>
protected override void OnDragEnter(DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop))
e.Effect = DragDropEffects.Copy;
base.OnDragEnter(e);
}


///<para>Just loads the dropped file from windows explorer.</para>
protected override void OnDragDrop(DragEventArgs e)
{
string[] files= e.Data.GetData(DataFormats.FileDrop) as string[];
if (files != null) {
if (files.Length == 1)
SetPerPixelBitmapFilename(files[0]);
else
MessageBox.Show(this, "Please, drop only one image file.", "Too many files dropped", MessageBoxButtons.OK, MessageBoxIcon.Stop);
}
base.OnDragDrop(e);
}


///<para>Just load a image file and display it on our test form.</para>
private void SetPerPixelBitmapFilename(string fileName)
{
Bitmap newBitmap;

try {

newBitmap = Image.FromFile(fileName) as Bitmap;
TestForm.SetBitmap(newBitmap, (byte)Track.Value);

}
catch (ApplicationException e) {
MessageBox.Show(this, e.Message, "Error with bitmap.", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
catch (Exception e) {
MessageBox.Show(this, e.Message, "Could not open image file.", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}

if (bitmap != null)
bitmap.Dispose();
bitmap = newBitmap;
}


///<para>Change the opacity level of our test form.</para>
private void Track_ValueChanged(object sender, EventArgs e)
{
byte opacity = (byte)Track.Value;
LabelValue.Text = opacity.ToString();
LabelValue.Refresh(); // We need this because on slow computers (mine!) the windows takes some time to update our label.

if (bitmap != null)
TestForm.SetBitmap(bitmap, opacity);
}


///<para>Start the computer browser in the specified uri.</para>
private void Link_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
e.Link.Visited = true;
using (System.Diagnostics.Process.Start(e.Link.LinkData. ToString())) {
}
}


private Label LabelValue; // label with current opacity level
private TrackBar Track; // trackbar to chabge opacity level
private MyPerPixelAlphaForm TestForm; // our test form
private Bitmap bitmap; // bitmap that is currently displaying on our test form
}



// Our Great Application!
class TheApp
{
[STAThread]
public static void Main()
{
Application.Run(new MyForm());
}
}

blake_daniel
دوشنبه 10 خرداد 1395, 19:23 عصر
دوستان کسی نیست ما رو توی مسیر بذاره؟؟!! :لبخند:
بر نمایش فرم از کدوم قسمت کد استفاده کنم؟؟!!
نمیخام هر دو فایل رو پروژه اضافه کنم

hahaie
سه شنبه 11 خرداد 1395, 11:43 صبح
سلام
مبحثی هست به اسم Alpha Blend ، مطالعه لینک های زیر میتونه کمکتون کنه

http://www.codeproject.com/Articles/20758/Alpha-Blended-Windows-Forms

http://www.codeproject.com/Articles/1822/Per-Pixel-Alpha-Blend-in-C




موفق باشید.

توی Xp هم جواب میده؟

مهرداد صفا
سه شنبه 11 خرداد 1395, 13:19 عصر
دوستان کسی نیست ما رو توی مسیر بذاره؟؟!! :لبخند:
بر نمایش فرم از کدوم قسمت کد استفاده کنم؟؟!!
نمیخام هر دو فایل رو پروژه اضافه کنم
سلام.
اگر قصد شفاف کردن کل فرم رو دارید:


this.Opacity=0
رو تست کردید؟


this.TransparencyKey=this.BackColor;
باعث میشه هر قسمت از فرم که رنگ this.BackColor هست به صورت شفاف نمایش داده بشه .

blake_daniel
سه شنبه 11 خرداد 1395, 15:11 عصر
سلام.
اگر قصد شفاف کردن کل فرم رو دارید:


this.Opacity=0
رو تست کردید؟


this.TransparencyKey=this.BackColor;
باعث میشه هر قسمت از فرم که رنگ this.BackColor هست به صورت شفاف نمایش داده بشه .

درود دوست عزیز
راستش قصد ندارم شفاف کنم فرم رو بلکه یه عکس PNG هست که خودش شفاف هست
من قصدم اینه که این عکس رو با دوتا کنترل تکست به جای فرم لاگین نمایش بدم(یعنی خود فرم معلوم نباشه)
از مورد اولی که گفتین استفاده نکردم ولی مورد دوم محدودیت داره و اصلا جواب کار منو نداد(قبلا امتحان کردم اونو)
لینک دومی که جناب آشتیانی گزاشتن کار منو انجام میده ولی به شکل دیگه من میخام ببینم از کدام قسمت اون دوتا فایل بالا استفاده کنم
که به چیزی شبیه به لینک زیر برسم؟
چیزی که من قصد دارم بسازم دقیقا این هست (http://uupload.ir/files/52ip_1.jpg)
کل فرمی که تو لینک بالا میبینین یه عکس PNG هست مشکل من فقط اینه که چجور اینو با دوتا تکست در جایی که مشخص شده نمایش بدم(بدون اینکه فرم مشخص باشه)
توی سایت Stackoverflow خوندم که نوشته بود میشه دقیقا همین کار رو توی یه فرم WPF انجام داد و با یه Using توی Winform اجرا کرد اون فرم رو شما چنین چیزی شنیدین؟

blake_daniel
پنج شنبه 13 خرداد 1395, 09:19 صبح
کسی نیست چنین کاری انجام داده باشه تو C# ???!!!
همچنان منتظریم!!!