Opening and closing multiple forms from a main form in VB.net - vb.net

In my project (kind of a screen saver) I have a main form and second form (PicView).
I want to open many instances of the second form and display a picture in it.
I can do that fine, but when I have opened e.g. 4 forms I would like to close the first before opening the next one so that the total number of forms stays at 4.
The problem I have is that the closing routine does not know about the form instances and the debugger tells me to create a new instance, but I would like to use the existing ones.
How can I make the form names visible to the main routine or do I need to pass reference to the created forms?
Thanks
Private Sub btnTest_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnTest.Click
gsPic1 = "D:\My Stuff\411CANON\IMG_1161.JPG"
gsPic2 = "D:\My Stuff\411CANON\IMG_1167.JPG"
gsPic3 = "D:\My Stuff\411CANON\IMG_1174.JPG"
gsPic4 = "D:\My Stuff\411CANON\IMG_1178.JPG"
ScreenSavePicIndex(gsPic1, 1)
Application.DoEvents()
ScreenSavePicIndex(gsPic2, 2)
Application.DoEvents()
ScreenSavePicIndex(gsPic3, 3)
Application.DoEvents()
ScreenSavePicIndex(gsPic4, 4)
MsgBox("Now Closing 1")
CloseScreenSaverPic(1)
Application.DoEvents()
MsgBox("Now Closing 3")
CloseScreenSaverPic(3)
Application.DoEvents()
MsgBox("Now Closing 4")
CloseScreenSaverPic(4)
Application.DoEvents()
End Sub
Private Sub CloseScreenSaverPic(ByVal iIndex As Integer)
Dim frmPicViewerScrSav(iIndex) As PicView
frmPicViewerScrSav(iIndex) = New PicView
frmPicViewerScrSav(iIndex).Close()
End Sub
Private Sub ScreenSavePicIndex(ByVal sFilePathandName As String, iIndex As Integer)
Dim iTargetHeight As Integer
Dim iTargetWidth As Integer
Dim dFactorHeight As Double
Dim dFactorWidth As Double
Dim objImage As System.Drawing.Image
Try
objImage = System.Drawing.Image.FromFile(sFilePathandName)
Catch ex As Exception
objImage = Nothing
End Try
Dim frmPicViewerScrSav(iIndex) As PicView
frmPicViewerScrSav(iIndex) = New PicView
Dim dFactor As Double
dFactor = 1
frmPicViewerScrSav(iIndex).FormBorderStyle = Windows.Forms.FormBorderStyle.None
iTargetWidth = Screen.PrimaryScreen.Bounds.Width / giScreenSavePicSize
iTargetHeight = Screen.PrimaryScreen.Bounds.Height / giScreenSavePicSize
'Check if the pic is bigger than what we want to display
If objImage.Width > iTargetWidth Then
'if it is wider then we need to find out how much bigger it is by factor
dFactorWidth = iTargetWidth / objImage.Width
End If
If objImage.Height > iTargetHeight Then
'if it is higher then we need to find out how much bigger it is by factor
dFactorHeight = iTargetHeight / objImage.Height
End If
If dFactorWidth > dFactorHeight Then
dFactor = dFactorWidth
Else
dFactor = dFactorHeight
End If
'Console.WriteLine("Factor is: " & dFactor)
frmPicViewerScrSav(iIndex).Width = objImage.Width * dFactor
frmPicViewerScrSav(iIndex).Height = objImage.Height * dFactor
objImage.Dispose()
Dim r As New Random()
Dim x As Integer = r.Next(Screen.PrimaryScreen.Bounds.Width - frmPicViewerScrSav(iIndex).Width)
Dim y As Integer = r.Next(Screen.PrimaryScreen.Bounds.Height - frmPicViewerScrSav(iIndex).Height)
Dim p As New Point(x, y)
'Console.WriteLine("Putting it at x= " & x & ", y= " & y)
frmPicViewerScrSav(iIndex).Location = p
frmPicViewerScrSav(iIndex).PictureBox1.Hide()
frmPicViewerScrSav(iIndex).PictureBox1.ImageLocation = sFilePathandName
frmPicViewerScrSav(iIndex).PictureBox1.SizeMode = PictureBoxSizeMode.Zoom
frmPicViewerScrSav(iIndex).PictureBox1.Show()
frmPicViewerScrSav(iIndex).Show()
End Sub

