Solved

.NET Winform's Simple Question

Posted on 2004-10-25
295 Views
Last Modified: 2010-05-18
Hi all,
I am exhusted finding a solution to a simple problem.. may be its simple but i wasn't able to find it..
In very short, i want to capture a form's (or panel's) image to HDD...
What exactly i want is to get the current image of a panel... and store its image to a file, with image of all of controls in it... in VB.NET
as simple as that..
plz help.. its little urgent..
Good Day to all of u...
-Kinjal
0
Question by:dkinjal
    6 Comments
     
    LVL 8

    Expert Comment

    by:sigmacon
    When the form is open, press ALT+Print Screen, then open Programs > Acces. > Paint, Paste it and save it. done. Does that help?
    0
     
    LVL 85

    Expert Comment

    by:Mike Tomlinson
    Try this out:

    Public Class Form1
        Inherits System.Windows.Forms.Form

    #Region " Windows Form Designer generated code "

        Public Sub New()
            MyBase.New()

            'This call is required by the Windows Form Designer.
            InitializeComponent()

            'Add any initialization after the InitializeComponent() call

        End Sub

        'Form overrides dispose to clean up the component list.
        Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
            If disposing Then
                If Not (components Is Nothing) Then
                    components.Dispose()
                End If
            End If
            MyBase.Dispose(disposing)
        End Sub

        'Required by the Windows Form Designer
        Private components As System.ComponentModel.IContainer

        'NOTE: The following procedure is required by the Windows Form Designer
        'It can be modified using the Windows Form Designer.  
        'Do not modify it using the code editor.
        Friend WithEvents Panel1 As System.Windows.Forms.Panel
        Friend WithEvents Timer1 As System.Windows.Forms.Timer
        Friend WithEvents NotifyIcon1 As System.Windows.Forms.NotifyIcon
        Friend WithEvents Button1 As System.Windows.Forms.Button
        Friend WithEvents Button2 As System.Windows.Forms.Button
        Friend WithEvents TextBox1 As System.Windows.Forms.TextBox
        Friend WithEvents Label1 As System.Windows.Forms.Label
        Friend WithEvents ListBox1 As System.Windows.Forms.ListBox
        Friend WithEvents Button3 As System.Windows.Forms.Button
        <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
            Me.components = New System.ComponentModel.Container
            Me.Panel1 = New System.Windows.Forms.Panel
            Me.Timer1 = New System.Windows.Forms.Timer(Me.components)
            Me.NotifyIcon1 = New System.Windows.Forms.NotifyIcon(Me.components)
            Me.Button1 = New System.Windows.Forms.Button
            Me.Button2 = New System.Windows.Forms.Button
            Me.TextBox1 = New System.Windows.Forms.TextBox
            Me.Label1 = New System.Windows.Forms.Label
            Me.ListBox1 = New System.Windows.Forms.ListBox
            Me.Button3 = New System.Windows.Forms.Button
            Me.Panel1.SuspendLayout()
            Me.SuspendLayout()
            '
            'Panel1
            '
            Me.Panel1.AutoScroll = True
            Me.Panel1.BackColor = System.Drawing.Color.LightPink
            Me.Panel1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle
            Me.Panel1.Controls.Add(Me.Button3)
            Me.Panel1.Controls.Add(Me.ListBox1)
            Me.Panel1.Controls.Add(Me.Label1)
            Me.Panel1.Controls.Add(Me.TextBox1)
            Me.Panel1.Controls.Add(Me.Button2)
            Me.Panel1.Location = New System.Drawing.Point(8, 40)
            Me.Panel1.Name = "Panel1"
            Me.Panel1.Size = New System.Drawing.Size(428, 240)
            Me.Panel1.TabIndex = 1
            '
            'Timer1
            '
            Me.Timer1.Interval = 25
            '
            'NotifyIcon1
            '
            Me.NotifyIcon1.Text = "RubberBand Screen Capture Demo"
            '
            'Button1
            '
            Me.Button1.Location = New System.Drawing.Point(8, 8)
            Me.Button1.Name = "Button1"
            Me.Button1.Size = New System.Drawing.Size(112, 24)
            Me.Button1.TabIndex = 2
            Me.Button1.Text = "Save Panel Image"
            '
            'Button2
            '
            Me.Button2.Location = New System.Drawing.Point(288, 8)
            Me.Button2.Name = "Button2"
            Me.Button2.Size = New System.Drawing.Size(128, 24)
            Me.Button2.TabIndex = 0
            Me.Button2.Text = "Button2"
            '
            'TextBox1
            '
            Me.TextBox1.Location = New System.Drawing.Point(88, 8)
            Me.TextBox1.Name = "TextBox1"
            Me.TextBox1.Size = New System.Drawing.Size(192, 20)
            Me.TextBox1.TabIndex = 1
            Me.TextBox1.Text = "TextBox1"
            '
            'Label1
            '
            Me.Label1.Location = New System.Drawing.Point(8, 8)
            Me.Label1.Name = "Label1"
            Me.Label1.Size = New System.Drawing.Size(72, 24)
            Me.Label1.TabIndex = 2
            Me.Label1.Text = "Label1"
            '
            'ListBox1
            '
            Me.ListBox1.Location = New System.Drawing.Point(8, 40)
            Me.ListBox1.Name = "ListBox1"
            Me.ListBox1.Size = New System.Drawing.Size(408, 147)
            Me.ListBox1.TabIndex = 3
            '
            'Button3
            '
            Me.Button3.Location = New System.Drawing.Point(288, 200)
            Me.Button3.Name = "Button3"
            Me.Button3.Size = New System.Drawing.Size(128, 24)
            Me.Button3.TabIndex = 4
            Me.Button3.Text = "Button3"
            '
            'Form1
            '
            Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
            Me.ClientSize = New System.Drawing.Size(448, 286)
            Me.Controls.Add(Me.Button1)
            Me.Controls.Add(Me.Panel1)
            Me.Name = "Form1"
            Me.Text = "RubberBand Screen Capture Demo"
            Me.Panel1.ResumeLayout(False)
            Me.ResumeLayout(False)

        End Sub

    #End Region

        Private Const SRCCOPY = &HCC0020

        Private Declare Function CreateDC Lib "gdi32" Alias "CreateDCA" (ByVal lpDriverName As String, ByVal lpDeviceName As String, ByVal lpOutput As String, ByVal lpInitData As String) As Integer
        Private Declare Function CreateCompatibleDC Lib "GDI32" (ByVal hDC As Integer) As Integer
        Private Declare Function CreateCompatibleBitmap Lib "GDI32" (ByVal hDC As Integer, ByVal nWidth As Integer, ByVal nHeight As Integer) As Integer
        Private Declare Function SelectObject Lib "GDI32" (ByVal hDC As Integer, ByVal hObject As Integer) As Integer
        Private Declare Function BitBlt Lib "GDI32" (ByVal hDestDC As Integer, ByVal X As Integer, ByVal Y As Integer, ByVal nWidth As Integer, ByVal nHeight As Integer, ByVal hSrcDC As Integer, ByVal SrcX As Integer, ByVal SrcY As Integer, ByVal Rop As Integer) As Integer
        Private Declare Function DeleteObject Lib "GDI32" (ByVal hObj As Integer) As Integer
        Private Declare Function DeleteDC Lib "GDI32" (ByVal hDC As Integer) As Integer

        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            Dim r As Rectangle = Me.RectangleToScreen(New Rectangle(Panel1.Location, Panel1.Size))
            Dim b As Bitmap = GetScreen(r.X, r.Y, r.Width, r.Height)
            b.Save("c:\Panel1.bmp")
            b.Dispose()
        End Sub

        Private Function GetScreen(ByVal X As Integer, ByVal Y As Integer, ByVal Width As Integer, ByVal Height As Integer) As Bitmap
            Dim hDeskDC As Integer
            Dim hTempDC As Integer
            Dim hBitmap As Integer
            Dim hTempBmp As Integer
            Dim desktopArea As Bitmap

            hDeskDC = CreateDC("DISPLAY", "", "", "")
            If hDeskDC Then
                hTempDC = CreateCompatibleDC(hDeskDC)
                If hTempDC Then
                    hBitmap = CreateCompatibleBitmap(hDeskDC, Width, Height)
                    If hBitmap Then
                        hTempBmp = SelectObject(hTempDC, hBitmap)
                        BitBlt(hTempDC, 0, 0, Width, Height, hDeskDC, X, Y, SRCCOPY)
                        desktopArea = Bitmap.FromHbitmap(New IntPtr(hBitmap))
                        DeleteObject(SelectObject(hTempDC, hTempBmp))
                    End If
                    DeleteDC(hTempDC)
                End If
                DeleteDC(hDeskDC)
            End If
            Return desktopArea
        End Function

    End Class
    0
     

    Author Comment

    by:dkinjal
    hi... sigmacon, i wanted it done programatically..!
    hi idlemind.. seems u r good in coventional programming..! Thanks for answering but its the Typical VB style, it in no way seem .nET or OO code.. I am sure, there must be some better (proper) way for doing it... Anyway i appereciate you anwering.. THanks..
    0
     
    LVL 85

    Expert Comment

    by:Mike Tomlinson
    Hi dkinjal,

    My previous example captured the entire screen (or a portion of it) using the Desktop DC.

    Here is a different approach that uses the Panels DC directly (instead of the Desktop DC) resulting in more compact code.  It still relies on the external function BitBlt though, but you are not going to find anything faster than BitBlt.

    Public Class Form1
        Inherits System.Windows.Forms.Form

        Private Declare Function BitBlt Lib "GDI32" _
            (ByVal hDestDC As IntPtr, _
            ByVal X As Integer, ByVal Y As Integer, _
            ByVal nWidth As Integer, ByVal nHeight As Integer, _
            ByVal hSrcDC As IntPtr, _
            ByVal SrcX As Integer, ByVal SrcY As Integer, _
            ByVal Rop As Integer) As Integer

        Private Const SRCCOPY = &HCC0020

        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            capturePanel(Panel1, "c:\panel1.bmp")
        End Sub

        Private Sub capturePanel(ByVal p As Panel, ByVal fileName As String)
            Dim g1 As Graphics = p.CreateGraphics()
            Dim img As Image = New Bitmap(p.Size.Width, p.Size.Height, g1)
            Dim g2 As Graphics = Graphics.FromImage(img)

            Dim dc1 As IntPtr = g1.GetHdc()
            Dim dc2 As IntPtr = g2.GetHdc()

            BitBlt(dc2, 0, 0, p.Size.Width, p.Size.Height, dc1, 0, 0, SRCCOPY)

            g1.ReleaseHdc(dc1)
            g2.ReleaseHdc(dc2)

            g1.Dispose()
            g2.Dispose()

            img.Save(fileName)
            img.Dispose()
        End Sub

    End Class
    0
     
    LVL 85

    Accepted Solution

    by:
    Here is an interesting link that *almost* does the job using only managed .Net code:
    http://www.experts-exchange.com/Programming/Programming_Languages/C_Sharp/Q_21127487.html

    The problem with that approach is the resulting image doesn't have the text from the controls on it and some of the controls don't draw properly (I notice some controls didn't have the proper 3D border).  I converted the code to VB.Net and made some minor modifications:

    Imports System.Drawing.Drawing2D

    Public Class Form1
        Inherits System.Windows.Forms.Form

        Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
            capturePanel(Panel1, "c:\panel1_B.bmp")
        End Sub

        Private Sub capturePanel(ByVal p As Panel, ByVal fileName As String)
            Dim pGraphics As Graphics = p.CreateGraphics()
            Dim pSize As Size = p.Size
            Dim bmp As Bitmap = New Bitmap(pSize.Width, pSize.Height, pGraphics)
            Dim bmpGraphics As Graphics = Graphics.FromImage(bmp)

            PaintControls(Point.Empty, p, bmpGraphics)

            pGraphics.Dispose()
            bmpGraphics.Dispose()

            bmp.Save(fileName)
            bmp.Dispose()
        End Sub

        Private Sub PaintControls(ByVal location As Point, ByVal c As Control, ByVal g As Graphics)
            Dim c2 As Control
            Dim c2Loc As Point

            g.ResetTransform()
            g.Transform = New Matrix(1, 0, 0, 1, location.X, location.Y)
            InvokePaintBackground(c, New PaintEventArgs(g, New Rectangle(Point.Empty, c.ClientSize)))
            InvokePaint(c, New PaintEventArgs(g, New Rectangle(Point.Empty, c.ClientSize)))
            For Each c2 In c.Controls
                c2Loc = New Point(location.X + c2.Left, location.Y + c2.Top)
                PaintControls(c2Loc, c2, g)
            Next
        End Sub

    End Class
    0
     

    Author Comment

    by:dkinjal
    hi IdleMind...
    i am very sorry.. i wasn't able to reply... really sorry...
    i also appologise to admins...
    Thanks anyway to all of u...
    -Kinjal
    0

    Write Comment

    Please enter a first name

    Please enter a last name

    We will never share this with anyone.

    Featured Post

    How to run any project with ease

    Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
    - Combine task lists, docs, spreadsheets, and chat in one
    - View and edit from mobile/offline
    - Cut down on emails

    Suggested Solutions

    Title # Comments Views Activity
    printing double sided for a pdf document 19 75
    Order table with macro 3 54
    sumHeights  challenge 17 35
    count7 challenge 12 28
    INTRODUCTION We all know how to code. But at times you simply want to insert a common code block into your existing code and amend it as per your requirements. This tool not only saves you time but also saves you the pain of typing it all out aga…
    Whether you've completed a degree in computer sciences or you're a self-taught programmer, writing your first lines of code in the real world is always a challenge. Here are some of the most common pitfalls for new programmers.
    An introduction to basic programming syntax in Java by creating a simple program. Viewers can follow the tutorial as they create their first class in Java. Definitions and explanations about each element are given to help prepare viewers for future …
    In this fifth video of the Xpdf series, we discuss and demonstrate the PDFdetach utility, which is able to list and, more importantly, extract attachments that are embedded in PDF files. It does this via a command line interface, making it suitable …

    846 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    8 Experts available now in Live!

    Get 1:1 Help Now