Display a Stream (Windows Forms)
For this post, let’s create a new Windows Forms App (Visual C#) and call it CvbViewer:
After the wizard finishes its work you should see an open Form1.cs [Design].
Don’t forget to disable the Prefer 32-bit check-box.
Before we can do anything useful we also need to add the Stemmer.Cvb.dll, Stemmer.Cvb.Forms.dll, Stemmer.Cvb.Aux.dll and Stemmer.Cvb.Extensions.dll to the references.
Open your Toolbox, right-click on the General tab and click on Choose items…
After loading finishes first try to enter Stemmer
in the Filter: text field. This should list:
- Display
- GenApiGrid
- StreamHandler
If that doesn’t show you anything you can click on Browse… and enter
%CVB%Lib\Net
and choose Stemmer.Cvb.Forms. Then confirm this and the Choose Toolbox Items dialog with Ok. You now should see three new entries under General:
- Display
- GenApiGrid
- StreamHandler
- We quickly add an “Open”-Button (
openButton
) and a “Grab”-CheckBox (grabCheckBox
) and anchor them to the Bottom, Left. - We add the StreamHandler as
streamHandler
to theForm1
. It will be placed below the Designer window in the Components section. - We add the Display as
display
and anchor it Top, Bottom, Left, Right.
As we finished our UI-design, we can double-click on the Open… button to create its Click handler and enter the following code:
private void openButton_Click(object sender, EventArgs e)
{
try
{
Device device = FileDialogs.LoadByDialog(path => DeviceFactory.Open(path), "CVB Devices|*.vin;*.emu;*.avi");
if (device == null)
return; // canceled
Device = device;
}
catch (IOException ex)
{
MessageBox.Show(ex.Message, "Error loading device", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
and
private Device Device
{
get { return _device; }
set
{
if (!ReferenceEquals(value, _device))
{
display.Image = value?.DeviceImage;
streamHandler.Stream = value?.Stream;
_device?.Dispose(); // old one is not needed anymore
_device = value;
}
}
}
private Device _device;
To make this work add the following namespaces:
using Stemmer.Cvb;
using Stemmer.Cvb.Forms;
using System.IO;
We use the helper FileDialogs.LoadByDialog
to easily open a FileDialog
that returns the opened Device
or null if canceled. This dialog supports avi- and emu-files as well a preconfigured vin-drivers.
We also utilize a Device Form1.Device
property to manage life-time of prior loaded devices and to assign the DeviceImage
to the display and the Device.Stream
to the streamHandler
. (If ?.
looks unfamiliar: that is automatic null
handling: null
is assigned if value == null
.)
When we run the app and load e.g. the GenICam.vin, we see a black image in the Display
. This is normal as we don’t do “Auto Snap” and no data has been acquired, yet.
Finally let’s connect to the grabCheckBox
’s CheckedChanged event by double-clicking on the CheckBox in the designer. Add the following code:
private void grabCheckBox_CheckedChanged(object sender, EventArgs e)
{
if (grabCheckBox.Checked)
streamHandler.Start();
else
streamHandler.Stop();
openButton.Enabled = !grabCheckBox.Checked;
}
And that’s it. You have your life-display :cvb: app.
If you want to be correct and properly clean-up, move the void Dispose(bool disposing)
(see the Dispose pattern for more info about this) method from the .Designer.cs into your implementation cs file and change it to:
protected override void Dispose(bool disposing)
{
if (disposing)
{
components?.Dispose();
Device?.Dispose();
}
base.Dispose(disposing);
}
components?.Dispose()
will dispose the streamHandler
, which will abort any ongoing acquisition. And last but not least we clean-up our opened Device
. This is especially useful if you use your window as a dialog in your application and must ensure that the Device
is not open anymore after the dialog is closed.