Visual C++ Why are two button clicks required to obtain button click event handler result

Marshall Hollimon 1 Reputation point
2020-09-07T21:59:11.207+00:00

Q&A - I have a small C++ app in which it takes two clicks of a button to produce the desired even handler action.

The app controls a voltage digitizer over the USB and plots the measured result in a pictureBox control. The app GUI has several Button controls, two of which are Run and Stop. Run_btn_Click starts the measurement and plotting (up to 600 data points) using a for-loop; Stop_btn_Click is intended to interrupt the action of Run. Both are button event handlers. The problem is that it takes two clicks of the Stop button to interrupt the Run button event handler. Either a doubleclick or two successive single clicks will work; time between single clicks doesn't seem to matter.

The following code excerpt is a condensed version of Run_btn_Click:

private: System::Void Run_btn_Click(System::Object^  sender, System::EventArgs^  e) {
-------------------------------------------//Variable definitions, pictureBox setup, etc.--------------------------

             A = false;

            // For-loop
             for(K = 0; K <600 && A == false; K++)
             {
             Application::DoEvents();
             OutBuffer[0] = 0x80; //Hex 0x80h is device command to "operate/do something"
             WinUsb_WritePipe(MyWinUSBInterfaceHandle, 0x01, &OutBuffer[0], 64, &BytesWritten, NULL);
             WinUsb_ReadPipe(MyWinUSBInterfaceHandle, 0x81, &InBuffer[0], 64, &BytesRead, NULL);

             DATAH = (InBuffer[0] << 8);      // DATA number high byte
             DATAL = InBuffer[1];       // DATA number low byte
             DATA = DATAH + DATAL;      // Combine bytes to get DATA number
             NUMF = (DATA*ADV)/1024;        // Denormalize: (DATA/1024)*(A-to-D full scale volts)
             textBox2->Text = Convert::ToString(NUMF);
             listBox1->Items->Add(NUMF);
             g->DrawLine(blackPen, Point(J,(400*(1-NUMF/FSV))), Point(J+1,(400*(1-NUMF/FSV))));
             this->textBox2->Update();
             this->listBox1->Update();
             this->pictureBox1->Update();

             J = J + 1;
             I = I + 1;
             Tmr->Interval = TI;         // Time between steps, set by GUI control
             Tmr->Enabled = true;
             GC::KeepAlive(Tmr);
             while(Tmr->Enabled==true)
                 {
                    ;
                 }
             Tmr->Enabled = false;
             } // End of for-loop
             return;
} // End of Run_btn_Click

Here's the code for Stop_btn_Click:

private: System::Void Stop_btn_Click(System::Object^  sender, System::EventArgs^  e) {
        A = true;
    } // End of Stop_btn_Click

Problem: while the for-loop is running, click Stop button once, nothing happens; click Stop button a second time, loop breaks, app is ready for another Run button click.

Any ideas why this second click is required and what should be done to make the app respond to the first Stop button Click?

Thanks for any help that can be offered.

Mick H
7 Sept 20
2:59 PM PDT USA

C++
C++
A high-level, general-purpose programming language, created as an extension of the C programming language, that has object-oriented, generic, and functional features in addition to facilities for low-level memory manipulation.
3,628 questions
{count} votes

3 answers

Sort by: Most helpful
  1. Marshall Hollimon 1 Reputation point
    2020-09-08T17:40:55.197+00:00

    Mr. Lowndes - thanks for the suggestion as to problem source. I'll give the worker thread a try as soon as I can.

    Mick H
    8 A7ug 20
    10:41 AM PDT USA

    0 comments No comments

  2. Marshall Hollimon 1 Reputation point
    2020-09-11T17:48:01.467+00:00

    I can't explain why it takes 2 clicks, but your problem undoubtedly stems from using DoEvents, which is always a bit of a fudge.

    Mr. Lowndes - I haven't gotten at the worker thread yet but I did try commenting out the line numbered 9 above to remove DoEvents. This did not affect the two-click problem which is still there. Any other ideas as to what might be causing the two-click requirement? Thanks.

    Mick H
    11 Sept 20
    10:48 AM PDT USA


  3. Marshall Hollimon 1 Reputation point
    2020-09-12T20:17:51.41+00:00

    By removing the DoEvents line of code, I'd expect that you wouldn't be able to have any click response until after the code you showed had finished executing.

    Mr. Lowndes - the app interrupts (and waits for a new Run_btn_Click) with or without Application.DoEvents; it is slower to interrupt without DoEvents.

    Thanks anyway for you time and thought.

    MickH
    12 Sept 20
    1:18 PM PDT USA

    0 comments No comments