在上篇文章中,我有提到過wndproc中可以處理所有經過窗體的事件,但是沒有具體的來說怎麼可以處理的。
其實,在wpf中,要想利用wndproc來處理所有的事件,需要利用到sourceinitialized event,首先需要建立乙個hwndsource物件,然後利用其addhook方法來將所有的windows訊息附加到乙個現有的事件中,這個就是wndproc。
void wsinitialized(object這樣,我們就成功地新增了乙個可以接收所有windows訊息的函式,那麼有了它,就讓我們用它來做一些有意義的事情吧。sender, eventargs e)
在wpf設計過程中,我是利用乙個無邊框窗體進行了重繪。所以當我設定其最大化時,肯定是要遮蔽工作列的:
this.windowstate = (this.windowstate == windowstate.normal ? windowstate.maximized : windowstate.normal);下面就讓我們來實現不遮蔽工作列(參考文章:maximizing window (with windowstyle=none) considering taskbar)。
#region 這一部分用於最大化時不遮蔽工作列上面這部分主要就是通過顯示器資訊來確定窗體顯示的workarea和monitorarea。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
上面的函式準備好以後,下面就開始處理最大化按鈕事件:
首先,讓我們來看乙個常量:
wm_getminmaxinfo
0x24
從字面意思看來就是這個訊息是用來處理窗體大小或者是位置變化的。程式可以使用這個訊息來過載原本存在的最大化資訊,位置資訊等等。
private intptr wndproc(intptr hwnd, int msg, intptr wparam, intptr lparam, ref上面的**就是通過處理wm_getminmaxinfo訊息來實現最大化時不遮蔽工作列。 我們來看看效果:bool
handled)
return (system.intptr)0
; }
需要補充一點的是,在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,本人美工太差 ...