I make a program in C# windows form I have tons of function in my form including two datagrid view that connected to dabase and including a camera that direcly connected to my PC I use AForge dll reference to connect to the camera device I just found the tutorial on youtube and it works perfecly for me, as I stated earlier I have too many programs in one form including that camera and it went out that the camera was need to be resized to a small resolution, so I decided to make a popup button that must show the wider resolution when I click the button on my form.
this is the code for my camera.
//Camera
// get the devices name
private void getCamList()
{
try
{
videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);
comboBox1.Items.Clear();
if (videoDevices.Count == 0)
throw new ApplicationException();
DeviceExist = true;
foreach (FilterInfo device in videoDevices)
{
comboBox1.Items.Add(device.Name);
}
comboBox1.SelectedIndex = 0; //make dafault to first cam
}
catch (ApplicationException)
{
DeviceExist = false;
comboBox1.Items.Add("No capture device on your system");
}
}
//refresh button
private void refresh_Click(object sender, EventArgs e)
{
getCamList();
}
//toggle start and stop button
private void start_Click(object sender, EventArgs e)
{
if (start.Text == "&Start")
{
if (DeviceExist)
{
videoSource = new VideoCaptureDevice(videoDevices[comboBox1.SelectedIndex].MonikerString);
videoSource.NewFrame += new NewFrameEventHandler(video_NewFrame);
CloseVideoSource();
videoSource.DesiredFrameSize = new Size(160, 120);
//videoSource.DesiredFrameRate = 10;
videoSource.Start();
lblCam.Text = "Device running...";
start.Text = "&Stop";
}
else
{
lblCam.Text = "Error: No Device selected.";
}
}
else
{
if (videoSource.IsRunning)
{
CloseVideoSource();
lblCam.Text = "Device stopped.";
start.Text = "&Start";
}
}
}
//eventhandler if new frame is ready
private void video_NewFrame(object sender, NewFrameEventArgs eventArgs)
{
Bitmap img = (Bitmap)eventArgs.Frame.Clone();
//do processing here
pictureBox1.Image = img;
}
//close the device safely
private void CloseVideoSource()
{
if (!(videoSource == null))
if (videoSource.IsRunning)
{
videoSource.SignalToStop();
videoSource = null;
}
}
//prevent sudden close while device is running
private void Form1_FormClosed(object sender, FormClosingEventArgs e)
{
CloseVideoSource();
}
} }
I also posted a picture so that you have further understanding what I am talking.
as you can see at the lower right corner I have a pop up button there honestly telling you I already tried different methods but nothing works unfotunately I cannot post what I've tried because I created it yesterday and can no longer undo the codes I tried. Any Idea?
Create a new Form
Place a PictureBox on this Form
Add all methods to initialize and get the current frame to the Form (should be refactored to an own class providing an event like FrameChanged giving you the current image)
add a method like to the Form
public void ShowCamPopup(string deviceName)
{
InitializeDevice(string deviceName, int width, int height);
this.Show();
this.BringToTop();
}
You should the really consider to refactor the communication with your cam to an own class which reduces duplicate code and allows you to do performance tweaks (which you will need for sure later) at a single position of your solution.
Related
For the application that i am creating i am trying to add in music which plays when form2 is opened. which seems to work just fine, the only issue i have is when i close the form it immediately starts playing the music again. Here is my code:
private void Form2_Load(object sender, EventArgs e)
{
music(true);
}
private void Form2_FormClosed(object sender, FormClosedEventArgs e)
{
music(false);
}
private void music(bool placeholder)
{
System.IO.Stream str = Properties.Resources.Music;
System.Media.SoundPlayer snd = new System.Media.SoundPlayer(str);
if (placeholder = true)
{
snd.Play();
} else
{
snd.Stop();
}
}
if i start my application it doesnt play any music which it should since it opens on form1. When i open form2 it plays the music as it should but when i close it, it restarts the music and it just keeps playing.
It was a simple error of judgment.
if (placeholder = true)
{
snd.Play();
} else
{
snd.Stop();
}
I suggest that you modify the above code to:
if (placeholder == true)
{
snd.Play();
} else
{
snd.Stop();
}
Please comment below if it doesn't work.
I am using AxMSTSCLib to develop a Windows App for creating RDP connections.
The steps listed below caused my remote desktop display disappear:
Start an RDP connection with full-screen mode
Click "restore down" button from connection bar
Click "maximize" button again to re-enter full-screen mode
Click "minimize" button
Then my app disappears, I can't see it in taskbar (but still be listed / running in taskmanager)
If I skip steps 2 & 3, it won't disappear when I click "minimize" button from connection bar, it's really weird.
I post some part of my code here, hope anyone can help me to find out the problem.
public partial class RdpShowForm : Form
{
public AxMSTSCLib.AxMsRdpClient9NotSafeForScripting oRemote;
public RdpShowForm()
{
InitializeComponent();
oRemote = new AxMSTSCLib.AxMsRdpClient9NotSafeForScripting();
((System.ComponentModel.ISupportInitialize)(this.oRemote)).BeginInit();
oRemote.Dock = System.Windows.Forms.DockStyle.Fill;
oRemote.Enabled = true;
oRemote.Name = "WindowsVM";
this.Controls.Add(oRemote); // Controls contains 'panel1' and 'oRemote'
((System.ComponentModel.ISupportInitialize)(this.oRemote)).EndInit();
oRemote.CreateControl();
this.panel1.Dock = System.Windows.Forms.DockStyle.Fill;
}
private void RdpShowForm_Load(object sender, EventArgs e)
{
NewRdpConnectionInstance();
}
private void NewRdpConnectionInstance()
{
oRemote.Server = 'xxx';
...
oRemote.FullScreen = true;
oRemote.AdvancedSettings7.DisplayConnectionBar = true;
oRemote.AdvancedSettings7.ConnectionBarShowMinimizeButton = true;
oRemote.AdvancedSettings7.ConnectionBarShowRestoreButton = true;
oRemote.OnConnected += rdpClient_OnConnected;
oRemote.OnLeaveFullScreenMode += rdpClient_OnLeaveFullScreenMode;
oRemote.Connect();
oRemote.Show();
oRemote.Focus();
}
private void rdpClient_OnConnected(object sender, EventArgs e)
{
this.panel1.Visible = false;
this.Visible = false;
}
private void rdpClient_OnLeaveFullScreenMode(object sender, EventArgs e)
{
this.Visible = true;
}
protected override void WndProc(ref Message m)
{
if (m.Msg == WM_SYSCOMMAND)
{
if (m.WParam.ToInt32() == MAXIMIZE)
{
this.Visible = false;
oRemote.FullScreen = true;
oRemote.Show();
}
}
base.WndProc(ref m);
}
}
I've tried some methods, but none of them worked.
oRemote.Bounds = Screen.PrimaryScreen.WorkingArea;
oRemote.IsAccessible = true;
this.ShowInTaskbar = true;
or
this.Visible = ture; // do not hide the main form
or
if (m.WParam.ToInt32() == MAXIMIZE)
{
oRemote.FullScreen = true;
oRemote.Show();
oRemote.Update();
oRemote.Refresh();
}
So far, the only solution that came into my mind is to disable the restore button, like this:
oRemote.AdvancedSettings7.ConnectionBarShowRestoreButton = false;
This way isn't fix the problem, just avoid the issue to be triggered.
I would appreciate any help.
Since AxMSTSCLib has a restore down issue, I turn to use a form to handle its fullscreen mode. In this way, I can get extensive control over full-screen mode behavior, write code to tell the container what to do when the restore down button is called.
// enable container-handled full-screen mode
oRemote.AdvancedSettings7.ContainerHandledFullScreen = 1;
Then, customize OnRequestGoFullScreen, OnRequestLeaveFullScreen, OnRequestContainerMinimize.
oRemote.OnRequestGoFullScreen += corey_OnRequestGoFullScreen;
oRemote.OnRequestLeaveFullScreen += corey_OnRequestLeaveFullScreen;
oRemote.OnRequestContainerMinimize += corey_OnRequestContainerMinimize;
private void corey_OnRequestGoFullScreen(object sender, EventArgs e)
{
// set the form to fullscreen
}
private void corey_OnRequestLeaveFullScreen(object sender, EventArgs e)
{
// set the form back to non-fullscreen mode
}
private void corey_OnRequestContainerMinimize(object sender, EventArgs e)
{
// minimize the form
}
The method I posted here can be a workaround to this issue.
I have a problem about System.Windows.Forms.PictureBox. I want to show a image on monitor and capture it on the camera. So I use Winform which include a picturebox. The picture box is:
PictureBox pb = new PictureBox();
pb.WaitOnLoad = true;
When I set a bitmap to PictureBox and capture the image from camera,
// Show bmp1
this.image.Image = bmp1;
this.image.Invalidate();
this.image.Refresh();
// Delay 1s
UseTimerToDelay1s();
// Show bmp2
this.image.Image = bmp2;
this.image.Invalidate();
this.image.Refresh();
// Capture
CaptureImageFromCamera();
It only capture the bmp1.
If I add a small delay like this,
this.image.Image = bmp2;
this.image.Invalidate();
this.image.Refresh();
UseTimerToDelay100ms();
CaptureImageFromCamera();
It capture bmp2. The Image set method seem to be a async method. Does any method to confirm the image is set? Thanks.
I'd use the first Paint event after assigning the new Image.
You can give it a try using a very large image url from this site.
The example uses google logo image url. Copy the following code and make sure you assign event handlers to the events:
bool newImageInstalled = true;
private void Form1_Load(object sender, EventArgs e)
{
pictureBox1.WaitOnLoad = true;
}
private void PictureBox1_Paint(object sender, PaintEventArgs e)
{
if (!newImageInstalled)
{
newImageInstalled = true;
BeginInvoke(new Action(() =>
{
//Capturing the new image
using (var bm = new Bitmap(pictureBox1.ClientSize.Width,
pictureBox1.ClientSize.Height))
{
pictureBox1.DrawToBitmap(bm, pictureBox1.ClientRectangle);
var tempFile = System.IO.Path.GetTempFileName() + ".png";
bm.Save(tempFile, System.Drawing.Imaging.ImageFormat.Png);
System.Diagnostics.Process.Start(tempFile);
}
}));
}
}
private void button1_Click(object sender, EventArgs e)
{
newImageInstalled = false;
pictureBox1.ImageLocation =
"https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png";
}
private void button2_Click(object sender, EventArgs e)
{
newImageInstalled = false;
pictureBox1.Image = null;
}
I am quite new to C# and I am trying to use one common serial port for 3 different forms: Form2, Form3, Form4
Form1.cs isn't needed for this because it's just needed to launch the programs of the other forms. Basically, all 3 forms must receive data from the same serial port at the same time. The problem I am facing is that only one form can receive data from the serial port, but the other two forms can't.
I found a question similar to this:
Using same serial port data received event on two different forms
Is that problem similar to mine? If yes, can I know where should I place the sample code in the aforementioned link in my code?
Can someone please help with this? Thanks in advance!
Form1:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Form2 f2 = new Form2();
f2.Show();
Form3 f3 = new Form3();
f3.Show();
Form4 f4 = new Form4();
f4.Show();
}
private void button2_Click(object sender, EventArgs e)
{
this.Close();
}
}
Form2:
public partial class Form2 : Form
{
GMapControl MainMap = new GMapControl();
//Initialise data type for latituide and longitude
double lat, lng;
//Initialise customise marker (plane maker). Declared as m.
GMapMarkerImage m = new GMapMarkerImage(new PointLatLng());
GMapOverlay overlayOne;
public Form2()
{
InitializeComponent();
SuspendLayout();
overlayOne = new GMapOverlay(MainMap, "OverlayOne");
MainMap.MapProvider = GMapProviders.YahooMap;
MainMap.SetCurrentPositionByKeywords("Singapore");
MainMap.MinZoom = 1;
MainMap.MaxZoom = 24;
MainMap.Zoom = 13;
MainMap.CanDragMap = true;
MainMap.DragButton = MouseButtons.Left;
MainMap.Dock = DockStyle.Fill;
MainMap.Manager.Mode = AccessMode.ServerAndCache;
Controls.Add(MainMap);
ResumeLayout(true);
}
public void button1_Click(object sender, EventArgs e)
{
if (!serialPort1.IsOpen) //if serial port is not open
try
{
serialPort1.Open(); //Open Serial Port
if (lat != 0 && lng != 0) //Display marker only when GPS has receive data
{
overlayOne.Markers.Add(m); //Add marker on the position given to the overlayOne layer
MainMap.Overlays.Add(overlayOne); //Add overlayOne layer to the MainMap layer
}
}
catch
{
//A message box will display this message, informing user either a wrong port has been chosen, or have not been plugged in.
MessageBox.Show("There was an error. Please make sure that the correct port was selected, and the device, plugged in.");
}
}
public void button2_Click(object sender, EventArgs e)
{
if (serialPort1.IsOpen) // if Serial Port is open
{
serialPort1.Close(); //Close Serial
overlayOne.Markers.Remove(m);
}
}
//When microsoft visual studio receive data
public void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
this.Invoke(new EventHandler(DoUpdate)); //for function DoUpdate
//Pause Microsoft Visual Studio for 100 milliseconds from receiving data,
//to ensure serialPort can be close successfully
Thread.Sleep(100);
}
//Function for updating data. Declared as DoUpdate.
public void DoUpdate(object sender, EventArgs e)
{
string[] c = serialPort1.ReadLine().Split(','); //Stored data seperately by using array & using the Split() function
lat = Convert.ToDouble(c[9]); //Convert Latitude string data to double data
lng = Convert.ToDouble(c[10]); //Convert Longitude string data to double data
//Input lat and lng data in m.
//Updating the position of the marker
m.Position = new PointLatLng(lat, lng);
}
}
Form3:
public partial class Form3 : Form
{
public Form3()
{
InitializeComponent();
}
private void pictureBox1_Click(object sender, EventArgs e)
{
if (!serialPort1.IsOpen) //if serial port is not open
try
{
serialPort1.Open(); //Open Serial Port
//Enable blocks to have colour
// ...
}
catch
{
//A message box will display this message, informing user either a wrong port has been chosen, or have not been plugged in.
MessageBox.Show("There was an error. Please make sure that the correct port was selected, and the device, plugged in.");
}
}
private void button2_Click(object sender, EventArgs e)
{
if (serialPort1.IsOpen) // if serial port is open
{
serialPort1.Close(); // Close serial Port
//Clear data in textboxes
FrontSonar.Text = " ";
LeftSonar.Text = " ";
RightSonar.Text = " ";
//Clear colours in the boxes
// ...
}
}
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e) //When microsoft visual studio receive data
{
this.Invoke(new EventHandler(DoUpdate1)); //To update and ensure sonar data infront of UAV can be displayed without error
this.Invoke(new EventHandler(DoUpdate2)); //To update and ensure sonar data left side of UAV can be displayed without error
this.Invoke(new EventHandler(DoUpdate3)); //To update and ensure sonar data on the right side of UAV can be displayed without error
Thread.Sleep(100);
}
private void DoUpdate1(object s, EventArgs e) //Display for Sonar infront of UAV
{
string[] c = serialPort1.ReadLine().Split(','); //Stored data seperately by using array & using the Split() function
FrontSonar.Text = c[1] + "\n";
double d = Convert.ToDouble(c[1]);
if (d > 500)
{
//Fill blocks with green
this.rectangleShape1.FillColor = System.Drawing.Color.Green;
this.rectangleShape2.FillColor = System.Drawing.Color.Green;
this.rectangleShape3.FillColor = System.Drawing.Color.Green;
}
else
if (d > 400 && d <= 500)
{
//Fill block with Orange colour
this.rectangleShape1.FillColor = System.Drawing.Color.Orange;
this.rectangleShape2.FillColor = System.Drawing.Color.Orange;
//Fill block with Lavender colour
this.rectangleShape3.FillColor = System.Drawing.Color.Lavender;
}
else
if (d <= 400)
{
//Fill block with red colour
this.rectangleShape1.FillColor = System.Drawing.Color.Red;
//Fill block with Lavender colour
this.rectangleShape2.FillColor = System.Drawing.Color.Lavender;
this.rectangleShape3.FillColor = System.Drawing.Color.Lavender;
}
}
private void DoUpdate2(object s, EventArgs e) //Display for Sonar on the left side of UAV
{
string[] c = serialPort1.ReadLine().Split(','); //Stored data seperately by using array & using the Split() function
// ....
}
private void DoUpdate3(object s, EventArgs e) //Display for Sonar on the right side of UAV
{
string[] c = serialPort1.ReadLine().Split(','); //Stored data seperately by using array & using the Split() function
// ...
}
}
Form4: (Still in progress)
public partial class Form4 : Form
{
public Form4()
{
InitializeComponent();
}
}
Yes, you can. Below is key points to achieve this:
Open serial port once, your approach if (!port.IsOpened) { port.Open(); } is right, extract this in a static method and call in each form (f2, f3, f4) to avoid copy/paste of this code snippet.
serialPort variable should be shared across all three forms, so the same opened and initialized port instance would be accessible for all forms. Considering code you've provided, create and initialize, open port in Form1 class, then pass initialized instance of serialPort into other form classes via constructor injection, basically add SerialPort port constructor parameter for Form2,3,4 classes and then:
// renamed button1_Click
private void OnSetup(object sender, EventArgs e)
{
this.port = new SerialPort(...);
// TODO: initialize port
Form2 f2 = new Form2(this.port);
f2.Show();
Form3 f3 = new Form3(this.port);
f3.Show();
Form4 f4 = new Form4(this.port);
f4.Show();
}
Then in each form constructor just subscribe to serialPort.DataReceived event and that's it.
public Form2(SerialPort port)
{
port.DataReceived += ...
}
Some recommendations,
Give variables and methods more descriptive names rather than form1, form2, c, d, button2_Click
Avoid magic numbers, extract constants in variables and give descriptive names, for instance there are multiple occurences of 400, 500 magic numbers, it is not clear for what they are.
In comments to a code you saying Pause Microsoft Visual Studio..., microsoft visual studio receives data..., this is not correct, execution of your application (but not Visual Studio) will be paused while Thread.Sleep() and your applciation will receive an incomming serial port data, Visual Studio is just a development environment and in such cases dos not involved in a port communication directly.
I'm trying to capture images from a webcam for one application in WPF/C#
1) I tried WIA but i het the error 0x80210015, I have read that this error occurs when there is no WIA device available. I read that in windows vista/7 WPD is used insted WIA but when i try a simple example
PortableDeviceManager deviceManager = new PortableDeviceManager();
deviceManager.RefreshDeviceList();
uint numberOfDevices = 1;
deviceManager.GetDevices(null, ref numberOfDevices);
if (numberOfDevices == 0)
{
Console.WriteLine("No device");
}
else
{
string[] deviceIds = new string[numberOfDevices];
deviceManager.GetDevices(ref deviceIds[0], ref numberOfDevices);
Console.WriteLine(deviceIds);
}
Console.Read();
i cant detect devices.
2) I triead with http://easywebcam.codeplex.com/ works, but i get randomly the error "An error occured while capturing the video image. The video captu..." and i need select the device always and i need execute webcam.start() several times (2 or 3) for that camera works.
I have two webcams
Chicony Web 2.0 (inbuilt webcam)
Genius FaceCam 2000
here is a simple take a picture kind of program
Image<Bgr, Byte> img;
private Capture capture;
private bool captureInProgress;
private void gumb_kamera_Click(object sender, EventArgs e)
{
}
private void processFunction(object sender, EventArgs e)
{
img = capture.QueryFrame();
// imageBox1.Image = img;
}
private void Form1_Load(object sender, EventArgs e)
{
if (capture == null)
{
try
{
capture = new Capture(0);
}
catch (NullReferenceException excpt)
{
MessageBox.Show(excpt.Message);
}
}
if (capture != null)
{
if (captureInProgress)
{
Application.Idle -= processFunction;
}
else
{
Application.Idle += processFunction;
}
captureInProgress = !captureInProgress;
}
}
private void button1_Click(object sender, EventArgs e)
{
imageBox1.Image = img;
}