2011-03-23 5 views
4

비 클라이언트 영역을 그리는 C# .NET WinForm 응용 프로그램이 있습니다. 모든 것이 잘 작동하고 양식이로드 될 때를 제외하고 그림이 예상대로 발생합니다.GetDCEx는 양식 표시 전에 null을 반환합니다. 비 클라이언트 영역에서 그리기

나는 WM_NCPAINT 벌금을 잡았지만 GetDCEx를 사용하여 DC를 얻으 려 할 때 양식이 완벽하게 논리적으로 표시 될 때까지 항상 null을 반환하지만 이는 비 클라이언트 영역이 창 크기가 조정될 때까지 다시 칠하지 않음을 의미합니다. 이는 양식이 최소화 된 상태에서 처음로드되거나 복원 될 때 NC 영역이 다시 그려지 지 않고 흰색으로 남아 있음을 의미합니다.

이것은 윈도우 7에 고유 한 것으로 보인다 나는이 상황에서 NC 영역에 그리는 어떻게 그래서

?

편집 : 에어로 글래스에 신경 쓰지 않아야하며 양식에서 완전히 비활성화 할 수 있습니다.

+1

주문형 NC 회화의 날은 끝났습니다. FormBorderStyle을 None으로 설정하고 OnPaint()를 사용합니다. –

+0

나는이 일을 생각했지만 나는 클라이언트 영역을 위해서만 폼 디자이너를 사용할 수있는 것을 좋아한다. OnPaint를 사용하여 크롬 양식을 그린 경우 양식 내용 주위에 여백을 수동으로 두어야합니다. 크롬이 변경되면 각 양식의 새 여백을 조정하기 위해 수동으로 컨트롤을 이동해야합니다. – Steve

+0

디자이너에서 크롬을 그리는 것이 문제가되지 않습니다. OnPaint는 정상적으로 실행됩니다. –

답변

2

GetDeXx 대신 GetWindowDC를 사용합니다. 아래 코드는 내가 사용하는 코드이며 Windows 7에서는 문제가 없습니다. 한스가 언급 한대로 가장 좋은 방법은 FormBorderStyle을 없음으로 설정하는 것이지만이 코드를 사용하여 내 경계에 넣는 것입니다. csharptest.net

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 

물론이 작업을 수행하면 크기 조정, 최소 최대 닫기 기능을 직접 처리해야합니다.

+0

GetWindowDC를 사용하기 위해 +1, GetDCEx를 사용하여 전달 된 Region 핸들의 기본 DC 핸들을 가져 오려고했으나 항상 null을 반환하고 사용자 정의 컨트롤의 테두리를 직접 그려야했습니다. GetWindowDC는 전체 윈도우의 Device 컨텍스트 핸들을 반환하지만 WM_NCPAINT 메시지의 WParam을 참조하지 않고 비 클라이언트 영역을 알고 있기 때문에 도움이됩니다. 감사! –

관련 문제