Related

Does Visual Basic process nested loops like this very slowly, or is there some other issue with my code?

Basically, I'm trying to loop through every pixel of a picture and check it against every pixel of another image. The problem is that it seems to just do this very slowly (I can no longer interact with the opened window, and Debug.WriteLine works). I want to be sure this is the problem rather than there just being something wrong with my code.
monPic and crop are dimmed as bitmaps at the top of my code.
Private Sub BtnCheck_Click(sender As Object, e As EventArgs) Handles btnCheck.Click
monPic = New Bitmap("../../../../" & picNum & ".png")
crop = New Bitmap("../../../../mm.png")
For x As Integer = 0 To monPic.Width - 1
Debug.WriteLine("level 1")
For y As Integer = 0 To monPic.Height - 1
Debug.WriteLine("level 2")
If CInt(monPic.GetPixel(x, y).A) <> 0 Then
For x2 As Integer = 0 To crop.Width - 1
Debug.WriteLine("level 3")
For y2 As Integer = 0 To crop.Height - 1
Debug.WriteLine("level 4")
If monPic.GetPixel(x, y).R = crop.GetPixel(x2, y2).R And monPic.GetPixel(x, y).G = crop.GetPixel(x2, y2).G And monPic.GetPixel(x, y).B = crop.GetPixel(x2, y2).B Then matches += 1
Next y2
Next x2
End If
Next y
Next x
lblMatches.Text = CStr(matches)
End Sub
This works quickly. It requires
Imports System.Security.Cryptography
Convert the 2 bitmaps to Byte arrays then hash with Sha256. Compare the hash.
Adapted from https://www.codeproject.com/Articles/9299/Comparing-Images-using-GDI
Private Function Compare(bmp1 As Bitmap, bmp2 As Bitmap) As String
Dim result = "It's a match!"
If Not (bmp1.Size = bmp2.Size) Then
result = "It's not even the same size"
Else
Dim ic As New ImageConverter
Dim btImage1(0) As Byte
btImage1 = CType(ic.ConvertTo(bmp1, btImage1.GetType), Byte())
Dim btImage2(0) As Byte
btImage2 = CType(ic.ConvertTo(bmp2, btImage2.GetType), Byte())
Dim shaM As New SHA256Managed
Dim hash1 = shaM.ComputeHash(btImage1)
Dim hash2 = shaM.ComputeHash(btImage2)
Dim i As Integer = 0
Do While i < hash1.Length AndAlso i < hash2.Length AndAlso result = "It's a match!"
If hash1(i) <> hash2(i) Then
result = "The pixels don't match"
End If
i = (i + 1)
Loop
End If
Return result
End Function
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim png1 As New Bitmap(path1)
Dim png2 As New Bitmap(path2)
Dim message = Compare(png1, png2)
MessageBox.Show(message)
End Sub

asp.net vb web application printing data to a sticky label machine from web server

I am developing a website where i'm pulling some data from a query and then needing to print this data to a brady pr300 plus label printer. I would like for the printing to happen automatically from the web server to the printer without having the print dialog box pop up on the client computer.
What is the best way to go about this? javascript, vb behind code?
I've been playing around with this without much luck. I created a printingclass with onbeginprint method and onprintpage method. When i call the print, it goes to the onbeginprint method, but for some reason it doesnt go to onprintpagemethod when i step through the code. The error i get is System.Drwaing.Printing.invalidprinterexception: no printers are installed.
I'm kind of stuck at the moment.
Public Sub PrintDocument()
Dim tprinter As New PCPrint
tprinter.PrinterFont = New Font("Verdana", 10)
tprinter.TextToPrint = "HELLO WORLD"
tprinter.PrintName = "testbrady"
tprinter.Print()
End Sub
Protected Overrides Sub OnBeginPrint(ByVal e As Printing.PrintEventArgs)
' Run base code
MyBase.OnBeginPrint(e)
'Check to see if the user provided a font
'if they didnt then we default to Times New Roman
If _font Is Nothing Then
'Create the font we need
_font = New Font("Times New Roman", 10)
End If
End Sub
Protected Overrides Sub OnPrintPage(ByVal e As Printing.PrintPageEventArgs)
' Run base code
MyBase.OnPrintPage(e)
'Declare local variables needed
Static curChar As Integer
Dim printHeight As Integer
Dim printWidth As Integer
Dim leftMargin As Integer
Dim rightMargin As Integer
Dim lines As Int32
Dim chars As Int32
'Set print area size and margins
With MyBase.DefaultPageSettings
printHeight = .PaperSize.Height - .Margins.Top - .Margins.Bottom
printWidth = .PaperSize.Width - .Margins.Left - .Margins.Right
leftMargin = .Margins.Left 'X
rightMargin = .Margins.Top 'Y
End With
MyBase.DefaultPageSettings.PrinterSettings.PrinterName = PrintName
'Check if the user selected to print in Landscape mode
'if they did then we need to swap height/width parameters
If MyBase.DefaultPageSettings.Landscape Then
Dim tmp As Integer
tmp = printHeight
printHeight = printWidth
printWidth = tmp
End If
'Now we need to determine the total number of lines
'we're going to be printing
Dim numLines As Int32 = CInt(printHeight / PrinterFont.Height)
'Create a rectangle printing are for our document
Dim printArea As New RectangleF(leftMargin, rightMargin, printWidth, printHeight)
'Use the StringFormat class for the text layout of our document
Dim format As New StringFormat(StringFormatFlags.LineLimit)
'Fit as many characters as we can into the print area
e.Graphics.MeasureString(_text.Substring(RemoveZeros(curChar)), PrinterFont, New SizeF(printWidth, printHeight), format, chars, lines)
'Print the page
e.Graphics.DrawString(_text.Substring(RemoveZeros(curChar)), PrinterFont, Brushes.Black, printArea, format)
'Increase current char count
curChar += chars
'Detemine if there is more text to print, if
'there is the tell the printer there is more coming
If curChar < _text.Length Then
e.HasMorePages = True
Else
e.HasMorePages = False
curChar = 0
End If
End Sub
Hello StackOverflow Members,
This is what i ended up doing to get the label printer to work.
Imports System.Drawing
Imports System.Drawing.Printing
Public Sub prt(variables)
Dim prn As New Printing.PrintDocument
Dim psz As New Printing.PaperSize With {
.RawKind = Printing.PaperKind.Custom,
.Width = 400,
.Height = 150
}
Using (prn)
prn.PrinterSettings.PrinterName = printer
prn.DefaultPageSettings.PaperSize = psz
prn.DefaultPageSettings.Margins.Left = 5
prn.DefaultPageSettings.Margins.Right = 5
prn.DefaultPageSettings.Margins.Top = 5
prn.DefaultPageSettings.Margins.Bottom = 5
AddHandler prn.PrintPage,
AddressOf Me.PrintPageHandler
prn.Print()
RemoveHandler prn.PrintPage,
AddressOf Me.PrintPageHandler
End Using
End Sub
Private Sub PrintPageHandler(ByVal sender As Object,
ByVal args As Printing.PrintPageEventArgs)
Dim shopnameX As Integer = 10, shopnameY As Integer = 10
Dim sfont As New Font("Arial Black", 14)
Dim strfomart As New StringFormat()
Dim StrRight As New StringFormat()
Dim StrLeft As New StringFormat()
strfomart.Alignment = StringAlignment.Center
StrRight.Alignment = StringAlignment.Far
StrLeft.Alignment = StringAlignment.Near
Dim dashValues As Single() = {5, 2, 5, 2}
Dim blackPen As New Pen(Color.Black, 1)
' blackPen.DashPattern = dashValues
Dim i As Integer, j As Integer
args.Graphics.DrawString(part.ToString, sfont, Brushes.Black, New
PointF(shopnameX, shopnameY))
End Sub

Hasmorepages property fails

