none
How To Change background color of titlebar of winform in vb.net? RRS feed

  • Question

  • I have used this code to set graphic on form but when I am doing alt+tab for moving to another window then graphic will remove from the form

    [DllImport("user32.dll")]
        static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);
    
        [DllImport("User32.dll")]
    
        private static extern IntPtr GetWindowDC(IntPtr hWnd);
    
        protected override void WndProc(ref System.Windows.Forms.Message m)
        {
            const int WM_NCPAINT = 0x85;
            base.WndProc(ref m);
    
            if (m.Msg == WM_NCPAINT)
            {
    
                IntPtr hdc = GetWindowDC(m.HWnd);
                if ((int)hdc != 0)
                {
                    Graphics g = Graphics.FromHdc(hdc);
                    Rectangle screenRectangle = RectangleToScreen(this.ClientRectangle);
                    int titleHeight = screenRectangle.Top - this.Top;
                    Rectangle rect = new Rectangle(0, 0, this.Width-100, 30);
                    g.FillRectangle(Brushes.Green, rect);                
                    g.Flush();
                    ReleaseDC(m.HWnd, hdc);
                }
    
            }
    
        }

    Monday, April 16, 2018 10:57 AM

All replies

  • Your question needs to be moved to the Visual C# forum:

    https://social.msdn.microsoft.com/Forums/vstudio/en-US/home?forum=csharpgeneral


    Paul ~~~~ Microsoft MVP (Visual Basic)

    Monday, April 16, 2018 12:33 PM
  • It is done now with DwmExtendFrameIntoClientArea

    Quick test with a gradient on Windows 10 :

    Declarations in VB.NET :

        <DllImport("Dwmapi.dll")>
        Shared Function DwmIsCompositionEnabled(ByRef enabled As Boolean) As Integer
        End Function
    
        <StructLayout(LayoutKind.Sequential)>
        Public Structure MARGINS
            Public cxLeftWidth, cxRightWidth, cyTopHeight, cyBottomHeight As Integer
            Public Sub New(ByVal left As Integer, ByVal right As Integer, ByVal top As Integer, ByVal bottom As Integer)
                cxLeftWidth = left
                cyTopHeight = top
                cxRightWidth = right
                cyBottomHeight = bottom
            End Sub
        End Structure
    
        <DllImport("Dwmapi.dll")>
        Shared Function DwmExtendFrameIntoClientArea(ByVal hwnd As IntPtr, ByRef margins As MARGINS) As Integer
        End Function
    
        <DllImport("Dwmapi.dll")>
        Shared Function DwmDefWindowProc(ByVal hWnd As IntPtr, ByVal msg As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr, ByRef plResult As IntPtr) As Boolean
        End Function


    • Edited by Castorix31 Monday, April 16, 2018 2:52 PM
    Monday, April 16, 2018 2:45 PM
  • This code seems to work fine even when Alt+Tab is used. You can use Telerik to convert it to C#. It draws a bitmap in the TitleBar.

    Option Strict On
    
    Imports System.Threading
    Imports System.Runtime.InteropServices
    
    Public Class Form1
    
        Private Const WM_NCACTIVATE As Integer = &H86
        Private Const WM_NCPAINT As Integer = &H85
    
        <DllImport("user32.dll", EntryPoint:="ReleaseDC")> Private Shared Function ReleaseDC(ByVal hWnd As IntPtr, ByVal hDC As IntPtr) As Integer
        End Function
    
        <DllImport("user32.dll", EntryPoint:="GetWindowDC")> Private Shared Function GetWindowDC(ByVal hWnd As IntPtr) As IntPtr
        End Function
    
        Dim Bmp As Bitmap
    
        Dim BmpWidthToUse As Integer = 0
    
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    
            Dim CurCulture As String = Thread.CurrentThread.CurrentCulture.TextInfo.CultureName
    
            For Each ResourceFile As DictionaryEntry In My.Resources.ResourceManager.GetResourceSet(Globalization.CultureInfo.CurrentCulture, True, True).OfType(Of Object)()
                If TypeOf (ResourceFile.Key) Is String Then
                    If ResourceFile.Key.ToString.Contains("_") Then
                        If CurCulture = ResourceFile.Key.ToString.Replace("_"c, "-"c) Then
                            Bmp = New Bitmap(CType(ResourceFile.Value, Image), CType(ResourceFile.Value, Image).Size)
                            BmpWidthToUse = CInt(((100 / Bmp.Height) * SystemInformation.CaptionHeight - 4) * (Bmp.Width / 100))
                            DrawIt = True
                        End If
                    ElseIf CurCulture = ResourceFile.Key.ToString Then
                        Bmp = New Bitmap(CType(ResourceFile.Value, Image), CType(ResourceFile.Value, Image).Size)
                        BmpWidthToUse = CInt(((100 / Bmp.Height) * SystemInformation.CaptionHeight - 4) * (Bmp.Width / 100))
                        DrawIt = True
                    End If
                End If
            Next
    
        End Sub
    
        Dim DrawIt As Boolean = False
    
        Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
            If m.Msg = WM_NCPAINT Then
                DrawTitleBar(True)
            Else
                MyBase.WndProc(m)
                If m.Msg = WM_NCACTIVATE Then
                    DrawTitleBar(False)
                End If
            End If
        End Sub
    
        Private Sub DrawTitleBar(ByVal drawform As Boolean)
            If DrawIt = True Then
                Dim hdc As IntPtr = GetWindowDC(Me.Handle)
                Using g As Graphics = Graphics.FromHdc(hdc)
                    g.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
                    If drawform Then
                        Using bm As New Bitmap(Me.Width, Me.Height)
                            Me.DrawToBitmap(bm, New Rectangle(0, 0, Me.Width, Me.Height))
                            g.DrawImage(bm, 0, 0, Me.Width, Me.Height)
                        End Using
                    End If
                    g.DrawImage(Bmp, Me.Width - BmpWidthToUse - 120, 4, BmpWidthToUse, SystemInformation.CaptionHeight - 4)
                End Using
                ReleaseDC(Me.Handle, hdc)
            End If
        End Sub
    
    
    End Class


    La vida loca

    Monday, April 16, 2018 3:30 PM
  •  Take a look at the following link.  It is a C++ example that shows how to use some of the Win32 apis which have been shown to you by Castorix31 and Mr. Monkeyboy.  If you are familiar with using Win32 apis and Vb.net or C#,  you should be able to convert the code manually or at least see how they should be used.

    Custom Window Frame Using DWM

     You may also want to take a look through some of the methods in the following link too.

    Visual Styles Reference


    If you say it can`t be done then i`ll try it

    Tuesday, April 17, 2018 1:12 AM
  • Thank you but after alt+tab original form will render by this code also
    Tuesday, April 17, 2018 5:50 AM
  • Thank you but after alt+tab original form will render by this code also

    Well in english I don't understand what that means. Will render what?

    La vida loca

    Tuesday, April 17, 2018 9:58 AM
  • I want to say that when I am doing alt+tab,the form without graphic is displaying. 
    Tuesday, April 17, 2018 12:07 PM
  • <DllImport("user32.dll")>
        Private Shared Function ReleaseDC(ByVal hWnd As IntPtr, ByVal hDC As IntPtr) As Integer
        End Function
    
        <DllImport("User32.dll")>
        Private Shared Function GetWindowDC(ByVal hWnd As IntPtr) As IntPtr
        End Function
    
        Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
            Const WM_NCPAINT As Integer = 133
            MyBase.WndProc(m)
            If m.Msg = WM_NCPAINT Then
                Dim hdc As IntPtr = GetWindowDC(m.HWnd)
                If CInt(hdc) <> 0 Then
                    Dim g As Graphics = Graphics.FromHdc(hdc)
                    Dim screenRectangle As Rectangle = RectangleToScreen(Me.ClientRectangle)
                    Dim titleHeight As Integer = screenRectangle.Top - Me.Top
                    Dim rect As Rectangle = New Rectangle(0, 0, Me.Width - 100, 30)
                    g.FillRectangle(Brushes.Green, rect)
                    g.Flush()
                    ReleaseDC(m.HWnd, hdc)
                End If
            End If
        End Sub
    Tuesday, April 17, 2018 12:14 PM
  • <DllImport("user32.dll")>
        Private Shared Function ReleaseDC(ByVal hWnd As IntPtr, ByVal hDC As IntPtr) As Integer
        End Function
    
        <DllImport("User32.dll")>
        Private Shared Function GetWindowDC(ByVal hWnd As IntPtr) As IntPtr
        End Function
    
        Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
            Const WM_NCPAINT As Integer = 133
            MyBase.WndProc(m)
            If m.Msg = WM_NCPAINT Then
                Dim hdc As IntPtr = GetWindowDC(m.HWnd)
                If CInt(hdc) <> 0 Then
                    Dim g As Graphics = Graphics.FromHdc(hdc)
                    Dim screenRectangle As Rectangle = RectangleToScreen(Me.ClientRectangle)
                    Dim titleHeight As Integer = screenRectangle.Top - Me.Top
                    Dim rect As Rectangle = New Rectangle(0, 0, Me.Width - 100, 30)
                    g.FillRectangle(Brushes.Green, rect)
                    g.Flush()
                    ReleaseDC(m.HWnd, hdc)
                End If
            End If
        End Sub

    This code does not run.

    It is not vb code. It is off topic.

    There is no question specified in this thread.

    The entire thread should be deleted unless op can ask a complete question that makes sense.

    Tuesday, April 17, 2018 1:45 PM