Window procedure must be reentrant?
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 28

Thread: Window procedure must be reentrant?

  1. #1
    Join Date
    Jul 2005
    Posts
    894

    Window procedure must be reentrant?

    If so, what if I want to keep some information when one message is processed. Obviously I need to save such information in a global or static data. As the result, it makes window procedure non-reentrant.

  2. #2
    Join Date
    Jun 2008
    Posts
    592

    Re: Window procedure must be reentrant?

    I am not for sure what you're implying. You usually parse these message asap since they are only active during the procedure. If you feel the need to collect them for later, you can create a vector of messages.
    0100 0111 0110 1111 0110 0100 0010 0000 0110 1001 0111 0011 0010 0000 0110 0110 0110 1111 0111 0010
    0110 0101 0111 0110 0110 0101 0111 0010 0010 0001 0010 0001 0000 0000 0000 0000
    0000 0000 0000 0000

  3. #3
    Join Date
    Jun 2010
    Location
    Germany
    Posts
    2,571

    Re: Window procedure must be reentrant?

    What you say about global or static data is correct, but why not keep them in local variables? They would be located in the stack frame and each "call instance" of the window procedure would get its own set of them.

  4. #4
    Join Date
    Jul 2005
    Posts
    894

    Re: Window procedure must be reentrant?

    If I save them in local variables then next time I enter the window procedure again, I will lose them. So that is why I need to keep them in static or global variables. But that would make window procedure non-reentrant. I wonder if there is any requirement that Window procedure must be reentrant? Thanks.
    Quote Originally Posted by Eri523 View Post
    What you say about global or static data is correct, but why not keep them in local variables? They would be located in the stack frame and each "call instance" of the window procedure would get its own set of them.

  5. #5
    Join Date
    Jun 2010
    Location
    Germany
    Posts
    2,571

    Re: Window procedure must be reentrant?

    Quote Originally Posted by LarryChen View Post
    If I save them in local variables then next time I enter the window procedure again, I will lose them. So that is why I need to keep them in static or global variables.
    Maybe a way to make that issue less severe is to limit static/global storage to certain message handlers rather than the entire window procedure. If you still got reentrance issues then, you might implement some syncronization stuff and/or something like the vector approach suggested by Joeman.

    On the sidenote: That vector approach somehow resembles something like your own local message queue. Interesting picture...

  6. #6
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    5,877

    Re: Window procedure must be reentrant?

    If so, what if I want to keep some information when one message is processed. Obviously I need to save such information in a global or static data.
    Absolutely not obvious. You may allocate a structure/object/memory and pass the pointer to CreateWindow. There in WM_CREATE handler you store it in window properties and use whenever you want that later.
    Best regards,
    Igor

  7. #7
    Join Date
    Jul 2005
    Posts
    894

    Re: Window procedure must be reentrant?

    Can you explain in more details how to allocate a structure/object/memory and pass the pointer to CreateWindow? I couldn't relate SetProp with CreateWindow. Thanks a lot.
    Quote Originally Posted by Igor Vartanov View Post
    Absolutely not obvious. You may allocate a structure/object/memory and pass the pointer to CreateWindow. There in WM_CREATE handler you store it in window properties and use whenever you want that later.

  8. #8
    Join Date
    Jun 2008
    Posts
    592

    Re: Window procedure must be reentrant?

    What You do is this

    Code:
    CreateWindowEx
     (
                0,
                "class name here",
                "window name here",
                WS_OVERLAPPEDWINDOW |  WS_VISIBLE ,
                x,
                y,
                Width,
                Height,
                HWND_DESKTOP,
                NULL,
                Instance_Here,
                (void*)this
     );
    In your procedure add
    Code:
        if( message == WM_NCCREATE )
        {
            cWindow* Window = (cWindow*)(LPCREATESTRUCT(lParam))->lpCreateParams;
            if( Window == 0 ) do error code here;
            else
            {
                if( SetProp( hwnd, "C++_Pointer", (void*)Window ) == 0 ) do error code here;
                else
                {
                    // call init setup
                    Window_Count++;
                }
            }
    
            return DefWindowProc( hwnd, message, wParam, lParam );
        }
    
        if( message == WM_NCDESTROY )
        {
            if( RemoveProp( hwnd, "C++_Pointer" ) == 0) do error code here;
            else
            {
                Window_Count--;
                if( Window_Count == 0 ) PostQuitMessage( 0 );
            }
    
            return DefWindowProc( hwnd, message, wParam, lParam );
        }
    
        void* Handle = GetProp( hwnd, "C++_Pointer" );
    
        if( Handle == 0 && message != WM_GETMINMAXINFO ) do error code here;
        else if( Handle == 0 ) return DefWindowProc( hwnd, message, wParam, lParam );
    
        return Window->Parse( message, wParam, lParam );
    This is code I use, but I removed the error checking and it is incomplete as you can see. This is just an example and not a how to guide.
    0100 0111 0110 1111 0110 0100 0010 0000 0110 1001 0111 0011 0010 0000 0110 0110 0110 1111 0111 0010
    0110 0101 0111 0110 0110 0101 0111 0010 0010 0001 0010 0001 0000 0000 0000 0000
    0000 0000 0000 0000

  9. #9
    Join Date
    Jul 2005
    Posts
    894

    Re: Window procedure must be reentrant?

    Thanks for the example and it is very helpful.
    Quote Originally Posted by Joeman View Post
    What You do is this

    Code:
    CreateWindowEx
     (
                0,
                "class name here",
                "window name here",
                WS_OVERLAPPEDWINDOW |  WS_VISIBLE ,
                x,
                y,
                Width,
                Height,
                HWND_DESKTOP,
                NULL,
                Instance_Here,
                (void*)this
     );
    In your procedure add
    Code:
        if( message == WM_NCCREATE )
        {
            cWindow* Window = (cWindow*)(LPCREATESTRUCT(lParam))->lpCreateParams;
            if( Window == 0 ) do error code here;
            else
            {
                if( SetProp( hwnd, "C++_Pointer", (void*)Window ) == 0 ) do error code here;
                else
                {
                    // call init setup
                    Window_Count++;
                }
            }
    
            return DefWindowProc( hwnd, message, wParam, lParam );
        }
    
        if( message == WM_NCDESTROY )
        {
            if( RemoveProp( hwnd, "C++_Pointer" ) == 0) do error code here;
            else
            {
                Window_Count--;
                if( Window_Count == 0 ) PostQuitMessage( 0 );
            }
    
            return DefWindowProc( hwnd, message, wParam, lParam );
        }
    
        void* Handle = GetProp( hwnd, "C++_Pointer" );
    
        if( Handle == 0 && message != WM_GETMINMAXINFO ) do error code here;
        else if( Handle == 0 ) return DefWindowProc( hwnd, message, wParam, lParam );
    
        return Window->Parse( message, wParam, lParam );
    This is code I use, but I removed the error checking and it is incomplete as you can see. This is just an example and not a how to guide.

  10. #10
    Join Date
    Aug 2010
    Posts
    51

    Smile Re: Window procedure must be reentrant?

    hi,


    I enter the window procedure again, I will lose them. So that is why I need to keep them in static or global variables. But that would make window procedure non-reentrant. I wonder if there is any requirement that Window procedure must be reentran

    thanks


    regards,
    phe9oxis,
    http://www.guidebuddha.com

  11. #11
    Join Date
    Jul 2005
    Posts
    894

    Re: Window procedure must be reentrant?

    If I want to show the time when the window was opened in the window last time, how can I do that by using SetProp and GetProp? If I save the time when processing WM_CREATE, then the time I get is always current time.
    Thanks.
    Quote Originally Posted by Joeman View Post
    What You do is this

    Code:
    CreateWindowEx
     (
                0,
                "class name here",
                "window name here",
                WS_OVERLAPPEDWINDOW |  WS_VISIBLE ,
                x,
                y,
                Width,
                Height,
                HWND_DESKTOP,
                NULL,
                Instance_Here,
                (void*)this
     );
    In your procedure add
    Code:
        if( message == WM_NCCREATE )
        {
            cWindow* Window = (cWindow*)(LPCREATESTRUCT(lParam))->lpCreateParams;
            if( Window == 0 ) do error code here;
            else
            {
                if( SetProp( hwnd, "C++_Pointer", (void*)Window ) == 0 ) do error code here;
                else
                {
                    // call init setup
                    Window_Count++;
                }
            }
    
            return DefWindowProc( hwnd, message, wParam, lParam );
        }
    
        if( message == WM_NCDESTROY )
        {
            if( RemoveProp( hwnd, "C++_Pointer" ) == 0) do error code here;
            else
            {
                Window_Count--;
                if( Window_Count == 0 ) PostQuitMessage( 0 );
            }
    
            return DefWindowProc( hwnd, message, wParam, lParam );
        }
    
        void* Handle = GetProp( hwnd, "C++_Pointer" );
    
        if( Handle == 0 && message != WM_GETMINMAXINFO ) do error code here;
        else if( Handle == 0 ) return DefWindowProc( hwnd, message, wParam, lParam );
    
        return Window->Parse( message, wParam, lParam );
    This is code I use, but I removed the error checking and it is incomplete as you can see. This is just an example and not a how to guide.

  12. #12
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    5,877

    Re: Window procedure must be reentrant?

    If I save the time when processing WM_CREATE, then the time I get is always current time.
    Then the problem is somewhere in your "get" code.
    Best regards,
    Igor

  13. #13
    Join Date
    Jul 2005
    Posts
    894

    Re: Window procedure must be reentrant?

    I think it is a design issue not coding issue. Whenever I open the window, the time saved to a struct is always current time when processing WM_CREATE. Basically I want to get last time when the window was opened. But unfortunately the last time is always overwritten by current time.
    Quote Originally Posted by Igor Vartanov View Post
    Then the problem is somewhere in your "get" code.

  14. #14
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    5,877

    Re: Window procedure must be reentrant?

    But unfortunately the last time is always overwritten by current time.
    You mean, some miracle happens in your program? Or silicon chips made a plot against you?
    I think it is a design issue not coding issue.
    I hardly see the difference. Design issue? Is that your design? Then just fix it.
    Best regards,
    Igor

  15. #15
    Join Date
    Jul 2005
    Posts
    894

    Re: Window procedure must be reentrant?

    Okey, here is my code. Basically I want to show last time when the window is opened. But current time is always shown instead. Would you please point out what mistake I made. Thanks.
    Code:
    LRESULT CALLBACK windowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
    
    TCHAR szName[] = _T("Hello window");
    
    struct time_tag
    {
    	char* time;
    };
    
    
    int APIENTRY WinMain(HINSTANCE hInstance,
                         HINSTANCE hPrevInstance,
                         LPSTR     lpCmdLine,
                         int       nCmdShow)
    {
     	// TODO: Place code here.
    
    	WNDCLASS wndClass;
    	MSG msg;
    
    	wndClass.lpszClassName = szName;
    	wndClass.lpfnWndProc = windowProc;
    	wndClass.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1));
    	wndClass.hCursor = LoadCursor(hInstance, MAKEINTRESOURCE(IDC_CURSOR1));
    	wndClass.lpszMenuName = NULL;
    	wndClass.cbClsExtra = 0;
    	wndClass.cbWndExtra = 0;
    	wndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    	wndClass.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
    	wndClass.hInstance = hInstance;
    
    
    	if(!RegisterClass(&wndClass))
    	{
    		return 1;
    	}
    
    
    	time_t t = time(NULL);
    	char* s = ctime(&t);
    	time_tag _time;
    
    	_time.time = s;
    
    	HWND hwnd = CreateWindow(szName, _T("hello"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,CW_USEDEFAULT,
    		                     CW_USEDEFAULT,CW_USEDEFAULT, NULL, NULL, hInstance, (void*)&_time);
    
    	ShowWindow(hwnd, nCmdShow);
    
    	while(GetMessage(&msg, NULL, 0, 0))
    	{
    		TranslateMessage(&msg);
    		DispatchMessage(&msg);
    	}
    
    	return 0;
    } 
    
    
    LRESULT _stdcall windowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
    	PAINTSTRUCT ps;
    	HDC hdc;
        
    	switch(msg)
    	{
    	case WM_CREATE:
    		{        
    		time_tag* pTimeTag;
    		pTimeTag = (time_tag*)((LPCREATESTRUCT)lParam)->lpCreateParams;
    
    		if(pTimeTag)
    		{
    			if(!SetProp(hwnd, _T("Last Time"), (void*)pTimeTag))
    				MessageBox(hwnd, _T("Failed setting time"), NULL, MB_OK);
    		}
    		return 0;
    		}
    	case WM_PAINT:
    		{
    		hdc = BeginPaint(hwnd, &ps);
    		RECT rect;
    		GetClientRect(hwnd, &rect);
    
    		time_tag* _time = (time_tag*)GetProp(hwnd, _T("Last Time"));
    
    		TCHAR* t_s = A2T(_time->time);
    		if(_time) 
    			TextOut(hdc, (rect.right - rect.left)/2, (rect.bottom - rect.top)/2, t_s, lstrlen(t_s)-1);
        	EndPaint(hwnd, &ps);
    		}
    		return 0;
    	case WM_DESTROY:	
    		PostQuitMessage(0);
    		return 0;
    	}
    	return DefWindowProc(hwnd, msg, wParam, lParam);
    }
    Quote Originally Posted by Igor Vartanov View Post
    You mean, some miracle happens in your program? Or silicon chips made a plot against you?
    I hardly see the difference. Design issue? Is that your design? Then just fix it.

Page 1 of 2 12 LastLast

Posting Permissions

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


Azure Activities Information Page

Windows Mobile Development Center


Click Here to Expand Forum to Full Width

This is a CodeGuru survey question.


Featured


HTML5 Development Center