I have created a routine that is intended to print a variable number of lines and/or pages, based on a queue of line information previously stored. Each page prints fine, but when printing more than one page, two pages overprint. I can't see my logic error, but there must be one. A copy of the offending code is follows. Nextline.newpage is a boolean set to true to force a new page. In my text example there were six "Newpage" and "hasmorepages" was set to true six times, and the routine was exited six times. Still the output was four pages with one printing correctly, and three with two pages printed on one sheet. Any help would be greatly appreciated. By the way, this is my first question, so be kind.
Private Sub PrintLines(Sender As Object, e As PrintPageEventArgs) Handles PrintDoc.PrintPage
Dim White As String = GetARGBString(PrinterDefaultBackcolor)
Do Until Lines.Count = 0
Dim Nextline As Lineformat = Lines.Dequeue
If Nextline.NewPage Then
e.HasMorePages = True
Exit Sub
End If
With Nextline
Dim LineBackColor As String = Nextline.backColor
If LineBackColor <> White Or .Borders = True Then DrawShape(Nextline, e)
If .Text <> "" Then DrawText(Nextline, e)
End With
Loop
End Sub
Private Sub DrawShape(Line As Lineformat, E As PrintPageEventArgs)
With Line
Dim Top As Integer = .Top * 100
Dim Left As Integer = .Left * 100
Dim Width As Integer = .BackGroundWidth * 100
Dim Height As Integer = .BackGroundHeight * 100
Dim Point As New Point(Left, Top)
Dim Size As New Size(Width, Height)
Dim Rect As New Rectangle(Point, Size)
Dim TransparentFillColor As String = "00" & Strings.Right(.backColor, 6)
Dim FillColor As FullColor = GetColorFromString(.backColor)
Dim BorderPen As New Pen(Color.Black)
Dim FillBrush As New SolidBrush(FillColor.Color)
E.Graphics.FillRectangle(FillBrush, Rect)
If Line.Borders = True Then
E.Graphics.DrawRectangle(BorderPen, Rect)
End If
End With
End Sub
Private Sub DrawText(Line As Lineformat, E As PrintPageEventArgs)
With Line
Dim MyFont = SetFontStyle(.FontFamily, .FontPoints, .FontBold, .FontItalic, .FontUnderline)
Dim TextColor As FullColor = GetColorFromString(.ForeColor)
Dim MyBrush As New SolidBrush(TextColor.Color)
Dim top As Integer = .Top * 100
Dim Left As Integer = .Left * 100
Dim Width As Integer = .LineWidth * 100
Dim Height As Integer = .LineHeight * 100
Dim point As New Point(Left, top)
Dim Size As New Size(Width, Height)
Dim Rect As New RectangleF(point, Size)
Dim SF As New StringFormat()
SF.FormatFlags = TextFormatFlags.WordEllipsis
E.Graphics.DrawString(.Text, MyFont, MyBrush, Rect, SF)
End With
End Sub
End Class

What has to be done to show a marquee output with a scroll menu?

