异型窗体制作(两种方法)

异型窗体制作可以说在网上一找就一堆,以下这些代码也算是对我以前写程序的一个总结吧。
记得这段代码我是在看了Windows C制作异型窗体的原理后写出来的。主要就是传一个Form的对象和一个Bitmap对象给SetWindowRegion方法,SetWindowRegion方法就会完成设置。
传的图片要有一个透明色,如果没有设置透明色,就会以图片(0,0)像素的颜色为透明色。具体的实现过程就是扫描图片的每个象素,如果这个像素的颜色和透明色不一样就往一个GraphicsPath对象里添加一个1×1的小矩形,当扫描完所有象素后,就利用这个GraphicsPath对象生成一个Region对象,然后把这个Region赋给窗体对象即可。
以下是代码:
None.gif using  System;
None.gif
using  System.Drawing;
None.gif
using  System.Drawing.Drawing2D;
None.gif
using  System.Windows.Forms;
None.gif
None.gif
public   class  Common
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
ExpandedSubBlockStart.gifContractedSubBlock.gif       
/**//// <summary>
InBlock.gif        
/// 设置窗体为不规则界面
InBlock.gif        
/// </summary>
InBlock.gif        
/// <remarks>根据背景图片来设置窗体的形状,
InBlock.gif        
/// 以背景图片的(0, 0)位置为透明色</remarks>
InBlock.gif        
/// <param name="MainForm">要设置的窗体</param>
ExpandedSubBlockEnd.gif        
/// <param name="BmpBack">设置形状所依据的图片</param>

InBlock.gif        public static void SetWindowRegion(Form MainForm,
InBlock.gif                Bitmap BmpBack)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif                Color TransparentColor;
InBlock.gif                TransparentColor 
= BmpBack.GetPixel(00);
InBlock.gif                SetWindowRegion(MainForm, BmpBack, TransparentColor);
ExpandedSubBlockEnd.gif        }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
InBlock.gif        
/// 设置窗体为不规则界面
InBlock.gif        
/// </summary>
InBlock.gif        
/// <param name="MainForm">要设置的窗体</param>
InBlock.gif        
/// <param name="BmpBack">设置形状所依据的图片</param>
ExpandedSubBlockEnd.gif        
/// <param name="TransparentColor">图片的透明色</param>

InBlock.gif        public static void SetWindowRegion(Form MainForm,
InBlock.gif                Bitmap BmpBack, Color TransparentColor)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif                Color TempColor;
InBlock.gif                GraphicsPath gp;
InBlock.gif
InBlock.gif                gp 
= new GraphicsPath();
InBlock.gif                MainForm.FormBorderStyle 
= FormBorderStyle.None;
InBlock.gif                MainForm.Width 
= BmpBack.Width;
InBlock.gif                MainForm.Height 
= BmpBack.Height;
InBlock.gif                MainForm.BackgroundImage 
= BmpBack;
InBlock.gif
InBlock.gif                
for (int nX = 0; nX < BmpBack.Width; nX++)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                        
for (int nY = 0; nY < BmpBack.Height; nY++)
ExpandedSubBlockStart.gifContractedSubBlock.gif                        
dot.gif{
InBlock.gif                                TempColor 
= BmpBack.GetPixel(nX, nY);
InBlock.gif                                
if (TempColor != TransparentColor)
ExpandedSubBlockStart.gifContractedSubBlock.gif                                
dot.gif{
InBlock.gif                                        gp.AddRectangle(
new Rectangle(nX, nY, 11));
ExpandedSubBlockEnd.gif                                }

ExpandedSubBlockEnd.gif                        }

ExpandedSubBlockEnd.gif                }

InBlock.gif
InBlock.gif                MainForm.Region 
= new Region(gp);
ExpandedSubBlockEnd.gif        }

ExpandedBlockEnd.gif}
以上代码执行时,如果图片比较小,生成异型窗体速度是非常快的,但如果图片比较大就很慢了。
后来实在无法忍受,在网上找到一个通过不安全代码实现的,把这个代码也贴出来:
ExpandedBlockStart.gif ContractedBlock.gif /**/ ///<author>Arild Fines</author>
ExpandedBlockEnd.gif
///<date>20.04.2002</date>

None.gif using  System;
None.gif
using  System.Drawing;
None.gif
using  System.Drawing.Drawing2D;
None.gif
using  System.Drawing.Imaging;
None.gif
using  System.Runtime.InteropServices;
None.gif
None.gif
namespace  Spider.Common
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
ExpandedSubBlockStart.gifContractedSubBlock.gif    
/**//// <summary>
InBlock.gif    
/// determines the meaning of the transparencyKey argument to the Convert method
ExpandedSubBlockEnd.gif    
/// </summary>

InBlock.gif    public enum TransparencyMode
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
InBlock.gif        
/// the color key is used to define the transparent region of the bitmap
ExpandedSubBlockEnd.gif        
/// </summary>

InBlock.gif        ColorKeyTransparent,
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
InBlock.gif        
/// the color key is used to define the area that should _not_ be transparent
ExpandedSubBlockEnd.gif        
/// </summary>

