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.
Printable View
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.
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.
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. ;)
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.
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... :cool:
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.Quote:
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.
What You do is this
In your procedure addCode:CreateWindowEx
(
0,
"class name here",
"window name here",
WS_OVERLAPPEDWINDOW | WS_VISIBLE ,
x,
y,
Width,
Height,
HWND_DESKTOP,
NULL,
Instance_Here,
(void*)this
);
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.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 );
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
Then the problem is somewhere in your "get" code. :)Quote:
If I save the time when processing WM_CREATE, then the time I get is always current time.
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.
You mean, some miracle happens in your program? Or silicon chips made a plot against you? :)Quote:
But unfortunately the last time is always overwritten by current time.
I hardly see the difference. Design issue? Is that your design? Then just fix it.Quote:
I think it is a design issue not coding issue.
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);
}