Today i continue my work, Building a menu with a vb.net console application. I found more samples to build with Windows forms. Still i try to get Basic Knowledge with the console surface.I was not able to put the following marquee text in a scroll menu, the second Code past the marquee text.
Module Module1
Dim aTimer As New System.Timers.Timer
Const marqueeText As String = "The quick brown fox... "
Dim sb As New System.Text.StringBuilder
Dim direction As Boolean = False
Sub Main()
aTimer.AutoReset = True
aTimer.Interval = 100 '1/10 second
AddHandler aTimer.Elapsed, AddressOf tick
aTimer.Start()
Console.ReadKey()
End Sub
Private Sub tick(ByVal sender As Object, ByVal e As System.Timers.ElapsedEventArgs)
Console.Clear()
If sb.Length = 0 Then sb.Append(marqueeText)
If direction Then
sb.Insert(0, sb(sb.Length - 1))
sb.Remove(sb.Length - 1, 1)
Else
sb.Append(sb(0))
sb.Remove(0, 1)
End If
Console.CursorLeft = 10 'no visible change
Console.CursorTop = 10 'visible change
Console.Write("{0}{1}", vbCr, sb.ToString)
End Sub
End Module
The marquee text Output from above is not easy to manage with the console.cursorleft command. I have no clue how to move it to the right or to put the marquee Output in the following Code, a scroll menu, on the third line.
Module Module1
Dim MenuList As New List(Of String)
Sub PrintMenu(highlight As Integer, left As Integer, top As Integer)
Dim Nickvektor() As Integer = {1, 2, 3, 4, 5}
For I = 0 To MenuList.Count - 1
Console.CursorLeft = left
Console.CursorTop = top + I
If I = highlight Then
Console.Write("{0}", "[" & Nickvektor(I) & "]")
Else
Console.Write(MenuList(I))
End If
Next
End Sub
Sub Main()
Console.CursorVisible = False
Dim x As Integer = 0
Dim Nickvektor() As String = {" "}
For counter As Integer = 0 To 0
Do
For Each s In Nickvektor
MenuList.Add(s)
Next
x += 1
Loop Until x = 5
Next
Console.SetCursorPosition(10, 16)
Console.Write("[ ]")
Dim CurrentItem As Integer = 0
Dim CurrentKey As ConsoleKey
While CurrentKey <> ConsoleKey.Enter
PrintMenu(CurrentItem, 10, 10)
CurrentKey = Console.ReadKey(True).Key
Select Case CurrentKey
Case ConsoleKey.DownArrow
CurrentItem += 1
Case ConsoleKey.UpArrow
CurrentItem -= 1
End Select
CurrentItem = (CurrentItem + MenuList.Count) Mod MenuList.Count
End While
End Sub
End Module
The menu Frame for the above Code can be used with the up and down arrows on the Keyboard.
Maybe it is to much work but i have no clue how to continue.
The first Solution for the marquee Output is an easy change of the original code. The wrap, vbCr, was the main Problem to move the text output toward the right edge oft he screen. The following code can be used to change the cursorTop Positon and also the cursorLeft Position of the Text.
Console.CursorVisible = False
Console.CursorLeft = 30
Console.CursorTop = 10
Console.Write("{0}", sb.ToString)
The heavy part are the Menu code Lines. To answer my own question some additional help was necessary.
I posted my question on the MS developer Network written in german language. With the following link it can be viewed.
For the case the link should be broken or other cases i post the code on this site.
Module Module1
Dim MenuList As New List(Of String)
Dim aTimer As New System.Timers.Timer
Const marqueeText As String = "The quick brown fox... "
Dim sb As New System.Text.StringBuilder
Dim direction As Boolean = False
Sub PrintMenu(highlight As Integer, left As Integer, top As Integer)
Dim Nickvektor() As Integer = {1, 2, 3, 4, 5}
For I = 0 To MenuList.Count - 1
Console.CursorLeft = left
Console.CursorTop = top + I
If I = highlight Then
Console.Write("{0}", "[" & Nickvektor(I) & "]")
Else
Console.Write(MenuList(I))
End If
Next
End Sub
Sub Main()
Console.CursorVisible = False
aTimer.AutoReset = True
aTimer.Interval = 100 '1/10 second
AddHandler aTimer.Elapsed, AddressOf tick
Dim x As Integer = 0
Dim Nickvektor() As String = {" "}
For counter As Integer = 0 To 0
Do
For Each s In Nickvektor
MenuList.Add(s)
Next
x += 1
Loop Until x = 5
Next
Console.SetCursorPosition(10, 16)
Console.Write("[ ]")
Dim CurrentItem As Integer = 0
Dim CurrentKey As ConsoleKey
While CurrentKey <> ConsoleKey.Enter
If CurrentItem = 2 Then ' Zero can be used to show the marquee output prompt
aTimer.Start() ' With a change to two or four the timer can be stoped:
'Else
'If aTimer.Enabled Then
' aTimer.Stop()
'End If
End If
PrintMenu(CurrentItem, 10, 10)
CurrentKey = Console.ReadKey(True).Key
Select Case CurrentKey
Case ConsoleKey.DownArrow
CurrentItem += 1
Case ConsoleKey.UpArrow
CurrentItem -= 1
End Select
CurrentItem = (CurrentItem + MenuList.Count) Mod MenuList.Count
End While
End Sub
Private Sub tick(ByVal sender As Object, ByVal e As System.Timers.ElapsedEventArgs)
If sb.Length = 0 Then sb.Append(marqueeText)
If direction Then
sb.Insert(0, sb(sb.Length - 1))
sb.Remove(sb.Length - 1, 1)
Else
sb.Append(sb(0))
sb.Remove(0, 1)
End If
Console.CursorVisible = False
Console.CursorLeft = 20
Console.CursorTop = 12 ' For the first Element CursorTop=10, fort he third 12
Console.Write("{0}", sb.ToString)
End Sub
End Module
To learn an other language like English i have to search a lot. Visual Basic Code is mostly written with English key words for the commands. I think it is easier to look up the maintainable changes for your self. To search is not every day funny.

