Sign in to follow this  

Problem with closing just the window not the app on Win32 app.

This topic is 4839 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

Hi, I'm new on Win32 programming.. so I'm having some problems with it. I have a Win32 with 2 windows and when I close the second one, the app is closing. But I want just the window being closed. How to do this? Here is the code:
// INCLUDES ///////////////////////////////////////////////
#define WIN32_LEAN_AND_MEAN  // just say no to MFC

#include <windows.h>   // include all the windows headers
#include <windowsx.h>  // include useful macros

// FUNCTIONS //////////////////////////////////////////////
LRESULT CALLBACK WindowProc(HWND hwnd, 
						    UINT msg, 
                            WPARAM wparam, 
                            LPARAM lparam)
{
    // this is the main message handler of the system
    PAINTSTRUCT		ps;		// used in WM_PAINT
    HDC				hdc;	// handle to a device context
    
    // what is the message 
    switch(msg)
    	{	
    	case WM_CREATE: 
            {
    		// do initialization stuff here
    
            // return success
    		return(0);
    		} break;
    
    	case WM_PAINT: 
    		{
    		// simply validate the window
    		hdc = BeginPaint(hwnd,&ps);	 
    		// you would do all your painting here
            EndPaint(hwnd,&ps);
    
            // return success
    		return(0);
       		} break;
    
    	case WM_DESTROY: 
    		{
    		// kill the application, this sends a WM_QUIT message 
    		PostQuitMessage(0);
    
            // return success
    		return(0);
    		} break;
    
    	default:break;
    
        } // end switch
    
    // process any messages that we didn't take care of 
    return (DefWindowProc(hwnd, msg, wparam, lparam));

} // end WinProc

// WINMAIN ////////////////////////////////////////////////
int WINAPI WinMain(	HINSTANCE hinstance,
					HINSTANCE hprevinstance,
					LPSTR lpcmdline,
					int ncmdshow)
{
    const char* names[] = { "WINCLASS1", "WINCLASS2" };
    WNDCLASSEX winclass, winclass2; // this will hold the classes we create
    HWND	   hwnd, hwnd2;	        // generic window handle
    MSG		   msg;		            // generic message
    
    // first fill in the window class stucture
    winclass.cbSize         = sizeof(WNDCLASSEX);
    winclass.style			= CS_DBLCLKS | CS_OWNDC | 
                              CS_HREDRAW | CS_VREDRAW;
    winclass.lpfnWndProc	= WindowProc;
    winclass.cbClsExtra		= 0;
    winclass.cbWndExtra		= 0;
    winclass.hInstance		= hinstance;
    winclass.hIcon			= LoadIcon(NULL, IDI_APPLICATION);
    winclass.hCursor		= LoadCursor(NULL, IDC_ARROW);
    winclass.hbrBackground	= (HBRUSH)GetStockObject(BLACK_BRUSH);
    winclass.lpszMenuName	= NULL;
    winclass.lpszClassName	= names[0];
    winclass.hIconSm        = LoadIcon(NULL, IDI_APPLICATION);
    
    // Second window
    winclass2 = winclass;
    winclass2.lpszClassName = names[1];
    
    // register the window classes
    if (!RegisterClassEx(&winclass) || !RegisterClassEx(&winclass2))
    	return(0);
    
    // create the first window
    if (!(hwnd = CreateWindowEx(0,                  // extended style
                                names[0],     // class
    						    "Window 1 Based on WINCLASS1", // title
    						    WS_OVERLAPPEDWINDOW | WS_VISIBLE,
    					 	    0,0,	    // initial x,y
    						    400,400,  // initial width, height
    						    NULL,	    // handle to parent 
    						    NULL,	    // handle to menu
    						    hinstance,// instance of this application
    						    NULL)))	// extra creation parms
    return(0);
    
    // create the second window
    if (!(hwnd2 = CreateWindowEx(0,                  // extended style
                                names[1],     // class
    						    "Window 2 Based on WINCLASS2", // title
    						    WS_OVERLAPPEDWINDOW | WS_VISIBLE,
    					 	    100,100,  // initial x,y
    						    400,400,  // initial width, height
    						    NULL,	  // handle to parent 
    						    NULL,	  // handle to menu
    						    hinstance,// instance of this application
    						    NULL)))	// extra creation parms
    return(0);
    
    // enter main event loop, but this time we use PeekMessage()
    // instead of GetMessage() to retrieve messages
    while(true)
    {
        // test if there is a message in queue, if so get it
    	if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
 	    { 
    	   // test if this is a quit
           if (msg.message == WM_QUIT)
               break;
    	
    	   // translate any accelerator keys
    	   TranslateMessage(&msg);
    
    	   // send the message to the window proc
    	   DispatchMessage(&msg);
  	    } // end if
        
        // main game processing goes here
    	
    } // end while
    
    // return to Windows like this
    return(msg.wParam);

} // end WinMain

///////////////////////////////////////////////////////////


* Ah.. the forum is messing up the code.

Share this post


Link to post
Share on other sites
I've added a windows counter. So, when there is no windows anymore (winCount = 0), WM_DESTROY calls PostQuitMessage(0);

Is there other way to do this? Or this is the solution?

Here it is:

