• Advertisement
Sign in to follow this  

Problem while exsiting loop.

This topic is 4217 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm havin problem while exiting the program after pressing ESC key. I'm using .NET2003,after initializing window and direct3d.when i press a key it should exist the window,it is doing so.But when i see the TASK MANAGER it shows tht program is running and it uses 99%of CPU. Here is my code:: #include<windows.h> //global declaration HINSTANCE hInstance; HWND wndHandle; //forward decl bool initWindow(HINSTANCE hInstance); LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM); bool initDirect3D(HWND); void render(); void cleanup(); BOOL keyboard_handler(WPARAM); //Entry point int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance, LPSTR nCmdLine,int CmdShow) { //initialize window if(!initWindow(hInstance)) return false; if(!initDirect3D(wndHandle)) return false; //main message loop MSG msg; ZeroMemory(&msg,sizeof(msg)); while(msg.message!=WM_QUIT) { //check the message queue if(PeekMessage(&msg,wndHandle,0U,0U,PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); } else { render(); } } return (int)msg.wParam; } bool initWindow(HINSTANCE hInstance) { //Register class WNDCLASSEX wcex; wcex.cbSize=sizeof(WNDCLASSEX); wcex.style=CS_HREDRAW|CS_VREDRAW; wcex.lpfnWndProc = (WNDPROC)WndProc; wcex.cbClsExtra=0; wcex.cbWndExtra=0; wcex.hInstance=hInstance; wcex.hIcon=0; wcex.hCursor=LoadCursor(NULL,IDC_ARROW); wcex.lpszClassName="Game"; wcex.hbrBackground=(HBRUSH)(COLOR_WINDOW+1); wcex.lpszMenuName=NULL; wcex.hIconSm=0; RegisterClassEx(&wcex); //create window wndHandle=CreateWindow("Game","Game",WS_EX_TOPMOST|WS_POPUP|WS_VISIBLE, CW_USEDEFAULT,CW_USEDEFAULT, 640,480,NULL,NULL,hInstance,NULL); if(!wndHandle) return false; //Display window ShowWindow(wndHandle,SW_SHOW); UpdateWindow(wndHandle); cleanup();//release d3d device n object return true; } //window proc LRESULT CALLBACK WndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam) { switch(message) { case WM_DESTROY: PostQuitMessage(0); break; case WM_KEYDOWN: if(keyboard_handler(wParam)) DestroyWindow(hWnd); break; } return DefWindowProc(hWnd,message,wParam,lParam); } //Keyboard handler BOOL keyboard_handler(WPARAM keystroke) { BOOL result=FALSE; switch(keystroke) { case VK_ESCAPE : result=TRUE;break; } return result; } Pls tell me wht is a problem,why i'm not existing the program correctly and why it is running in background.

Share this post


Link to post
Share on other sites
Advertisement
I think you need to send a WM_CLOSE instead of a 'DestroyWindow' when you want to exit. The WM_CLOSE will in turn do the DestroyWindow. However I'm not sure if that's the real problem.

Share this post


Link to post
Share on other sites
In WndProc(), when you handle a message, you are not suppose to also call DefWindowProc(). Only call DefWindowProc() if you do not handle the message yourself. This usually means that instead of a break statement at the end of a case block, you use a return statement to immediately return out of the function. Usually you return 0, although it can depend based on which message you handle. Look at the documentation for each message to make sure.

By the way, my basic window procedure usually looks like this:

LRESULT CALLBACK WndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)
{
switch(message)
{
case WM_CLOSE:
{
DestroyWindow(hWnd);
return 0;
}
case WM_DESTROY:
{
PostQuitMessage(0);
return 0;
}
}
return DefWindowProc(hWnd,message,wParam,lParam);
}

To add in your WM_KEYDOWN message handler, you could have:

case WM_KEYDOWN:
{
if(keyboard_handler(wParam))
{
PostMessage(hWnd, WM_CLOSE, 0, 0);
}
return 0;
}



The WM_CLOSE message should also take care of any other ways your program might need to end. For example, hitting the [X] at the top-right of the window will send a WM_CLOSE message. If you tell your computer to shutdown, Windows should also send a WM_CLOSE message.

Share this post


Link to post
Share on other sites
regarding the usage issue
it simply makes sense that if you make your program loop continously , it will take
100% usage (it doesn't really take 100% cause it's priority is not set to real time , windows reserves a portion of the time to keep executing) .if your game is in windowed mode (mine sweeper , solitare) , it shouldn't hog the cpu . the simplest solution is to throw in a sleep command that would cease execution of your thread , and give the others a chance to execute.
if the app is in full screen , you would need all the speed you can get , therfore disabling
the sleep command is necessary.
if (Windowed) Sleep(1);

your app is a thread not a window. so telling the os to destroy a window associated with your
thread doesn't really close it. for example in notepad , if you press ctrl+f it opens the find
window , yet closing that window doesn't close notepad. so notepad sends a DestroyWindow
with the hwnd of the find window , so it would erase that window from existance.

conclusion:
The WM_DESTROY message is sent when a window is being destroyed. It is sent to the window procedure of the window being destroyed after the window is removed from the screen.

The WM_CLOSE message is sent as a signal that a window or an application should terminate.

check out the "windows overview" article in the MSDN

Share this post


Link to post
Share on other sites
Quote:
Original post by Agony
In WndProc(), when you handle a message, you are not suppose to also call DefWindowProc(). Only call DefWindowProc() if you do not handle the message yourself. This usually means that instead of a break statement at the end of a case block, you use a return statement to immediately return out of the function. Usually you return 0, although it can depend based on which message you handle. Look at the documentation for each message to make sure.

By the way, my basic window procedure usually looks like this:
*** Source Snippet Removed ***
To add in your WM_KEYDOWN message handler, you could have:
*** Source Snippet Removed ***

The WM_CLOSE message should also take care of any other ways your program might need to end. For example, hitting the [X] at the top-right of the window will send a WM_CLOSE message. If you tell your computer to shutdown, Windows should also send a WM_CLOSE message.


The problem still continues after refering your code,i'm working in fullscreen.

Share this post


Link to post
Share on other sites
I think the problem is that your applications gets WM_CLOSE, but you don't handle it, so it just stops displaying the window and keeps on running doing nothing never exiting. My guess is you need to handle the WM_CLOSE message in your WndProc function, and when you get it call PostQuitMessage or DestroyWindow or something.

Share this post


Link to post
Share on other sites
Quote:
Original post by blarn
I think the problem is that your applications gets WM_CLOSE, but you don't handle it, so it just stops displaying the window and keeps on running doing nothing never exiting. My guess is you need to handle the WM_CLOSE message in your WndProc function, and when you get it call PostQuitMessage or DestroyWindow or something.


I'm doin the samething just go through my code or Agony's code still its give me problem.

Share this post


Link to post
Share on other sites
your problem is here.


while(msg.message!=WM_QUIT)
{
//check the message queue
if(PeekMessage(&msg,wndHandle,0U,0U,PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
render();
}
}



you never quit this loop.
yeah you have destroy the window, but you never end the application.
your quit condition is WM_QUIT, but your application never send this.
i think you should add PostQuitMessage after DestroyWindow line.

Share this post


Link to post
Share on other sites
Remove the wndHandle from the PeekMessage. WM_QUIT does not get sent to any particular window but to your thread.

Make it: PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE )

If you insert a HWND there you will only receive messages with that HWND.

Share this post


Link to post
Share on other sites
Quote:
Original post by Endurion
Remove the wndHandle from the PeekMessage. WM_QUIT does not get sent to any particular window but to your thread.

Make it: PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE )

If you insert a HWND there you will only receive messages with that HWND.


Thanx ur solution have solved my problem.thanx alot

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement