简体   繁体   中英

How could I display a crosshair cursor with x-y coordinates when hovering over a picturebox?

I want to make a crosshair pointer when hovering over a picturebox and store a co-ordinates when mouse left button is pressed over a picturebox.

My code looks like below:

private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) {
        cv::VideoCapture cap;
        cap.open(0);

        if (!cap.isOpened()) {
            MessageBox::Show("Failed To Open WebCam");
            _getch();
            return;
        }

        ///query_maximum_resolution(cap, pictureBox1->Width, pictureBox1->Height);
        cap.set(CV_CAP_PROP_FRAME_WIDTH, pictureBox1->Width);
        cap.set(CV_CAP_PROP_FRAME_HEIGHT, pictureBox1->Height);

        Pen^ myPen = gcnew Pen(Brushes::Red);

        while (1)
        {
            cap.read(frame);

            pictureBox1->Image = mat2bmp.Mat2Bimap(frame);
            Graphics^ g = Graphics::FromImage(pictureBox1->Image);
            Point pos = this->PointToClient(System::Windows::Forms::Cursor::Position);
            g->DrawLine(myPen, pos.X, 0, pos.X, pictureBox1->Height);
            g->DrawLine(myPen, 0, pos.Y, pictureBox1->Width, pos.Y);
            pictureBox1->Refresh();
            delete g;
        }
    }

But when I run the code it becomes slower and non responsive. Any idea to make it fast and efficient. Any help would be helpful.

IO happens on the UI thread, which is the main application UI rendering thread. Button click is an event handler and will come on the UI thread. If you have a while loop running inside your UI thread, it will make the application hang. Work done on UI thread should be small or Asynchronous.

Edit 1: Just found out that you have marked winform as one of the tag. If you are using winforms, you have to add a MouseHover event handler to your UI controls. Whenever the mouse reaches in this area, this method will be called ( https://docs.microsoft.com/en-us/dotnet/api/system.windows.forms.control.mousehover?view=netframework-4.7.2 ). In this method just write the above code without the while loop. Something like this.

private: System::Void button1_MouseHover(System::Object^  sender, System::EventArgs^  e) {
    cv::VideoCapture cap;
    cap.open(0);

    if (!cap.isOpened()) {
        MessageBox::Show("Failed To Open WebCam");
        _getch();
        return;
    }

    ///query_maximum_resolution(cap, pictureBox1->Width, pictureBox1->Height);
    cap.set(CV_CAP_PROP_FRAME_WIDTH, pictureBox1->Width);
    cap.set(CV_CAP_PROP_FRAME_HEIGHT, pictureBox1->Height);

    Pen^ myPen = gcnew Pen(Brushes::Red);

    cap.read(frame);

    pictureBox1->Image = mat2bmp.Mat2Bimap(frame);
    Graphics^ g = Graphics::FromImage(pictureBox1->Image);
    Point pos = this->PointToClient(System::Windows::Forms::Cursor::Position);
    g->DrawLine(myPen, pos.X, 0, pos.X, pictureBox1->Height);
    g->DrawLine(myPen, 0, pos.Y, pictureBox1->Width, pos.Y);
    pictureBox1->Refresh();
    delete g;
}

Note: This event also comes in the UI thread. This will come everytime mouse oves in the region of interest. Hence you will not need the while loop. Adding a while loop here will again result in the same issue that you have asked in the question.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM