Imports System.Reflection
Imports System.Windows.Forms

Public Module cUI_Performance
    Public Sub EnableDoubleBuffer(ctrl As Control)
        SetOptimizedStyles(ctrl)

        ' DataGridView separat (DoubleBuffered ist protected)
        Dim dgv = TryCast(ctrl, DataGridView)
        If dgv IsNot Nothing Then SetDoubleBufferedDgv(dgv)

        For Each child As Control In ctrl.Controls
            EnableDoubleBuffer(child)
        Next
    End Sub

    Private Sub SetOptimizedStyles(c As Control)
        ' SetStyle (protected) per Reflection setzen
        Dim miSetStyle = c.GetType().GetMethod("SetStyle", BindingFlags.Instance Or BindingFlags.NonPublic)
        If miSetStyle IsNot Nothing Then
            Dim styles = ControlStyles.AllPaintingInWmPaint Or ControlStyles.UserPaint Or ControlStyles.OptimizedDoubleBuffer
            miSetStyle.Invoke(c, New Object() {styles, True})
        End If

        ' UpdateStyles (protected) per Reflection aufrufen (optional)
        Dim miUpdate = c.GetType().GetMethod("UpdateStyles", BindingFlags.Instance Or BindingFlags.NonPublic)
        If miUpdate IsNot Nothing Then
            miUpdate.Invoke(c, Nothing)
        Else
            ' Fallback: neu zeichnen
            c.Invalidate(True)
        End If
    End Sub

    Private Sub SetDoubleBufferedDgv(dgv As DataGridView)
        Dim pi = GetType(DataGridView).GetProperty("DoubleBuffered", BindingFlags.Instance Or BindingFlags.NonPublic)
        If pi IsNot Nothing Then pi.SetValue(dgv, True, Nothing)
    End Sub

    ' WM_SETREDRAW: Zeichnung temporär an/aus
    <Runtime.InteropServices.DllImport("user32.dll")>
    Private Function SendMessage(hWnd As IntPtr, msg As Integer, wParam As IntPtr, lParam As IntPtr) As IntPtr
    End Function
    Private Const WM_SETREDRAW As Integer = &HB

    Public Sub SuspendPainting(c As Control)
        If c.IsHandleCreated Then SendMessage(c.Handle, WM_SETREDRAW, IntPtr.Zero, IntPtr.Zero)
    End Sub
    Public Sub ResumePainting(c As Control, Optional invalidate As Boolean = True)
        If c.IsHandleCreated Then
            SendMessage(c.Handle, WM_SETREDRAW, CType(1, IntPtr), IntPtr.Zero)
            If invalidate Then c.Invalidate(True)
        End If
    End Sub
End Module