WPF換膚之三 WPF中的WndProc

2021-09-08 08:52:56 字數 3467 閱讀 2258

在上篇文章中,我有提到過wndproc中可以處理所有經過窗體的事件,但是沒有具體的來說怎麼可以處理的。

其實,在wpf中,要想利用wndproc來處理所有的事件,需要利用到sourceinitialized  event,首先需要建立乙個hwndsource物件,然後利用其addhook方法來將所有的windows訊息附加到乙個現有的事件中,這個就是wndproc。

void wsinitialized(object

sender, eventargs e)

這樣,我們就成功地新增了乙個可以接收所有windows訊息的函式,那麼有了它,就讓我們用它來做一些有意義的事情吧。

在wpf設計過程中,我是利用乙個無邊框窗體進行了重繪。所以當我設定其最大化時,肯定是要遮蔽工作列的:

this.windowstate = (this.windowstate == windowstate.normal ? windowstate.maximized : windowstate.normal);
下面就讓我們來實現不遮蔽工作列(參考文章:maximizing window (with windowstyle=none) considering taskbar)。

#region 這一部分用於最大化時不遮蔽工作列

private

static

void

wmgetminmaxinfo(system.intptr hwnd, system.intptr lparam)

marshal.structuretoptr(mmi, lparam,

true

); }

//////

point aka pointapi

///[structlayout(layoutkind.sequential)]

public

struct

point

}[structlayout(layoutkind.sequential)]

public

struct

minmaxinfo

;///win32

[structlayout(layoutkind.sequential, pack = 0

)]

public

struct

rect

//abs needed for bidi os

}

///win32

public

intheight

}///win32

public rect(int left, int top, int right, int

bottom)

///win32

public

rect(rect rcsrc)

///win32

public

bool

isempty

}///return a user friendly representation of this struct

public

override

string

tostring()

"; }

return

"rect ";

}///determine if 2 rect are equal (deep compare)

public

override

bool equals(object

obj)

return (this ==(rect)obj);

}///return the hashcode for this struct (not garanteed to be unique)

public

override

intgethashcode()

///determine if 2 rect are equal (deep compare)

public

static

bool

operator ==(rect rect1, rect rect2)

///determine if 2 rect are different(deep compare)

public

static

bool

operator !=(rect rect1, rect rect2)

}[structlayout(layoutkind.sequential, charset =charset.auto)]

public

class

monitorinfo

[dllimport(

"user32")]

internal

static

extern

bool

getmonitorinfo(intptr hmonitor, monitorinfo lpmi);

[dllimport(

"user32")]

internal

static

extern intptr monitorfromwindow(intptr handle, int

flags);

#endregion

上面這部分主要就是通過顯示器資訊來確定窗體顯示的workarea和monitorarea。

上面的函式準備好以後,下面就開始處理最大化按鈕事件:

首先,讓我們來看乙個常量:

wm_getminmaxinfo

0x24

從字面意思看來就是這個訊息是用來處理窗體大小或者是位置變化的。程式可以使用這個訊息來過載原本存在的最大化資訊,位置資訊等等。

private intptr wndproc(intptr hwnd, int msg, intptr wparam, intptr lparam, ref

bool

handled)

return (system.intptr)0

; }

上面的**就是通過處理wm_getminmaxinfo訊息來實現最大化時不遮蔽工作列。 我們來看看效果:

需要補充一點的是,在windowform中,我們可以通過point p = new point(lparam.toint32())來確定我們的滑鼠座標在窗體的哪個位置上,但是在wpf中,point沒有帶有單個引數的方法,這裡只能通過

int x = lparam.toint32() & 0xffff

;

int y = lparam.toint32() >> 16;

來獲取。

希望這篇文章對你有用。

WPF換膚之三 WPF中的WndProc

原文 wpf換膚之三 wpf中的wndproc 在上篇文章中,我有提到過wndproc中可以處理所有經過窗體的事件,但是沒有具體的來說怎麼可以處理的。其實,在wpf中,要想利用wndproc來處理所有的事件,需要利用到sourceinitialized event,首先需要建立乙個hwndsourc...

閒話WPF之三(XAML的名字空間)

在前一篇文章中,指出 xmlns 的作用是設定 xml檔案的命名空間。類似的,xmlns x 的作用也是指定命名空間。這裡為什麼是 x而不是其他的,我們可以簡單的理解為其只是 ms的乙個命名而已,沒有任何特殊的意義,當然,為了避免和它的衝突,我們定義自己的命名空間的時候不能是x。而另乙個 x cla...

WPF換膚之五 建立漂亮的窗體

原文 wpf換膚之五 建立漂亮的窗體 換膚效果 經過了前面四章的講解,我們終於知道了如何拖拉窗體使之改變大小,也知道了如何處理滑鼠事件,同時,也知道了如何利用更好的編寫方式來編寫乙個方便實用和維護的換膚程式。下面請看換膚效果 首先宣告,窗體樣式和按鈕樣式均來自於codeproject,本人美工太差 ...