CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 12 of 12
  1. #1
    Join Date
    Jul 2006
    Posts
    75

    GetMessage : how to identify message

    Hi, everyone

    I'm checking messages in a message loop. After i call GetMessage i'm trying to identify message from message field of the MSG structure. I found that identifiers differs from those which are passed to window procedure as a uMsg parameter.
    Where can i find definitions?

  2. #2
    Join Date
    Nov 2002
    Location
    California
    Posts
    4,556

    Re: GetMessage : how to identify message

    Most message loops involve calls to GetMessage, TranslateMessage, and DispatchMessage. The TranslateMessage function can and will change the content of the message, so it is possible that the message is changed as between the time it is retrieved via GetMessage and the time that the WinProc sees it from DispatchMessage.

    As for definitions, they are found in windows.h, where you will see a variety of WM_xxx defines like:
    Code:
    #define WM_INITDIALOG                   0x0110
    #define WM_COMMAND                      0x0111
    Mike

  3. #3
    Join Date
    Jul 2006
    Posts
    75

    Re: GetMessage : how to identify message

    I'm using the following code:

    Code:
    while(GetMessage(&msg,0,0,0))
    	{
    		if(msg.message == WM_SIZE)
    			OutputDebugString(L"SIZE");
    		
    		TranslateMessage(&msg);
    		DispatchMessage(&msg);
    	}
    I want to catch WM_SIZE message. I never get into OutputDebugString.

  4. #4
    Join Date
    Apr 1999
    Posts
    27,449

    Re: GetMessage : how to identify message

    Quote Originally Posted by Sh@dow View Post
    I'm using the following code:

    Code:
    while(GetMessage(&msg,0,0,0))
    	{
    		if(msg.message == WM_SIZE)
    			OutputDebugString(L"SIZE");
    		
    		TranslateMessage(&msg);
    		DispatchMessage(&msg);
    	}
    I want to catch WM_SIZE message. I never get into OutputDebugString.
    How do we know it isn't an issue with OutputDebugString()?

    What if you just did this:
    Code:
    while(GetMessage(&msg,0,0,0))
    {
    	OutputDebugString(L"Message recieved");
    	TranslateMessage(&msg);
    	DispatchMessage(&msg);
    }
    Do you see anything now? If not, then you need to fix the issue with OutputDebugString. What if you resized the window? Do you see it sent then? If not, then Windows creates this message after your call to OutputDebugString.

    Regards,

    Paul McKenzie

  5. #5
    Join Date
    Jul 2006
    Posts
    75

    Re: GetMessage : how to identify message

    Do you see anything now? If not, then you need to fix the issue with OutputDebugString. What if you resized the window? Do you see it sent then? If not, then Windows creates this message after your call to OutputDebugString.
    I tried this. I see that messages arriving. I can capture WM_PAINT for example. But not WM_SIZE.
    I also tried this:
    Code:
    	while(GetMessage(&msg,0,0,0))
    	{
    		if(msg.message == WM_SIZE)
    			Sleep(1);		
    		TranslateMessage(&msg);
    		DispatchMessage(&msg);
    	}
    And put a breakpoint to Sleep(1). Never stopped there.

    I think that WM_SIZE is not placed into queue and WNdProc is called with WM_SIZE by other message but not sure.

  6. #6
    Join Date
    Jul 2006
    Posts
    75

    Re: GetMessage : how to identify message

    Yes. It seems that WM_SIZE is non queued message.

    I will describe the problem more deeply.

    I have a thread that creates a window. It has message loop and window proc. Working ok.
    I have another thread which send a WM_APP+xx message to it using PostThreadMessage.
    In message loop i first check if message is WM_APP if not process it as usual if yes do custom tasks.

    I found that when window is resized the WM_APP message is lost. PostThreadMessage returns OK always. I found that on resize many calls to WndProc occurs and messages sent at that time using PostThreaMessage are lost (GetMessage does not get them).

    MSDN states that:

    Messages sent by PostThreadMessage are not associated with a window. As a general rule, messages that are not associated with a window cannot be dispatched by the DispatchMessage function. Therefore, if the recipient thread is in a modal loop (as used by MessageBox or DialogBox), the messages will be lost. To intercept thread messages while in a modal loop, use a thread-specific hook.
    As i understand thread specific hook is that what i have:
    Code:
    while(GetMessage(&msg,0,0,0))
    	{
    		if(!FilterCommand(msg)) //true if WM_APP+xx false if not, custom job here
    		{
    			TranslateMessage(&msg);
    			DispatchMessage(&msg);
    		}
    	}
    So that is not and issue here.
    Than there is another note:
    The system only does marshalling for system messages (those in the range 0 to (WM_USER-1)). To send other messages (those >= WM_USER) to another process, you must do custom marshalling.
    I can't understand what is this about.

  7. #7
    Join Date
    Apr 1999
    Posts
    27,449

    Re: GetMessage : how to identify message

    Quote Originally Posted by Sh@dow View Post
    I tried this. I see that messages arriving. I can capture WM_PAINT for example. But not WM_SIZE.
    I also tried this:
    Code:
    	while(GetMessage(&msg,0,0,0))
    	{
    		if(msg.message == WM_SIZE)
    			Sleep(1);		
    		TranslateMessage(&msg);
    		DispatchMessage(&msg);
    	}
    And put a breakpoint to Sleep(1). Never stopped there.
    You didn't do what I stated. You didn't place that check after the call to TranslateMessage, or DispatchMessage. That is what I meant by the message may have been generated later by Windows.

    Regards,

    Paul McKenzie

  8. #8
    Join Date
    Jul 2006
    Posts
    75

    Re: GetMessage : how to identify message

    I have tried this:
    Code:
    	while(GetMessage(&msg,0,0,0))
    	{
    		if(!FilterCommand(msg))
    		{
    			TranslateMessage(&msg);
    			if(msg.message == WM_SIZE)
    			{
    				Sleep(1);
    			}
    			DispatchMessage(&msg);
    		}
    	}
    and this
    Code:
    	while(GetMessage(&msg,0,0,0))
    	{
    		if(!FilterCommand(msg))
    		{
    			TranslateMessage(&msg);
    			DispatchMessage(&msg);
    			if(msg.message == WM_SIZE)
    			{
    				Sleep(1);
    			}
    		}
    	}
    Never drop down into Sleep(1).
    FIlter command simply ckecks if message is WM_APP+xx or not:
    Code:
    	if(!((msg.message >=WM_APP)&&(msg.message<=0xBFFF)))
    	{
    		OutputDebugString(L"SYSTEM MESSAGE\n");	
    		return false;
    	}
             return true;

  9. #9
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,620

    Re: GetMessage : how to identify message

    As i understand thread specific hook is that what i have:
    No, you understand this wrong. Thread specific hook here is message filtering hook technique used specifically for dialogs.

    WH_MSGFILTER
    MessageProc callback function
    Best regards,
    Igor

  10. #10
    Join Date
    Jul 2006
    Posts
    75

    Re: GetMessage : how to identify message

    Here what i found about that:
    Messages sent to a UI thread through PostThreadMessage are lost if the messages are posted while the user is manipulating a window owned by the thread. Messages might be lost if they are sent while the user moves or resizes the window or if the window is a modal dialog box.
    When an UI thread is involved in modal behavior, the thread pumps messages in a message loop internal to the modal system rather than in the thread's main message loop. Messages that are posted to a window can still be dispatched to the window procedure of the target window, because the messages are associated with a window. However, thread messages need to be handled directly by the message loop, because they cannot be automatically dispatched elsewhere. Since the secondary message loop does not know about the thread message, it will be dropped.
    So there are main thread message loop and secondary internal message loop. When resize happens messages are sent to internal loop and not processed in thread's main loop.
    Am i correct?

  11. #11
    Join Date
    Nov 2002
    Location
    California
    Posts
    4,556

    Re: GetMessage : how to identify message

    Ans#1: WM_SIZE is never posted to the message queue, at least not by Windows. WM_SIZE is a sent message only, sent directly to the WndProc by Windows, so it will never be detected in the message loop.

    Ans#2: Never use PostThreadMessage to post a message to a thread that has a visible UI. You have already discovered the reason why: messages are lost when the window is in a modal loop, such as during resize or moving operations. Although it might be possible to install a thread-specific hook as mentioned in the docs (and indeed that is what MFC does to get past this issue), it's usually better to select a different mechanism for inter-thread communication.

    Why, for example, are you PostThreadMessage'ing the message to the thread? Couldn't you have a hidden window whose entire job is to listen for messages posted using the standard PostMessage, which is not encumbered by the problems of PostThreadMessage?

    Mike

  12. #12
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,620

    Re: GetMessage : how to identify message

    Quote Originally Posted by Sh@dow View Post
    When resize happens messages are sent to internal loop and not processed in thread's main loop.
    Am i correct?
    When in message loop, every message visits DispatchMessage. This system call analyzes user input (keyboard and mouse events) and synthesizes additional appropriate window messages if needed. In case when mouse input should result in window resizing, Windows synthesizes WM_SIZE and sends it immediately to target window. You can tell this by result of InSendMessage.

    Another possible effect is that a few messages could be produced based on a single user input event. Until the messages appear got and processed by window procedure, no other message from the thread message queue is received.

    Nonqueued Messages

    Hope this makes the situation with WM_SIZE more understandable.
    Last edited by Igor Vartanov; April 16th, 2012 at 07:55 PM.
    Best regards,
    Igor

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured