How to Update a variable on screen inside a loop?

Edited:
I have solved the problem below, but new problem exist :
How to gain control for the OK or CANCEL button while Button1 is pressed and in the loop?


I want the variable to be updated continuously after I pressed a button. However, I can't do that with UpdateData(false) which placed inside a loop. Anyone know the solution?

My sample code:

void CAaaDlg::OnButton1()
{
      while (1==1)
            {
            m_a=m_a+1;
            UpdateData(false);
                   UpdateWindow();
            }
}
mingming_ewAsked:
Who is Participating?

[Webinar] Streamline your web hosting managementRegister Today

x
 
Dariusz DziaraConnect With a Mentor ProgrammerCommented:
Try this:

void CAaaDlg::OnButton1()
{
  MSG msg;
  m_bDooLoop = TRUE;

  while (m_bDooLoop) {
    m_a=m_a+1;
    UpdateData(false);

    while(PeekMessage(&Msg, NULL, 0, 0, PM_REMOVE) {
      TranslateMessage(&Msg);
      DispatchMessage(&Msg);
    }
  }
}

void CAaaDlg::OnButton2()
{
  m_bDooLoop = FALSE;  
}

Where
  m_bDooLoop is member of your window class
0
 
NorbertCommented:
The problem is that the message loop is not reached while you are inside the loop
may be the function RedrawWindow will help
or you have to build your own MessageLoop:
MSG msg;
 
if(GetMessage(&msg,NULL,0,0))
{
    TranslateMessage(&msg);
    DispatchMessage(&msg);
}
This will enebls your program to handle messages when it is inside the loop
0
 
mingming_ewAuthor Commented:
I solved this problem by UpdateWIndow()

waiting solution for quitting the loop by pressing button
0
Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

 
pepenietoCommented:
I think that when you press the button, you must create a new task that will update the variable continuosly:

h=CreateThread(NULL,10000,<your function name>,NULL,NULL,&ThreadId);

....

and the function:

unsigned long _stdcall <function name>(void*t) {
  while(1) {
    UpdateData(false);
    // if you watn to kill this task in one moment, check here a semaphore with <WaitForSingleObject> and then <return 0;>
  }

This, you will have a task that only update the variables, but I can´t find utility for this because you can call UpdateData when you want this update.



0
 
ch52jbCommented:
If you want to trap the messages from the ok and cancel buttons, you need to do what norbert suggests.  This will allow the messages to be used.  What you can also do is add an event to the buttons to set a member variable, which you can monitor from inside the loop.
0
 
NorbertCommented:
Windows is an event driven system
The Operating system shedules the incomming events to the program that hosts the window where the event occures.
But it does not send them! The program have to poll for new events
so you have to call GetMessage or may be PeakMessage because GetMessage will wait until a message occures
you are using MFC so this Message Loop is hidden inside the deep of MFC
but it is still there.
If you Don't ask events are stored inside the queue but never tomething will happens
0
 
mingming_ewAuthor Commented:
Thanks for the input of everyone. However, I am a novice in VC++ and can't truly understand you guys valuable comment.

My program just have 2 button, one for quit, one for start counting.
m_a will keep counting in a loop after you press Button1 and will allow you to stop when you press Quit.

Can anyone post the code here? Coz I can't quite understand some of the comment above.
I though pepenieto's ans is close to what I want, but I dunno how to implement.
0
 
pepenietoCommented:
Here´s the code:
unsigned long __stdcall Increment(void*t) {
extern CDlg dlg;
      while (1) {
            res=WaitForSingleObject(m_Semaforo,5);
            if (res!=WAIT_OBJECT_0) {
                  // do something like...
                  dlg.Increment();
            } else {
                  break;
            }
      }
      return 0;
}

void CDlg::Increment() {
  m_var++;
}

void CDlg::Button1() {
      DWORD ThreadId;
      if (!m_switch) {
            h=CreateThread(NULL,10000,Increment,NULL,NULL,&ThreadId);
            m_switch=1;
      }
}

void CDlg::Button2() {
      if (m_switch) {
            ReleaseSemaphore(m_Semaforo,1,NULL);
            m_switch=0;
      }
}

.....

The next are class members (of CDlg):
      HANDLE m_Semaforo;
      int m_switch;
      m_var;

And the method CDlg::Increment() will be public.

This you create a new task that do all the work that you want to do in background, and at the same time the window process all messages (of course, if Button2 is pressed, the code associated will be executed) and you don´t have to write the process of the messages again.
0
 
pepenietoCommented:
Sorry, but CDlg::Increment() does not exist. It´s a function, not a method member of CDlg.
0
All Courses

From novice to tech pro — start learning today.