C WinForm 中在視窗標題欄上加按鈕

2021-04-08 16:41:34 字數 3404 閱讀 6092

在視窗標題欄上加按鈕本來不是什麼新鮮事了,我在vc++下早也實現過了(相信很多人也都實現過了)。今天乙個朋友問我c# winform下可否實現,我就順便拿c#寫了乙個。

原理是一樣的,都是重寫視窗過程(wndproc),處理一些非客戶區訊息(wm_nc***x),可以說本來沒有什麼新意,可是從寫這個程式的過程中,我也學到了兩個技巧:

1)、c#中重寫視窗過程不用再呼叫setwindowlong api了,直接overide乙個wndproc就可以了。

2)、windows api中的hdc可以通過graphics.fromhdc()轉換為(建立出)system.drawing.graphics,然後就可以用.net framework (gid+??)提供的繪圖功能方便地進行畫圖了。終於可以拋開討厭的gdi api了(說實在話,在c#中呼叫windows api真的太麻煩了:)).

**如下:

using system;

using system.drawing;

using system.drawing.drawing2d;

using system.collections;

using system.componentmodel;

using system.windows.forms;

using system.data;

using system.runtime.interopservices;

using system.diagnostics;

///

/// form1 的摘要說明。

///

public class form1 : system.windows.forms.form

///

/// 必需的設計器變數。

///

private system.componentmodel.container components = null;

public form1()

// windows 窗體設計器支援所必需的

initializecomponent();

// todo: 在 initializecomponent 呼叫後新增任何建構函式**

///

/// 清理所有正在使用的資源。

///

protected override void dispose( bool disposing )

if( disposing )

if (components != null)

components.dispose();

base.dispose( disposing );

#region windows 窗體設計器生成的**

///

/// 設計器支援所需的方法 - 不要使用**編輯器修改

/// 此方法的內容。

///

private void initializecomponent()

// form1

this.autoscalebasesize = new system.drawing.size(6, 14);

this.clientsize = new system.drawing.size(292, 266);

this.name = "form1";

this.text = "form1";

this.sizechanged += new system.eventhandler(this.form1_sizechanged);

#endregion

///

/// 應用程式的主入口點。

///

[stathread]

static void main()

[dllimport ("user32.dll")]

private static extern intptr getwindowdc(intptr hwnd);

[dllimport ("user32.dll")]

private static extern int releasedc(intptr hwnd, intptr hdc);

[dllimport ("kernel32.dll")]

private static extern int getlasterror();

//標題欄按鈕的矩形區域。

rectangle m_rect = new rectangle(205, 6, 20, 20);

protected override void wndproc(ref message m)

base.wndproc(ref m);

switch(m.msg)

case 0x86://wm_ncactivate

goto case 0x85;

case 0x85://wm_ncpaint

intptr hdc = getwindowdc(m.hwnd);

//把dc轉換為.net的graphics就可以很方便地使用framework提供的繪圖功能了

graphics gs = graphics.fromhdc(hdc);

gs.fillrectangle(new lineargradientbrush(m_rect, color.pink, color.purple, lineargradientmode.backwarddiagonal), m_rect);

stringformat strfmt = new stringformat();

strfmt.alignment = stringalignment.center;

strfmt.linealignment = stringalignment.center;

gs.drawstring("√", this.font, brushes.blanchedalmond, m_rect, strfmt);

gs.dispose();

//釋放gdi資源

releasedc(m.hwnd, hdc);

break;

case 0xa1://wm_nclbuttondown

point mousepoint = new point((int)m.lparam);

mousepoint.offset(-this.left, -this.top);

if(m_rect.contains(mousepoint))

messagebox.show("hello");

break;

//在視窗大小改變時及時更新按鈕的區域。

private void form1_sizechanged(object sender, system.eventargs e)

m_rect.x = this.bounds.width - 95;

m_rect.y = 6;

m_rect.width = m_rect.height = 20;

C WinForm 中在視窗標題欄上加按鈕

在視窗標題欄上加按鈕本來不是什麼新鮮事了,我在vc 下早也實現過了 相信很多人也都實現過了 今天乙個朋友問我c winform下可否實現,我就順便拿c 寫了乙個。原理是一樣的,都是重寫視窗過程 wndproc 處理一些非客戶區訊息 wm nc x 可以說本來沒有什麼新意,可是從寫這個程式的過程中,我...

C WinForm 中在視窗標題欄上加按鈕 轉

system using system.drawing using system.drawing.drawing2d using system.collections using system.componentmodel using system.windows.forms using syste...

移動無標題欄視窗

一般情況下,移動乙個窗體需要將滑鼠放置在標題欄上才能拖動窗體,為 什麼非要使用標題欄呢?其實我們可以使用乙個巧妙的方法來實現將滑鼠放置 在窗體上按下就可拖動窗體,下面先看實現 在form1的 private 部分宣告過程 在private部分加入下列 procedure wmnchittest va...