【问题标题】:Why does SetWindowRgn not work for static controls?为什么 SetWindowRgn 不适用于静态控件?
【发布时间】:2020-05-23 20:54:44
【问题描述】:

我在使静态控件四舍五入时遇到了一些问题。我不明白为什么 SetWindowRgn 在这里不适用于静态控件。我也试过 SelectClipRgn 并且它有效。但是为什么 SetWindowRgn 没有呢? Microsoft 文档指出

系统不显示位于外部的窗口的任何部分 窗口区域。

控件必须根据文档进行舍入和裁剪。但事实并非如此。这是我的问题示例:

#include <windows.h>

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, PWSTR pCmdLine, int nCmdShow)
{

    const wchar_t CLASS_NAME[] = L"Sample Window Class";

    WNDCLASS wc = { };

    wc.lpfnWndProc = WindowProc;
    wc.hInstance = hInstance;
    wc.lpszClassName = CLASS_NAME;

    RegisterClass(&wc);

    HWND hwnd = CreateWindowEx(
        0,                              // Optional window styles.
        CLASS_NAME,                     // Window class
        L"Learn to Program Windows",    // Window text
        WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,            // Window style

        // Size and position
        CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,

        NULL,       // Parent window    
        NULL,       // Menu
        hInstance,  // Instance handle
        NULL        // Additional application data
    );

    if (hwnd == NULL)
    {
        return 0;
    }


    HRGN hrgnMain = CreateRoundRectRgn(0, 0, 200, 200, 5, 5);
    int res = SetWindowRgn(hwnd, hrgnMain, TRUE);

    ShowWindow(hwnd, nCmdShow);

    HWND hControl = CreateWindow(L"Static", L"hello, world", WS_VISIBLE | WS_CHILD | SS_NOTIFY | SS_LEFTNOWORDWRAP,
        20, 20, 40, 40, hwnd, NULL, hInstance, NULL);

    HRGN hrgnControl = CreateRoundRectRgn(0, 0, 10, 10, 5, 5);
    res = SetWindowRgn(hControl, hrgnControl, TRUE);

    ShowWindow(hwnd, nCmdShow);

    MSG msg = { };
    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return 0;
}

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;

    case WM_PAINT:
    {
        PAINTSTRUCT ps;
        HDC hdc = BeginPaint(hwnd, &ps);
        FillRect(hdc, &ps.rcPaint, (HBRUSH)(COLOR_WINDOW + 1));
        EndPaint(hwnd, &ps);
    }
    return 0;
    }

    return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

【问题讨论】:

  • 最好的办法是从头开始设计一个新控件,尤其是对于像静态控件这样简单的控件。
  • 究竟是什么方式不起作用?请更具体。您能否展示您实际看到的内容以及您想要实现的目标的屏幕截图?
  • @Remy Lebeau,控件必须根据 Microsoft 文档进行舍入和裁剪。但事实并非如此。
  • @Ken White,首先我在 cmets 中回复,然后编辑我的问题。你希望我提供什么样的细节?问题非常简单明了:SetWindowRgn 不剪辑控件,而文档则相反。我放了一个样本。我认为这就够了。
  • @OleksiyPlotnyts'kyy “你希望我提供什么样的细节?” - 我让你提供的怎么样? “SetWindowRgn 不剪辑控件” - 是的,确实如此。我以前做过。请参阅can i use Regions functions with child controls?,这导致Using SetWindowRgn,其中讨论了将SetWindowRgn() 用于子控件(请参阅“CS_PARENTDC 和剪切路径”)。

标签: c++ windows user-interface winapi


【解决方案1】:

一些内置控件使用CS_PARENTDC 类样式。

CS_PARENTDC 将子窗口的剪切区域设置为父窗口的剪切区域。这与想要安装自定义区域的SetWindowRgn 冲突。根据您的窗口刷新方式,您可以获得不同的自定义区域组合是否有效。例如,如果您调整父窗口的大小,您可以通过设置区域和部分不设置区域来部分刷新控件。

Parent Display Device Contexts 声明:

如果父窗口使用 私有或类设备上下文,如果父窗口剪辑其子窗口 窗口,或者如果子窗口剪辑其子窗口或同级窗口 窗户。

但看起来只为父窗口设置WS_CLIPCHILDREN 是不够的。在控件样式中添加 WS_CLIPSIBLINGSWS_CLIPCHILDREN 标志(即使您只有一个孩子)会触发所需的行为。

HWND hControl = CreateWindow(
                    L"Static",
                    L"hello, world",
                    WS_CLIPSIBLINGS | WS_VISIBLE | WS_CHILD | SS_NOTIFY | SS_LEFTNOWORDWRAP,
                    20, 20, 40, 40,
                    hwnd,
                    NULL,
                    hInstance,
                    NULL);

你的代码没有WS_CLIPSIBLINGS

还有WS_CLIPSIBLINGS

也可以使用GetClassLongPtrSetClassLongPtr 删除CS_PARENT 样式。因为CS_PARENT 仅用于重用剪辑区域,所以它不应该有任何其他意想不到的效果。

SetClassLongPtr(
        hControl,
        GCL_STYLE,
        GetClassLongPtr( hControl, GCL_STYLE ) & ~CS_PARENTDC );

【讨论】:

  • 您还可以提供有关 CS_PARENTDC 样式的信息,这显然是为标准控件指定的。我刚刚检查了控件 WNDCLASSW 的样式位,它们确实有 CS_PARENTDC 位。通过替换 GCL_STYLE 将其删除后,一切都按预期工作。
猜你喜欢
  • 2021-10-31
  • 1970-01-01
  • 1970-01-01
  • 2022-11-29
  • 2021-06-07
  • 2021-02-17
  • 2020-06-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多