分享
 
 
 

C#制作不规则窗口 ( 24bit Color 以上适用 )

王朝c#·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

C#制作不规则窗口 ( 24bit Color 以上适用 )

時間: 2004/3/17

作者: Robert

參考: http://www.codeproject.com/csharp/bmprgnform.asp?target=region

電郵: zsc771120@yahoo.com.cn

關鍵字: Region Gif 不規則 窗口 視窗 GraphicsPath 按鈕 圖片 Form Button

目的: 幫助受 C# 不規則窗口困擾的人

介紹

這篇文章說明怎麼製作圖片按鈕和窗體. Region 技術不但能做不規則窗口, 也能做不規則控件外觀, 比

如說不規則按鈕.

程序介紹

說明: 我修改程序介紹中的注釋, 不修改程序列表的說明. 畢竟 E 文我們看起來沒有中文舒服.

1. 主函數說明

下面的程序用倆個主函數產生 位圖區域 (bitmap regionss ), 源代碼放在 BitmapRegion.cs中, 你可

以直接導入這個類別, 使用裡面的函數.

// Create and apply the given bitmap region on the supplied control

// 產生支持位圖區域 ( bitmap region ) 控件

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)

{

// 強制轉換 control object 到 Form object

Form form = (Form)control;

// 由於我們的Form邊界類型 ( Form.FormBorderStyle ) 不是 None,

// 所以我們的Form尺寸比位圖大一點

form.Width += 15;

form.Height += 35;

// 設定 Form 邊界類型是 None

form.FormBorderStyle = FormBorderStyle.None;

// 設定 Form 背景圖片

form.BackgroundImage = bitmap;

// 計算圖片中不透明部分的邊界 (建議用 Gif 圖片 )

GraphicsPath graphicsPath = CalculateControlGraphicsPath(bitmap);

// 建立區域 ( Region )

form.Region = new Region(graphicsPath);

}

// 處理按鈕 ( button 類別 )

else if(control is System.Windows.Forms.Button)

{

// control object 轉成 Button object 類別

Button button = (Button)control;

// 清除 Button 上面的文字

button.Text = "";

// 更改鼠標樣式是手狀鼠標

button.Cursor = Cursors.Hand;

// 設定背景圖樣

button.BackgroundImage = bitmap;

//計算圖片中不透明部分的邊界 (建議用 Gif 圖片 )

GraphicsPath graphicsPath = CalculateControlGraphicsPath(bitmap);

// 建立區域 ( Region )

button.Region = new Region(graphicsPath);

}

// 這裡你可以模仿 Form 或者 Button 建立心的類別出歷程序, 比如Panel

}

// 計算圖片不透明區域 返回 GraphicsPath

private static GraphicsPath CalculateControlGraphicsPath(Bitmap bitmap)

{

// 建立GraphicsPath, 給我們的位圖路徑計算使用

GraphicsPath graphicsPath = new GraphicsPath();

// 使用左上角 (0,0) 點作為透明色

// 如果這裡是紅色, 那麼我們計算是圖片中不包含紅色區域路徑

Color colorTransparent = bitmap.GetPixel(0, 0);

// 存儲第一個不透明點, 這個值決定我們開始檢查不透明區域.

int colOpaquePixel = 0;

// 檢查所有的行 ( Y axis )

for(int row = 0; row < bitmap.Height; row ++)

{

// 重置 colOpaquePixel 值

colOpaquePixel = 0;

// 檢查所有的列 ( X axis )

for(int col = 0; col < bitmap.Width; col ++)

{

// 如果是不透明點, 標記之後尋這個點之後的位置

if(bitmap.GetPixel(col, row) != colorTransparent)

{

// 找到不透明點, 標記這個位置

colOpaquePixel = col;

// 建立新變量保存當前點位置

int colNext = col;

// 從找到的不透明點開始繼續搜索不透明點,

//一直到找到透明點 或者 找到圖片寬度搜索完畢

for(colNext=colOpaquePixel; colNext<bitmap.Width; colNext++)

if(bitmap.GetPixel(colNext, row) == colorTransparent)

break;

// 把不透明區域加入我們的GraphicsPath

graphicsPath.AddRectangle(new Rectangle(colOpaquePixel,

row, colNext - colOpaquePixel, 1));

// 找到之後不用搜索不透明點

col = colNext;

}

}

}

// 返回計算出來的不透明圖片路徑

return graphicsPath;

}

產生不規則窗體

下面這倆行代碼能產生不規則圖形. 你不必改變 Form.FormBorderStyle是None, 程序自己幫你做這件事

.

public class Form1 : System.Windows.Forms.Form

{

// 導入背景圖片

private Bitmap bmpFrmBack = new Bitmap(typeof(Form1), "back.bmp");

public Form1()

{

InitializeComponent();

// 讓你的床體透明吧

BitmapRegion.CreateControlRegion(this, bmpFrmBack);

}

}

產生不規則按鈕

和產生不規則窗體一樣產生不規則按鈕

public class Form1 : System.Windows.Forms.Form

{

// 導入窗體背景圖片

private Bitmap bmpFrmBack = new Bitmap(typeof(Form1), "back.bmp");

// 導入按鈕背景圖片

private Bitmap bmpBob = new Bitmap(typeof(Form1), "bob.bmp");

public Form1()

{

InitializeComponent();

// 產生不規則窗體

BitmapRegion.CreateControlRegion(this, bmpFrmBack);

// 產生不規則按鈕

BitmapRegion.CreateControlRegion(button1, bmpBob);

}

}

如果你想在鼠標盡入/離開按鈕的時候顯示不同不規則按鈕, 只需要在按鈕的 MouseLeave和MouseEnter

裡面寫上下面的代碼就可以了.

private void button1_MouseEnter(object sender, System.EventArgs e)

{

// 產生不規則按鈕

BitmapRegion.CreateControlRegion(button1, bmpBobSay);

}

private void button1_MouseLeave(object sender, System.EventArgs e)

{

// 產生不規則按鈕

BitmapRegion.CreateControlRegion(button1, bmpBob);

}

移動不規則窗口

因為不規則窗口沒有標題欄, 怎麼移動呢? 下面代碼給你答案, 代碼很簡單, 我就不做中文解釋了 ( 我

做中文的部分就是不規則窗體 )

private void Form1_MouseMove(object sender,

System.Windows.Forms.MouseEventArgs e)

{

// Check if dragging of the form has occurred

if(e.Button == MouseButtons.Left)

{

// If this is the first mouse move event for left click dragging

// of the form, store the current point clicked so that we can use

// it to calculate the form's new location in subsequent mouse move

// events due to left click dragging of the form

if(isFirst == true)

{

// Store previous left click position

prevLeftClick = new Point(e.X, e.Y);

// Subsequent mouse move events will not be treated as first time,

// until the left mouse click is released or other mouse click

// occur

isFirst = false;

}

// On subsequent mouse move events with left mouse click down.

// (i.e. During dragging of form)

else

{

// This flag here is to do alternate processing for the form

// dragging because it causes serious flicking when u allow

// every such events to change the form's location.

// You can try commenting this out to see what i mean

if(toBlock == false)

this.Location = new Point(this.Location.X + e.X -

prevLeftClick.X, this.Location.Y + e.Y - prevLeftClick.Y);

// Store new previous left click position

prevLeftClick = new Point(e.X, e.Y);

// Allow or deny next mouse move dragging event

toBlock = !toBlock;

}

}

// This is a new mouse move event so reset flag

else

isFirst = true;

}

完成程序列表

BitmapRegion.cs

using System;

using System.Drawing;

using System.Drawing.Drawing2D;

using System.Windows.Forms;

namespace BitmapRegionTest

