I am trying to stream webcam at C++/CLI winform application with using picture-box.
With the help of timer,i can stream webcam on picture-box but VideoCapture cap(0); Mat frame; are declare continuously. How can i transfer these two to a button click and use inside this timer.
private: System::Void Timer1_Tick(System::Object^ sender, System::EventArgs^ e) {
VideoCapture cap(0);
Mat frame;
cap.read(frame);
System::Drawing::Graphics^ graphics2 = pictureBox1->CreateGraphics();
System::IntPtr ptr2(frame.ptr());
System::Drawing::Bitmap^ b2 = gcnew System::Drawing::Bitmap(frame.cols,
frame.rows, frame.step, System::Drawing::Imaging::PixelFormat::Format24bppRgb, ptr2);
System::Drawing::RectangleF rect2(0, 0, pictureBox1->Width, pictureBox1->Height);
graphics2->DrawImage(b2, rect2);
}
Related
I am a rookie to C#.
Here is the problem. I created a new thread to open my form1 twice in Program.cs.
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Thread secThread = new Thread(new ThreadStart(runForm));
secThread.Start();
Application.Run(new Form1());
}
private static void runForm()
{
Thread.Sleep(1000);
Application.Run(new Form1());
}
what I want is making two different users to do what they want such as clicking controlls &
mousemove in each form
Is it possible to add a cursor on both of these forms?
I mean "one form one cursor" in the form at the same pc.
Users dont need to do things across forms.
I have tried DrawCursorsOnForm in MSDN but nothing happened.(cursorImg is just a normal image.)
private void Form1_Load(object sender, EventArgs e){
Cursor cur = new Cursor(cursorImg.GetHicon());
DrawCursorsOnForm(c);
}
private void DrawCursorsOnForm(Cursor cursor)
{
// If the form's cursor is not the Hand cursor and the
// Current cursor is the Default, Draw the specified
// cursor on the form in normal size and twice normal size.
if (this.Cursor != Cursors.Hand &
Cursor.Current == Cursors.Default)
{
//// Draw the cursor stretched.
Graphics graphics = this.CreateGraphics();
Rectangle rectangle = new Rectangle(
new Point(100, 50), new Size(cursor.Size.Width * 2,
cursor.Size.Height * 2));
cursor.DrawStretched(graphics, rectangle);
// Draw the cursor in normal size.
//rectangle.Location = new Point(
//rectangle.Width + rectangle.Location.X,
//rectangle.Height + rectangle.Location.Y);
//rectangle.Size = cursor.Size;
//cursor.Draw(graphics, rectangle);
// Dispose of the cursor.
//cursor.Dispose();
}
What should I tried next?
I just began learning WinForms and am currently baffled on how to get the senders' (mouses') position (coordinates). I tried searching but to no avail.
This is my, somewhat, of a try but, sadly, it ended up with an error:
private: System::Void pictureBox1_MouseHover(System::Object^ sender, System::EventArgs^ e) {
this->pictureBox1->Location = System::Drawing::Point(sender::Position.X - 5, sender::Position.Y - 5);
MessageBox::Show("Foo", "Bar", MessageBoxButtons::OK, MessageBoxIcon::Stop);
}
So my question here is quite clear, I think: how can I get the senders' position (in this case, the mouses'). Explanations would also be of help. Thank you.
Since I didn't find a valid answer I took the longer route.
Firstly, I declared a boolean in the namespace with the value of false (it will change to true when the mouse will touch the picture). Then I create two new methods: one to get the X and Y of the mouse and execute code if the mouse is touching the picture and the second one to determine whether the mouse is touching the picture or not.
private: System::Void picture_MouseMove(Object^ sender, System::Windows::Forms::MouseEventArgs^ e) {
int VMouseX = e->X,
VMouseY = e->Y;
if (VMouseEntered) {
VMouseEntered = false;
this->picture->Location = System::Drawing::Point(VMouseX + 17, VMouseY + 17);
}
}
private: System::Void picture_MouseEnter(System::Object^ sender, System::EventArgs^ e) {
VMouseEntered = true;
}
Then, I create two new EventHandlers for the picture. The first EventHandler is to listen for mouse movement, the second one is to check whether the mouse is touching the picture.
this->picture->MouseMove += gcnew System::Windows::Forms::MouseEventHandler(this, &Form1::picture_MouseMove); // Checks for mouse movement.
this->picture->MouseEnter += gcnew System::EventHandler(this, &Form1::picture_MouseEnter); // Checks whether the mouse is touching the picture.
Done. I hope that this will help someone.
I haven't used Unity 3D but I gather you can use Screen.lockCursor to take control of the mouse for FPS games. Is this possible in WPF/Win32?
Obviously you have to release it when exiting or in the event of a crash
Thanks
I found the answer spread across a whole bunch of links, so
(1) Set a captureMouse flag, press once to go into this mode, again to come out,
hide the cursor while you are in there
bool captureMouse = false;
private void viewport3D1_MouseDown(object sender, MouseButtonEventArgs e)
{
if (!captureMouse)
{
captureMouse = true;
Mouse.OverrideCursor = Cursors.None;
}
else
{
Mouse.OverrideCursor = null;
captureMouse = false;
}
}
(2) While you're in this mode constantly put the mouse back to the middle of the window
private void theWindow_MouseMove(object sender, MouseEventArgs e)
{
if (!captureMouse)
return;
Point windowPoint = WpfToRealPixels(theWindow, new Point(500, 500));
NativeMethods.SetCursorPos((int)windowPoint.X, (int)windowPoint.Y);
oldP = new Point(500, 500);
}
(3) Translate the co-ords
private Point WpfToRealPixels(Window w, Point p)
{
return theWindow.PointToScreen(p);
}
(4) To put the mouse back you'll need a native Win32 call
public partial class NativeMethods
{
[System.Runtime.InteropServices.DllImportAttribute("user32.dll", EntryPoint = "SetCursorPos")]
[return: System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.Bool)]
public static extern bool SetCursorPos(int X, int Y);
}
Hope that helps someone.
I am currently building a windows form application and I have got the next problem,
I can't declare a variable global because the syntax im using won't allow me to do that, also, i need to declare the variable in the method it self and at last, it must loop so its able to count. This is what I have got so far:
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {
int i;
m_bIsTimerOn = true;
while (m_bIsTimerOn)
{
i++;
label1->Text = (i.ToString());
}
}
private: System::Void button2_Click(System::Object^ sender, System::EventArgs^ e) {
m_bIsTimerOn = false;
timer1->Enabled = false;
}
m_bIsTimerOn is a globally boolean. As you might see here my problem is if i press button1 the program is just stuck in the while loop. I would like to know that the moment you press button2 the while loop stops I also would like to know if this is even possible. If you could response in c++ that would also be fine.
Thank you in advance.
I suppose you want to increment i while timer is on. If you need to update i for each timer tick then it's pretty easy, remove that loop (and that variable BTW) and simply do update inside timer Tick event:
private:
int _i;
void button1_Click(Object^ sender, EventArgs^ e) {
_i = 0;
timer1->Enabled = true;
}
void _timer1_Tick(Object^ sender, EventArgs^ e) {
label1->Text = (i++).ToString();
}
void button2_Click(Object^ sender, EventArgs^ e) {
timer1->Enabled = false;
}
If i must be updated independently from timer ticks then you have to move it to a BackgroundWorker or simply in event handler for Application::Idle:
void OnIdle(Object^ sender, EventArgs^ e) {
label1->Text = (_i++).ToString();
}
void button1_Click(Object^ sender, EventArgs^ e) {
_i = 0;
Application::Idle += gcnew EventHandler(this, Form1::OnIdle);
timer1->Enabled = true;
}
void button2_Click(Object^ sender, EventArgs^ e) {
Application::Idle -= gcnew EventHandler(this, Form1::OnIdle);
timer1->Enabled = false;
}
As final note: you may even keep your loop as is and put a call to Application::DoEvents() just after your label1->Text = (i.ToString()); but this will probably consumes a lot of CPU, slow down your application and open your code to reentrancy, I'd really avoid something like that...
Your program is in endless loop because the while loop prevents the messages from getting processed and hence your button2_Click does not get invoked. To make you application capable of processing the messages that occurs, add Application.DoEvents() in your loop as:
while (m_bIsTimerOn)
{
i++;
label1->Text = (i.ToString());
Application.DoEvents(); // causes the application to handle pending events
}
So now, if you press the second button, m_bIsTimerOn will become false and your loop will terminate.
I have winforms application and i have texture SimpleTexture.xnb compiled as HiDef. I need to run XNA 3D visualisation from my winforms application in separate window. I try this:
private void button1_Click(object sender, EventArgs e)
{
System.Threading.Thread thStartGame = new System.Threading.Thread(StartGame);
thStartGame.Start();
}
private void StartGame()
{
using (Game1 game = new Game1())
{
game.Run();
}
}
But i get error:
Error loading "SimpleTexture". This file was compiled for the HiDef profile, and cannot be loaded into a Reach GraphicsDevice.
What can i do to run this??
Change reach to hidef:
YourGraphicsDeviceManager.PreparingDeviceSettings += new EventHandler<PreparingDeviceSettingsEventArgs (graphics_PreparingDeviceSettings);
void graphics_PreparingDeviceSettings(object sender, PreparingDeviceSettingsEventArgs e)
{
e.GraphicsDeviceInformation.GraphicsProfile = GraphicsProfile.HiDef;
}