Click to See Complete Forum and Search --> : Why I can't quit properly?


Freeman Yan
April 1st, 2003, 10:54 PM
When I try the code in the book "Programming Windows" by Charles Petzold, I always can't quit from the program properly.

I used the code like this:

case WM_DESTROY:
PostQuitMessage(0);
return 0;

to quit. The window can be closed every time, but there still a process left in Windows. Then next time, when I want to compile it and run again, the VC6 will give out an error.

What makes this happen? Thank you in advance!

CBasicNet
April 2nd, 2003, 12:19 AM
It is hard to determine what is wrong, from the limited information you are giving.

Is it possible for you to post the message loop?

Is it a multithreaded app?

filthy_mcnasty
April 2nd, 2003, 01:36 AM
process WM_CLOSE in the same manner instead of WM_DESTROY

Freeman Yan
April 2nd, 2003, 02:40 AM
process WM_CLOSE in the same manner instead of WM_DESTROY

Thanks! It works!

But another strange problem appeared. If I don't resize or move the window, I can't close it by clicking the cross at the right top corner. But the Alt+F4 works anyway.

Thank you again!

Freeman Yan
April 2nd, 2003, 02:43 AM
Originally posted by CBasicNet
Is it possible for you to post the message loop?

Is it a multithreaded app?

Thank you! It is a very simple program. The message loop is:

switch (message)
{
case WM_RBUTTONDOWN:
iCount = -1;
InvalidateRgn(hwnd, NULL, TRUE);
return 0;

case WM_LBUTTONDBLCLK:
//MessageBox(NULL, "Left button pressed!", "Reminder", MB_OK);
++iCount;
pt[iCount].x = GET_X_LPARAM(lParam);
pt[iCount].y = GET_Y_LPARAM(lParam);

//InvalidateRgn(hwnd, NULL, TRUE);
hdc = GetDC(hwnd);
Ellipse(hdc, pt[iCount].x-5, pt[iCount].y, pt[iCount].x+15, pt[iCount].y+20);
TextOut( hdc, pt[iCount].x, pt[iCount].y, TEXT("1"), 1);
ReleaseDC(hwnd, hdc);
return 0;

case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);

GetClientRect(hwnd, &rect);

//TextOut( hdc, nX, nY, TEXT("1"), 1);
for (i=0; i<=iCount; ++i)
{
Ellipse(hdc, pt[i].x-5, pt[i].y, pt[i].x+15, pt[i].y+20);
TextOut( hdc, pt[i].x, pt[i].y, TEXT("1"), 1);
}

EndPaint(hwnd, &ps);
return 0;

case WM_CLOSE:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);

I just practise how to draw texts and graphics in a window.

Freeman Yan
April 3rd, 2003, 12:44 AM
I have simplified the code to this, but it still can't be closed properly! There is always something left. I have to use ctrl+alt+delete to find it and remove. :( Please give me some advice. Thanks!

#include <windows.h>
#include <Windowsx.h>
#include <Mmsystem.h>

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// TODO: Place code here.
static TCHAR szAppName[] = TEXT("TryToDraw");

HWND hwnd;
MSG msg;
WNDCLASS wndclass;

wndclass.lpszClassName = szAppName;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hIcon = LoadIcon(NULL, IDI_WINLOGO);
wndclass.hInstance = hInstance;
wndclass.lpfnWndProc = WndProc;
wndclass.lpszMenuName = NULL;
wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;

if ( !RegisterClass(&wndclass) )
{
MessageBox(NULL, TEXT("Go"), szAppName, MB_ICONERROR);
return 0;
}

hwnd = CreateWindow(
szAppName, // registered class name
TEXT("The Program for Clicking"), // window name
WS_OVERLAPPEDWINDOW, // window style
CW_USEDEFAULT, // horizontal position of window
CW_USEDEFAULT, // vertical position of window
CW_USEDEFAULT, // window width
CW_USEDEFAULT, // window height
NULL, // handle to parent or owner window
NULL, // menu handle or child identifier
hInstance, // handle to application instance
NULL // window-creation data
);

ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);

while (GetMessage(&msg, hwnd, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}

return msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
RECT rect;

switch (message)
{
case WM_CREATE:
PlaySound(TEXT("hellowin.wav"), NULL, SND_FILENAME | SND_ASYNC);
return 0;

case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);

GetClientRect(hwnd, &rect);

EndPaint(hwnd, &ps);
return 0;

case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}

preetham
April 3rd, 2003, 02:21 AM
instead of using return 0, use break;
I guess only then will the message processing be complete.
In your case(return 0) DefWindowProc() will never be executed.
Regards,
Preetham.
"All you touch and all you see will all you'll ever be"

filthy_mcnasty
April 3rd, 2003, 11:36 AM
case WM_DESTROY and everything:
default:
return DefWindowProc(hwnd, message, wParam, lParam);
}

return 0;

}


using return 0 is fine but then you have to set the very bottom of your code to look something like this instead. he's right, the defwindowproc part wont run set up like that.

Freeman Yan
April 3rd, 2003, 10:15 PM
Thank you, Preetham!

But the problem is still there after I converted the code into break.
Actually, in my previous case (return 0), the DefWindowProc also can be executed. Otherwise, the program window won't show.

Originally posted by preetham
instead of using return 0, use break;
I guess only then will the message processing be complete.
In your case(return 0) DefWindowProc() will never be executed.
Regards,
Preetham.

Freeman Yan
April 3rd, 2003, 10:35 PM
Thank you, filthy_mcnasty!

I tried to create a new project in VC++ 6.0. This time, the project is simple "hellowin" project. Then I copied the message loop part to the new project. The problem disappeared! So I think if the problem is caused by other parts?

Regards,
Freeman

filthy_mcnasty
April 3rd, 2003, 10:48 PM
well basically the way you had it set up it wasn't running DefWindowProc to properly close everything out. if any of those messages were hit *WM_DESTROY in the case of the window closing* it wouldn't run that function.

Freeman Yan
April 3rd, 2003, 11:48 PM
Dear all,

Thank you for your kindness! I have found the problem. It is caused by

while (GetMessage(&msg, hwnd, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}

The second param of GetMessage() should be NULL here... I am sorry for troubling you with such a mistake. :p

Regards,
Freeman

filthy_mcnasty
April 4th, 2003, 12:00 AM
you're exactly right. goes to show how easy it is to overlook something like that.

glad you got it working.