{

/// <summary>

/// Summary description for BitmapRegion.

/// </summary>

public class BitmapRegion

{

public BitmapRegion()

{}

/// <summary>

/// Create and apply the region on the supplied control

/// </summary>

/// <param name="control">The Control object to apply the region to</param>

/// <param name="bitmap">The Bitmap object to create the region

from</param>

public static void CreateControlRegion(Control control, Bitmap bitmap)

{

// Return if control and bitmap are null

if(control == null || bitmap == null)

return;

// Set our control's size to be the same as the bitmap

control.Width = bitmap.Width;

control.Height = bitmap.Height;

// Check if we are dealing with Form here

if(control is System.Windows.Forms.Form)

{

// Cast to a Form object

Form form = (Form)control;

// Set our form's size to be a little larger that the

bitmap just

// in case the form's border style is not set to none in

the first place

form.Width += 15;

form.Height += 35;

// No border

form.FormBorderStyle = FormBorderStyle.None;

// Set bitmap as the background image

form.BackgroundImage = bitmap;

// Calculate the graphics path based on the bitmap supplied

GraphicsPath graphicsPath =

CalculateControlGraphicsPath(bitmap);

// Apply new region

form.Region = new Region(graphicsPath);

}

// Check if we are dealing with Button here

else if(control is System.Windows.Forms.Button)

{

// Cast to a button object

Button button = (Button)control;

// Do not show button text

button.Text = "";

// Change cursor to hand when over button

button.Cursor = Cursors.Hand;

// Set background image of button

button.BackgroundImage = bitmap;

// Calculate the graphics path based on the bitmap supplied

GraphicsPath graphicsPath =

CalculateControlGraphicsPath(bitmap);

// Apply new region

button.Region = new Region(graphicsPath);

}

}

/// <summary>

/// Calculate the graphics path that representing the figure in the bitmap

/// excluding the transparent color which is the top left pixel.

/// </summary>

/// <param name="bitmap">The Bitmap object to calculate our graphics path

from</param>

/// <returns>Calculated graphics path</returns>

private static GraphicsPath CalculateControlGraphicsPath(Bitmap bitmap)

{

// Create GraphicsPath for our bitmap calculation

GraphicsPath graphicsPath = new GraphicsPath();

// Use the top left pixel as our transparent color

Color colorTransparent = bitmap.GetPixel(0, 0);

// This is to store the column value where an opaque pixel is first

found.

// This value will determine where we start scanning for trailing

opaque pixels.

int colOpaquePixel = 0;

// Go through all rows (Y axis)

for(int row = 0; row < bitmap.Height; row ++)

{

// Reset value

colOpaquePixel = 0;

// Go through all columns (X axis)

for(int col = 0; col < bitmap.Width; col ++)

{

// If this is an opaque pixel, mark it and search

for anymore trailing behind

if(bitmap.GetPixel(col, row) != colorTransparent)

{

// Opaque pixel found, mark current

position

colOpaquePixel = col;

// Create another variable to set the

current pixel position

int colNext = col;

// Starting from current found opaque

pixel, search for anymore opaque pixels

// trailing behind, until a transparent

pixel is found or minimum width is reached

for(colNext = colOpaquePixel; colNext <

bitmap.Width; colNext ++)

if(bitmap.GetPixel(colNext, row) ==

colorTransparent)

break;

// Form a rectangle for line of opaque

pixels found and add it to our graphics path

graphicsPath.AddRectangle(new

Rectangle(colOpaquePixel, row, colNext - colOpaquePixel, 1));

// No need to scan the line of opaque

pixels just found

col = colNext;

}

}

}

// Return calculated graphics path

return graphicsPath;

}

}

}

///////////////////////////////////////////////////////////////////////////////////////////

//////////

Form1.cs

using System;

using System.Drawing;

using System.Collections;

using System.ComponentModel;

using System.Windows.Forms;

using System.Data;

//using System.Runtime.InteropServices;

namespace BitmapRegionTest

