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

时间:2010-11-11 12:28:34

标签: c# .net windows winapi nonclient

我想在自定义控件中理解某些内容。我处理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以检查是否有任何非客户端画应该发生。这是正常的吗?

1 个答案:

答案 0 :(得分:0)

我的猜测是它的

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