惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

D
Docker
U
Unit 42
Google DeepMind News
Google DeepMind News
B
Blog RSS Feed
S
SegmentFault 最新的问题
阮一峰的网络日志
阮一峰的网络日志
雷峰网
雷峰网
Microsoft Security Blog
Microsoft Security Blog
爱范儿
爱范儿
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
博客园_首页
Apple Machine Learning Research
Apple Machine Learning Research
罗磊的独立博客
GbyAI
GbyAI
Stack Overflow Blog
Stack Overflow Blog
Martin Fowler
Martin Fowler
宝玉的分享
宝玉的分享
L
LangChain Blog
Engineering at Meta
Engineering at Meta
量子位
有赞技术团队
有赞技术团队
博客园 - 【当耐特】
A
About on SuperTechFans
Y
Y Combinator Blog

博客园 - 李通通

c# 控件透明 资料整理 提升windows forms应用速度的几个简单方法 利用压缩网页来提升网站浏览速度(转载) datalist嵌套datalist的实例 - 李通通 - 博客园 求助。问个关于NBear的简单问题 - 李通通 - 博客园 一些flash播放器 技巧/诀窍:在ASP.NET中重写URL SEO参考:DIV+CSS三行两列经典布局 - 李通通 - 博客园 使用 jQuery 简化 Ajax 开发 未来职业定位 下一代数据访问:使概念级别成为现实 LINQ 项目 .NET 语言集成查询 LINQ 获得汉字字符串的首字母(T-SQL函数) asp.net控件开发基础(10) -- 集合属性的使用 asp.net控件开发基础(9) -- 属性类型转换器 asp.net控件开发基础(8) -- 复合控件实现事件 ClientScriptManager类,用于管理客户端脚本引发服务器事件回发
c#窗体png图片
李通通 · 2007-11-16 · via 博客园 - 李通通

using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace ConsoleApplication3
{
    static class Program
    {
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new MyForm());
        }

        #region Win32Class
        // a static class to expose needed win32 gdi functions.
        class Win32
        {
            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;

            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;
            }

            [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);

            #region DC About

            [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);

            #endregion
        }

        #endregion

        #region PerPixelAlphaFormClass
        /**/
        /// <para>PerPixel forms should derive from this base class</para>
        /// <author><name>Rui Godinho Lopes</name><email>rui@ruilopes.com</email></author>
        class PerPixelAlphaForm : Form
        {
            /**/
            /// <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);//  select the newbitmap,return the oldbitmap

                    Win32.Size size = new Win32.Size(bitmap.Width, bitmap.Height);//create the size of LayeredWindow
                    Win32.Point pointSource = new Win32.Point(0, 0);
                    Win32.Point topPos = new Win32.Point(Left, Top);//LayeredWindow start position
                    Win32.BLENDFUNCTION blend = new Win32.BLENDFUNCTION();

                    /**/
                    /////????
                    blend.BlendOp = Win32.AC_SRC_OVER;
                    blend.BlendFlags = 0;
                    blend.SourceConstantAlpha = opacity;
                    blend.AlphaFormat = Win32.AC_SRC_ALPHA;

                    //the most important function
                    Win32.UpdateLayeredWindow(this.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
            {
                //set form style
                get
                {
                    CreateParams cp = base.CreateParams;
                    cp.ExStyle |= 0x00080000; // This form has to have the WS_EX_LAYERED extended style
                    return cp;
                }
            }
        }

        #endregion

        #region MyPerPixelAlphaFormClass
        /**/
        /// <para>Our test form for this sample application. The bitmap will be displayed in this window.</para>
        class MyPerPixelAlphaForm : PerPixelAlphaForm
        {
            public MyPerPixelAlphaForm()
            {
                Text = "PerPixelAlpha Layered Form";
                TopMost = true;
                FormBorderStyle = FormBorderStyle.FixedDialog;
                MinimizeBox = false;
                MaximizeBox = false;
                ControlBox = false;
            }

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

        }
        #endregion

        #region MainFormClass
        /**/
        ///<para>The "controller" dialog box.</para>
        class MyForm : Form
        {
            public MyForm()
            {
                Font = new Font("tahoma", 8);
                Text = "perpixelalpha# - Sample application";
                FormBorderStyle = FormBorderStyle.FixedDialog;
                MinimizeBox = true;
                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();

                this.DoubleClick += new EventHandler(MyForm_DoubleClick);
            }

            /**/
            ///<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()))
                {
                }
            }

            // Our member varaibles:

            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

            //exit window
            private void MyForm_DoubleClick(object sender, EventArgs e)
            {
                this.Close();
            }
        }

        #endregion
    }
}