GetDCEx在表单show之前返回null。在非客户区域上绘图

时间:2011-03-23 17:38:29

标签: c# .net winapi

我有一个C#.NET WinForm应用程序,它吸引到非客户区域。一切正常,绘图按预期发生,但表单加载时除外。

我捕获WM_NCPAINT很好,但是当我尝试使用GetDCEx获取DC时,它总是返回null,直到显示的形式完全合乎逻辑但这意味着非客户区域不会再次绘制,直到窗口调整大小为止表示当表单首次加载或从最小化状态恢复时,NC区域不会重绘并保持白色。

这似乎是Windows 7独有的。

那么在这种情况下如何绘制到NC区域?

编辑:我应该补充一点,我不关心Aero玻璃,我的表格完全禁用了它。

1 个答案:

答案 0 :(得分:2)

我使用GetWindowDC而不是GetDCEx。下面是我使用的代码,我没有遇到过Windows 7的问题。正如Hans评论的那样,最好的方法是将FormBorderStyle设置为None,但之后我想使用{{{{ 3}}

Imports System.Runtime.InteropServices

Public Class NCForm    
  Inherits Form

  Public Sub New()
    Me.FormBorderStyle = FormBorderStyle.None
  End Sub

  Protected Overrides Sub WndProc(ByRef m As Message)
    MyBase.WndProc(m)

    If m.Msg = Win32.WM_NCCALCSIZE Then        
      If m.WParam <> IntPtr.Zero Then
        Dim tmpResize As Win32.NCCALCSIZE_PARAMS = Marshal.PtrToStructure(m.LParam, GetType(Win32.NCCALCSIZE_PARAMS))
        With tmpResize.rcNewWindow
          .Left += 2
          .Top += 2
          .Right -= 2
          .Bottom -= 2
        End With
        Marshal.StructureToPtr(tmpResize, m.LParam, False)
      Else
        Dim tmpResize As Win32.RECT = Marshal.PtrToStructure(m.LParam, GetType(Win32.RECT))
        With tmpResize
          .Left += 2
          .Top += 2
          .Right -= 2
          .Bottom -= 2
        End With
        Marshal.StructureToPtr(tmpResize, m.LParam, False)
      End If
      m.Result = New IntPtr(1)

    ElseIf m.Msg = Win32.WM_NCPAINT Then
      Dim tmpDC as IntPtr = Win32.GetWindowDC(m.HWnd)
      Using tmpG As Graphics = Graphics.FromHdc(tmpDC)
        tmpG.DrawRectangle(Pens.Red, New Rectangle(0, 0, Me.Width - 1, Me.Height - 1))
        tmpG.DrawRectangle(SystemPens.Window, New Rectangle(1, 1, Me.Width-3, Me.Height - 3))
      End Using
      Win32.ReleaseDC(m.HWnd, tmpDC)
    End If
  End Sub

当然,一旦你这样做,那么你必须自己处理任何调整大小,最小 - 最大,关闭功能。