日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > C# >内容正文

C#

一起谈.NET技术,C#创建不规则窗体的几种方式

發布時間:2025/4/16 C# 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 一起谈.NET技术,C#创建不规则窗体的几种方式 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

????現在,C#創建不規則窗體不是一件難事,下面總結一下:

????? 一、自定義窗體,一般為規則的圖形,如圓、橢圓等。

做法:重寫Form1_Paint事件(Form1是窗體的名字),最簡單的一種情況如下:

System.Drawing.Drawing2D.GraphicsPath shape = new System.Drawing.Drawing2D.GraphicsPath();

shape.AddEllipse(0,0,this.Height, this.Width);

this.Region = new Region(shape);

即重繪窗體的規則。

??? 二、利用背景圖片實現

????? 1.?????? 設置窗體的背景圖片,其中背景圖片是24位(不包括24)以下的位圖(BMP圖片),并且要設置TansparencyKey的值,一般為你背景圖片的背景色,即創建不規則圖片時的底色,一般設為你圖片中沒有的顏色。

??? 這種做法的不好的地方就是背景圖片一定要16位或者更低的,而且還要確保客戶端的顯示。如果監視器的顏色深度設置大于 24 位,則不管 TransparencyKey 屬性是如何設置的,窗體的非透明部分都會產生顯示問題。若要避免出現這種問題,請確保“顯示”控制面板中的監視器顏色深度的設置小于 24 位。當開發具有這種透明功能的應用程序時,請牢記應使您的用戶意識到此問題。

???? 實現步驟如下:

1.?新建windows application

2.?選擇窗體,找到BackgroundImage屬性,點擊打開新的窗口,選擇下面的導入資源文件,選擇你的不規則的BMP圖片

3.?找到窗體的TansparencyKey,將它設置為你背景圖片的背景色(如黃色)

4.?找到窗體的FormBorderStyle,將其設置為none,即不顯示標題欄

5.?運行

????? 2.?????? 跟背景圖片一樣的圖形,不過是動態加載,遍歷位圖以實現不規則窗體。它的原理是這樣的,在Formload事件中寫方法使得窗體的描繪區域發生改變。

??? 實現步驟如下:

1.?建立winform應用程序

2.?找到窗體的Load事件,雙擊進行編輯

3.?編寫方法,主要的代碼如下:

?

代碼
????
class?BitmapRegion
????{
????????
public?BitmapRegion()
????????{?}


????????
///?<summary>?
????????
///?Create?and?apply?the?region?on?the?supplied?control
????????
///?創建支持位圖區域的控件(目前有button和form)
????????
///?</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?
????????????
//當控件是form時
????????????if?(control?is?System.Windows.Forms.Form)
????????????{
????????????????
//?Cast?to?a?Form?object
????????????????
//強制轉換為FORM
????????????????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的邊界FormBorderStyle不為NONE時,應將FORM的大小設置成比位圖大小稍大一點
????????????????form.Width?=?control.Width;
????????????????form.Height?
=?control.Height;
????????????????
//?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?
????????????
//當控件是button時
????????????else?if?(control?is?System.Windows.Forms.Button)
????????????{
????????????????
//?Cast?to?a?button?object?
????????????????
//強制轉換為?button
????????????????Button?button?=?(Button)control;
????????????????
//?Do?not?show?button?text?
????????????????
//不顯示button?text
????????????????button.Text?=?"";

????????????????
//?Change?cursor?to?hand?when?over?button?
????????????????
//改變?cursor的style
????????????????button.Cursor?=?Cursors.Hand;
????????????????
//?Set?background?image?of?button?
????????????????
//設置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?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.
????????????
//第一個找到點的X
????????????int?colOpaquePixel?=?0;
????????????
//?Go?through?all?rows?(Y?axis)?
????????????
//?偏歷所有行(Y方向)
????????????for?(int?row?=?0;?row?<?bitmap.Height;?row++)
????????????{
????????????????
//?Reset?value?
????????????????
//重設
????????????????colOpaquePixel?=?0;
????????????????
//?Go?through?all?columns?(X?axis)?
????????????????
//偏歷所有列(X方向)
????????????????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?
????????????????????????
//將不透明點加到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;
????????}
????}

?

?????? 4.?運行

?????? 三、調用類庫實現

主要就是根據一些坐標,然后根據這些坐標繪制窗體

代碼如下:

?

代碼 public?Form3()

????????{

????????????InitializeComponent();

????????????
//創建不規則窗體

????????????POINTAPI[]?poin;

????????????poin?
=?new?POINTAPI[5];

????????????poin[
0].x?=?90;

????????????poin[
0].y?=?90;

????????????poin[
1].x?=?this.Width;

????????????poin[
1].y?=?0;

????????????poin[
2].x?=?Width;

????????????poin[
2].y?=?this.Height?/?2;

????????????poin[
3].x?=?Width?/?2;

????????????poin[
3].y?=?Height?/?2;

????????????poin[
4].x?=?0;

????????????poin[
4].y?=?Width;

?

????????????Boolean?flag?
=?true;

????????????IntPtr?hRgn?
=?CreatePolygonRgn(ref?poin[0],?8,?1);

????????????SetWindowRgn(
this.Handle,?hRgn,?ref?flag);

????????????
this.BackColor?=?Color.BurlyWood;

????????}

?

????????[StructLayout(LayoutKind.Sequential)]

????????
private?struct?POINTAPI

????????{

????????????
internal?int?x;

????????????
internal?int?y;

????????}

?

????????[DllImport(
"gdi32.dll")]

????????
private?static?extern?IntPtr?CreatePolygonRgn(ref?POINTAPI?lpPoint,int?nCount,int?nPolyFillMode);

?

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

????????
private?static?extern?IntPtr?SetWindowRgn(IntPtr?hWnd,IntPtr?hRgn,?ref?Boolean?bRedraw);

?

????????
//設置窗體顯示狀態

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

????????
private?static?extern?int?SetWindowPos(IntPtr?hwnd,int?hWndInsertAfter,int?x,int?y,int?cx,int?cy,int?wFlags);

?

????????
private?void?Start_Btn_Click(object?sender,?EventArgs?e)

????????{
//始終顯示在前面

?

????????????SetWindowPos(
this.Handle,?-1,?0,?0,?0,?0,?1);

????????}

?

????????
private?void?button1_Click(object?sender,?EventArgs?e)

????????{

????????????
//最小化始終顯示在前面

????????????SetWindowPos(
this.Handle,?-1,?0,?0,?0,?0,?0);

?

????????}

????? 當然,我們也可以自定義窗體的動作,如按著某個軌跡一定,下面的代碼中的BackgroundForm程序中就小試了一下,效果還不錯,下面是這些程序的效果圖(有點亂)和代碼:

?

?

????? 代碼下載: 不規則窗體

????? 代碼是.Net 2.0的,也可以轉換為其他版本的,只要運行主程序即可。(PS:圖片做的不是很好看,就隨便亂P了一通)

????? 以上的四種方法有利也有弊,希望大家提意見或者更好的解決方案。

轉載于:https://www.cnblogs.com/waw/archive/2011/09/02/2163187.html

總結

以上是生活随笔為你收集整理的一起谈.NET技术,C#创建不规则窗体的几种方式的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。