#define WIN32_LEAN_AND_MEAN // just say no to MFC

#include <windows.h> // include all the windows headers
#include <windowsx.h> // include useful macros

// GLOBALS ////////////////////////////////////////////////
// windows counting
int winCount = 0;

// FUNCTIONS //////////////////////////////////////////////
LRESULT CALLBACK WindowProc(HWND hWnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam)
{
// this is the main message handler of the system
PAINTSTRUCT ps; // used in WM_PAINT
HDC hdc; // handle to a device context

// what is the message
switch(Msg)
{
case WM_CREATE:
{
winCount++;
// do initialization stuff here

// return success
return(0);
} break;

case WM_PAINT:
{
// simply validate the window
hdc = BeginPaint(hWnd,&ps);
// you would do all your painting here
EndPaint(hWnd,&ps);

// return success
return(0);
} break;

case WM_DESTROY:
{
winCount--;

// No windows left, so send WM_QUIT
if(!winCount)
{
// kill the application, this sends a WM_QUIT message
PostQuitMessage(0);
}

// return success
return(0);
} break;

default:
break;

} // end switch

// process any messages that we didn't take care of
return (DefWindowProc(hWnd, Msg, wParam, lParam));

} // end WinProc

int WINAPI WinMain( HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
const char* names[] = { "WINCLASS1", "WINCLASS2" };
WNDCLASSEX winclass, winclass2; // this will hold the class we create
HWND hWnd, hWnd2; // generic window handle
MSG Msg; // generic message

// first fill in the window class stucture
winclass.cbSize = sizeof(WNDCLASSEX);
winclass.style = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
winclass.lpfnWndProc = WindowProc;
winclass.cbClsExtra = 0;
winclass.cbWndExtra = 0;
winclass.hInstance = hInstance;
winclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
winclass.hCursor = LoadCursor(NULL, IDC_ARROW);
winclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
winclass.lpszMenuName = NULL;
winclass.lpszClassName = names[0];
winclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

winclass2 = winclass;
winclass2.lpszClassName = names[1];

// register the window class
if (!RegisterClassEx(&winclass) || !RegisterClassEx(&winclass2))
return(0);

// create the first window
if (!(hWnd = CreateWindowEx(0, // extended style
names[0], // class
"Window 1 Based on WINCLASS1", // title
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
0,0, // initial x,y
400,400, // initial width, height
NULL, // handle to parent
NULL, // handle to menu
hInstance,// instance of this application
NULL))) // extra creation parms
return(0);

// create the second window
if (!(hWnd2 = CreateWindowEx(0, // extended style
names[1], // class
"Window 2 Based on WINCLASS2", // title
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
100,100, // initial x,y
400,400, // initial width, height
NULL, // handle to parent
NULL, // handle to menu
hInstance,// instance of this application
NULL))) // extra creation parms
return(0);

// enter main event loop, but this time we use PeekMessage()
// instead of GetMessage() to retrieve messages
while(true)
{
// test if there is a message in queue, if so get it
if (PeekMessage(&Msg, NULL, 0, 0, PM_REMOVE))
{
// test if this is a quit
if (Msg.message == WM_QUIT)
{
break;
}

// translate any accelerator keys
TranslateMessage(&Msg);

// send the message to the window proc
DispatchMessage(&Msg);
} // end if

// main game processing goes here

} // end while

// return to Windows like this
return(Msg.wParam);

} // end WinMain

Share this post


Link to post
Share on other sites
Quote:
Original post by Maquiavel
Is there other way to do this?
Yes. Give the two window classes separate window procedures. If they have the exact same definition, then you obviously need only one window class. If so, then move the code to terminate the application out of the window procedures and into the main loop.

Master window messaging.

Share this post


Link to post
Share on other sites
Quote:
Original post by AckPacket
here's a question for ya. Why are you
#define WIN32_LEAN_AND_MEAN

??

what does this do, i've never seen it. im sure it has nothing to do with your prob, but just curious.

by putting that before including "windows.h", it cuts out some of the stuff automatically included, reducing compile time. i just found the following quickly (so there may be more to it):


#ifndef WIN32_LEAN_AND_MEAN
#include <cderr.h>
#include <dde.h>
#include <ddeml.h>
#include <dlgs.h>
#include <lzexpand.h>
#include <mmsystem.h>
#include <nb30.h>
#include <rpc.h>
#include <shellapi.h>
#include <winperf.h>
#include <winsock.h>
...
#endif /* WIN32_LEAN_AND_MEAN */



if you do need some of those headers (i.e. winsock.h for networking) you can still manually include them.

Share this post


Link to post
Share on other sites
Quote:
Original post by AckPacket
#define WIN32_LEAN_AND_MEAN
what does this do, i've never seen it.


I'll tell you what id does, at bloody annoys me ;). All my new projects start with that. It restricts certain headers that are classed as 'advanced stuff'. Presumably to lower compile time. PCH surly makes this redundant and 99% of the time I need something which it restricts. And i never remeber to remove it till my app fails to compile!

In fact whilst im moaning I may as well ask, im using VC6 is there anyway to edit the "Win32 App" wizard generator?Ive never found the source code anywhere. Do i have to create my own from scratch?

Share this post


Link to post
Share on other sites

This topic is 4839 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.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this