【问题标题】:Should I receive WM_NCPAINT when there is no client area?没有客户区时我应该收到 WM_NCPAINT 吗?
【发布时间】:2011-05-08 10:49:01
【问题描述】:

我想在我的自定义控件中了解一些内容。我处理 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 不修改“rect”,然后接收 WM_NCPAINT,我有义务比较边界和客户端 rect 以检查是否有任何非客户端绘画应该发生。这正常吗?

【问题讨论】:

    标签: c# .net windows winapi nonclient


    【解决方案1】:

    我的猜测是

    1) Windows 更容易以这种方式执行此操作(没有缺少边框的特殊情况),并且不发送它的好处只是边际性能提升。
    2) 现在无法更改,因为某些程序需要发送消息,因为它们在处理程序中做了太多。如果您阅读 Raymond Chen 的博客,您就会知道这对 windows api 团队有多么重要。

    【讨论】:

      猜你喜欢
      • 2014-08-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-05
      • 1970-01-01
      • 2015-10-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多