Hi,
I have created a simple dialog application in which I have a button and a status window. I have managed to properly display status messages to this status window using sendmessage when the user hits the button. However, there seem to be a timing issue when I try to go fancy...

I want it to behave like this:

When button is pressed:
- Display "Running..." as the status mesage
- Run a procedure (takes many seconds)
- Append " DONE" to the status message and display it.

When I coded this, what happens is that "Running...DONE" is displayed after the procedure is run which takes a few seconds. Nothing was displayed before the procedure started. Are the send messaged supposed to be instant? If not, is there a way I can trigger it to display it instantly?

I should add that I added these messages in the switch/case structure for the controls in the window. The main event loop contains the TranslateMessage and DispatchMessage functions. Perhaps that is the reason for the issue. I just don't know where to put my procedure so that I can get the desired functionality...

Thanks!

Recommended Answers

All 5 Replies

Yeah, the SendMessage command is instant.

I assume that your status window object had processed the sent message properly, please try its UpdateWindow method to make sure the update information appeared.

If I were to code something like that I'd have two window classes registered, i.e., a main program window that in your case apparently has the button on it, and a display/output/status window that appears when the button is clicked and is perhaps closed by the user ( [X] ) after processing is done. In such a case I'd have two window procedures in my program. I'd create the display/output/status window through a CreateWindowEx() call and at that point I'd have the hWnd of that window which I'd likely save one way or another because it needs to persist. Having that hWnd you would be able to get a device context for it and draw to it at any time and the results would be all but instantaneous. A fancier and more complex way to go about it would be to define a custom message to SendMessage() to the status window, and in either the wParam or lParam you could include a flag that could be checked when the status window receives the message. It could then do an InvalidateRect() / UpdateWindow() call to cause a specific message to be TextOut()'ed during the WM_PAINT. No code is shown so I'm not exactly sure what problem you are having, but what you are trying to do is quite easily doable.

Thanks for your inputs. Yes, sorry, I didn't add any code which I know makes it harder to understand this. My appkication is just a variation of the excellent tuturial you can find here:

http://www.relisoft.com/win32/windlg.html

The key section is this part of the main switch structure:

    case IDC_BUTTON3:
        if (command == BN_CLICKED)
          strcpy(statusMessage, "Processing data...");
          _status.SetString(statusMessage);
        // Run a process that takes 10 seconds.
          strcat(statusMessage, " DONE");
         _status.SetString(statusMessage);
        break;

Perhaps this will make it easier to understand.

The main event loop looks like this:

MSG  msg;
int status;
while ((status = GetMessage (&msg, 0, 0, 0)) != 0)
{
    if (status == -1)
        return -1;
    if (!IsDialogMessage (hDialog, &msg))
    {
        TranslateMessage ( &msg );
        DispatchMessage ( &msg );
    }
}

Any ideas as to why my send messaged are not instant?? It seems that they are sent AFTER the long process has completed and that is too late in this case.

Thanks,

I have to make a confession; I'm just not that good with the Windows Dialog Engine and almost never use it to do anything. Rather, I CreateWindow() all my windows. So, I might not be the best source of help here. However, here is a thought that may give you some ideas. You apparently need to get that dialog painted somehow quickly in response to something happening. The fact is the WM_PAINT message is a very low priority message in Windows, and what the operating system prefers to do rather than spending a lot of effort repainting windows is accumulate invalid regions within internal structures until the window desperately needs to be repainted, and then sends one WM_PAINT message with perhaps a great deal of 'dirty bits' in its 'Invalid Region'. That's probably why you are only getting one WM_PAINT at the end of the processing instead of one at the beginning and one at the end. So, like ebookfinder said, somehow you're going to have to force a WM_PAINT message both before and after. With CreateWindow() windows that is usually done with the InvalidateRect(), UpdateWindow() sequence. I expect that would work with dialogs, but I wouldn't bet my life or paycheck on it. Hope tis helps.

Hi again!
You guys are awesome!! You were both right on the spot. What happens is that my message gets stuck as the window is not updated just because I sent the message. I created a method following your advice:

   void Update (void)
   {
       UpdateWindow(_hWnd);
   }

And then I send the command: _status.Update(); when I want to update the window. It works like a charm. Here is how my case structure ended up looking like:

   case IDC_BUTTON3:
        if (command == BN_CLICKED)
        {_status.SetString("Wait...");
        _status.Update();
        Sleep(2000);
        _status.SetString("DONE!");}

Again, many thanks for pointing this out to me! What a great resource this is.

Cheers!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.