If this is your first visit, be sure to
check out the FAQ by clicking the
link above. You may have to register or Login
before you can post: click the register link above to proceed. To start viewing messages,
select the forum that you want to visit from the selection below.

Everything was working perfectly till I decided to update few **STATIC** controls' text with SetWindowText during an event which occurs in a different thread periodically, approximately once per second, the text on the STATIC controls gets updated only in every 10th iteration of this event. I am using SendMessage() to send WM_USER message to the main window which in turn updates the STATIC controls.

Now the skin of the window just goes away after a minute or so of running the app and there only remains grey rectangle, the buttons which have custom skins set with **BM_SETIMAGE** doesn't get affected by this error.

Now I am totally out of ideas on what would be going wrong. What you think I should be taking care of while doing something like this ?

**If I stop the update of the STATIC controls in the WM_USER handler, the graphic problem goes away.**

Everything was working perfectly till I decided to update few **STATIC** controls' text with SetWindowText during an event which occurs in a different thread periodically, approximately once per second, the text on the STATIC controls gets updated only in every 10th iteration of this event. I am using SendMessage() to send WM_USER message to the main window which in turn updates the STATIC controls.

You provide no details on how your main window really "updates the STATIC controls". Besides, considering the fact that SendMessage blocks GUI thread when called from other thread I would say that some other way needed for notifying GUI thread. First I would try to switch to PostMessage. Another thing is WM_USER which message is not recommended to use, and WM_APP must be used instead.

And I can see no reason to blit bitmap separately from texting out. The text may be output to memory dc alright, and the only action affecting paint dc would be the final blit.

Now the skin of the window just goes away after a minute or so of running the app and there only remains grey rectangle, the buttons which have custom skins set with **BM_SETIMAGE** doesn't get affected by this error.

That grey rectangle gives me an impression of you exhausting GDI handles by not properly releasing GDI resources. Not obligatory this is related to your static updates.

**If I stop the update of the STATIC controls in the WM_USER handler, the graphic problem goes away.**

I must say, out of all the forums I have asked yours is the most educated answer

Originally Posted by Igor Vartanov

You provide no details on how your main window really "updates the STATIC controls".

I was Setting the text of the controls with SetWindowText(), then I changed it to SendMessage( WM_SETTEXT ) and this change did affect the problem, In the short run that I was able to test the app it didn't reproduce the graphic error.

Originally Posted by Igor Vartanov

Besides, considering the fact that SendMessage blocks GUI thread when called from other thread I would say that some other way needed for notifying GUI thread. First I would try to switch to PostMessage

I was using PostMessage but on an another forum people suggested that I should use SendMessage then I don't have to worry about synchronization. But I guess since I am sending pointers to global string through WM_USER and even if the values of these string change it won't affect the outcome, I am safe ??

Originally Posted by Igor Vartanov

Another thing is WM_USER which message is not recommended to use, and WM_APP must be used instead.

Wasn't even aware about WM_APP(am new to this stuff), can you please explain why I should use WM_APP instead ?

Originally Posted by Igor Vartanov

And I can see no reason to blit bitmap separately from texting out. The text may be output to memory dc alright, and the only action affecting paint dc would be the final blit.

Point taken.

Originally Posted by Igor Vartanov

That grey rectangle gives me an impression of you exhausting GDI handles by not properly releasing GDI resources. Not obligatory this is related to your static updates.

Hmm. possibly the best explanation of the problem cause I have found till, seems logical, I will check if there are GDI leaks.

I was Setting the text of the controls with SetWindowText(), then I changed it to SendMessage( WM_SETTEXT ) and this change did affect the problem, In the short run that I was able to test the app it didn't reproduce the graphic error.

As I can see from your code, the text is provided via text_format structure. So why would you use native SetWindowText call?

In case you provide the text this way, the only thing you need to update the static window is InvalidateRect(hwndStatic, NULL, TRUE).

Besides, there's no need to do that in main thread, as entire Windows API is thread safe, and therefore you can InvalidateRect or SetWindowText immediately in context of your worker thread alright. Of course in case of InvalidateRect+WM_PAINT your text reading/writing must have a protection against simultaneous access, by means of critical section, for example.

I was using PostMessage but on an another forum people suggested that I should use SendMessage then I don't have to worry about synchronization. But I guess since I am sending pointers to global string through WM_USER and even if the values of these string change it won't affect the outcome, I am safe ??

Yes, you're right, posting messages doesn't get along with pointers. But I cannot see any reason so far for passing pointers to notify your main thread to update static texts. (see above)

Wasn't even aware about WM_APP(am new to this stuff), can you please explain why I should use WM_APP instead ?

WM_USER came from Windows 3.x ages. Windows 95/NT provide new style common controls like list view, header bar, tool bar, etc., that internally use WM_USER. So to avoid any conflicts applications must use WM_APP and upper values for their custom messages.

As I can see from your code, the text is provided via text_format structure. So why would you use native SetWindowText call?

In case you provide the text this way, the only thing you need to update the static window is InvalidateRect(hwndStatic, NULL, TRUE).

Besides, there's no need to do that in main thread, as entire Windows API is thread safe, and therefore you can InvalidateRect or SetWindowText immediately in context of your worker thread alright. Of course in case of InvalidateRect+WM_PAINT your text reading/writing must have a protection against simultaneous access, by means of critical section, for example.

The WM_PAINT handler is for the main window, its not for STATIC control. I was advised to never update window from another thread, so I changed it such a way that whenever the static control in needed to be updated with anew text the main window is sent a message(WM_APP) and in that message handler the new text is set. Prior to that I was simple updating the static controls from worker thread.

Originally Posted by Igor Vartanov

Yes, you're right, posting messages doesn't get along with pointers. But I cannot see any reason so far for passing pointers to notify your main thread to update static texts. (see above)

WM_USER came from Windows 3.x ages. Windows 95/NT provide new style common controls like list view, header bar, tool bar, etc., that internally use WM_USER. So to avoid any conflicts applications must use WM_APP and upper values for their custom messages.

Writer locks the storage, writes data, unlocks the storage and posts a notification message to main thread

Main thread pumps its message queue, finally gets the notification message, locks the storage, reads data to a local buffer, unlocks the storage, updates static control text with the text copy in local bufer

The whole sense of this complex exchange is the only: nobody locks anybody's thread while updating GUI controls. In the light of this your approach makes no sense: SendMessage locks worker thread and intrudes into normal message pumping. As for me it's much better to let Windows decide how to do the task most effective way.