个人资料

跳过导航链接首页 > 博客列表 > 博客正文

wpf解决嵌入win32窗口遮挡的问题的方法

分类:

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中后的渲染效果会打折扣.

参考项目:https://github.com/songshizhao/DxKeyboard/blob/master/WpfApplication8/WpfApplication8/MainWindow.xaml.vb

置父的逻辑关系主要是select case 嵌入游戏中间的部分,效果不错,实现了嵌入和异形窗口.

下面是最后的成品展示视频(wpf和Form1窗口已经嵌入了游戏中)


admin
最初发表2019/6/8 22:54:06 最近更新2019/6/8 23:10:20 399
为此篇作品打分
10
   评论