Hey all i have this code here:
Dim p As Process = Process.GetProcessesByName("Cal").FirstOrDefault
Dim target_hwnd As Long = FindWindow(vbNullString, "Calculator")
If p IsNot Nothing Then
SetWindowPos(target_hwnd, 0, winSize(0), winSize(1), winSize(2), winSize(3), 0)
AppActivate(p.Id)
Dim img As New Bitmap(145, 145) 'size fo the caption area
Dim gr As Graphics = Graphics.FromImage(img)
'sets the offsets and use image size to set region
gr.CopyFromScreen(New Point(winSize(0) + 44, winSize(1) + 179), Point.Empty, img.Size)
img.Save("test.jpg", Drawing.Imaging.ImageFormat.Jpeg)
Process.Start("test.jpg")
End If
As long as i have the window in view it takes the screen shot just fine without any problems. However when i move the form off screen (where i am unable to see it) it only captures a black image.
I've been trying this code out:
Private Declare Function PrintWindow Lib "user32.dll" (ByVal hwnd As IntPtr, ByVal hdcBlt As IntPtr, ByVal nFlags As UInt32) As Boolean
Dim screenCapture As Bitmap
Dim otherForm As New Form
Private Sub CaptureScreen()
Dim target_hwnd As Long = FindWindow(vbNullString, "Calculator")
SetWindowPos(target_hwnd, 0, winSize(0), winSize(1), winSize(2), winSize(3), 0)
screenCapture = New Bitmap(245, 245)
Dim g As Graphics = Graphics.FromImage(screenCapture)
Dim hdc As IntPtr = g.GetHdc
Form1.PrintWindow(target_hwnd, hdc, Nothing)
g.ReleaseHdc(hdc)
g.Flush()
g.Dispose()
If IO.File.Exists("d:\test.jpg") Then
IO.File.Delete("d:\test.jpg")
End If
screenCapture.Save("d:\test.jpg", Drawing.Imaging.ImageFormat.Jpeg)
End Sub
Private Sub Button3_Click(sender As System.Object, e As System.EventArgs) Handles Button3.Click
CaptureScreen()
End Sub
Now the above code DOES capture an image even when the window is off screen. The problem with the code above is that i can't tell it to only capture an area within that window that i was able to do with the CopyFromScreen i first posted.
Is this possible using the PrintWindow?
I was able to do this:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim fileName = "Calculator.jpg"
Dim fileNameCrop = "Calculator-crop.jpg"
' |--b|---|x|
' | | | a|-Form Left to image area
' | V | | b|-Form Top to image area
' a-->[c] | | | c|-Image area Width to capture
' | | | | | c|-Image area Height to capture
' |_________| V V V V
Dim CropRect As New Rectangle(97, 189, 36, 29)
Dim OrignalImage = Image.FromFile(fileName)
Dim CropImage = New Bitmap(CropRect.Width, CropRect.Height)
Using grp = Graphics.FromImage(CropImage)
grp.InterpolationMode = Drawing2D.InterpolationMode.NearestNeighbor
grp.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
grp.DrawImage(OrignalImage, New Rectangle(0, 0, CropRect.Width, CropRect.Height), CropRect, GraphicsUnit.Pixel)
CropImage.Save(fileNameCrop)
End Using
OrignalImage.Dispose()
CropImage.Dispose()
'delete org image
If FileIO.FileSystem.FileExists(fileName) Then FileIO.FileSystem.DeleteFile(fileName)
End Sub
And just crop out the area after i saved the forms image from the first code posted in the OP.
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 making an arcade shooting game in Visual Basic which spawns enemies at the top of the form which move vertically downward toward the player. My current code spawns the enemy, but any attempt to add another 'enemyShip' to the 'enemyShips' array fails and hence, only a single enemy is spawned. Any help as to how to spawn multiple enemies would be appreciated. My current code is below:
Dim enemySize As Integer = 32
Dim enemySpawn As New Point(150, 0)
Dim enemyShip As New Rectangle(150, 0, enemySize, enemySize)
Dim enemyLoc As New Point(enemyShip.Location)
Dim enemySpr As Image = My.Resources.sprEnemy32x32
Dim enemySpeed As Integer = 5
Dim enemyShips(-1) As Rectangle
Dim intCount As Integer = 0
Dim g, bbg As Graphics
Dim backBuff As Bitmap
Private Sub frmMain_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
g = Me.CreateGraphics
backBuff = New Bitmap(300, 300, Imaging.PixelFormat.Format32bppPArgb)
bbg = Graphics.FromImage(backBuff)
tmrSpawn.Enabled = True
tmrRender.Enabled = True
End Sub
Private Sub tmrSpawn_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tmrSpawn.Tick
SpawnEnemy()
End Sub
Private Sub SpawnEnemy()
'Add enemyShip to index in array enemyShips
'Add 1 to enemyShip's index so new rectangle is stored in the next index
ReDim Preserve enemyShips(intCount)
enemyShips(intCount) = enemyShip
intCount += 1
'Move newly created enemyShip vertically downward on the form
For Each Me.enemyShip In enemyShips
enemyLoc = New Point(enemyShip.Location.X, enemyShip.Location.Y + enemySpeed)
enemyShip.Location = enemyLoc
Next
End Sub
Private Sub tmrRender_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tmrRender.Tick
bbg.DrawImage(enemySpr, enemyShip)
g.DrawImage(backBuff, 0, 0)
bbg.Clear(Color.Gray)
End Sub
I am using Visual Studio express 2013, VB. Simplifying the problem as much as I can, I have a form with a tab control that has 2 tab pages. I want to print both tab pages on the click of one button. Currently I am trying to use CreateGraphics on the individual tabs but I just get the first tab printing on both pages. Here is my code, can anyone please see what I am doing wrong or if I am on completely the wrong lines. It looks to me like the CreateGraphics is not retrieving the right tabpages graphics.
Private Declare Auto Function BitBlt Lib "gdi32.dll" (ByVal hdcDest As IntPtr, ByVal nXDest As Integer, ByVal nYDest As Integer, ByVal nWidth As Integer, ByVal nHeight As Integer, ByVal hdcSrc As IntPtr, ByVal nXSrc As Integer, ByVal nYSrc As Integer, ByVal dwRop As System.Int32) As Boolean
Private Const SRCCOPY As Integer = &HCC0020
Private PagePrinting As Integer
Private Sub ToolStripButton2_Click(sender As Object, e As EventArgs) Handles ToolStripButton2.Click
If PrintDialog1.ShowDialog() = DialogResult.OK Then
PagePrinting = 0
PrintDocument1.Print()
End If
End Sub
Private Sub PrintDocument1_PrintPage(sender As Object, e As PrintPageEventArgs) Handles PrintDocument1.PrintPage
If PagePrinting = 0 Then
e.Graphics.DrawImage(GetImage1(), e.MarginBounds)
Else
e.Graphics.DrawImage(GetImage2(), e.MarginBounds)
End If
PagePrinting = PagePrinting + 1
If PagePrinting = 2 Then e.HasMorePages = False Else e.HasMorePages = True
End Sub
Private Function GetImage1() As Bitmap
Dim me_gr As Graphics = Me.BillTabControl.TabPages("PAGE1").CreateGraphics
Dim bm As New Bitmap(Me.BillTabControl.TabPages("PAGE1").ClientSize.Width, Me.BillTabControl.TabPages("PAGE1").ClientSize.Height, me_gr)
Dim bm_gr As Graphics = Graphics.FromImage(bm)
Dim bm_hdc As IntPtr = bm_gr.GetHdc
Dim me_hdc As IntPtr = me_gr.GetHdc
BitBlt(bm_hdc, 0, 0, Me.BillTabControl.TabPages("PAGE1").ClientSize.Width, Me.BillTabControl.TabPages("PAGE1").ClientSize.Height, me_hdc, 0, 0, SRCCOPY)
me_gr.ReleaseHdc(me_hdc)
bm_gr.ReleaseHdc(bm_hdc)
GetImage1 = bm
End Function
Private Function GetImage2() As Bitmap
Dim me_gr As Graphics = Me.BillTabControl.TabPages("PAGE2").CreateGraphics
Dim bm As New Bitmap(Me.BillTabControl.TabPages("PAGE2").ClientSize.Width, Me.BillTabControl.TabPages("PAGE2").ClientSize.Height, me_gr)
Dim bm_gr As Graphics = Graphics.FromImage(bm)
Dim bm_hdc As IntPtr = bm_gr.GetHdc
Dim me_hdc As IntPtr = me_gr.GetHdc
BitBlt(bm_hdc, 0, 0, Me.BillTabControl.TabPages("PAGE2").ClientSize.Width, Me.BillTabControl.TabPages("PAGE2").ClientSize.Height, me_hdc, 0, 0, SRCCOPY)
me_gr.ReleaseHdc(me_hdc)
bm_gr.ReleaseHdc(bm_hdc)
GetImage2 = bm
End Function
Have you tried selecting the second tab before creating the graphics with SelectTab?
You may also want to add a breakpoint to this line to make sure it is being called:
e.Graphics.DrawImage(GetImage2(), e.MarginBounds)
Here is the code that works.
Private Function GetImage1() As Bitmap
Dim bm As New Bitmap(Me.BillTabControl.TabPages("PAGE1").ClientSize.Width, Me.BillTabControl.TabPages("PAGE1").ClientSize.Height)
Me.BillTabControl.TabPages("PAGE1").DrawToBitmap(bm, Me.BillTabControl.TabPages("PAGE1").ClientRectangle)
GetImage1 = bm
End Function
Private Function GetImage2() As Bitmap
Dim bm As New Bitmap(Me.BillTabControl.TabPages("PAGE2").ClientSize.Width, Me.BillTabControl.TabPages("PAGE2").ClientSize.Height)
Me.BillTabControl.TabPages("PAGE2").DrawToBitmap(bm, Me.BillTabControl.TabPages("PAGE2").ClientRectangle)
GetImage2 = bm
End Function
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.