vb.net graphics draw line above all controls

I have a form and want to draw a diagnol line accross it. This is how I'm drawing the line.

Private Sub Form1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint

g.DrawLine(Pens.Red, ClientRectangle.X, ClientRectangle.Y, ClientRectangle.X + ClientRectangle.Width, ClientRectangle.Y + ClientRectangle.Height)

end sub

I also have a few controls sited on the form. The line draws on the forms surface only and is hidden behind each of the controls. How can I draw lines (or graphic object in general) that draws at the highest z order so that they appear to be on top of everything. Any easy way to do this?
glenn_rAsked:
Who is Participating?
 
Mike TomlinsonConnect With a Mentor Middle School Assistant TeacherCommented:
You can draw on the desktop hDC...but this method is NOT peristent.  It may fit your requirements, though, just depends what you're doing.
Public Class Form1
 
    Private Declare Function GetDesktopWindow Lib "user32" () As IntPtr
    Public Declare Function GetWindowDC Lib "user32" Alias "GetWindowDC" (ByVal hWnd As IntPtr) As Integer
    Public Declare Function ReleaseDC Lib "user32" Alias "ReleaseDC" (ByVal hWnd As IntPtr, ByVal hDc As Integer) As Integer
 
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim deskWnd As IntPtr = GetDesktopWindow()
        Dim hDc As Integer = GetWindowDC(deskWnd)
        Dim g As Graphics = Graphics.FromHdc(hDc)
        g.DrawLine(Pens.Red, Me.Location.X, Me.Location.Y, Me.Location.X + Me.Size.Width, Me.Location.Y + Me.Size.Height)
        g.Dispose()
        ReleaseDC(deskWnd, hDc)
    End Sub
 
End Class

Open in new window

DesktopDC.jpg
0
 
oobaylyCommented:
If you store the screen coordinates for the top-left & bottom-right corners of the form and hook the paint event for each control, you can draw the line across all the controls.

Currently doesn't draw on textboxes, comboboxes, listboxes and scrollbars though, but it is a first attempt.
    Private corners As Point()
 
    Private Sub HookPaint(ByVal control As Control)
        ' Hook the paint event for the control, and do for an child controls
        AddHandler control.Paint, AddressOf control_Paint
        For Each child As Control In control.Controls
            HookPaint(child)
        Next
    End Sub
 
    Private Sub control_Paint(ByVal sender As Object, ByVal e As PaintEventArgs)
        ' Convert screen point to the control's coordinates
        Dim local As Point() = New Point() { _
            DirectCast(sender, Control).PointToClient(corners(0)), _
            DirectCast(sender, Control).PointToClient(corners(1))}
 
        e.Graphics.DrawLine(Pens.Black, local(0), local(1))
    End Sub
 
    Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs)
        ' Convert the form's client corners to screen cordinates
        corners = New Point() { _
            Me.PointToScreen(Me.ClientRectangle.Location), _
            Me.PointToScreen(New Point(Me.ClientRectangle.Right, Me.ClientRectangle.Bottom))}
        HookPaint(Me)
    End Sub

Open in new window

0
 
glenn_rAuthor Commented:
oobayly I like your solution. The fact that your working within the confines of .net interests me. How do you think we can get the remaining controls (textboxes, scrollbars, etc. painted with the line?

Thanks,
Glenn
0
 
oobaylyCommented:
To be quite honest, I'm not too sure. I also reckon it'd be a a great deal of work. Subclassing the controls isn't really an option as there may any amount of types of controls on the form.

Personally, I'd go with Idle_Mind's solution. Using win32 calls isn't a major issue. and it does draw across all the child controls.
0
All Courses

From novice to tech pro — start learning today.