Click here to Skip to main content
13,140,231 members (47,887 online)
Rate this:
Please Sign up or sign in to vote.
See more:
Hello, guys
If the message handling time exceeds 5 seconds, the Window goes to "Not responding" state and the messages in message queue is not processed. Is there a simple function call to handle messages so that the window does not freeze?
Thanks in advance
Posted 24-Jan-13 11:06am

1 solution

Rate this: bad
Please Sign up or sign in to vote.

Solution 1

Typically, you need to do all lengthy operation in a different thread, other then UI thread. Manipulating with handling message is a really bad idea.

[EDIT: unrelated part of post removed; I did not notice this is a C application]

Any particular reason to use C, not even C++?

mr.abzadeh 24-Jan-13 18:12pm
Thanks, threading Ok, but for passing results to UI, I need some help in windows API because I program in native C.
Is calling the following function a good idea, somewhere in my lengthy calculation periodically?
void uDoEvents( HWND hWnd )
MSG uMsg;
while ( PeekMessageW( &uMsg, hWnd, 0, 0, PM_NOREMOVE ) )
int bRet = GetMessageW( &uMsg, hWnd, 0, 0 );
if ( bRet == 0 ) break;
if ( bRet == -1 ) break;
TranslateMessage( &uMsg );
DispatchMessage( &uMsg );
Sergey Alexandrovich Kryukov 24-Jan-13 18:22pm
Sorry, I did not notice this is a C application.
Threads, anyway. Don't get into trouble...
mr.abzadeh 24-Jan-13 18:24pm
For example, I created a new thread to burn data to cd, calling ICDBurn::Burn( hWnd ), buf the ICDBurn::Burn method appeared under my window, meaning that I should not pass hWnd to ICDBurn::Burn, because the calling thread had no window. How I should tell ICDBurn::Burn that hWnd will be it's Parent Window?
Sergey Alexandrovich Kryukov 24-Jan-13 19:01pm
There are two aspect of this: passing parameter and synchronization.

Google "pass parameter to thread windows", you will find out; thread method has a void pointer which you can use to pass any structure pointer.

Synchronization: you cannot do any UI operation in the non-UI thread; if you need to notify UI, pass HWND to thread and use PostMessage to pass some data to a window, with any information you want. You will pick up (handle) those messages in from a usual message processing mechanism. Better use some custom message ID, use anything started from WM_USER:

This is a raw style of doing it all.

mr.abzadeh 26-Jan-13 1:08am
Ok, It's good idea, but It may not help passing parameter hWnd in case lengthy calculations, at least in this case:
I have Window A, that wants to call this code:
ICDBurn::Burn( hWndA );
ICDBurn::Burn creates It's own Window, Say Window B, and sets Its parent window to hWndA, and Burns data to CD(lengthy calculation).
If I call ICDBurn::Burn( hWndA ) from a non-window thread, It works, But Window B will appear behind Window A, and my application's users will not notice It, and I can not post any message to hWndB because I do not have It's code. The only way is calling ICDBurn::Burn( hWndA ) from window A, or possibly another window, but this freezes the calling window and even controls on It. for example, the progress controls on Window A freeze. So, I think It's necessary to have a way to call UI functions that take long time, from a window thread, without freezing the calling window.
Can you please show me an Idea?
Nothing will freeze. You should execute Burn is a separate thread. Preemption will keep UI responsive (do you understand preemption, but the way?). OK. Now, it does not matter what's behind and what's not. You will put everything in Z-order the way you want, and activate the windows you want. Besides, as UI is always responsive, you can activate/deactivate during the Burn any time. Active or inactive state cannot affect the ability of the window to get, dispatch and handle all those custom messages (status, percentage of completion, etc.).
Is it all clear now?
mr.abzadeh 26-Jan-13 4:45am
Yes, It's clear. By using threads, every thing works well, except the following:
I do not know the window handle for Window B created by ICDBurn::Burn( hWndA );
So, I can not bring it to foreground, So I can do nothing in Z order.
However, I am able to find hWndB by calling this code:
HWND hWndB = FindWindowW( L"Burn to disc" );
but this code may not be portable as the window title may change in different versions of operating system.
It's evident that microsoft knew that window B shoud come to top of Z order, and parameter hWnd of ICDBurn::Burn( HWND hWnd ) is there so that the caller can specify the parent window of the window ICDBurn::Burn creates.
Separate creation of window and Burn. Burn should be 1) abstracted from UI (WM_* messages are not UI, it should be pure data), 2) executed in separate thread. All windows and other UI objects should be create/manipulated only in UI thread.
I hope, it resolves the issue.

By the way, alternative is using PostTheadMessage.
mr.abzadeh 26-Jan-13 4:55am
If no simple and portable way exists to control Z order of the window created by ICDBurn::Burn (or similar functions whose code is not accessible), This may be treated as a problem with microsoft windows, which must be resolved.
I only mentioned Z order to say: this is irrelevant. Actually, if you have some top-level windows, and activate some of them in certain order, it creates Z order between then. It's not related to your problem. I only mentioned it in reply to your concern that one window will be hidden under something. But the meaning of my answer was: it does not matter, show it the way you need, for thread synchronization, it does not matter, and UI will be kept responsive.
mr.abzadeh 26-Jan-13 5:54am
Thanks for your help. I got the answer of my questions
Great. You are welcome.
Good luck now, call again.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
Top Experts
Last 24hrsThis month

Advertise | Privacy |
Web03 | 2.8.170915.1 | Last Updated 24 Jan 2013
Copyright © CodeProject, 1999-2017
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100