{

/// <summary>

/// Summary description for Form1.

/// </summary>

public class Form1 : System.Windows.Forms.Form

{

// [DllImport("user32.dll")]

// private static extern bool PostMessage(IntPtr hWnd, int msg, long wParam,

long lParam);

private System.Windows.Forms.Button button1;

private System.Windows.Forms.Button button2;

private System.Windows.Forms.Button button3;

private System.Windows.Forms.Button button4;

/// <summary>

/// Required designer variable.

/// </summary>

private System.ComponentModel.Container components = null;

// Load our bitmaps

private Bitmap bmpFrmBack = new Bitmap(typeof(Form1), "back.bmp");

private Bitmap bmpBob = new Bitmap(typeof(Form1), "bob.bmp");

private Bitmap bmpBobSay = new Bitmap(typeof(Form1), "bobsay.bmp");

private Bitmap bmpSmiles = new Bitmap(typeof(Form1), "smiles.bmp");

private Bitmap bmpSmilesAngry = new Bitmap(typeof(Form1),

"smilesangry.bmp");

private Bitmap bmpGreenBtnUp = new Bitmap(typeof(Form1), "greenbtnup.bmp");

private Bitmap bmpGreenBtnDown = new Bitmap(typeof(Form1),

"greenbtndown.bmp");

private Bitmap bmpX = new Bitmap(typeof(Form1), "x.bmp");

private Bitmap bmpXSmile = new Bitmap(typeof(Form1), "xsmile.bmp");

// To store the location of previous mouse left click in the form

// so that we can use it to calculate the new form location during dragging

private Point prevLeftClick;

// To determine if it is the first time entry for every dragging of the

form

private bool isFirst = true;

// Acts like a gate to do allow or deny

private bool toBlock = true;

public Form1()

{

//

// Required for Windows Form Designer support

//

InitializeComponent();

// Make our bitmap region for the form

BitmapRegion.CreateControlRegion(this, bmpFrmBack);

// Make our bitmap regions for the buttons

BitmapRegion.CreateControlRegion(button1, bmpBob);

BitmapRegion.CreateControlRegion(button2, bmpSmiles);

BitmapRegion.CreateControlRegion(button3, bmpGreenBtnUp);

BitmapRegion.CreateControlRegion(button4, bmpX);

}

/// <summary>

/// Clean up any resources being used.

/// </summary>

protected override void Dispose( bool disposing )

{

if( disposing )

{

if (components != null)

{

components.Dispose();

}

}

base.Dispose( disposing );

}

#region Windows Form Designer generated code

/// <summary>

/// Required method for Designer support - do not modify

/// the contents of this method with the code editor.

/// </summary>

private void InitializeComponent()

{

this.button1 = new System.Windows.Forms.Button();

this.button2 = new System.Windows.Forms.Button();

this.button3 = new System.Windows.Forms.Button();

this.button4 = new System.Windows.Forms.Button();

this.SuspendLayout();

//

// button1

//

this.button1.Location = new System.Drawing.Point(104, 88);

this.button1.Name = "button1";

this.button1.TabIndex = 0;

this.button1.Text = "button1";

this.button1.Click += new System.EventHandler(this.button1_Click);

this.button1.MouseEnter += new

System.EventHandler(this.button1_MouseEnter);

this.button1.MouseLeave += new

System.EventHandler(this.button1_MouseLeave);

//

// button2

//

this.button2.Location = new System.Drawing.Point(328, 80);

this.button2.Name = "button2";

this.button2.TabIndex = 1;

this.button2.Text = "button2";

this.button2.Click += new System.EventHandler(this.button2_Click);

this.button2.MouseEnter += new

System.EventHandler(this.button2_MouseEnter);

this.button2.MouseLeave += new

System.EventHandler(this.button2_MouseLeave);

//

// button3

//

this.button3.Location = new System.Drawing.Point(184, 200);

this.button3.Name = "button3";

this.button3.TabIndex = 2;

this.button3.Text = "button3";

this.button3.Click += new System.EventHandler(this.button3_Click);

this.button3.MouseEnter += new

System.EventHandler(this.button3_MouseEnter);

this.button3.MouseLeave += new

System.EventHandler(this.button3_MouseLeave);

//

// button4

//

this.button4.Location = new System.Drawing.Point(344, 232);

this.button4.Name = "button4";

this.button4.TabIndex = 3;

this.button4.Text = "button4";

this.button4.Click += new System.EventHandler(this.button4_Click);

this.button4.MouseEnter += new

System.EventHandler(this.button4_MouseEnter);

this.button4.MouseLeave += new

System.EventHandler(this.button4_MouseLeave);

//

// Form1

//

this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);

this.ClientSize = new System.Drawing.Size(432, 270);

this.Controls.AddRange(new System.Windows.Forms.Control[] {

this.button4,

this.button3,

this.button2,

this.button1});

this.Name = "Form1";

this.Text = "Form1";

this.MouseMove += new

System.Windows.Forms.MouseEventHandler(this.Form1_MouseMove);

this.ResumeLayout(false);

}

