C 中無邊框異型窗體的製作

2022-07-26 19:30:13 字數 4015 閱讀 3388

本篇內容來自

對於c# 更改窗體外觀感覺並不那麼輕鬆 更改窗體外觀涉及到使用gdi+ 我所知道的有兩種方法:

有系統邊框的窗體  處理窗體的paint方法,在paint方法中 引數e.graphics屬性將返回乙個物件 用來作畫  但是這個畫布的區域是窗體的客戶區 所以無法修改到窗體的標題欄 邊框等位置的。要更改標題欄只有獲取整個視窗的控制代碼 這樣建立的畫布是整個窗體區域 但是對於我這樣的初學者來說 對於控制代碼 windowsapi還很不熟悉 我相信大多數的初學者或者學生都和我有相同的困惑 所以我使用了第二種辦法 無邊框窗體

無邊框的窗體 把formborderstyle的屬性設定為none 就去掉了邊框 剩下的窗體客戶區和和整個窗體大小是相同的 再使用e.graphics作畫就是在整個窗體上作畫 我主要也是描述這樣的一種方法 相信對很多和我一樣的人有很多幫助

對於乙個窗體 它除了外觀以外還有2個主要特徵:1.可以拖動 可以拖拽大小 2.具有控制按鈕 關閉 最大化 最小化。我主要描述第二種方法

回到主題 介紹處理無邊框窗體的經驗,下面是最終效果:

這就是乙個無邊框窗體 可以注意到它的外觀 四個角是圓的 有控制按鈕 並且還可以拖拽,當滑鼠移動到窗體的四個角和邊緣的時候可以拖拽大小

這個窗體沒有標題欄和邊框的限制 控制項可以放在窗體上任何地方

下面就是直奔主題了:

先說一說製作這個窗體的思路(窗體整合自system.windows.forms.form):

1.設定formborderstyle屬性為none 讓它成為乙個無邊框窗體

2.設定窗體的region屬性 該屬性設定窗體的有效區域 而我們把窗體的有效區域設定為圓角矩形 窗體就變成圓角的了

3.自定義控制項 3個按鈕 控制窗體的最大化 最小化 還原 關閉

4.使窗體可以拖動 在邊緣按下滑鼠可以拖拽大小

主要涉及gdi+中兩個重要的類 graphics和graphicspath類 分別位於system.drawing和system.drawing.drawing2d

首先我們建立乙個c# windows窗體應用程式專案 將預設的form1改名成mainform 設定formborderstyle屬性為none 讓它成為乙個無邊框窗體

接著我們需要這樣乙個函式 private void  setwindowregion() 此函式設定窗體有效區域為圓角矩形,以及乙個輔助函式 private graphicspath getroundedrectpath(rectangle rect, int radius)此函式用來建立圓角矩形路徑,將在setwindowregion()中呼叫它

public

void

setwindowregion()

private graphicspath getroundedrectpath(rectangle rect, int

radius)

view code

在窗體尺寸改變的時候我們需要呼叫setwindowregion()將窗體變成圓角的

private

void mainform_resize(object

sender, eventargs e)

到此 窗體的形狀部分就完成了 通過建立不同的graphicspath物件 可以將窗體設定為任意形狀 三角形 六邊形 橢圓 以及任何不規則圖形來製作不規則窗體

然後可以通過給窗體設定背景或者在窗體上作畫來更改外觀 無論是什麼形狀只要超過了窗體有效區域的部分都會被裁掉 這樣給換**帶來了極大的方便 只需要換一張背景圖而已 不需要去做圓角 就像迅雷7那樣 換**就換一張背景

然後是自定義控制項 3個按鈕 通過gdi+可以繪製比較漂亮的按鈕 這部分相對簡單很多 就不敘述了,這方面的資料也很好找

將這3個按鈕控制項拖到窗體右上角設定它們的anchor屬性為top right 讓它們的位置始終相對於窗體右上角改變 並編寫它們的單擊事件處理** 模擬窗體的最大化最小化和關閉

這裡需要注意一點的就是 最大化的時候直接使用this.windowstate = formwindowstate.maximized會遮蓋工作列 在執行這行**前先限制窗體的最大尺寸為螢幕的工作區

this.maximumsize = new

size(screen.primaryscreen.workingarea.width, screen.primaryscreen.workingarea.height);

this.windowstate = formwindowstate.maximized;

接下再執行的時候 窗體就是圓角 並且具有控制按鈕了 只差拖動和拖拽大小了 下面完成最後一部分

實現這部分只能通過處理windows訊息來完成 使用windows系統的功能來完成窗體的拖拽大小和移動 我們只需要處理wm_nchittest訊息就可以完成這部分功能 wm_nchittest是告知滑鼠事件位置的訊息 是很常用的乙個訊息。查詢msdn api可以找到這些常量 wm_nchittest常量位址

這裡我們需要使用10個常量 1個wm_nchittest 9個wm_nchittest訊息結果

const

int wm_nchittest = 0x0084

;const

int ht_left = 10

;const

int ht_right = 11

;const

int ht_top = 12

;const

int ht_topleft = 13

;const

int ht_topright = 14

;const

int ht_bottom = 15

;const

int ht_bottomleft = 16

;const

int ht_bottomright = 17

;const

int ht_caption = 2;

定義好這些常量之後 就需要處理windows訊息了 c#處理 windows訊息就重寫wndproc(ref message msg)函式

protected

override

void wndproc(ref

message msg)

//左上角

else

if (nposx <= this.left + 6 && nposy <= this.top + 6

)

//左下角

else

if (nposx <= this.left + 6 && nposy >= this.bottom - 6

)

//右上角

else

if (nposx >= this.right - 6 && nposy <= this.top + 6

)

else

if (nposx >= this.right - 2

)

else

if (nposy >= this.bottom - 2

)

else

if (nposx <= this.left + 2

)

else

if (nposy <= this.top + 2

)

else

}base.wndproc(ref

msg);

}

view code

最後 為了使窗體不會出現閃爍 可以使用雙快取 在重繪的時候進行雙快取 在窗體的resize事件中重繪並使用雙快取

private

void mainform_resize(object

sender, eventargs e)

這可以有效消除窗體控制按鈕的閃爍情況

WPF中製作無邊框窗體

原文 wpf中製作無邊框窗體 眾所周知,在winform中,如果要製作乙個無邊框窗體,可以將窗體的formborderstyle屬性設定為none來完成。如果要製作成異形窗體,則需要使用或者使用gdi 自定義繪製。那麼,在wpf中,我們怎樣製作乙個無邊框窗體呢?答案是將window的windowst...

WPF中製作無邊框窗體

原文 wpf中製作無邊框窗體 眾所周知,在winform中,如果要製作乙個無邊框窗體,可以將窗體的formborderstyle屬性設定為none來完成。如果要製作成異形窗體,則需要使用或者使用gdi 自定義繪製。那麼,在wpf中,我們怎樣製作乙個無邊框窗體呢?答案是將window的windowst...

C 移動無邊框窗體

private point mouseoffset private bool ismousedown false private void form1 mousedown object sender,system.windows.forms.mouseeventargs e private void...