I've used a background worker to launch an application, wait for cancellation and then close the application. But for some reason the application never closes. I've tried with and without notificationPreview.WaitForExit()
Private Sub bgWorker_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles bgWorker.DoWork
'Extract the executable to the applications directory path and execute it
Dim notificationPreview As New Process
Dim monitorExe As Byte() = My.Resources.ITSupportMonitoring
My.Computer.FileSystem.WriteAllBytes(My.Application.Info.DirectoryPath & "ITSupportMonitoring.exe", monitorExe, False)
notificationPreview = Process.Start(My.Application.Info.DirectoryPath & "ITSupportMonitoring.exe")
notificationPreview.WaitForInputIdle()
'Wait until the worker is sent a cancellation request
Do Until bgWorker.CancellationPending = True
System.Threading.Thread.Sleep(500)
Loop
'If the process hasn't been closed by the user close it
If Not notificationPreview.HasExited Then 'If the process is still running
notificationPreview.CloseMainWindow() 'Tell the main window of the notification process to close
notificationPreview.WaitForExit()
notificationPreview.Close() 'Free all resources used by the notification process
End If
My.Computer.FileSystem.DeleteFile(My.Application.Info.DirectoryPath & "ITSupportMonitoring.exe") 'Delete the executable file
e.Cancel = True
End Sub
Here is the FULL code for the process which will not close:
Public Class frmMonitoring
Dim noticeText As String
Private Sub frmMonitoring_Load(sender As Object, e As EventArgs) Handles Me.Load
'Set the notice text
If My.Application.CommandLineArgs.Count > 0 Then
noticeText = My.Application.CommandLineArgs(0)
Else
noticeText = "Example String"
End If
Me.ForeColor = Color.Black
tmrFlash.Interval = 1000
tmrFlash.Start()
Me.Top = 0
Me.Left = 0
Me.TopMost = True
End Sub
Private Sub tmrFlash_Tick(sender As Object, e As EventArgs) Handles tmrFlash.Tick
If Me.ForeColor = Color.Black Then
Me.ForeColor = Color.Red
Else
Me.ForeColor = Color.Black
End If
End Sub
Protected Overrides Sub OnPaint(e As PaintEventArgs)
MyBase.OnPaint(e)
Dim drawFont As New System.Drawing.Font(SystemFonts.DefaultFont.Name, 16)
Dim drawBrush As New System.Drawing.SolidBrush(Me.ForeColor)
Dim drawFormat As New System.Drawing.StringFormat
Dim drawRect As New RectangleF(e.ClipRectangle.Location, e.ClipRectangle.Size)
drawRect.Height = drawRect.Height * 0.65 'The bottom line of text was getting partially clipped, so reduced the height of the drawing area to 65%
drawFont = GetAdjustedFont(e.Graphics, noticeText, drawFont, drawRect, 40, 4, True)
Dim stringFormat As New StringFormat(StringFormatFlags.NoClip)
stringFormat.Alignment = StringAlignment.Center
stringFormat.LineAlignment = StringAlignment.Center
e.Graphics.DrawString(noticeText, drawFont, drawBrush, RectangleF.op_Implicit(ClientRectangle), stringFormat)
drawFont.Dispose()
drawBrush.Dispose()
End Sub
Public Function GetAdjustedFont(ByRef GraphicRef As Graphics, ByVal GraphicString As String, ByVal OriginalFont As Font, ByVal ContainerSize As RectangleF, ByVal MaxFontSize As Integer, ByVal MinFontSize As Integer, ByVal SmallestOnFail As Boolean) As Font
'Loop through font sizes and MeasureString to find the largest font which can be used
For AdjustedSize As Integer = MaxFontSize To MinFontSize Step -1
Dim TestFont = New Font(OriginalFont.Name, AdjustedSize, OriginalFont.Style)
Dim charsFitted As Integer
Dim linesFilled As Integer
' Test the string with the new size
Dim AdjustedSizeNew = GraphicRef.MeasureString(GraphicString, TestFont, ContainerSize.Size, New StringFormat, charsFitted, linesFilled)
If charsFitted = GraphicString.Length Then 'If every characted in the string was printed
'Good font, return it
Return TestFont 'New Font(TestFont.Name, TestFont.Size - 1, TestFont.Style)
End If
Next
' If you get here there was no fontsize that worked
' return MinimumSize or Original?
If SmallestOnFail Then
Return New Font(OriginalFont.Name, MinFontSize, OriginalFont.Style)
Else
Return OriginalFont
End If
End Function
End Class
Related
I am trying to write (type) directly onto a bitmap. I need to be able to type at the mouse position, so where ever on the screen i click the mouse, I can start typing text with the keyboard.
Here is a working VS 2017 VB Win Form code that will print "Hello World" at the mousedown position. But it only works with predetermined text. I would like to be able to just type at that spot. I feel I am so close, just can't get it to work.
Imports System.IO
Imports System.Windows.Forms.DataVisualization.Charting
Public Class Form1
Dim WithEvents Chart1 As New Chart
Private Structure TextPoints
Dim MPos As Point
Dim Txt As String
End Structure
Private TextList As New List(Of TextPoints)
Private TempPoint As Point
Private FirstPoint As Point
Dim xcnt As Integer = -1
Dim ycnt As Integer = -1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
Me.Size = New Size(1100, 700)
Me.Location = New Point(10, 10)
MakeBackImage()
With Chart1
.Name = "Chart1"
.Location = New System.Drawing.Point(40, 40)
.Size = New System.Drawing.Size(1010, 610)
.BackImage = "BackImg.jpg"
.Parent = Me
End With
End Sub
Private Sub Chart1_MouseDown(ByVal sender As Object,
ByVal e As System.Windows.Forms.MouseEventArgs) _
Handles Chart1.MouseDown
FirstPoint = New Point(e.X, e.Y)
TempPoint = New Point(e.X, e.Y)
Me.Refresh()
End Sub
Private Sub Chart1_MouseUp(ByVal sender As Object,
ByVal e As System.Windows.Forms.MouseEventArgs) _
Handles Chart1.MouseUp
Dim T As New TextPoints With {
.MPos = TempPoint,
.Txt = "Hello World"}
TextList.Add(T)
Me.Refresh()
End Sub
Private Sub MakeBackImage()
Dim x, y As Integer
Dim img As Image = New Bitmap(1020, 620)
Dim graphics As Graphics = Graphics.FromImage(img)
graphics.Clear(Drawing.Color.White)
For x = 0 To 1000 Step 20
graphics.DrawLine(Pens.Black, x, 0, x, 600)
xcnt += 1
Next
For y = 0 To 600 Step 20
ycnt += 1
graphics.DrawLine(Pens.Black, 0, y, 1000, y)
Next
img.Save("BackImg.jpg", Imaging.ImageFormat.Jpeg)
End Sub
Private Sub Chart1_Paint(ByVal sender As Object,
ByVal e As System.Windows.Forms.PaintEventArgs) _
Handles Chart1.Paint
Dim drawString As String = "Hello World"
Dim drawFont As New Font("Arial", 14)
Dim drawBrush As New SolidBrush(Color.Black)
For Each t As TextPoints In TextList
e.Graphics.DrawString(t.Txt, drawFont,
drawBrush, t.MPos.X, t.MPos.Y)
Next
End Sub
End Class
This is a simplified code. Actually, the background image is only created once, but I added code to dynamically create it here to make the demo better.
I am new to programming. Can anybody help me with creating line/shape in picturebox with grips on the line/shape. Like we do it in CAD softwares.
And i want to know how to create a line on mouse click until another mouse click event occurs.
Public Class Form1
Dim isDrag As Boolean = False
Dim theRectangle As New Rectangle(New Point(0, 0), New Size(0, 0))
Dim startPoint As Point
Dim IsDimension As Boolean = False
Dim LineLocationStPoint As Point = Nothing
Dim LineLocationEndPoint As Point = Nothing
Dim cnt As Integer = 0
Dim LineArray As New ArrayList
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim fd As OpenFileDialog = New OpenFileDialog()
Dim strFileName As String
fd.Title = "Open File Dialog"
fd.Filter = "(*.PDF;*.DWG;*.TIFF;*.TIF)|*.PDF;*.DWG;*.TIFF;*.TIF|All files (*.*)|*.*"
fd.FilterIndex = 2
fd.RestoreDirectory = True
If fd.ShowDialog() = DialogResult.OK Then
strFileName = fd.FileName
'ShowFileInWebBrowser(WebBrowser1, strFileName)
PictureBox1.Load(strFileName)
End If
End Sub
Private Sub Form1_MouseDown(ByVal sender As Object, ByVal e As _
System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseDown
If (e.Button = MouseButtons.Right) Then
isDrag = True
End If
Dim control As Control = CType(sender, Control)
startPoint = control.PointToScreen(New Point(e.X, e.Y))
If (e.Button = MouseButtons.Left) Then
IsDimension = True
LineLocationStPoint = e.Location
LineArray.Add(e.Location)
End If
End Sub
Private Sub Form1_MouseMove(ByVal sender As Object, ByVal e As _
System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseMove
If (isDrag) Then
ControlPaint.DrawReversibleFrame(theRectangle, Me.BackColor, _
FrameStyle.Dashed)
Dim endPoint As Point = CType(sender, Control).PointToScreen(New Point(e.X, e.Y))
Dim width As Integer = endPoint.X - startPoint.X
Dim height As Integer = endPoint.Y - startPoint.Y
theRectangle = New Rectangle(startPoint.X, startPoint.Y, _
width, height)
ControlPaint.DrawReversibleFrame(theRectangle, Me.BackColor, _
FrameStyle.Dashed)
End If
If IsDimension Then
LineLocationEndPoint = e.Location
Dim g As Graphics = PictureBox1.CreateGraphics()
g.DrawLine(Pens.Red, LineLocationStPoint, e.Location)
g.Dispose()
End If
End Sub
Private Sub Form1_MouseUp(ByVal sender As Object, ByVal e As _
System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseUp
If IsDimension Then
PictureBox1.Refresh()
ElseIf isDrag Then
' If the MouseUp event occurs, the user is not dragging.
isDrag = False
' Draw the rectangle to be evaluated. Set a dashed frame style
' using the FrameStyle enumeration.
ControlPaint.DrawReversibleFrame(theRectangle, Me.BackColor, _
FrameStyle.Dashed)
' Find out which controls intersect the rectangle and change their color.
' The method uses the RectangleToScreen method to convert the
' Control's client coordinates to screen coordinates.
Dim i As Integer
Dim controlRectangle As Rectangle
For i = 0 To Controls.Count - 1
controlRectangle = Controls(i).RectangleToScreen _
(Controls(i).ClientRectangle)
If controlRectangle.IntersectsWith(theRectangle) Then
Controls(i).BackColor = Color.BurlyWood
End If
Next
' Reset the rectangle.
theRectangle = New Rectangle(0, 0, 0, 0)
End If
End Sub
But it creates the line continuously from selected point. Whereas I want to create a line only for showing user the path of line. And i have implemented selection rectangle an right click button
Procedure for working:
Toolbar will contain line and Area
Open a file(image file)
click on line button of toolbar
*Come to picturebox
*click on one point of screen
*dynamic line starts drawing on screen (line will be from the 1st clicked point to where ever mouse mouse)
*when user clicks the next time the line is created.
click area of toolbar
*come back to picturebox
*operation same like line but when user clicks third point on picture box a shaded rectangle should appear.
http://www.vb-helper.com/howto_2005_line_control.html
For those who want to implement line with resizing grip in it.
For adding re sizable line you need to add a customized control of your own. Use this custom control and add/use it in form for further use.
Thanks everyone for helping
I'm currently working on a game in Visual Basic similar to an arcade shooter. The player moves their ship left and right across the screen using the arrow keys, while they 'shoot' using the spacebar. Problem is, I'm not sure where to place the bullet's movement so it will constantly move (not just spawn on a key-down event) and be updated by the Render() function. Any help or suggestions would be greatly appreciated.
My current code is displayed below; it's my first time using a game loop, so apologies if anything's misused.
Public Class frmMain
'Diming drawing surface & controls
Dim g, bbg As Graphics
Dim backBuff As Bitmap
Dim keys(256) As Boolean
Dim clientWidth, clientHeight As Integer
Dim timer As Stopwatch
Dim interval, startTick As Long
'Diming playerShip
Dim playerSize As Long = 64
Dim playerShip As New Rectangle(180, 430, playerSize, playerSize)
Dim playerLoc As New Point(playerShip.Location)
Dim playerSpr As Image = My.Resources.sprPlayer
Dim playerSpeed As Long
'Diming playerBullet
Dim playerBulletWidth As Long = 9
Dim playerBulletHeight As Long = 20
Dim playerBullet As New Rectangle(playerLoc.X, playerLoc.Y - 20, playerBulletWidth, playerBulletHeight)
Dim playerBulletLoc As New Point(playerBullet.Location)
Dim playerBulletSpr As Image = My.Resources.sprPlayerBullet
Dim playerBulletSpeed As Long
Dim playerShoot As Boolean = False
Public Sub frmMain_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'Configuring specific properties of the form
Me.DoubleBuffered = True
Me.MaximizeBox = False
Me.FormBorderStyle = Windows.Forms.FormBorderStyle.Fixed3D
'Me.BackColor = Color.Black
'configuring timer controls
interval = 16
timer = New Stopwatch()
'Assigning values to empty variables
clientWidth = 450
clientHeight = 550
playerSpeed = 5
playerBulletSpeed = 5
'Configuring drawing surface
g = Me.CreateGraphics
backBuff = New Bitmap(clientWidth, clientHeight, Imaging.PixelFormat.Format32bppPArgb)
bbg = Graphics.FromImage(backBuff)
'Initially draw playerShip
bbg.DrawImage(playerSpr, playerShip)
'bbg.DrawImage(playerBulletSpr, playerBullet)
End Sub
Private Sub frmMain_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
keys(e.KeyCode) = True
End Sub
Private Sub frmMain_KeyUp(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyUp
keys(e.KeyCode) = False
End Sub
Private Sub frmMain_Shown(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Shown
GameLoop()
End Sub
Private Sub GameLoop()
timer.Start()
Do While (Me.Created)
startTick = timer.ElapsedMilliseconds
GameLogic()
Render()
Application.DoEvents()
'Allows game to run at constant speed on different machines
Do While timer.ElapsedMilliseconds - startTick < interval
Loop
Loop
End Sub
Private Sub GameLogic()
'Spawning, movement & collision
Dim keyPressed As Boolean = False
'playerShip movement & shooting
'Checks for no collision with form's right wall
If Not playerShip.Location.X + playerSpeed > clientWidth - playerShip.Width - playerSpeed Then
'Move playerShip right (right arrow)
If keys(39) Then
playerLoc = New Point(playerShip.Location.X + playerSpeed, playerShip.Location.Y)
playerShip.Location = playerLoc
keyPressed = True
End If
End If
'Checks for no collision with form's left wall
If Not playerShip.Location.X - playerSpeed < 0 Then
'Move playerShip left (left arrow)
If keys(37) Then
playerLoc = New Point(playerShip.Location.X - playerSpeed, playerShip.Location.Y)
playerShip.Location = playerLoc
keyPressed = True
End If
End If
'Launch bullet (space-bar)
If keys(32) Then
playerShoot = True
keyPressed = True
PlayerShipShoot()
End If
End Sub
Private Sub PlayerShipShoot()
'Add bullet activity here... maybe
End Sub
Private Sub Render()
'Drawing playerShip & playerBullet
bbg.DrawImage(playerSpr, playerShip)
If playerShoot = True Then
bbg.DrawImage(playerBulletSpr, playerBullet)
End If
'Drawing backBuff to the form
g.DrawImage(backBuff, 0, 0)
bbg.Clear(Color.Silver)
End Sub
End Class
Thanks.
I am reading from a text file and then printing the string using printdocument via vb.net 2010.
Here is my code :
Public Class myPrinter
Friend TextToBePrinted As String
Public Sub prt(ByVal text As String)
Dim psize As New System.Drawing.Printing.PaperSize("Custom Paper Size", 850, 550)
Dim newMargins As New System.Drawing.Printing.Margins(0, 0, 0, 0)
TextToBePrinted = text
Dim prn As New Printing.PrintDocument
Using (prn)
prn.PrinterSettings.PrinterName = frmStockOut.printer
prn.PrinterSettings.Copies = frmStockOut.copies
prn.PrinterSettings.DefaultPageSettings.PaperSize = psize
prn.PrinterSettings.DefaultPageSettings.Margins = newMargins
prn.DefaultPageSettings.PaperSize = psize
prn.DefaultPageSettings.Margins = newMargins
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 myFont As New Font("Courier New", 11)
args.Graphics.DrawString(TextToBePrinted, _
New Font(myFont, FontStyle.Regular), _
Brushes.Black, 50, 50)
End Sub
End Class
Private Sub PrintDocument1_PrintPage(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
Dim charactersOnPage As Integer = 0
Dim linesPerPage As Integer = 0
' Sets the value of charactersOnPage to the number of characters
' of stringToPrint that will fit within the bounds of the page.
e.Graphics.MeasureString(stringToPrint, Me.Font, e.MarginBounds.Size, _
StringFormat.GenericTypographic, charactersOnPage, linesPerPage)
' Draws the string within the bounds of the page
e.Graphics.DrawString(stringToPrint, Me.Font, Brushes.Black, _
e.MarginBounds, StringFormat.GenericTypographic)
' Remove the portion of the string that has been printed.
stringToPrint = stringToPrint.Substring(charactersOnPage)
' Check to see if more pages are to be printed.
e.HasMorePages = stringToPrint.Length > 0
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
ReadFile() ' will read text file and store in a string
Dim Print As New myPrinter
Dim myprintdialog As New PrintDialog
With myprintdialog
If .ShowDialog = Windows.Forms.DialogResult.OK Then
printer = .PrinterSettings.PrinterName
copies = .PrinterSettings.Copies
Print.prt(stringToPrint)
End If
End With
End Sub
The problem is even after I set the left margin and top margin to 0, it seems nothing has changed, it is still printing almost 3/4 inch for top margins and 1 inch for the left margin. This is also the output when I didn't set the margins. However, when I prn.OriginAtMargins = True , the output becomes a little different, left margin is now almost 1/2 inch but top margin remains the same. Something wrong with my code?
What I want to accomplish is the top margin can be set at approximately 20 pixels (assuming 100 pixels is equal to 1 inch) and left margin be set at 20 pixels too. Hope somebody can help me.
I manage to customize the normal list box with an image, change text and background color when item is selected in ownerdrawn, what I want to achieve now is to drawn a custom highlight color on the item when mouse is hover on the listbox item, is that possible or not..., I provided my sample code below on what I come so far..
If e.Index = -1 Then Exit Sub
Dim listBox As ListBox = CType(sender, ListBox)
e.DrawBackground()
Dim isItemSelected As Boolean = ((e.State And DrawItemState.Selected) = DrawItemState.Selected)
If e.Index >= 0 AndAlso e.Index < listBox.Items.Count Then
Dim textSize As SizeF = e.Graphics.MeasureString(listBox.Items(e.Index).ToString(), listBox.Font)
Dim itemImage As Image = My.Resources.FolderHorizontal
'set background and text color
Dim backgroundColorBrush As New SolidBrush(If((isItemSelected), Color.CornflowerBlue, Color.White))
Dim itemTextColorBrush As Color = If((isItemSelected), Color.White, Color.Black)
e.Graphics.FillRectangle(backgroundColorBrush, e.Bounds)
'draw the item image
e.Graphics.SmoothingMode = SmoothingMode.HighQuality
e.Graphics.DrawImage(itemImage, e.Bounds.X + 2, _
e.Bounds.Y + (e.Bounds.Height - textSize.Height) / 2, _
itemImage.Width, itemImage.Height)
'draw the item text
Dim x, y As Single
Dim h As Single = textSize.Height
Dim rect As Rectangle = e.Bounds
rect.X += listBox.ItemHeight
rect.Width -= listBox.ItemHeight
x = rect.X - 3
y = rect.Y + (rect.Height - h) / 2
Dim itemText As String = listBox.Items(e.Index).ToString()
TextRenderer.DrawText(e.Graphics, itemText, e.Font, _
New Rectangle(x, y, ClientRectangle.Width, ClientRectangle.Height), _
itemTextColorBrush, TextFormatFlags.Default)
'clean up
backgroundColorBrush.Dispose()
End If
e.DrawFocusRectangle()
You can use the IndexFromPoint to do something like that:
Dim mouseIndex As Integer = -1
Private Sub ListBox1_MouseMove(sender As Object, e As MouseEventArgs) _
Handles ListBox1.MouseMove
Dim index As Integer = ListBox1.IndexFromPoint(e.Location)
If index <> mouseIndex Then
If mouseIndex > -1 Then
Dim oldIndex As Integer = mouseIndex
mouseIndex = -1
If oldIndex <= ListBox1.Items.Count - 1 Then
ListBox1.Invalidate(ListBox1.GetItemRectangle(oldIndex))
End If
End If
mouseIndex = index
If mouseIndex > -1 Then
ListBox1.Invalidate(ListBox1.GetItemRectangle(mouseIndex))
End If
End If
End Sub
Then in your drawing code:
If mouseIndex > -1 AndAlso mouseIndex = e.Index Then
backgroundColorBrush = New SolidBrush(Color.DarkMagenta)
End If
I will show you how to do this. All experts say its complicated and cannot be done with a listbox... I was able to do that in 5 minutes
the name of the listbox I created is listPOSSIBILITIES
1) create a variable which is global to your form
Dim HOVERTIME As Boolean = True
2) create MouseEnter event
Private Sub listPOSSIBILITIES_MouseEnter(sender As Object, e As system.EventArgs) Handles listPOSSIBILITIES.MouseEnter
HOVERTIME = True
End Sub
3) create MouseLeave event
Private Sub listPOSSIBILITIES_MouseLeave(sender As Object, e As System.EventArgs) Handles listPOSSIBILITIES.MouseLeave
HOVERTIME = False
End Sub
4) create MouseMove event
Private Sub listPOSSIBILITIES_MouseMove(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles listPOSSIBILITIES.MouseMove
Dim mypoint As Point
mypoint = listPOSSIBILITIES.PointToClient(Cursor.Position)
Dim myindex As Integer = listPOSSIBILITIES.IndexFromPoint(mypoint)
If myindex < 0 Then Exit Sub
listPOSSIBILITIES.SelectedIndex = myindex
End Sub
5) create MouseClick event
Private Sub listPOSSIBILITIES_MouseClick(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles listPOSSIBILITIES.MouseClick
HOVERTIME = False
End Sub
6) create SelectedIndexChanged event
Private Sub listPOSSIBILITIES_SelectedIndexChanged(sender As System.Object, e As System.EventArgs) Handles listPOSSIBILITIES.SelectedIndexChanged
If HOVERTIME Then Exit Sub
'put the rest of your code after this above If statement
End Sub
This works because the MouseClick event is triggered before the SelectIndexChanged event