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

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

時間: 2004/3/17
作者: Robert
參考: http://www.codeproject.com/csharp/bmprgnform.asp?target=region
電郵: [email protected]
關鍵字: 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

  1<bitmap.width; "back.bmp");="" "bob.bmp");="" #="" (="" (i.e.="" )="" +="" -="" .="" 1));="" :="" <summary="" a="" allow="" alternate="" as="" be="" because="" bitmap="" bitmap(typeof(form1),="" bitmapregion.createcontrolregion(button1,="" bitmapregion.createcontrolregion(this,="" bitmapregion.cs="" bitmapregiontest="" bmpbob="new" bmpbob);="" bmpbobsay);="" bmpfrmback="new" bmpfrmback);="" break;="" button1_mouseenter(object="" button1_mouseleave(object="" calculate="" can="" causes="" change="" check="" class="" click="" clicked="" col="colNext;" colnext="" colnext++)="" colopaquepixel,="" commenting="" current="" deny="" do="" down.="" dragging="" due="" during="" e)="" e.x="" e.y="" e.y);="" else="" event="" events="" every="" first="" flag="" flicking="" for="" form="" form's="" form)="" form,="" form.formborderstyle是none,="" form1="" form1()="" form1_mousemove(object="" graphicspath.addrectangle(new="" graphicspath;="" has="" here="" i="" if="" if(bitmap.getpixel(colnext,="" if(e.button="MouseButtons.Left)" if(isfirst="true)" if(toblock="false)" in="" initializecomponent();="" is="" isfirst="true;" it="" left="" location="" location.="" mean="" mouse="" mouseleave和mouseenter="" move="" namespace="" new="" next="" not="" occur="" occurred="" of="" on="" or="" other="" out="" point="" point(e.x,="" point(this.location.x="" position="" previous="" prevleftclick="new" prevleftclick.x,="" prevleftclick.y);="" private="" processing="" public="" rectangle(colopaquepixel,="" released="" reset="" return="" row)="colorTransparent)" row,="" see="" sender,="" serious="" so="" store="" subsequent="" such="" system.drawing.drawing2d;="" system.drawing;="" system.eventargs="" system.windows.forms.form="" system.windows.forms.mouseeventargs="" system.windows.forms;="" system;="" that="" the="" this="" this.location="new" this.location.y="" time,="" to="" toblock="!toBlock;" treated="" try="" u="" until="" use="" using="" void="" we="" what="" when="" will="" with="" you="" {="" }="" 下面代碼給你答案,="" 下面這倆行代碼能產生不規則圖形.="" 代碼很簡單,="" 你不必改變="" 做中文的部分就是不規則窗體="" 只需要在按鈕的="" 和產生不規則窗體一樣產生不規則按鈕="" 因為不規則窗口沒有標題欄,="" 如果你想在鼠標盡入="" 完成程序列表="" 導入按鈕背景圖片="" 導入窗體背景圖片="" 導入背景圖片="" 怎麼移動呢?="" 我="" 我就不做中文解釋了="" 找到之後不用搜索不透明點="" 把不透明區域加入我們的graphicspath="" 產生不規則按鈕="" 產生不規則窗體="" 移動不規則窗口="" 程序自己幫你做這件事="" 裡面寫上下面的代碼就可以了.="" 讓你的床體透明吧="" 返回計算出來的不透明圖片路徑="" 離開按鈕的時候顯示不同不規則按鈕,="">   
  2/// Summary description for BitmapRegion.   
  3///    
  4public class BitmapRegion   
  5{   
  6public BitmapRegion()   
  7{} 
  8
  9#  /// <summary>   
 10/// Create and apply the region on the supplied control   
 11/// </summary>   
 12/// <param name="control"/>The Control object to apply the region to   
 13/// <param name="bitmap"/>The Bitmap object to create the region 
 14
 15#  from   
 16public static void CreateControlRegion(Control control, Bitmap bitmap)   
 17{   
 18// Return if control and bitmap are null   
 19if(control == null || bitmap == null)   
 20return;   
 21  
 22// Set our control's size to be the same as the bitmap   
 23control.Width = bitmap.Width;   
 24control.Height = bitmap.Height; 
 25
 26#  // Check if we are dealing with Form here   
 27if(control is System.Windows.Forms.Form)   
 28{   
 29// Cast to a Form object   
 30Form form = (Form)control; 
 31
 32#  // Set our form's size to be a little larger that the 
 33
 34#  bitmap just   
 35// in case the form's border style is not set to none in 
 36
 37#  the first place   
 38form.Width += 15;   
 39form.Height += 35; 
 40
 41#  // No border   
 42form.FormBorderStyle = FormBorderStyle.None; 
 43
 44#  // Set bitmap as the background image   
 45form.BackgroundImage = bitmap; 
 46
 47#  // Calculate the graphics path based on the bitmap supplied   
 48GraphicsPath graphicsPath = 
 49
 50#  CalculateControlGraphicsPath(bitmap); 
 51
 52#  // Apply new region   
 53form.Region = new Region(graphicsPath);   
 54} 
 55
 56#  // Check if we are dealing with Button here   
 57else if(control is System.Windows.Forms.Button)   
 58{   
 59// Cast to a button object   
 60Button button = (Button)control; 
 61
 62#  // Do not show button text   
 63button.Text = "";   
 64  
 65// Change cursor to hand when over button   
 66button.Cursor = Cursors.Hand; 
 67
 68#  // Set background image of button   
 69button.BackgroundImage = bitmap;   
 70  
 71// Calculate the graphics path based on the bitmap supplied   
 72GraphicsPath graphicsPath = 
 73
 74#  CalculateControlGraphicsPath(bitmap); 
 75
 76#  // Apply new region   
 77button.Region = new Region(graphicsPath);   
 78}   
 79} 
 80
 81#  /// <summary>   
 82/// Calculate the graphics path that representing the figure in the bitmap   
 83/// excluding the transparent color which is the top left pixel.   
 84/// </summary>   
 85/// <param name="bitmap"/>The Bitmap object to calculate our graphics path 
 86
 87#  from   
 88/// <returns>Calculated graphics path</returns>   
 89private static GraphicsPath CalculateControlGraphicsPath(Bitmap bitmap)   
 90{   
 91// Create GraphicsPath for our bitmap calculation   
 92GraphicsPath graphicsPath = new GraphicsPath(); 
 93
 94#  // Use the top left pixel as our transparent color   
 95Color colorTransparent = bitmap.GetPixel(0, 0); 
 96
 97#  // This is to store the column value where an opaque pixel is first 
 98
 99#  found.   
100// This value will determine where we start scanning for trailing 
101
102#  opaque pixels.   
103int colOpaquePixel = 0; 
104
105#  // Go through all rows (Y axis)   
106for(int row = 0; row &lt; bitmap.Height; row ++)   
107{   
108// Reset value   
109colOpaquePixel = 0; 
110
111#  // Go through all columns (X axis)   
112for(int col = 0; col &lt; bitmap.Width; col ++)   
113{   
114// If this is an opaque pixel, mark it and search 
115
116#  for anymore trailing behind   
117if(bitmap.GetPixel(col, row) != colorTransparent)   
118{   
119// Opaque pixel found, mark current 
120
121#  position   
122colOpaquePixel = col; 
123
124#  // Create another variable to set the 
125
126#  current pixel position   
127int colNext = col; 
128
129#  // Starting from current found opaque 
130
131#  pixel, search for anymore opaque pixels   
132// trailing behind, until a transparent 
133
134#  pixel is found or minimum width is reached   
135for(colNext = colOpaquePixel; colNext &lt;
136
137#  bitmap.Width; colNext ++)   
138if(bitmap.GetPixel(colNext, row) == 
139
140#  colorTransparent)   
141break; 
142
143#  // Form a rectangle for line of opaque 
144
145#  pixels found and add it to our graphics path   
146graphicsPath.AddRectangle(new 
147
148#  Rectangle(colOpaquePixel, row, colNext - colOpaquePixel, 1)); 
149
150#  // No need to scan the line of opaque 
151
152#  pixels just found   
153col = colNext;   
154}   
155}   
156} 
157
158#  // Return calculated graphics path   
159return graphicsPath;   
160}   
161}   
162}   
163/////////////////////////////////////////////////////////////////////////////////////////// 
164
165#  //////////   
166Form1.cs   
167using System;   
168using System.Drawing;   
169using System.Collections;   
170using System.ComponentModel;   
171using System.Windows.Forms;   
172using System.Data;   
173//using System.Runtime.InteropServices; 
174
175#  namespace BitmapRegionTest   
176{   
177/// <summary>   
178/// Summary description for Form1.   
179/// </summary>   
180public class Form1 : System.Windows.Forms.Form   
181{   
182// [DllImport("user32.dll")]   
183// private static extern bool PostMessage(IntPtr hWnd, int msg, long wParam, 
184
185#  long lParam); 
186
187#  private System.Windows.Forms.Button button1;   
188private System.Windows.Forms.Button button2;   
189private System.Windows.Forms.Button button3;   
190private System.Windows.Forms.Button button4; 
191
192#  /// <summary>   
193/// Required designer variable.   
194/// </summary>   
195private System.ComponentModel.Container components = null; 
196
197#  // Load our bitmaps   
198private Bitmap bmpFrmBack = new Bitmap(typeof(Form1), "back.bmp");   
199private Bitmap bmpBob = new Bitmap(typeof(Form1), "bob.bmp");   
200private Bitmap bmpBobSay = new Bitmap(typeof(Form1), "bobsay.bmp");   
201private Bitmap bmpSmiles = new Bitmap(typeof(Form1), "smiles.bmp");   
202private Bitmap bmpSmilesAngry = new Bitmap(typeof(Form1), 
203
204#  "smilesangry.bmp");   
205private Bitmap bmpGreenBtnUp = new Bitmap(typeof(Form1), "greenbtnup.bmp");   
206private Bitmap bmpGreenBtnDown = new Bitmap(typeof(Form1), 
207
208#  "greenbtndown.bmp");   
209private Bitmap bmpX = new Bitmap(typeof(Form1), "x.bmp");   
210private Bitmap bmpXSmile = new Bitmap(typeof(Form1), "xsmile.bmp"); 
211
212#  // To store the location of previous mouse left click in the form   
213// so that we can use it to calculate the new form location during dragging   
214private Point prevLeftClick; 
215
216#  // To determine if it is the first time entry for every dragging of the 
217
218#  form   
219private bool isFirst = true; 
220
221#  // Acts like a gate to do allow or deny   
222private bool toBlock = true; 
223
224#  public Form1()   
225{   
226//   
227// Required for Windows Form Designer support   
228//   
229InitializeComponent(); 
230
231#  // Make our bitmap region for the form   
232BitmapRegion.CreateControlRegion(this, bmpFrmBack); 
233
234#  // Make our bitmap regions for the buttons   
235BitmapRegion.CreateControlRegion(button1, bmpBob);   
236BitmapRegion.CreateControlRegion(button2, bmpSmiles);   
237BitmapRegion.CreateControlRegion(button3, bmpGreenBtnUp);   
238BitmapRegion.CreateControlRegion(button4, bmpX);   
239} 
240
241#  /// <summary>   
242/// Clean up any resources being used.   
243/// </summary>   
244protected override void Dispose( bool disposing )   
245{   
246if( disposing )   
247{   
248if (components != null)   
249{   
250components.Dispose();   
251}   
252}   
253base.Dispose( disposing );   
254} 
255
256#  #region Windows Form Designer generated code   
257/// <summary>   
258/// Required method for Designer support - do not modify   
259/// the contents of this method with the code editor.   
260/// </summary>   
261private void InitializeComponent()   
262{   
263this.button1 = new System.Windows.Forms.Button();   
264this.button2 = new System.Windows.Forms.Button();   
265this.button3 = new System.Windows.Forms.Button();   
266this.button4 = new System.Windows.Forms.Button();   
267this.SuspendLayout();   
268//   
269// button1   
270//   
271this.button1.Location = new System.Drawing.Point(104, 88);   
272this.button1.Name = "button1";   
273this.button1.TabIndex = 0;   
274this.button1.Text = "button1";   
275this.button1.Click += new System.EventHandler(this.button1_Click);   
276this.button1.MouseEnter += new 
277
278#  System.EventHandler(this.button1_MouseEnter);   
279this.button1.MouseLeave += new 
280
281#  System.EventHandler(this.button1_MouseLeave);   
282//   
283// button2   
284//   
285this.button2.Location = new System.Drawing.Point(328, 80);   
286this.button2.Name = "button2";   
287this.button2.TabIndex = 1;   
288this.button2.Text = "button2";   
289this.button2.Click += new System.EventHandler(this.button2_Click);   
290this.button2.MouseEnter += new 
291
292#  System.EventHandler(this.button2_MouseEnter);   
293this.button2.MouseLeave += new 
294
295#  System.EventHandler(this.button2_MouseLeave);   
296//   
297// button3   
298//   
299this.button3.Location = new System.Drawing.Point(184, 200);   
300this.button3.Name = "button3";   
301this.button3.TabIndex = 2;   
302this.button3.Text = "button3";   
303this.button3.Click += new System.EventHandler(this.button3_Click);   
304this.button3.MouseEnter += new 
305
306#  System.EventHandler(this.button3_MouseEnter);   
307this.button3.MouseLeave += new 
308
309#  System.EventHandler(this.button3_MouseLeave);   
310//   
311// button4   
312//   
313this.button4.Location = new System.Drawing.Point(344, 232);   
314this.button4.Name = "button4";   
315this.button4.TabIndex = 3;   
316this.button4.Text = "button4";   
317this.button4.Click += new System.EventHandler(this.button4_Click);   
318this.button4.MouseEnter += new 
319
320#  System.EventHandler(this.button4_MouseEnter);   
321this.button4.MouseLeave += new 
322
323#  System.EventHandler(this.button4_MouseLeave);   
324//   
325// Form1   
326//   
327this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);   
328this.ClientSize = new System.Drawing.Size(432, 270);   
329this.Controls.AddRange(new System.Windows.Forms.Control[] {   
330
331
332#  this.button4,   
333
334
335#  this.button3,   
336
337
338#  this.button2,   
339
340
341#  this.button1});   
342this.Name = "Form1";   
343this.Text = "Form1";   
344this.MouseMove += new 
345
346#  System.Windows.Forms.MouseEventHandler(this.Form1_MouseMove);   
347this.ResumeLayout(false); 
348
349#  }   
350#endregion 
351
352#  /// <summary>   
353/// The main entry point for the application.   
354/// </summary>   
355[STAThread]   
356static void Main()   
357{   
358Application.Run(new Form1());   
359} 
360
361#  private void button1_MouseEnter(object sender, System.EventArgs e)   
362{   
363// Make bitmap region for button   
364BitmapRegion.CreateControlRegion(button1, bmpBobSay);   
365} 
366
367#  private void button1_MouseLeave(object sender, System.EventArgs e)   
368{   
369// Make bitmap region for button   
370BitmapRegion.CreateControlRegion(button1, bmpBob);   
371} 
372
373#  private void button2_MouseEnter(object sender, System.EventArgs e)   
374{   
375// Make bitmap region for button   
376BitmapRegion.CreateControlRegion(button2, bmpSmilesAngry);   
377} 
378
379#  private void button2_MouseLeave(object sender, System.EventArgs e)   
380{   
381// Make bitmap region for button   
382BitmapRegion.CreateControlRegion(button2, bmpSmiles);   
383} 
384
385#  private void button3_MouseEnter(object sender, System.EventArgs e)   
386{   
387// Make bitmap region for button   
388BitmapRegion.CreateControlRegion(button3, bmpGreenBtnDown);   
389} 
390
391#  private void button3_MouseLeave(object sender, System.EventArgs e)   
392{   
393// Make bitmap region for button   
394BitmapRegion.CreateControlRegion(button3, bmpGreenBtnUp);   
395} 
396
397#  private void button4_MouseEnter(object sender, System.EventArgs e)   
398{   
399// Make bitmap region for button   
400BitmapRegion.CreateControlRegion(button4, bmpXSmile);   
401} 
402
403#  private void button4_MouseLeave(object sender, System.EventArgs e)   
404{   
405// Make bitmap region for button   
406BitmapRegion.CreateControlRegion(button4, bmpX);   
407} 
408
409#  private void button1_Click(object sender, System.EventArgs e)   
410{   
411MessageBox.Show("bob");   
412} 
413
414#  private void button2_Click(object sender, System.EventArgs e)   
415{   
416MessageBox.Show("smiles");   
417} 
418
419#  private void button3_Click(object sender, System.EventArgs e)   
420{   
421MessageBox.Show("green button");   
422} 
423
424#  private void button4_Click(object sender, System.EventArgs e)   
425{   
426MessageBox.Show("Exiting now...");   
427Close();   
428}   
429/*   
430protected override void OnMouseDown(MouseEventArgs e)   
431{   
432if(e.Button == MouseButtons.Left)   
433{   
434const int HTCAPTION = 2;   
435const int WM_NCLBUTTONDOWN = 161;   
436  
437int ix = e.X &amp; 0xffff;   
438int iy = e.Y &amp; 0xffff;   
439long ll = ix | iy &lt;&lt; 16; 
440
441#  PostMessage(this.Handle, WM_NCLBUTTONDOWN, HTCAPTION, ll);   
442}   
443}   
444*/   
445private void Form1_MouseMove(object sender, 
446
447#  System.Windows.Forms.MouseEventArgs e)   
448{   
449// Check if dragging of the form has occurred   
450if(e.Button == MouseButtons.Left)   
451{   
452// If this is the first mouse move event for left click 
453
454#  dragging of the form,   
455// store the current point clicked so that we can use it to 
456
457#  calculate the form's   
458// new location in subsequent mouse move events due to left 
459
460#  click dragging of the form   
461if(isFirst == true)   
462{   
463// Store previous left click position   
464prevLeftClick = new Point(e.X, e.Y); 
465
466#  // Subsequent mouse move events will not be treated 
467
468#  as first time, until the   
469// left mouse click is released or other mouse 
470
471#  click occur   
472isFirst = false;   
473} 
474
475#  // On subsequent mouse move events with left mouse click 
476
477#  down. (During dragging of form)   
478else   
479{   
480// This flag here is to allow alternate processing 
481
482#  for dragging the form because it   
483// causes serious flicking when u allow every such 
484
485#  events to change the form's location.   
486// You can try commenting this out to see what i 
487
488#  mean   
489if(toBlock == false)   
490this.Location = new Point(this.Location.X + 
491
492#  e.X - prevLeftClick.X, this.Location.Y + e.Y - prevLeftClick.Y); 
493
494#  // Store new previous left click position   
495prevLeftClick = new Point(e.X, e.Y); 
496
497#  // Allow or deny next mouse move dragging event   
498toBlock = !toBlock;   
499}   
500} 
501
502#  // This is a new mouse move event so reset flag   
503else   
504isFirst = true;   
505}   
506}   
507}</bitmap.width;>
Published At
Categories with Web编程
Tagged with
comments powered by Disqus