-
August 6th, 2010, 07:07 PM
#1
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.
-
August 6th, 2010, 07:18 PM
#2
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
-
August 6th, 2010, 07:21 PM
#3
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.
-
August 6th, 2010, 07:44 PM
#4
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.
Originally Posted by Eri523
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.
-
August 6th, 2010, 08:00 PM
#5
Re: Window procedure must be reentrant?
Originally Posted by LarryChen
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...
-
August 7th, 2010, 12:30 AM
#6
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
-
August 7th, 2010, 07:57 PM
#7
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.
Originally Posted by Igor Vartanov
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.
-
August 7th, 2010, 11:57 PM
#8
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
-
August 8th, 2010, 09:30 PM
#9
Re: Window procedure must be reentrant?
Thanks for the example and it is very helpful.
Originally Posted by Joeman
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.
-
August 12th, 2010, 12:35 AM
#10
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
-
August 18th, 2010, 12:56 PM
#11
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.
Originally Posted by Joeman
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.
-
August 18th, 2010, 01:50 PM
#12
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
-
August 18th, 2010, 02:13 PM
#13
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.
Originally Posted by Igor Vartanov
Then the problem is somewhere in your "get" code.
-
August 18th, 2010, 04:21 PM
#14
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
-
August 18th, 2010, 05:35 PM
#15
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);
}
Originally Posted by Igor Vartanov
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.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|