在win10桌面窗口层的workerw嵌入应用,黑色像素变为透明

在写c#程序
总之使用如下方式将窗口设置为桌面workerw的子窗口

            EnumWindows(new Callback(Find_SHELLDLL_DefView), 0);
           IntPtr chiWnd = FindWindowEx(workerw,IntPtr.Zero,"TXMiniSkin", null);
           //IntPtr chiWnd = workerw;
           if(chiWnd==IntPtr.Zero)
           {
               chiWnd = workerw;

           }
                    SetParent(this.Handle,chiWnd);

                        //回调函数
        private IntPtr workerw = IntPtr.Zero;
        public bool Find_SHELLDLL_DefView(IntPtr hwnd,int lParam)
        {
            if(FindWindowEx(hwnd,IntPtr.Zero,"SHELLDLL_DefView",null)!=IntPtr.Zero)
            {
                workerw = hwnd;
                return false;
            }
            return true;
        }

图片说明
然后就出问题了,我的窗口貌似所有的黑色像素都变成了无色
图片说明
仔细看上面的图片,会发现窗口实际上遮住了图标但是背景层穿越过来了。像是图标穿上了隐身衣。
求解这种情况,希望解决黑色像素丢失的问题

将该窗口的Owner设置成桌面的Shell 窗口。

这是因为DWM设置了ARGB型的透明色,而你的程序使用的是传统的RGB,黑色的Alpha通道被误认为是完全透明。

以下内容引用自文章《DWM 窗体玻璃效果实现》


一个特殊问题是使用位模式 0x00000000 以黑色呈现 GDI 项目,在使用 Alpha 管道时也会碰巧出现完全透明的黑色。这意味着如果您使用黑色 GDI 画笔或笔进行绘制,将会得到透明的颜色,而不是黑色。当您尝试使用默认文本颜色控制位于玻璃区域中的文本标签时,这种问题表现得就特别明显。因为默认文本颜色通常为黑色,DWM 会认为它是透明的,因此文本将错误地写入玻璃区域。图 10 显示了一个这样的示例。第一行使用 GDI+ 编写,第二行是一个使用默认颜色的文本标签控件。可以看出,其中的内容几乎无法辨认,因为它实际上是错误呈现的文件,文本显示为灰色,而不是黑色。

图 10 透明对话框
令人欣慰的是,可以通过多种方法解决此问题。其中一种方法是使用所有者描述的控件。另一种方法是呈现到具有 Alpha 管道的位图。但控制文本的最简单方法是让 .NET Framework 2.0 为您使用 GDI+。通过在您的控件上设置 UseCompatibleTextRendering 属性可以很容易地做到这一点。默认情况下,此属性设置为 false,这样,为 .NET Framework 的以前版本编写的控件将以相同的方式呈现。但是,如果将其设置为 true,则文本将正确呈现。您可以使用 Application.SetUseCompatibleTextRenderingDefault 方法在全局设置该属性。如果您使用的是 Visual Studio® 2005,则模板代码将包括一个调用,以便在创建窗体之前在主例程中将兼容文本呈现设置为 false。您可以编辑它,将其设置为 true(如下所示),这时在玻璃窗口中进行编写时,所有控件看上去都会是正确的。

static void Main()
{
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(true);
    Application.Run(new GlassForm());
}

您可以在 Miguel A. Lacouture 在 2006 年 3 月份的《MSDN 杂志》上发表的文章“Build World-Ready Apps Using Complex Scripts In Windows Forms Controls”中找到有关此内容和使用 TextRenderer 类的详细信息。
在开始呈现窗口之前应启用玻璃效果。组合引擎将查看您窗口的 Alpha 值,并将模糊效果应用到透明区域。这在使用某些 GDI 函数时可能会出现问题,因为这些函数不保留 Alpha 值。您可以在需要时使用 GDI+,但应谨慎使用,因为 GDI+ 调用在软件中呈现,而不是在硬件上呈现,因此窗口刷新频率较高时使用 GDI+ 调用可能导致耗费大量的系统资源。
可以通过相同方法在 DirectX 应用程序中获得玻璃效果。您需要做的只是控制呈现目标的 Alpha 值和使用两个启用玻璃效果的 DWM 函数之一。无论在何处指示 DWM 使用玻璃效果,它都将使用呈现目标的 Alpha 值。无论在其他任何地方,呈现目标均应为不透明的,否则将得到未定义的行为。