窗体的FormBorderStyle样式为None
在创建总的窗体区域时初始region为0
Region region = new Region(new Rectangle(this.location, Size.Empty));然后将一张图片提取进来做背景图,并使用Region.Union掏空特定颜色值的象素从而制作出不规则窗体的效果。后来在一些机子上测试,同一个程序出现两种运行效果。在配置好的机子上出来的效果跟预期一样,正常。而在一些配置差的机子上运行后出来的窗体则整体向上偏移一个标题栏的高度,并象左偏移一个窗体左边框的宽度(就是外围的一些该掏空的透明没有被掏去,而窗体底下的一些不属于透明色的象素则被掏空),为什么会这样?高手指点啊!

解决方案 »

  1.   

    下面这个类你试试:
    ///<author>Arild Fines</author>
    ///<date>20.04.2002</date>
    using System;
    using System.Drawing;
    using System.Drawing.Drawing2D;
    using System.Drawing.Imaging;
    using System.Runtime.InteropServices;namespace Jh.UserControls
    {    /// <summary>
        /// determines the meaning of the transparencyKey argument to the Convert method
        /// </summary>
        public enum TransparencyMode
        {
            /// <summary>
            /// the color key is used to define the transparent region of the bitmap
            /// </summary>
            ColorKeyTransparent,
            /// <summary>
            /// the color key is used to define the area that should _not_ be transparent
            /// </summary>
            ColorKeyOpaque
        } /// <summary>
    /// a class to convert a color-keyed bitmap into a region
    /// </summary>
    public class BitmapToRegion
    { #region 构造方法 /// <summary>
    /// ctor made private to avoid instantiation
    /// </summary>
    private BitmapToRegion()
    {}
    #endregion #region 公共静态方法 /// <summary>
    /// the meat of this class
    /// converts the bitmap to a region by scanning each line one by one
    /// this method will not affect the original bitmap in any way
    /// </summary>
    /// <param name="bitmap">The bitmap to convert</param>
    /// <param name="transparencyKey">The color which will indicate either transparency or opacity</param>
    /// <param name="mode">Whether the transparency key should indicate the transparent or the opaque region</param>
    public unsafe static Region Convert( Bitmap bitmap, Color transparencyKey,TransparencyMode mode )
    {
    //sanity check
    if ( bitmap == null )
    throw new ArgumentNullException( "Bitmap", "Bitmap cannot be null!" ); //flag = true means the color key represents the opaque color
    bool modeFlag = ( mode == TransparencyMode.ColorKeyOpaque );
                
    GraphicsUnit unit = GraphicsUnit.Pixel;
    RectangleF boundsF = bitmap.GetBounds( ref unit );
    Rectangle bounds = new Rectangle( (int)boundsF.Left, (int)boundsF.Top, 
    (int)boundsF.Width, (int)boundsF.Height ); uint key = (uint)((transparencyKey.A << 24) | (transparencyKey.R << 16) | 
    (transparencyKey.G << 8) | (transparencyKey.B << 0));
    //get access to the raw bits of the image
    BitmapData bitmapData = bitmap.LockBits( bounds, ImageLockMode.ReadOnly, 
    PixelFormat.Format32bppArgb );
    uint* pixelPtr = (uint*)bitmapData.Scan0.ToPointer(); //avoid property accessors in the for
    int yMax = (int)boundsF.Height;
    int xMax = (int)boundsF.Width; //to store all the little rectangles in
    GraphicsPath path = new GraphicsPath(); for ( int y = 0; y < yMax; ++y )
    {
    //store the pointer so we can offset the stride directly from it later
    //to get to the next line
    byte* basePos = (byte*)pixelPtr; for ( int x = 0; x < xMax; ++x, ++pixelPtr  )
    {      
    //is this transparent? if yes, just go on with the loop
    if ( modeFlag ^ ( *pixelPtr == key ) )
    continue; //store where the scan starts
    int x0 = x; //not transparent - scan until we find the next transparent byte
    while( x < xMax && !( modeFlag ^ ( *pixelPtr == key ) ) )
    {
    ++x;
    pixelPtr++;
    } //add the rectangle we have found to the path
    path.AddRectangle( new Rectangle( x0, y, x-x0, 1 ) );
    }
    //jump to the next line
    pixelPtr = (uint*)(basePos + bitmapData.Stride);
    } //now create the region from all the rectangles
    Region region = new Region( path ); //clean up
    path.Dispose();
    bitmap.UnlockBits( bitmapData ); return region;
    }
    #endregion }
       /*
    Exsample:
    Bitmap bm = (Bitmap)Bitmap.FromStream( this.GetType().Assembly.GetManifestResourceStream("BitmapToRegion.Image1.bmp" ) );
                Color col = bm.GetPixel( 1, 1 );            this.Width = bm.Width;
                this.Height = bm.Height;            this.Region = BitmapToRegion.Convert( bm, col, TransparencyMode.ColorKeyOpaque);//.ColorKeyTransparent );//
                this.BackgroundImage = bm; //*/
    }
      

  2.   

    不行啊,编译的时候提示“(52): 不安全代码只会在使用 /unsafe 编译的情况下出现”
      

  3.   

    搞定了,可能跟CPU的计算速度有关,等窗体show出来后在扣图就OK了!