当没有客户区时我应该接收 WM_NCPAINT 吗?

发布于 2024-10-01 13:59:10 字数 1248 浏览 3 评论 0原文

我想在我的自定义控件中了解一些内容。我处理 WM_NCCALCSIZE 将客户区设置为整个窗口,换句话说,没有非客户区。我原以为不会收到 WM_NCPAINT,但每次窗口大小更改时我仍然收到它。这是我的 WndProc 代码:

if (m.Msg == Win32Calls.WM_NCPAINT)
{
    // I don't know why WM_NCPAINT is sent when WM_NCCALCSIZE has stated that there is no client area, so here is my workaround to stop processing here
    if (Bounds.Size == ClientSize)
        return;

    // Draw borders if any

    if (handled)
        return;
}
else if (m.Msg == Win32Calls.WM_NCCALCSIZE)
{
    if (m.WParam != IntPtr.Zero)
    {
        Win32Calls.NCCALCSIZE_PARAMS csp;

        csp = (Win32Calls.NCCALCSIZE_PARAMS)Marshal.PtrToStructure(m.LParam, typeof(Win32Calls.NCCALCSIZE_PARAMS));
        Rectangle rect = new Rectangle(csp.rgrc0.Left, csp.rgrc0.Top,
            csp.rgrc0.Right - csp.rgrc0.Left, csp.rgrc0.Bottom - csp.rgrc0.Top);

        _drawManager.NcCalcSize(ref rect);

        csp.rgrc0.Left = rect.X;
        csp.rgrc0.Right = rect.X + rect.Width;
        csp.rgrc0.Top = rect.Y;
        csp.rgrc0.Bottom = rect.Y + rect.Height;
        Marshal.StructureToPtr(csp, m.LParam, false);
    }
}

因此,当发生调整大小时,我检查并正确接收到 WM_NCCALCSIZE,_drawManager.NcCalcSize 不会修改“矩形”,然后接收到 WM_NCPAINT,我必须比较边界和客户端矩形以检查是否任何非客户端绘画都应该发生。这是正常的吗?

There is something I would like to understand in my custom control. I handle WM_NCCALCSIZE to set the client area to the entire window, in other terms there is no nonclient area. I was expecting to not receive WM_NCPAINT but I still receive it each time the window size changes. Here is my WndProc code:

if (m.Msg == Win32Calls.WM_NCPAINT)
{
    // I don't know why WM_NCPAINT is sent when WM_NCCALCSIZE has stated that there is no client area, so here is my workaround to stop processing here
    if (Bounds.Size == ClientSize)
        return;

    // Draw borders if any

    if (handled)
        return;
}
else if (m.Msg == Win32Calls.WM_NCCALCSIZE)
{
    if (m.WParam != IntPtr.Zero)
    {
        Win32Calls.NCCALCSIZE_PARAMS csp;

        csp = (Win32Calls.NCCALCSIZE_PARAMS)Marshal.PtrToStructure(m.LParam, typeof(Win32Calls.NCCALCSIZE_PARAMS));
        Rectangle rect = new Rectangle(csp.rgrc0.Left, csp.rgrc0.Top,
            csp.rgrc0.Right - csp.rgrc0.Left, csp.rgrc0.Bottom - csp.rgrc0.Top);

        _drawManager.NcCalcSize(ref rect);

        csp.rgrc0.Left = rect.X;
        csp.rgrc0.Right = rect.X + rect.Width;
        csp.rgrc0.Top = rect.Y;
        csp.rgrc0.Bottom = rect.Y + rect.Height;
        Marshal.StructureToPtr(csp, m.LParam, false);
    }
}

So, when a resize occurs, I checked and WM_NCCALCSIZE is correctly received, _drawManager.NcCalcSize does not modify "rect", then WM_NCPAINT is received and I'm obliged to compare the bounds and client rect to check if any non client painting should occur. Is this normal?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

べ繥欢鉨o。 2024-10-08 13:59:10

我的猜测是,

1)Windows 这样做更容易(没有缺少边框的特殊情况),并且不发送它的好处只是边际性能增益。
2)现在无法更改,因为某些程序需要发送消息,因为它们在处理程序中做了太多事情。如果您阅读 Raymond Chen 的博客,您就会知道这对于 Windows API 团队有多么重要。

My guess would be that it's

1) Easier for Windows to do it this way(no special case for missing border), and the benefit of not sending it is only a marginal performance gain.
2) It can't be changed now since some programs require the message to be sent since they do too much in the handler. And if you read Raymond Chen's blog you'll know how important that is to the windows api team.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文