Trouble with Timer_tick not stopping

I'm very new to programming and vb.net, trying to self teach more so as a hobby, as I have an idea for a program that I would find useful, but I am having trouble getting past this issue and I believe it is to do with the timer.
I have a form of size.(600,600) with one button of size.(450,150) that is set location(100,50) on the form. When clicked I want to move down it's own height, then add a new button in it's place. The code included below works as desired for the first two clicks, but on the third click the button keeps moving and the autoscroll bar extends. I initially thought it was the autoscroll function or the location property, but realised that as the button keeps moving, the timer hasn't stopped. I am aware that the code is probably very clunky in terms of achieving the outcome, and that there are a few lines/variables that are currently skipped over by the compiler (these are from older attempts to figure this out).
I have looked around and can't find the cause of my problem. Any help would be greatly appreciated. Apologies if the code block looks messy - first go.
Public Class frmOpenScreen
Dim intWButtons, intCreateButtonY, intCreateButtonX 'intTimerTick As Integer
Dim arrWNames() As String
Dim ctrlWButtons As Control
Dim blnAddingW As Boolean
Private Sub btnCreateW_Click(sender As System.Object, e As System.EventArgs) Handles btnCreateW.Click
'Creates new Button details including handler
Dim strWName, strWShort As String
Dim intCreateButtonY2 As Integer
Static intNumW As Integer
Dim B As New Button
strWName = InputBox("Please enter the name name of the button you are creating. Please ensure the spelling is correct.", "Create W")
If strWName = "" Then
MsgBox("Nothing Entered.")
Exit Sub
End If
strWShort = strWName.Replace(" ", "")
B.Text = strWName
B.Width = 400
B.Height = 150
B.Font = New System.Drawing.Font("Arial Narrow", 21.75)
B.AutoSizeMode = Windows.Forms.AutoSizeMode.GrowAndShrink
B.Anchor = AnchorStyles.Top
B.Margin = New Windows.Forms.Padding(0, 0, 0, 0)
'Updates Crucial Data (w name array, number of w buttons inc Create New)
If intNumW = 0 Then
ReDim arrWNames(0)
Else
intNumW = UBound(arrWNames) + 1
ReDim Preserve arrWNames(intNumW)
End If
arrWNames(intNumW) = strWShort
intNumW = intNumW + 1
intWButtons = WButtonCount(intWButtons) + 1
'updates form with new button and rearranges existing buttons
intCreateButtonY = btnCreateW.Location.Y
intCreateButtonX = btnCreateW.Location.X
‘intTimerTick = 0
tmrButtonMove.Enabled = True
‘Do While intTimerTick < 16
‘ 'blank to do nothing
‘Loop
'btnCreateW.Location = New Point(intCreateButtonX, intCreateButtonY + 150)
B.Location = New Point(intCreateButtonX, intCreateButtonY)
Me.Controls.Add(B)
B.Name = "btn" & strWShort
intCreateButtonY2 = btnCreateW.Location.Y
If intCreateButtonY2 > Me.Location.Y Then
Me.AutoScroll = False
Me.AutoScroll = True
Else
Me.AutoScroll = False
End If
'MsgBox(intCreateButtonY)
End Sub
Function WButtonCount(ByRef buttoncount As Integer) As Integer
buttoncount = intWButtons
If buttoncount = 0 Then
Return 1
End If
Return buttoncount
End Function
Public Sub tmrButtonMove_Tick(sender As System.Object, e As System.EventArgs) Handles tmrButtonMove.Tick
Dim intTimerTick As Integer
If intTimerTick > 14 Then
intTimerTick = 0
End If
If btnCreateW.Location.Y <= intCreateButtonY + 150 Then
btnCreateW.Top = btnCreateW.Top + 10
End If
intTimerTick += 1
If intTimerTick = 15 Then
tmrButtonMove.Enabled = False
End If
End Sub
End Class
So my current understanding is that the tick event handler should be increasing the timertick variable every time it fires, and that once it has hits 15 it should diable the timer and stop the button moving, but it is not doing so.
Thanks in advance.
IntTimerTick is initialized to 0 at the beginning of every Tick event. This won't happen if you declare it to be static:
Static Dim intTimerTick As Integer