Move image from picturebox to another picturebox in another form - vb.net

im trying to move an image from a PictureBox to another PictureBox in another Form that was captured by a WebCam, but my code is not working.
Public Class Form12
Private _capture As Emgu.CV.Capture
Private _captureInProgress As Boolean
Dim form23 As Form23
Private Sub btnSave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSave.Click
form23.SetPictureBoxImage(captureImageBox.Image)
form23.Show()
End Sub
Private Sub captureButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles captureButton.Click
If (_capture Is Nothing) Then
Try
_capture = New Emgu.CV.Capture
Catch excpt As NullReferenceException
MessageBox.Show(excpt.Message)
End Try
End If
If (Not _capture Is Nothing) Then
If _captureInProgress Then
Me.captureButton.Text = "Start Capture"
RemoveHandler Application.Idle, New EventHandler(AddressOf Me.ProcessFrame)
Else
captureButton.Text = "Capture"
AddHandler Application.Idle, New EventHandler(AddressOf Me.ProcessFrame)
End If
_captureInProgress = Not _captureInProgress
End If
End Sub
Private Sub ProcessFrame(ByVal sender As Object, ByVal arg As EventArgs)
Dim frame As Emgu.CV.Image(Of Emgu.CV.Structure.Bgr, Byte) = Me._capture.QueryFrame
Dim grayFrame As Emgu.CV.Image(Of Emgu.CV.Structure.Gray, Byte) = frame.Convert(Of Emgu.CV.Structure.Gray, Byte)()
Dim smoothedGrayFrame As Emgu.CV.Image(Of Emgu.CV.Structure.Gray, Byte) = grayFrame.PyrDown.PyrUp
captureImageBox.Image = frame.Bitmap
End Sub
Private Sub ReleaseData()
If (Not _capture Is Nothing) Then
_capture.Dispose()
End If
End Sub
2nd Form
Public Class Form23
Public Sub SetPictureBoxImage(ByVal image As Bitmap)
PictureBox1.Image = image
End Sub
End Class
all the webcam thing is working, just the transfer of image is not. sorry just a newbie here. just got this codes from a tutorial.Thanks!

Forms are classes - it says so at the top of all of them:
Public Class Form817
So, an instance of them should be created and thats is what your code should use everywhere:
Dim myFrm As Form817 ' DECLARES the variable
myFrm = New Form817 ' Initialize myFrm as an instance of Form817
' short method:
Dim myFrm As New Form817
The problem is here:
form23.SetPictureBoxImage(captureImageBox.Image)
form23.Show()
VB is not case sensitive AND your code did not create and instance, so the first line is referencing the class, not the instance. When you normally do something like Form23.Show - without creating an instance, VB creates one for you with the same name. This is called the default form instance and should be avoided (always).
Your image transfer fails because the code references one thing (Form23), but another is shown (a new instance of Form23).

Related

VB.net WindowsForm changing then [System.Data.MissingPrimaryKeyException]