#endregion

/// <summary>

/// The main entry point for the application.

/// </summary>

[STAThread]

static void Main()

{

Application.Run(new Form1());

}

private void button1_MouseEnter(object sender, System.EventArgs e)

{

// Make bitmap region for button

BitmapRegion.CreateControlRegion(button1, bmpBobSay);

}

private void button1_MouseLeave(object sender, System.EventArgs e)

{

// Make bitmap region for button

BitmapRegion.CreateControlRegion(button1, bmpBob);

}

private void button2_MouseEnter(object sender, System.EventArgs e)

{

// Make bitmap region for button

BitmapRegion.CreateControlRegion(button2, bmpSmilesAngry);

}

private void button2_MouseLeave(object sender, System.EventArgs e)

{

// Make bitmap region for button

BitmapRegion.CreateControlRegion(button2, bmpSmiles);

}

private void button3_MouseEnter(object sender, System.EventArgs e)

{

// Make bitmap region for button

BitmapRegion.CreateControlRegion(button3, bmpGreenBtnDown);

}

private void button3_MouseLeave(object sender, System.EventArgs e)

{

// Make bitmap region for button

BitmapRegion.CreateControlRegion(button3, bmpGreenBtnUp);

}

private void button4_MouseEnter(object sender, System.EventArgs e)

{

// Make bitmap region for button

BitmapRegion.CreateControlRegion(button4, bmpXSmile);

}

private void button4_MouseLeave(object sender, System.EventArgs e)

{

// Make bitmap region for button

BitmapRegion.CreateControlRegion(button4, bmpX);

}

private void button1_Click(object sender, System.EventArgs e)

{

MessageBox.Show("bob");

}

private void button2_Click(object sender, System.EventArgs e)

{

MessageBox.Show("smiles");

}

private void button3_Click(object sender, System.EventArgs e)

{

MessageBox.Show("green button");

}

private void button4_Click(object sender, System.EventArgs e)

{

MessageBox.Show("Exiting now...");

Close();

}

/*

protected override void OnMouseDown(MouseEventArgs e)

{

if(e.Button == MouseButtons.Left)

{

const int HTCAPTION = 2;

const int WM_NCLBUTTONDOWN = 161;

int ix = e.X & 0xffff;

int iy = e.Y & 0xffff;

long ll = ix | iy << 16;

PostMessage(this.Handle, WM_NCLBUTTONDOWN, HTCAPTION, ll);

}

}

*/

private void Form1_MouseMove(object sender,

System.Windows.Forms.MouseEventArgs e)

{

// Check if dragging of the form has occurred

if(e.Button == MouseButtons.Left)

{

// If this is the first mouse move event for left click

dragging of the form,

// store the current point clicked so that we can use it to

calculate the form's

// new location in subsequent mouse move events due to left

click dragging of the form

if(isFirst == true)

{

// Store previous left click position

prevLeftClick = new Point(e.X, e.Y);

// Subsequent mouse move events will not be treated

as first time, until the

// left mouse click is released or other mouse

click occur

isFirst = false;

}

// On subsequent mouse move events with left mouse click

down. (During dragging of form)

else

{

// This flag here is to allow alternate processing

for dragging the form because it

// causes serious flicking when u allow every such

events to change the form's location.

// You can try commenting this out to see what i

mean

if(toBlock == false)

this.Location = new Point(this.Location.X +

e.X - prevLeftClick.X, this.Location.Y + e.Y - prevLeftClick.Y);

// Store new previous left click position

prevLeftClick = new Point(e.X, e.Y);

// Allow or deny next mouse move dragging event

toBlock = !toBlock;

}

}

// This is a new mouse move event so reset flag

else

isFirst = true;

}

}

}

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有