以文本方式查看主题

-  中文XML论坛 - 专业的XML技术讨论区  (http://bbs.xml.org.cn/index.asp)
--  『 Dot NET,C#,ASP,VB 』  (http://bbs.xml.org.cn/list.asp?boardid=43)
----  C#透明窗体(png图片渐变)源码  (http://bbs.xml.org.cn/dispbbs.asp?boardid=43&rootid=&id=84961)


--  作者:卷积内核
--  发布时间:5/28/2010 2:34:00 PM

--  C#透明窗体(png图片渐变)源码

//
// Copyright ?2002 Rui Godinho Lopes <rui@ruilopes.com>
// All rights reserved.
//
// This source file(s) may be redistributed unmodified by any means
// PROVIDING they are not sold for profit without the authors expressed
// written consent, and providing that this notice and the authors name
// and all copyright notices remain intact.
//
// Any use of the software in source or binary forms, with or without
// modification, must include, in the user documentation ("About" box and
// printed documentation) and internal comments to the code, notices to
// the end user as follows:
//
// "Portions Copyright ?2002 Rui Godinho Lopes"
//
// An email letting me know that you are using it would be nice as well.
// That's not much to ask considering the amount of work that went into
// this.
//
// THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED. USE IT AT YOUT OWN RISK. THE AUTHOR ACCEPTS NO
// LIABILITY FOR ANY DATA DAMAGE/LOSS THAT THIS PRODUCT MAY CAUSE.
//

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


Win32Class#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);

    DC About#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

PerPixelAlphaFormClass#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

MyPerPixelAlphaFormClass#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

MainFormClass#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();


W 3 C h i n a ( since 2003 ) 旗 下 站 点
苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
1,265.625ms