Print Form in VB windows application - vb.net

I created one windows application using VS2013, the form contains few labels and textboxes. Form1 has little bit larges so I unable to print in actual size, it prints on portrait mode.
In my project I have added PrintForm and PageSetup dialogue, but this page setup won't works well, if I click on Landscape in PageSetup and then print, it prints the form in portrait mode.
page setup coding
' initialize the page settings
PageSetupDialog1.PageSettings = New Printing.PageSettings
' hide the network button
PageSetupDialog1.ShowNetwork = False
If PageSetupDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then
Dim settings() As Object = New Object() _
{PageSetupDialog1.PageSettings.Margins, _
PageSetupDialog1.PageSettings.PaperSize, _
PageSetupDialog1.PageSettings.Landscape, _
PageSetupDialog1.PrinterSettings.PrinterName, _
PageSetupDialog1.PrinterSettings.PrintRange}
End If

You need to think about if you really want to print the whole form as there might be buttons etc the user doesn't need to see and it is worthwhile learning how to design a page to be printed only containing relevant information.
For printing a form you can:
Option 1) Download the Visual Basic Powerpack as it contains the form print control and use this:
or
Option 2)
Turn your form into a bitmap and put into the document.print routine.
Here is some code you can play around with:
Imports System.Drawing.Printing
Public Class Form1
Dim WithEvents mPrintDocument As New PrintDocument
Dim mPrintBitMap As Bitmap
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim prtdoc As New PrintDocument
Dim strDefaultPrinter As String = prtdoc.PrinterSettings.PrinterName
MsgBox(strDefaultPrinter)
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
' Copy the form's image into a bitmap.
mPrintBitMap = New Bitmap(Me.Width, Me.Width)
Dim lRect As System.Drawing.Rectangle
lRect.Width = Me.Width
lRect.Height = Me.Width
Me.DrawToBitmap(mPrintBitMap, lRect)
' Make a PrintDocument and print.
mPrintDocument = New PrintDocument
mPrintDocument.DefaultPageSettings.Landscape = True
'mPrintDocument.Print() 'send the document to the printer
Me.PrintPreviewDialog1.Document = mPrintDocument
PrintPreviewDialog1.ShowDialog()
End Sub
Private Sub m_PrintDocument_PrintPage(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles mPrintDocument.PrintPage
' Draw the image centered.
Dim lWidth As Integer = e.MarginBounds.X + (e.MarginBounds.Width - mPrintBitMap.Width) \ 2
Dim lHeight As Integer = e.MarginBounds.Y + (e.MarginBounds.Height - mPrintBitMap.Height) \ 2
e.Graphics.DrawImage(mPrintBitMap, lWidth, lHeight)
' There's only one page.
e.HasMorePages = False
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Application.Exit()
End Sub
End Class

Related

How to make a button click quickly switch between two images in a picturebox vb

Making a joke VB program that requires a button click to make a PictureBox very quickly switch between two pictures. I tried using the sleep command but nothing changes on screen. Here's what I've tried so far.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
TransClass2.Image = My.Resources._21
System.Threading.Thread.Sleep(100)
TransClass2.Image = My.Resources._11
System.Threading.Thread.Sleep(100)
End Sub
TransClass2 is a class that inherits PictureBox. It's used to add transparent functionalities to PictureBoxes.
Public Class TransClass
Inherits PictureBox
Protected Overrides Sub OnPaintBackground(e As System.Windows.Forms.PaintEventArgs)
MyBase.OnPaintBackground(e)
If Parent IsNot Nothing Then
Dim index As Integer = Parent.Controls.GetChildIndex(Me)
For i As Integer = Parent.Controls.Count - 1 To index + 1 Step -1
Dim c As Control = Parent.Controls(i)
If c.Bounds.IntersectsWith(Bounds) AndAlso c.Visible = True Then
Dim bmp As New Bitmap(c.Width, c.Height, e.Graphics)
c.DrawToBitmap(bmp, c.ClientRectangle)
e.Graphics.TranslateTransform(c.Left - Left, c.Top - Top)
e.Graphics.DrawImageUnscaled(bmp, Point.Empty)
e.Graphics.TranslateTransform(Left - c.Left, Top - c.Top)
bmp.Dispose()
End If
Next
End If
End Sub
End Class
Mark the click handler as Async, then use Await Task.Delay():
Private Async Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
TransClass2.Image = My.Resources._21
Await Task.Delay(100)
TransClass2.Image = My.Resources._11
Await Task.Delay(100)
End Sub
I think 100 might be too fast!

How can I print a document with textboxes showing? (vB)

So I have been trying to print a document where the textboxes are shown on top of a picturebox, however it just doesn't seem to work.
Imports System.Drawing.Printing
Public Class Form1
Dim WithEvents mPrintDocument As New PrintDocument
Dim mPrintBitMap As Bitmap
Private Sub m_PrintDocument_PrintPage(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles mPrintDocument.PrintPage
' Draw the image centered.
Dim lWidth As Integer = e.MarginBounds.X + (e.MarginBounds.Width / 0.95 - mPrintBitMap.Width) \ 1
Dim lHeight As Integer = e.MarginBounds.Y + (e.MarginBounds.Height / 0.9 - mPrintBitMap.Height) \ 2
e.Graphics.DrawImage(mPrintBitMap, lWidth, lHeight)
' There's only one page.
e.HasMorePages = False
End Sub
Private Sub btnPrint_Click(sender As Object, e As EventArgs) Handles btnPrint.Click
picFij.SendToBack()
lblDN.BringToFront()
mPrintBitMap = New Bitmap(Me.Width, Me.Width)
Dim lRect As System.Drawing.Rectangle
lRect.Width = Me.Width
lRect.Height = Me.Width
Me.DrawToBitmap(mPrintBitMap, lRect)
mPrintDocument = New PrintDocument
printPreviewDialog1.Document = mPrintDocument
PrintPreviewDialog1.ShowDialog()
End Sub
I attempted a BringToFront() and SendToBack() but that didn't work.
This is what I want to print:
https://cdn.discordapp.com/attachments/358502382910570497/546555282940100648/unknown.png
And this is print preview
https://cdn.discordapp.com/attachments/358502382910570497/546555621806178324/unknown.png
Any ideas?
Make the PictureBox the Parent of your TextBox, then it should show up when you call DrawToBitmap(). For example, to keep TextBox1 in the same location, convert it screen coords, then back to client coords with respect to the PictureBox:
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim pt As Point = TextBox1.PointToScreen(New Point(0, 0))
TextBox1.Parent = PictureBox1
TextBox1.Location = PictureBox1.PointToClient(pt)
End Sub

Visual Indication of Focus and Adding Click Event To all TextBoxes

I'm working on a program wherein I have around 400 Text Boxes and I need to program an effect to make them show that they have focus. I can get the visual part down (Unless someone knows how to add a soft blue outline to a text box in VB), but I'm having trouble with creating GotFocus and LostFocus events that handle all of my Text Boxes at once. I've tried
Dim txtBox = Me.Controls.OfType(Of TextBox)
Private Sub TextBox_GotFocus(sender As Object, e As EventArgs) Handles txtBox.GotFocus
But I get a "Must have WithEvents variable" error which I don't quite understand how to fix. I've tried
Public Sub txtBoxGotFocusHandler(ByVal sender As Object,
ByVal e As System.EventArgs)
For Each txtBox As TextBox In Me.Controls 'References all text boxes in form
If txtBox.Focus = True Then
txtBox.BackColor = Color.Black
End If
Next
And I've tried a few other somewhat related things I've seen around the internet, but to no avail. Any help would be appreciated
You can make your app at runtime with any controls. You could query the layout of your app from SQL and from a simple change your app layout changes.
Private FocusRectangle As System.Drawing.Graphics
Private OldRectangle As System.Drawing.Graphics
Private MyTextBoxes As New List(Of TextBox)
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
MyTextBoxes.Clear()
For xcount = 0 To 399
MyTextBoxes.Add(New TextBox)
With MyTextBoxes.Item(xcount)
.Name = "MyTextBoxes" & (xcount + 1).ToString
.Text = ""
.Location = New Point(0, 0)
.Size = New Size(50, 13)
.Visible = True
AddHandler .GotFocus, AddressOf MyTextBoxes_GotFocus
AddHandler .LostFocus, AddressOf MyTextBoxes_LostFocus
End With
Me.Controls.Add(MyTextBoxes.Item(xcount))
'add them to a panel....
'Panel1.Controls.add(MyTextBoxes.Item(xcount))
Next
End Sub
Sub MyTextBoxes_GotFocus(sender As Object, e As EventArgs)
Dim ThisTextBox As TextBox = DirectCast(sender, TextBox)
Dim xPen As New System.Drawing.Pen(Color.LightBlue)
FocusRectangle = Me.CreateGraphics()
FocusRectangle.DrawRectangle(xPen, ThisTextBox.Location.X - 1, ThisTextBox.Location.Y - 1, ThisTextBox.Size.Width + 1, ThisTextBox.Size.Height + 1)
OldRectangle = FocusRectangle
End Sub
Sub MyTextBoxes_LostFocus(sender As Object, e As EventArgs)
Dim ThisTextBox As TextBox = DirectCast(sender, TextBox)
OldRectangle.Dispose()
End Sub
Private Sub Form1_MouseMove(sender As Object, e As MouseEventArgs) Handles Me.MouseMove
MyTextBoxes.Item(0).Focus()
End Sub
If you created your form with the Designer, the WithEvents is added for you automatically.
If you are declaring 400 text boxes as Private fields, you would declare them as Private WitheEvents txtBox As TextBox
If you're creating the text boxes programatically and adding them to a collection of textboxes or something, then you can't do WithEvents.
But all WithEvents does is allow you to add Handeles TextBox.SomeEvent to a function. Instead you can do this:
Dim txtBox As New TextBox
...
AddHandler txtBox.GotFocus, AddressOf txtBoxGotFocusHandler
Me.Controls.Add(txtBox)

Printing vb.net forms with a loop

Hi I am tring print multiple copies of box labels that are on a form using vb.net
the copies will depent on the amount of boxes on the job and will range from 1 to 500 copies.
I would like to print these but also print a choosen box number if required.
Can any one help as all my attempts have failed.
The problem is it captures the screen including msgboxs of what is currenting being printed or done and calls them all document 1. Is there a simple way to print without screen capture.
here is my code at the moment
Imports System
Imports System.Windows.Forms
Imports System.Drawing
Imports System.Drawing.Printing
Public Class print
Inherits Form
Private WithEvents printButton As New Button
Private WithEvents printDocument1 As New PrintDocument
Dim memoryImage As Bitmap
Private Sub CaptureScreen()
Dim myGraphics As Graphics = Me.CreateGraphics()
Dim s As Size = Me.Size
memoryImage = New Bitmap(s.Width, s.Height, myGraphics)
Dim memoryGraphics As Graphics = Graphics.FromImage(memoryImage)
memoryGraphics.CopyFromScreen(Me.Location.X, Me.Location.Y, 0, 0, s)
End Sub
Private Sub printDocument1_PrintPage(ByVal sender As System.Object, _
ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles _
printDocument1.PrintPage
e.Graphics.DrawImage(memoryImage, 0, 0)
End Sub
Private Sub printButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles printButton.Click
Dim numberofboxes As Integer = 3
Dim startbox As Integer = 1
Dim counter As Integer = 1
For index As Integer = startbox To numberofboxes
CaptureScreen()
printDocument1.Print()
lblFirstBoxPrint.Text = counter
counter = counter + 1
printDocument1.PrinterSettings.PrintToFile = True
printDocument1.PrinterSettings.PrintFileName = "C:\Users\Joseph\Desktop\test '" & counter & "'.xps"
printDocument1.Print()
Next
End Sub
Public Shared Sub Main()
Application.Run(New print())
End Sub
Private Sub print_Load(sender As Object, e As EventArgs) Handles MyBase.Load
printButton.Text = "Print Form"
Me.Controls.Add(printButton)
End Sub
End Class
If you desire to actually print your form, as it appears on screen, consider the built-in PrintForm Component. After adding the component, and setting properties, printing is a one line process.
PrintForm1.Print()
See this MSDN tutorial for further details.

Control array in VB.NET

How do I make a control array for buttons in VB.NET? Like in Visual Basic 6.0...
Is it possible that the syntax can be like the following?
dim a as button
for each a as button in myForm
a.text = "hello"
next
Controls in .NET are just normal objects so you can freely put them into normal arrays or lists. The special VB6 construct of control arrays is no longer necessary.
So you can for example say,
Dim buttons As Button() = { Button1, Button2, … }
For Each button As Button In Buttons
button.Text = "foo"
End For
Alternatively, you can directly iterate over the controls inside a container (e.g. a form):
For Each c As Control In MyForm.Controls
Dim btt As Button = TryCast(c, Button)
If btt IsNot Nothing Then ' We got a button!
btt.Text = "foo"
End If
End For
Notice that this only works for controls that are directly on the form; controls nested into containers will not be iterated this way; you can however use a recursive function to iterate over all controls.
You can't create a control array in VB.NET, but you can archive similar functionality using the Handles keyword.
public sub Button_Click(sender as Object, e as EventArgs) Handles Button1.Click, Button2.Click, Button3.Click
'Do Something
End Sub
Yes, you can do this. But I don't think you can iterate buttons directly by giving myForm.
You create a Form and add a Layout 10 * 10, and try this,
Public Class Form1
Private NRow As Integer = 10
Private NCol As Integer = 10
Private BtnArray(NRow * NCol - 1) As Button
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
TableLayoutPanel1.Size = Me.ClientSize
For i As Integer = 0 To BtnArray.Length - 1
BtnArray(i) = New Button()
BtnArray(i).Anchor = AnchorStyles.Top Or AnchorStyles.Bottom Or AnchorStyles.Left Or AnchorStyles.Right
BtnArray(i).Text = CStr(i)
TableLayoutPanel1.Controls.Add(BtnArray(i), i Mod NCol, i \ NCol)
AddHandler BtnArray(i).Click, AddressOf ClickHandler
Next
End Sub
Public Sub ClickHandler(ByVal sender As Object, ByVal e As System.EventArgs)
MsgBox("I am button #" & CType(sender, Button).Text)
End Sub
End Class