Link to home
Start Free TrialLog in
Avatar of mingming_ew
mingming_ew

asked on

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();
            }
}
Avatar of Norbert
Norbert
Flag of Germany image

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
Avatar of mingming_ew
mingming_ew

ASKER

I solved this problem by UpdateWIndow()

waiting solution for quitting the loop by pressing button
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.



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.
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
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.
ASKER CERTIFIED SOLUTION
Avatar of Dariusz Dziara
Dariusz Dziara
Flag of Poland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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.
Sorry, but CDlg::Increment() does not exist. It´s a function, not a method member of CDlg.