-I created 2 forms after I use hide() and show() to switch between form.
-In the 2nd form, I create datatable (bond to datagrid) and primary key for datatable to use find().
-After I press [BACK] button form 2nd form to 1st form (use hide() and show() function) and come back to use 2nd form application again. the runtime error show this [System.Data.Missing.PrimaryKeyException: Table doesn't have a primary key]
1st Form
Public Class MainMenu
Public MainForm As MainMenu
Public AssetCheckForm As AssetCheck
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
AssetCheckForm.Show()
MainForm.Hide()
End Sub
Public Sub MainMenu_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
MainForm = New MainMenu()
AssetCheckForm = New AssetCheck()
End Sub End Class
2nd Form
Dim dtAsset As New DataTable("AssetTable")
Public Sub readData()
If readStatus = 0 Then
Try
Dim splits As String()
Using sr As StreamReader = New StreamReader(inputcsvname)
'read the first line for the table columns
splits = sr.ReadLine.Split(","c)
For i As Integer = 0 To UBound(splits)
dtAsset.Columns.Add(splits(i))
Next
'read the rest of the lines to add rows
Do While Not sr.EndOfStream
splits = sr.ReadLine.Split(","c)
dtAsset.Rows.Add(splits)
Loop
End Using
Catch ex As Exception
Finally
End Try
dtAsset_display = dtAsset.Copy()
totalcount.Text = getRowsCount(dtAsset_display)
dtAsset.Columns("AsstCode").Unique = True
dtAsset.PrimaryKey = New DataColumn() {dtAsset.Columns("AsstCode")}
'bind display part to DataGrid
DataGrid1.DataSource = dtAsset
Private Sub BackButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonF4.Click
clearData()
MainMenu.MainForm.Show()
MainMenu.AssetCheckForm.Hide()
End Sub
I think I missed something about VB.net WinForm concept.
Does anyone know what this error means?
The fact that you are calling MainForm = New MainMenu() in MainForm it means you now have two instances of MainForm.
So then when you call MainMenu.MainForm.Show() you are showing your new instance, not the existing one.
You need to change this around so that you store the reference to the existing MainForm in your AssetCheckForm form.
Something like this:
Public Class MainMenu
Private AssetCheckForm As AssetCheckForm
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Me.AssetCheckForm = New AssetCheckForm
Me.AssetCheckForm.MainMenu = Me
Me.Hide()
Me.AssetCheckForm.Show()
End Sub
End Class
Public Class AssetCheckForm
Friend MainMenu As MainMenu
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Me.MainMenu.Show()
Me.Close()
End Sub
End Class

Changing a Control's property via a delegate

First off, pardon me if my English is bad, I'm not a native English speaker.
I'm fairly new to programming and I'm trying to teach myself VB.NET
I came across a problem while trying to learn about Delegates. (see code below)
What I'm trying to accomplish is to update a specified Control's text property via a thread. However, as soon as I start the thread, I get an ArgumentException Error. I have completely no idea what's wrong. Anybody have an idea what i've done wrong here?
Public Class Form1
Delegate Sub myDelegate1(ByVal s_Name As Control, ByVal s_txt As String)
Public txtUpdate As New myDelegate1(AddressOf upd_ControlTextProperty)
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Label1.Text = vbnullstring
End Sub
Private Sub upd_ControlTextProperty(ByVal ControlName As Control, ByVal txt As String)
ControlName.Text = txt
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim thread1 As New Threading.Thread(AddressOf threadstart)
thread1.IsBackground = True
thread1.Start()
End Sub
Private Sub threadstart()
Me.Invoke(Me.txtUpdate, New Object(), {Label1, "This is Label 1"})
End Sub
End Class
As TheValyreanGroup said, your delegate is supposed to accept two arguments, and you pass it three :
Me.Invoke(Me.txtUpdate, New Object(), {Label1, "This is Label 1"})
^-1--------^ ^-2--------^ ^-3-----------------------^
So just remove the New Object() thing, and transform this {Label1, ...} into just a string :
Me.Invoke(Me.txtUpdate, "This is Label 1")
OK Better that way.
On a second hand, what you are doing is not very usefull.
You create a new Thread from your UI Thread.
With this new Thread, you invoke back the UI Thread and you stop your Thread...
Remember that a Control can be updated only by the Thread who created the Form (the UI thread).
Unless you have a good reason to work with your background thread, you can resume your code to :
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Label1.Text = vbnullstring
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Label1.Text = "This is Label 1"
End Sub
End Class
UPDATE
(from comments)
To make it more clear, here is a schema (that I took on https://androidkennel.org/android-networking-tutorial-with-asynctask/, if any restrictions apply I will remove the image)
The Main UI Thread is used for things :
React to user events (clicks, inputs...) and start background threads that will do the process
Update the User Interface when the background thread is over or during the task.
When I say what you're doing is not usefull is because your background thread does not do any processing, it just signals the UI thread to update the UI...
I would try this approach. upd_ControlTextProperty can be called successfully either from the UI thread or your new thread.
Public Class Form1
Delegate Sub myDelegate1(ByVal s_Name As Control, ByVal s_txt As String)
Public txtUpdate As New myDelegate1(AddressOf upd_ControlTextProperty)
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Label1.Text = ""
End Sub
Private Sub upd_ControlTextProperty(ByVal ControlName As Control, ByVal txt As String)
If Me.InvokeRequired = True Then
Me.Invoke(txtUpdate, New Object() {ControlName, txt})
Else
ControlName.Text = txt
End If
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim thread1 As New Threading.Thread(AddressOf threadstart)
thread1.IsBackground = True
thread1.Start()
End Sub
Private Sub threadstart()
upd_ControlTextProperty(Label1, "This is Label 1")
End Sub
End Class

VB.net difficulty in using RedirectStandardInput for my program

I am trying to make a simple chat program in vb using netcat. Here is my code
Public Class Form1
Dim p As New Process
Dim pstrt As New System.Diagnostics.ProcessStartInfo
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
Go()
End Sub
Sub Go()
pstrt.FileName = "cmd.exe"
pstrt.Arguments = "/c nc -l -p1234"
pstrt.UseShellExecute = False
pstrt.RedirectStandardOutput = True
pstrt.RedirectStandardInput = True
AddHandler p.OutputDataReceived, AddressOf yo
p.StartInfo = pstrt
p.Start()
p.BeginOutputReadLine()
End Sub
Sub yo(ByVal sender As Object, ByVal e As DataReceivedEventArgs)
UpdateTextBox(e.Data)
End Sub
Private Delegate Sub UpdateTextBoxDelegate(ByVal Text As String)
Private Sub UpdateTextBox(ByVal tot As String)
If Me.InvokeRequired Then
Dim delgt As New UpdateTextBoxDelegate(AddressOf UpdateTextBox)
Dim args As Object() = {tot}
Me.Invoke(delgt, args)
Else
RichTextBox1.Text &= tot & Environment.NewLine
End If
End Sub
Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click
'Shell(TextBox1.Text)
'Console.WriteLine(TextBox1.Text)
p.StandardInput.WriteLine(TextBox1.Text)
End Sub
End Class
The form has a richtextbox, a textbox and two buttons.
The problem is that:
when using redirectstandardinput, the received text is not displayed in richtextbox but the sent text can be viewed by the receiver.
when I don't redirectstandardinput then the received text is displayed in the richtextbox but the sent text cannot be viewed by the receiver.
I have also tried to use the commented code (for button2 click code) to use to send text when not using redirectstandardinput.
For me, your code is working correctly without changes, with
pstrt.RedirectStandardOutput = True
pstrt.RedirectStandardInput = True
See the screenshot:
I guess your problem can be with netcat.
Try with simple commands first like seen on the sample.
Try on another machine. I tested on Windows 8.0, .NET 4.0.

Custom control mybase.OnTextChanged not firing

I have a custom text box control which validates input (striped out unwanted chars). This works fine apart from when I also want to do further processing on an implementation of the control.
Example I have 3 "specialTextbox"s on a form. sText1, sText2 and sText3. sText1 & sText2 work as as intended. However, I need to make changes on the forum when the value of sText3 is changed, so I have a handler in the form to handle the ctext changed event:
Private Sub sText3(sender As Object, e As EventArgs) Handles sText3.TextChanged
'do some stuff here
End Sub
However this routine appears to override the OnTextChanged method of the custom text box. I have tried includeing a call to MyBase.OnTextChanged, but this still doesn't cascade up and no matter what I do I can't seem to get the text box to do its validation duties.
Must be something really simple, but I'm stumped!
Here is a class which overrides textbox
Public Class restrictedTextBox
Inherits Windows.Forms.TextBox
Protected validChars As List(Of Char)
Public Sub New(ByVal _validChars As List(Of Char))
MyBase.New()
validChars = _validChars
End Sub
Public Sub setValidChars(ByVal chrz As List(Of Char))
validChars = chrz
End Sub
Protected Overrides Sub OnTextChanged(e As System.EventArgs)
MyBase.OnTextChanged(e)
Dim newValue As String = ""
For Each c As Char In Me.Text.ToCharArray
Dim valid As Boolean = False
For Each c2 As Char In validChars
If c = c2 Then valid = True
Next
If valid Then newValue &= c.ToString
Next
Me.Text = newValue
End Sub
End Class
Here is a form which has a a custom textbox
Public Class frmNewForm
Private Sub btnOK_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnOK.Click
MessageBox.Show("the text from the restricted text is: " & txtRestricted.Text)
End Sub
End Class
Here is a form with a custom text box, which implements the TextChanged event
Public Class frmNewForm2
Private Sub btnOK_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnOK.Click
MessageBox.Show("the text from the restricted text is: " & txtRestricted.Text)
End If
Private Sub txtRestricted_TextChanged(sender As Object, e As EventArgs) Handles txtRestricted.TextChanged
'now that I have implemented this method, the restrictedTextBox.OnTextChanged() doesn't fire - even if I call MyBase.OnTextChanged(e)
'just to be completely clear. the line of code below DOES get executed. But the code in restrictedTextBox.vb does NOT
lblAwesomeLabel.Text=txtRestricted.Text
End Sub
End Class
It fires, but probably not the way you are implementing it.
Your sample code does not have an empty constructor for the textbox, which means you are most likely not using the designer when you are adding the textbox to the form.
But your form shows it was created by the designer:
Private Sub txtRestricted_TextChanged(sender As Object, e As EventArgs) _
Handles txtRestricted.TextChanged
End Sub
That's not possible with your posted code. If you are creating "new" controls programmatically, then you need to wire up the events programmatically, too.
Drop the handler and just leave the stub:
Private Sub txtRestricted_TextChanged(sender As Object, e As EventArgs)
'yada-yada-yada
End Sub
then when you create a new textbox, wire it up:
txtRestricted = new restrictedTextBox(myCharsList)
AddHandler txtRestricted.TextChanged, AddressOf txtRestricted_TextChanged
Me.Controls.Add(txtRestricted)

ProgressBar Woes. Getting UI thread to update while reading database

I'm having trouble getting a progress bar to update. I'd be okay just with a moving marquee bar. Basically, I'm reading a database routine in a SqliteReader.vb class. I'm new to visual basic, and I'm sure I need to use the worker_DoWork routine, but I'm not sure how to expose my variables coming from Form1: graphData, graphComputations, m_debug to the worker_DoWork sub. How is this usually done?
Public Class SqliteReader
Public Sub ReadDataBase
End Sub
End Class
This is updating a graph (zedgraph element) on the main form, Form1.vb. I call the progressbar from the main form like this:
ProgressBar.Initialize(channelArray, computationArray, m_debug)
ProgressBar.vb below:
Partial Public Class ProgressBar
Dim DataAcquisition As New SqliteReader
Dim WithEvents worker As New BackgroundWorker
Public Sub Initialize(ByRef graphData As Channels(), ByRef graphComputations As Computations(), ByVal m_debug As Integer)
DataAcquisition = SqliteReader.GetInstance()
Me.Show()
Me.Update()
Dim Update_Thread As Thread(AddressOf Update_ThreadExecute)
Update_Thread.Priority = ThreadPriority.Normal
Update_Thread.Start()
DataAcquisition.ParseEntireDatabase(graphData, graphComputations, m_debug)
Me.Close()
End Sub
Private Sub ProgressBarStart(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
DataAcquisition = SqliteReader.GetInstance()
progress.Style = ProgressBarStyle.Marquee
worker.WorkerReportsProgress = True
worker.WorkerSupportsCancellation = True
worker.RunWorkerAsync()
End Sub
Private Sub worker_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles worker.DoWork
Dim worker As BackgroundWorker = DirectCast(sender, BackgroundWorker)
DataAcquisition = SqliteReader.GetInstance()
' I probably need
' DataAcquisition.ParseEntireDatabase(graphData, graphComputations, m_debug)
' here... but how do I expose graphdata, graphcomputations and m_debug to this sub?
End Sub
Private Sub worker_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles worker.ProgressChanged
dataProgress = CInt(((DataAcquisition.currentRow + 1) / DataAcquisition.totalRows) * 100)
progress.Value = dataProgress
End Sub
RunWorkerAsync has a second version that takes a parameter. You can use that to pass any values (or references) your worker needs.
That said, you shouldn't be updating form elements from inside the worker. Your worker should fire the ProgressChanged event when you want the UI to update, and you handle it there. That one also has a version that can send a value back. (Or many values if you send back an array, list, or custom class.)
The last step in this is that you need to actually fire ProgressChanged. DataAcquisition.ParseEntireDatabase may not do that, in which case using it won't allow this method to work.
If graphData, graphComputations, m_debug are already members of ProgressBar and worker_DoWork is a member of ProgressBar, then you have nothing more to do. You should be able to access them directly.
For Rapunzo, above.. My Final Solution was this:
Partial Public Class ProgressBar
Dim _mDataAcquisition As New SqliteReader
Public Property DataProgress As Integer = 0
Dim WithEvents _mProgressWorker As New BackgroundWorker
Public Sub Initialize(ByRef graphData As List(Of Channels), ByRef auxData As List(Of Channels), _
ByRef graphComputations As List(Of Computations))
_mDataAcquisition = SqliteReader.GetInstance()
Show()
Update()
_mDataAcquisition.ParseEntireDatabase(graphData, auxData, graphComputations)
Close()
End Sub
Private Sub ProgressBarStart(ByVal sender As System.Object, ByVal e As EventArgs) Handles MyBase.Load
progress.Style = ProgressBarStyle.Blocks
_mProgressWorker.WorkerReportsProgress = True
_mProgressWorker.WorkerSupportsCancellation = True
_mProgressWorker.RunWorkerAsync()
progress.Visible = True
progress.Maximum = 100
progress.Value = 0
End Sub
Public Sub WorkerProgressChanged()
progress.Value = DataProgress
Invalidate()
End Sub
Private Sub WorkerRunWorkerCompleted(ByVal sender As Object, _
ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) _
Handles _mProgressWorker.RunWorkerCompleted
progress.Visible = False
progress.Value = 0
Close()
End Sub
From there, just call ProgressBar.Initialize to start it
To update:
ProgressBar.DataProgress = CInt((currentIt / totalIt) * 100)
ProgressBar.WorkerProgressChanged()
and to end:
ProgressBar.DataProgress = 100
ProgressBar.WorkerProgressChanged()
Hope this helps.