Thread: Problem with manually updating windows

  1. #1
    Registered User
    Join Date
    Dec 2004
    Posts
    20

    Problem with manually updating windows

    I wrote myself a little application that does some wild I/O on the hdd (hashing files to be precise). I'm using a window with a multline edit control for a simple output which files have been processed so far. Since I have no idea about multithreading (as far as I understand it such things should be done in worker threads), I just update the output window text out of the processing loop after each completed file. Because I'm not returning from my processing function, these updates won't be painted until all files are finished (kind of useless for a progress report ). So I tried to manually RedrawWindow() after each update. Interestingly enough this works fine... until the output window loses focus once. After that no further updates are painted, only the whole bunch at once at function return.
    I'd really appreciate any ideas why this happens. And of course how to fix it .

    TIA

  2. #2
    Registered User joed's Avatar
    Join Date
    Mar 2004
    Posts
    59
    Might try putting a PeekMessage call within your processing loop to catch messages. If the program doesn't respond to messages for a few seconds, Windows freaks out. PeekMessage (with PM_REMOVE option) removes messages from the queue, although you might want to process WM_QUIT etc. You won't need to do it continuously, but perhaps every second or two. Hope that works.

  3. #3
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    Are you using UpdateWindow() after your InvalidateRect() call?

    This should post the paint msg directly to the callback, bypassing the OS and app msg que.
    "Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
    Friedrich Nietzsche

    "I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
    George Best

    "If you are going through hell....keep going."
    Winston Churchill

  4. #4
    Registered User
    Join Date
    Dec 2004
    Posts
    20
    Thank you very much joed, calling PeekMessage() once before redrawing the window did the trick.
    Still I'd like to know, why the updating process works without PeekMessage() as long as you don't move the focus away from the window. Is there some special message send from Windows to my window when it's not focused and should update, that doesn't get processed until I use PeekMessage()?

    @novacain:
    Actually I tried all combinations of InvalidateRect(), UpdateWindow() and RedrawWindow() while trying to get this to work. At the moment I use

    RedrawWindow(outputWnd.output(), 0, 0, RDW_INVALIDATE | RDW_ERASE | RDW_ERASENOW | RDW_UPDATENOW);

    Might be a little overkill .

  5. #5
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    PeekMessage() returns imediately even if there is no message (GetMessage() does not return until there is a message).

    This probably un-blocks a thread.

    MSDN
    "Messages sent between threads are processed only when the receiving thread executes message retrieval code. The sending thread is blocked until the receiving thread processes the message. However, the sending thread will process incoming nonqueued messages while waiting for its message to be processed."

    >>Actually I tried all combinations of InvalidateRect(), UpdateWindow() and RedrawWindow() while trying to get this to work.

    InvalidateRect(NULL,NULL,TRUE);//redraw all windows full client areas and backgrounds
    UpdateWindow(NULL);//post directly to the callback
    "Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
    Friedrich Nietzsche

    "I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
    George Best

    "If you are going through hell....keep going."
    Winston Churchill

  6. #6
    Registered User
    Join Date
    Dec 2004
    Posts
    20
    Since I have no idea about multithreading this might be totally off, but doesn't your quote from MSDN refer to sending messages between different threads in one process?

    In my previous post I speculated, that windows sends some special message to my window when it's unfocused and should update, which is not processed until I use PeekMessage() (and subsequent dispatch them). But it also works with just removing those messages... Maybe windows stops sending messages to queues that were inactive for too long or the queue is full (don't think so).

    Well, it is working for now. But since I failed to understand the real reason for the problem, I might run into related problems at another time.

    Edit:
    Are there any advantages if I use InvaildateRect and UpdateWindow instead of RedrawWindow?
    Last edited by New++; 07-11-2005 at 11:16 AM.

  7. #7
    Registered /usr
    Join Date
    Aug 2001
    Location
    Newport, South Wales, UK
    Posts
    1,273
    While you probably don't want to get into full multithreading at this point in time, might I suggest that you persue a "dual-threaded" model instead? One thread for your processing, the other for the GUI (Really all programs should have a seperate thread for the GUI).

    Read up on CreateThread and have a go.

    P.S. I think RedrawWindow calls InvalidateRect and UpdateWindow in most cases, depending on the flags.

  8. #8
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    Sorry to confuse............

    >>Since I have no idea about multithreading this might be totally off,
    Soory misread your original post and thought you were using threads to process the files (and they were blocking).

    >>Maybe windows stops sending messages to queues that were inactive for too long or the queue is full (don't think so).

    Paint and timer msgs can be 'ignored', that is they have the lowest priority and other msgs will be processed before them.
    Thats the only advantage of using UpdateWindow() and posting directly to the windows callback. Though RDW_UPDATENOW may do same.
    "Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
    Friedrich Nietzsche

    "I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
    George Best

    "If you are going through hell....keep going."
    Winston Churchill

  9. #9
    Registered User
    Join Date
    Dec 2004
    Posts
    20
    Quote Originally Posted by novacain
    >>Maybe windows stops sending messages to queues that were inactive for too long or the queue is full (don't think so).

    Paint and timer msgs can be 'ignored', that is they have the lowest priority and other msgs will be processed before them.
    Thats the only advantage of using UpdateWindow() and posting directly to the windows callback. Though RDW_UPDATENOW may do same.
    It seems this time I was confused. Indeed RedrawWindow with RDW_UPDATENOW sends its messages directly and does not return before they are executed. So if the queue could be full or not doesn't really matter.
    But if this is the whole truth, using PeekMessage() to remove just one message from the queue (no dispatch or anything) when manually updating the window shouldn't be necessary (or even making it work), should it? Argh, help.

    I'd really like to understand exactly what is the reason for windows not longer updating the window after my RedrawWindow() call (which works fine) when the window lost focus once, and why removing messages from the queue (which is not used for RedrawingWindow()) solves the problem. Are there any other resources on the web I could look into (Besides MSDN)?

  10. #10
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    Be careful....

    Some times you just have to accept...

    You are dealing with Windows....

    some things are better not explained...

    and some things can't be explained.



    "Once you have discounted the impossible, whatever remains, no matter how improbable, is your solution." Sherlock Holmes (A.C. Doyle)
    "Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
    Friedrich Nietzsche

    "I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
    George Best

    "If you are going through hell....keep going."
    Winston Churchill

  11. #11
    Registered User joed's Avatar
    Join Date
    Mar 2004
    Posts
    59
    Window detects an infinite loop if messages are not gotten in a few seconds time. In XP at least, the window turns white and the frame changes to allow the user to close the program. Without this feature, a user would have to CTRL-ALT-DEL and hunt down the crashed program in the Task Manager.

  12. #12
    Registered User
    Join Date
    Dec 2004
    Posts
    20
    I see. Are such features documented somewhere, or do just pick them up with experience?

    Well, sooner or later I'll have to look into multithreading and then these kinds of problems will be in the past (replaced by new ones ). Thanks for the help.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. windows problem
    By ElastoManiac in forum Windows Programming
    Replies: 3
    Last Post: 11-25-2005, 07:17 AM
  2. Application Termination Problem in Windows XP
    By wasabee in forum Windows Programming
    Replies: 2
    Last Post: 04-11-2003, 12:53 PM
  3. C++ Gurus, UNIX vs. Windows ascii problem perhaps?
    By puck in forum C++ Programming
    Replies: 6
    Last Post: 03-28-2003, 10:33 PM
  4. problem with updating window....
    By Supar in forum Windows Programming
    Replies: 3
    Last Post: 05-23-2002, 10:25 PM
  5. Problem with Borland 5.5 Compiling Windows Programs
    By Unregistered in forum C++ Programming
    Replies: 3
    Last Post: 08-28-2001, 09:04 AM