使用C#(在VS2005下)实现自定义的Windwos窗体是多么简单,发挥你的想像,你也可以做出像QQ那样外观的应用程序。
1。首先要在PS等图形处理软件下做好自己的样式,如下图所示:
注意:图片格式为32位的Bmp格式,且要透明的区域用单色,如纯红,透明区域最好是能对称,否则效果很差。
2。实现代码如下:
///
<summary>
/// 创建自定义窗体或控件
/// Wendy,Bear据网上资料搜集整理优化
/// </summary>
public class BitmapRegion
{
public BitmapRegion()
{ }
/// <summary>
/// 创建支持位图区域的控件(目前有button和form)
/// </summary>
/// <param name="control"> 控件 </param>
/// <param name="bitmap"> 位图 </param>
public static void CreateControlRegion(Control control, Bitmap bitmap)
{
// 判断是否存在控件和位图
if (control == null || bitmap == null )
return ;
// 设置控件大小为位图大小
control.Width = bitmap.Width;
control.Height = bitmap.Height;
// 当控件是form时
if (control is System.Windows.Forms.Form)
{
// 强制转换为FORM
Form form = (Form)control;
// 当FORM的边界FormBorderStyle不为NONE时,应将FORM的大小设置成比位图大小稍大一点
form.Width = control.Width;
form.Height = control.Height;
// 没有边界
form.FormBorderStyle = FormBorderStyle.None;
// 将位图设置成窗体背景图片
form.BackgroundImage = bitmap;
//
// 将背景图片设为居中
// 董,2006.3.28
form.BackgroundImageLayout = ImageLayout.Center;
// 计算位图中不透明部分的边界
GraphicsPath graphicsPath = CalculateControlGraphicsPath(bitmap);
// 应用新的区域
form.Region = new Region(graphicsPath);
}
// 当控件是button时
else if (control is System.Windows.Forms.Button)
{
// 强制转换为 button
Button button = (Button)control;
// 不显示button text
button.Text = "" ;
// 改变 cursor的style
button.Cursor = Cursors.Hand;
// 设置button的背景图片
button.BackgroundImage = bitmap;
// 计算位图中不透明部分的边界
GraphicsPath graphicsPath = CalculateControlGraphicsPath(bitmap);
// 应用新的区域
button.Region = new Region(graphicsPath);
}
}
/// <summary>
/// 计算位图中不透明部分的边界
/// 注意:此方法只适用规则的四角对称的图形
/// </summary>
/// <param name="bitmap"> 要绘制区域的位图 </param>
/// <returns> 计算后的图形路径 </returns>
private static GraphicsPath CalculateControlGraphicsPath(Bitmap bitmap)
{
// 创建 GraphicsPath
GraphicsPath graphicsPath = new GraphicsPath();
// 使用左上角的一点的颜色作为我们透明色
Color colorTransparent = bitmap.GetPixel( 0 , 0 );
// 第一个找到点的X
int colOpaquePixel = 0 ;
// 遍历所有行(Y方向)
for ( int row = 0 ; row < bitmap.Height;)
{
// Reset value
// 重设
colOpaquePixel = 0 ;
// 遍历所有列(X方向)
for ( int col = 0 ; col < bitmap.Width; col ++ )
{
// 如果是不需要透明处理的点则标记,然后继续遍历
if (bitmap.GetPixel(col, row) != colorTransparent)
{
// 记录当前
colOpaquePixel = col;
// 记录右边界
int colNext = bitmap.Width - col;
// 将不透明点加到graphics path
if (col == 0 )
{
// 将中间大部分不透明区域加入
graphicsPath.AddRectangle( new Rectangle(colOpaquePixel + 1 , row, colNext - colOpaquePixel - 2 , bitmap.Height - row - row - 1 ));
// 置row为最大以便跳出循环
row = bitmap.Height;
}
else
{
// 顶部区域单行加入
graphicsPath.AddRectangle( new Rectangle(colOpaquePixel + 1 , row, colNext - colOpaquePixel - 2 , 1 ));
// 底部区域单行加入
graphicsPath.AddRectangle( new Rectangle(colOpaquePixel + 1 , bitmap.Height - row - 2 , colNext - colOpaquePixel - 2 , 1 ));
row ++ ;
}
// 跳出循环继续遍历下一列
break ;
}
}
}
// 返回
return graphicsPath;
}
} // end class
/// 创建自定义窗体或控件
/// Wendy,Bear据网上资料搜集整理优化
/// </summary>
public class BitmapRegion
{
public BitmapRegion()
{ }
/// <summary>
/// 创建支持位图区域的控件(目前有button和form)
/// </summary>
/// <param name="control"> 控件 </param>
/// <param name="bitmap"> 位图 </param>
public static void CreateControlRegion(Control control, Bitmap bitmap)
{
// 判断是否存在控件和位图
if (control == null || bitmap == null )
return ;
// 设置控件大小为位图大小
control.Width = bitmap.Width;
control.Height = bitmap.Height;
// 当控件是form时
if (control is System.Windows.Forms.Form)
{
// 强制转换为FORM
Form form = (Form)control;
// 当FORM的边界FormBorderStyle不为NONE时,应将FORM的大小设置成比位图大小稍大一点
form.Width = control.Width;
form.Height = control.Height;
// 没有边界
form.FormBorderStyle = FormBorderStyle.None;
// 将位图设置成窗体背景图片
form.BackgroundImage = bitmap;
//
// 将背景图片设为居中
// 董,2006.3.28
form.BackgroundImageLayout = ImageLayout.Center;
// 计算位图中不透明部分的边界
GraphicsPath graphicsPath = CalculateControlGraphicsPath(bitmap);
// 应用新的区域
form.Region = new Region(graphicsPath);
}
// 当控件是button时
else if (control is System.Windows.Forms.Button)
{
// 强制转换为 button
Button button = (Button)control;
// 不显示button text
button.Text = "" ;
// 改变 cursor的style
button.Cursor = Cursors.Hand;
// 设置button的背景图片
button.BackgroundImage = bitmap;
// 计算位图中不透明部分的边界
GraphicsPath graphicsPath = CalculateControlGraphicsPath(bitmap);
// 应用新的区域
button.Region = new Region(graphicsPath);
}
}
/// <summary>
/// 计算位图中不透明部分的边界
/// 注意:此方法只适用规则的四角对称的图形
/// </summary>
/// <param name="bitmap"> 要绘制区域的位图 </param>
/// <returns> 计算后的图形路径 </returns>
private static GraphicsPath CalculateControlGraphicsPath(Bitmap bitmap)
{
// 创建 GraphicsPath
GraphicsPath graphicsPath = new GraphicsPath();
// 使用左上角的一点的颜色作为我们透明色
Color colorTransparent = bitmap.GetPixel( 0 , 0 );
// 第一个找到点的X
int colOpaquePixel = 0 ;
// 遍历所有行(Y方向)
for ( int row = 0 ; row < bitmap.Height;)
{
// Reset value
// 重设
colOpaquePixel = 0 ;
// 遍历所有列(X方向)
for ( int col = 0 ; col < bitmap.Width; col ++ )
{
// 如果是不需要透明处理的点则标记,然后继续遍历
if (bitmap.GetPixel(col, row) != colorTransparent)
{
// 记录当前
colOpaquePixel = col;
// 记录右边界
int colNext = bitmap.Width - col;
// 将不透明点加到graphics path
if (col == 0 )
{
// 将中间大部分不透明区域加入
graphicsPath.AddRectangle( new Rectangle(colOpaquePixel + 1 , row, colNext - colOpaquePixel - 2 , bitmap.Height - row - row - 1 ));
// 置row为最大以便跳出循环
row = bitmap.Height;
}
else
{
// 顶部区域单行加入
graphicsPath.AddRectangle( new Rectangle(colOpaquePixel + 1 , row, colNext - colOpaquePixel - 2 , 1 ));
// 底部区域单行加入
graphicsPath.AddRectangle( new Rectangle(colOpaquePixel + 1 , bitmap.Height - row - 2 , colNext - colOpaquePixel - 2 , 1 ));
row ++ ;
}
// 跳出循环继续遍历下一列
break ;
}
}
}
// 返回
return graphicsPath;
}
} // end class
3.调用代码如下:


