C++ 为什么SetWindowRgn不适用于静态控件?
我在使静态控件四舍五入方面有一些问题。我不明白为什么SetWindowRgn在这里不适用于静态控件。我还尝试了SelectClipRgn,它可以工作。但是为什么SetWindowRgn没有呢?Microsoft文档声明: 系统不显示窗口外部的任何部分 窗口区域的属性 必须根据文件对控件进行四舍五入和剪裁。但事实并非如此。以下是我的问题示例:C++ 为什么SetWindowRgn不适用于静态控件?,c++,windows,user-interface,winapi,C++,Windows,User Interface,Winapi,我在使静态控件四舍五入方面有一些问题。我不明白为什么SetWindowRgn在这里不适用于静态控件。我还尝试了SelectClipRgn,它可以工作。但是为什么SetWindowRgn没有呢?Microsoft文档声明: 系统不显示窗口外部的任何部分 窗口区域的属性 必须根据文件对控件进行四舍五入和剪裁。但事实并非如此。以下是我的问题示例: #include <windows.h> LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg,
#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);
}
一些内置控件使用CS\u PARENTDC类样式
CS_PARENTDC将子窗口的剪裁区域设置为父窗口的剪裁区域。这与要安装自定义区域的SetWindowRgn冲突。根据窗口的刷新方式,您可以获得自定义区域的不同组合是否正常工作。例如,如果调整父窗口的大小,则可以使用区域集部分刷新控件,而不使用区域集部分刷新控件
声明:
如果父窗口使用
如果父窗口剪辑其子窗口,则为私有或类设备上下文
窗口,或者如果子窗口剪辑其子窗口或同级窗口
窗户
但看起来仅为父窗口设置WS_CLIPCHILDREN是不够的。即使只有一个子项,在控件样式中添加WS_CLIPSIBLINGS或WS_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_剪辑的代码
还有我们的剪贴画
或者,可以使用GetClassLongPtr和SetClassLongPtr删除CS_父样式。因为CS_PARENT只用于重用剪裁区域,所以它不应该有任何其他意外的效果
SetClassLongPtr(
hControl,
GCL_STYLE,
GetClassLongPtr( hControl, GCL_STYLE ) & ~CS_PARENTDC );
最好的想法是从头开始设计一个新的控件,特别是对于一些简单的东西,比如静态控件。它到底以什么方式不起作用?请说得更具体些。你能展示你实际看到的以及你想要实现的东西的屏幕截图吗?@Remy Lebeau,控件必须根据Microsoft文档进行舍入和剪裁。“但事实并非如此。”肯·怀特,首先我在评论中回答,然后编辑我的问题。你想让我提供什么样的细节?问题非常简单明了:SetWindowRgn不剪裁控件,而文档中的情况正好相反。我放了一个样品。我想这就足够了。@OleksiyPlotnyts'kyy你想让我提供什么样的细节我要你提供什么呢?SetWindowRgn不剪裁控件-是的,它剪裁控件。我以前做过。请参阅,这将导致,其中讨论如何对子控件使用SetWindowRgn请参阅CS_PARENTDC和剪裁路径。您还可以提供有关CS_PARENTDC样式的信息,显然,该样式是为标准控件指定的。我刚刚检查了控件的WNDCLASSW的样式位,它们确实有CS\u PARENTDC位。通过替换GCL_样式将其移除后,一切正常。