InBlock.gif        ColorKeyOpaque
ExpandedSubBlockEnd.gif    }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
/**//// <summary>
InBlock.gif    
/// a class to convert a color-keyed bitmap into a region
ExpandedSubBlockEnd.gif    
/// </summary>

InBlock.gif    public class BitmapToRegion
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
InBlock.gif        
/// ctor made private to avoid instantiation
ExpandedSubBlockEnd.gif        
/// </summary>

InBlock.gif        private BitmapToRegion()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{}
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
InBlock.gif        
/// the meat of this class
InBlock.gif        
/// converts the bitmap to a region by scanning each line one by one
InBlock.gif        
/// this method will not affect the original bitmap in any way
InBlock.gif        
/// </summary>
InBlock.gif        
/// <param name="bitmap">The bitmap to convert</param>
InBlock.gif        
/// <param name="transparencyKey">The color which will indicate either transparency or opacity</param>
ExpandedSubBlockEnd.gif        
/// <param name="mode">Whether the transparency key should indicate the transparent or the opaque region</param>

InBlock.gif        public unsafe static Region Convert( Bitmap bitmap, Color transparencyKey, TransparencyMode mode )
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
//sanity check
InBlock.gif
            if ( bitmap == null )
InBlock.gif                
throw new ArgumentNullException( "Bitmap""Bitmap cannot be null!" );
InBlock.gif
InBlock.gif            
//flag = true means the color key represents the opaque color
InBlock.gif
            bool modeFlag = ( mode == TransparencyMode.ColorKeyOpaque );
InBlock.gif            
InBlock.gif            GraphicsUnit unit 
= GraphicsUnit.Pixel;
InBlock.gif            RectangleF boundsF 
= bitmap.GetBounds( ref unit );
InBlock.gif            Rectangle bounds 
= new Rectangle( (int)boundsF.Left, (int)boundsF.Top, 
InBlock.gif                (
int)boundsF.Width, (int)boundsF.Height );
InBlock.gif
InBlock.gif            
uint key = (uint)((transparencyKey.A << 24| (transparencyKey.R << 16| 
InBlock.gif                (transparencyKey.G 
<< 8| (transparencyKey.B << 0));
InBlock.gif
InBlock.gif            
//get access to the raw bits of the image
InBlock.gif
            BitmapData bitmapData = bitmap.LockBits( bounds, ImageLockMode.ReadOnly, 
InBlock.gif                PixelFormat.Format32bppArgb );
InBlock.gif            
uint* pixelPtr = (uint*)bitmapData.Scan0.ToPointer();
InBlock.gif
InBlock.gif            
//avoid property accessors in the for
InBlock.gif
            int yMax = (int)boundsF.Height;
InBlock.gif            
int xMax = (int)boundsF.Width;
InBlock.gif
InBlock.gif            
//to store all the little rectangles in
InBlock.gif
            GraphicsPath path = new GraphicsPath();
InBlock.gif
InBlock.gif            
for ( int y = 0; y < yMax; y++ )
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
//store the pointer so we can offset the stride directly from it later
InBlock.gif                
//to get to the next line
InBlock.gif
                byte* basePos = (byte*)pixelPtr;
InBlock.gif
InBlock.gif                
for ( int x = 0; x < xMax; x++, pixelPtr++  )
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{      
InBlock.gif                    
//is this transparent? if yes, just go on with the loop
InBlock.gif
                    if ( modeFlag ^ ( *pixelPtr == key ) )
InBlock.gif                        
continue;
InBlock.gif
InBlock.gif                    
//store where the scan starts
InBlock.gif
                    int x0 = x;
InBlock.gif
InBlock.gif                    
//not transparent - scan until we find the next transparent byte
InBlock.gif
                    while( x < xMax && !( modeFlag ^ ( *pixelPtr == key ) ) )
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
dot.gif{
InBlock.gif                        
++x;
InBlock.gif                        pixelPtr
++;
ExpandedSubBlockEnd.gif                    }

InBlock.gif
InBlock.gif                    
//add the rectangle we have found to the path
InBlock.gif
                    path.AddRectangle( new Rectangle( x0, y, x-x0, 1 ) );
ExpandedSubBlockEnd.gif                }

InBlock.gif                
//jump to the next line
InBlock.gif
                pixelPtr = (uint*)(basePos + bitmapData.Stride);
ExpandedSubBlockEnd.gif            }

InBlock.gif
InBlock.gif            
//now create the region from all the rectangles
InBlock.gif
            Region region = new Region( path );
InBlock.gif
InBlock.gif            
//clean up
InBlock.gif
            path.Dispose();
InBlock.gif            bitmap.UnlockBits( bitmapData );
InBlock.gif
InBlock.gif            
return region;
ExpandedSubBlockEnd.gif        }
 
ExpandedSubBlockEnd.gif    }
  
ExpandedBlockEnd.gif}

None.gif
以上代码的使用类似于我写的代码,只不过这个需要在窗体类里自己将RegionConvert方法返回来到Region设置给窗体的Region属性。

转载于:https://www.cnblogs.com/srw962/archive/2005/10/19/258156.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值