wpf设计一个异形窗口只需要设置
WindowStyle="None" AllowsTransparency="True"
再设置背景颜色为透明,或者使用OpacityMask(遮罩,有像素的区域显示)就可以实现异形窗口
但是随之而来带来一个问题.当我把wpf窗口使用win32 api中setparent置父,导致win32父窗体不能显示wpf子窗体.
因为渲染手段不同.如果wpf窗体与Win32窗体程序混用,那么Win32窗体只能在WPF窗体之上,所以就会遮挡.
这个问题是天生的.
而我的一个小玩具项目是需要把一个 wpf窗口嵌入到一个游戏窗口(win32 directX),而且实现异形窗口.
解决方法根据msdn论坛上提供的思路(曲线救国)如下:
因为将wpf设置为winform的子窗口因为遮挡不显示,那么将wpf设置为一个winform(Form1)窗口的子窗口.把Form1窗口透明则不存在遮挡问题.
设置这个winform窗口透明使用api:SetLayeredWindowAttributes
作用是设置某一颜色为透明,这里我Form1上全部的whiteSmoke颜色为透明.
使用winapi让窗口透明,如下.(关于引用大量win32api我在之前写过)
Const GWL_EXSTYLE = -20 Const WS_EX_TRANSPARENT = &H20 Const WS_EX_LAYERED = &H80000 Const LWA_ALPHA = 2 '// Public Sub MakeTransparent() Me.BackColor = System.Drawing.Color.WhiteSmoke Dim ret As Long = User32Methods.GetWindowLongPtr(Me.Handle, GWL_EXSTYLE) ret = ret Or WS_EX_LAYERED User32Methods.SetWindowLongPtr(Me.Handle, GWL_EXSTYLE, ret) User32Methods.SetLayeredWindowAttributes(Me.Handle, RGB(System.Drawing.Color.WhiteSmoke.R, System.Drawing.Color.WhiteSmoke.G, System.Drawing.Color.WhiteSmoke.B), 0, LayeredWindowAttributeFlag.LWA_COLORKEY) End Sub
注意:这时候wpf不要使用AllowsTransparency="True",因为这样无论如何wpf似乎都无法显示在winform窗口之中,那么实现异形窗口,要设置wpf窗口透明解决办法就是设置wpf的背景颜色为WhiteSmoke,也就是前面代码父窗口设置为透明的颜色.也就是实现异形窗口的思路完全变为winform实现异形窗口的思路.
然后再将Form1作为子窗口置于目标游戏窗口之中即可.因为wpf置于Form1之中,所以wpf的层级得以提高,但问题也有,因为wpf界面有良好的抗锯齿显示效果,但wpf置于winform中后的渲染效果会打折扣.
置父的逻辑关系主要是select case 嵌入游戏中间的部分,效果不错,实现了嵌入和异形窗口.
下面是最后的成品展示视频(wpf和Form1窗口已经嵌入了游戏中)