2011-10-12 4 views
1

_clearOnDisabled 속성이 true 일 때 texte를 제거하기 위해 datetimepicker 객체를 재정의하고 싶습니다. _readOnly 속성이 true이면 텍스트를 검은 색이 아닌 회색으로 표시하고 싶습니다.datetimepicker vb.net을 재정의하십시오.

그래서 WndProc로 시도했지만 모든 단일 객체가 내 datetimepicker뿐만 아니라 내 기능을 통과하는 것 같습니다. WM_PAINT 메시지를 입력하면 CPU가 100 %가됩니다. 나는 또한 그것에서 얻는하지 OnPaint를하지만를 무시하려고 도움

Imports System.Drawing 
Imports System.Windows.Forms 
Imports DTP.WindowsMessages 

Public Class DTP 
    Inherits System.Windows.Forms.DateTimePicker 

    Private _readOnly As Boolean = False 
    Private _clearOnDisabled As Boolean = True 
    Private _backColorReadOnly As Color = MyBase.BackColor 

    Public Sub New() 
     MyBase.New() 
    End Sub 

    Public Overrides Property BackColor() As Color 
     Get 
      Return MyBase.BackColor 
     End Get 
     Set(ByVal Value As Color) 
      MyBase.BackColor = Value 
      If Not _readOnly Then 
       Me.Invalidate() 
      End If 
     End Set 
    End Property 

    Protected Overrides Sub WndProc(ByRef m As Message) 
     Select Case m.Msg 
      Case WM_ERASEBKGND 
       Dim g As Graphics = Graphics.FromHdc(m.WParam) 
       Dim backBrush As SolidBrush 

       If _readOnly Then 
        backBrush = New SolidBrush(_backColorReadOnly) 
        g.FillRectangle(backBrush, Me.ClientRectangle) 
       Else 
        backBrush = New SolidBrush(MyBase.BackColor) 
        g.FillRectangle(backBrush, Me.ClientRectangle) 
       End If 
       g.Dispose() 
      Case WM_LBUTTONDOWN, WM_KEYDOWN 
       If Not _readOnly Then 
        MyBase.WndProc(m) 
       End If 

       'Case WM_PAINT ', WM_NCPAINT, WM_DRAWITEM 
       ' If Not _clearOnDisabled Then 
       '  MyBase.WndProc(m) 
       ' End If 

      Case Else 
       MyBase.WndProc(m) 
     End Select 
    End Sub 

    Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs) 
     If Not _clearOnDisabled Then 
      MyBase.OnPaint(e) 
     End If 
    End Sub 

    Protected Overrides Sub OnPaintBackground(ByVal pevent As System.Windows.Forms.PaintEventArgs) 
     MyBase.OnPaintBackground(pevent) 
    End Sub 

    Public Property [ReadOnly]() As Boolean 
     Get 
      Return _readOnly 
     End Get 
     Set(ByVal Value As Boolean) 
      _readOnly = Value 
      Me.Invalidate() 
     End Set 
    End Property 

    Public Property BackColorReadOnly() As Color 
     Get 
      Return _backColorReadOnly 
     End Get 
     Set(ByVal Value As Color) 
      _backColorReadOnly = Value 
      If _readOnly Then 
       Me.Invalidate() 
      End If 
     End Set 
    End Property 

End Class 

답변

1

에 대한

들으은 페인트 메시지를 먹고 있지만, 후 페인트하지 마십시오.

Case WM_PAINT 
    MyBase.WndProc(m) 
    If _clearOnDisabled Then 
    Dim dc As IntPtr = GetWindowDC(Me.Handle) 
    Using g As Graphics = Graphics.FromHdc(dc) 
     g.FillRectangle(SystemBrushes.Window, New Rectangle(SystemInformation.Border3DSize.Width, _ 
                  SystemInformation.Border3DSize.Height, _ 
                  Me.ClientSize.Width - SystemInformation.VerticalScrollBarWidth, _ 
                  Me.ClientSize.Height)) 
    End Using 
    ReleaseDC(Me.Handle, dc) 
    End If 

당신은 할 수 있습니다 OnPaint, OnPaintBackground 오버라이드를 제거하십시오.

+0

안녕하세요,이 작품은 훌륭합니다! 그러나 'Dim g As Graphics = Graphics.FromHdc (m.WParam)'과의 차이점은 무엇입니까? 성능 향상이 있습니까? – Naster

+0

@Naster WParam이 작동하지 않습니다. [WM_PAINT 메시지] (http://msdn.microsoft.com/en-us/library/dd145213(v=vs.85)asp)에서 사용되지 않습니다. – LarsTech