3

我正在编写一个自定义 Win32 UI 控件,我想在其中加入视觉主题。我在其中加载主题WM_NCCREATE

case WM_NCCREATE:
{
    HTHEME hTheme = ::OpenThemeData(hWnd, L"EDIT");
    assert(hTheme);
    assert(::GetWindowTheme(hWnd) != 0);

}
return 1;

然后在控制被破坏时释放它们:

case WM_DESTROY:
{
    HTHEME hTheme = ::GetWindowTheme(hWnd);
    assert(hTheme);
    if(::CloseThemeData(hTheme) != S_OK)
    {
        assert(NULL);
    }
}
break;

这很好用,直到有人试图更改该控件的样式。以下调用(仅靠自身,甚至没有更改任何样式):

::SetWindowLongPtr(hChildWnd, GWL_STYLE, dwStyle);

将返回 NULL GetWindowThemehChildWnd

那么,这是一个错误还是一个功能

PS。为了制作一个可重现的 Win32 示例,我必须从 VS 2017 调整现有的 Win32 解决方案。(是它的完整源代码。)它的工作方式是这样的:在其中我创建了一个小的子控件(如下所示的灰色)有问题的主题:

在此处输入图像描述

然后当您单击主窗口的白色区域时,我尝试更改其样式并且其主题消失了:

在此处输入图像描述

要查看该项目的完整 Win32 代码,我还将其发布在 PasteBin 上

4

1 回答 1

1

根据窗口样式文件:

“创建窗口后,这些样式无法修改,除非另有说明。”

因为这是不允许的,所以主题引擎并不总是检查更改的样式,并且在某些情况下会根据旧数据绘制标题。唯一有保证和可支持的解决方案是应用程序销毁窗口并使用新样式重新创建它,而不是试图即时更改它们。

可以找到类似的讨论:http: //social.msdn.microsoft.com/Forums/en/windowscompatibility/thread/7b5ef777-ff0d-4f15-afed-5588f93f0e23

于 2019-03-25T07:23:07.050 回答