Thread: Just starting Windows Programming, School me!

  1. #1
    Absent Minded Programmer
    Join Date
    May 2005
    Posts
    968

    Just starting Windows Programming, School me!

    Okay, so I've been reading the introductory chapters in my ancient MFC book (6.0). I've come to gain a bit of understanding about how the whole thing works in terms of messages and procedures.

    Now, catch me if I'm wrong people!

    This is our new main function, it's our entry into the windows API, I see here we are checking for a quit message. Now I'm understanding this part, but the part I'm iffy about is the scope of this check? Is this only for our main window? Or does this apply to all parts of the program?


    Code:
    int WINAPI WinMain(	HINSTANCE	hInstance,			// Instance
    					HINSTANCE	hPrevInstance,		// Previous Instance
    					LPSTR		lpCmdLine,			// Command Line Parameters
    					int			nCmdShow)			// Window Show State
    {
    	MSG		msg;									// Windows Message Structure
    	BOOL	done=FALSE;								// Bool Variable To Exit Loop
    
    	// Ask The User Which Screen Mode They Prefer
    	if (MessageBox(NULL,"Would You Like To Run In Fullscreen Mode?", "Start FullScreen?",MB_YESNO|MB_ICONQUESTION)==IDNO)
    	{
    		fullscreen=FALSE;							// Windowed Mode
    	}
    
    	// Create Our OpenGL Window
    	if (!CreateGLWindow("Jon C's Game",640,480,16,fullscreen))
    	{
    		return 0;									// Quit If Window Was Not Created0
    	}
    
    	while(!done)									// Loop That Runs While done=FALSE
    	{
    		if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))	// Is There A Message Waiting?
    		{
    			if (msg.message==WM_QUIT)				// Have We Received A Quit Message?
    			{
    				done=TRUE;							// If So done=TRUE
    			}
    			else									// If Not, Deal With Window Messages
    			{
    				TranslateMessage(&msg);				// Translate The Message
    				DispatchMessage(&msg);				// Dispatch The Message
    			}
    		}
    		else										// If There Are No Messages
    		{
    			// Draw The Scene.  Watch For ESC Key And Quit Messages From DrawGLScene()
    			if (active)								// Program Active?
    			{
    				if (keys[VK_ESCAPE])				// Was ESC Pressed?
    				{
    					done=TRUE;						// ESC Signalled A Quit
    				}
    				else								// Not Time To Quit, Update Screen
    				{
    					DrawGLScene();					// Draw The Scene
    					SwapBuffers(hDC);				// Swap Buffers (Double Buffering)
    				}
    			}
    
    			if (keys[VK_F1])						// Is F1 Being Pressed?
    			{
    				keys[VK_F1]=FALSE;					// If So Make Key FALSE
    				KillGLWindow();						// Kill Our Current Window
    				fullscreen=!fullscreen;				// Toggle Fullscreen / Windowed Mode
    				// Recreate Our OpenGL Window
    				if (!CreateGLWindow("NeHe's OpenGL Framework",640,480,16,fullscreen))
    				{
    					return 0;						// Quit If Window Was Not Created
    				}
    			}
    		}
    	}
    
    	// Shutdown
    	KillGLWindow();									// Kill The Window
    	return (msg.wParam);							// Exit The Program
    }

    My guess is that the message checks in the winmain function go for the ENTIRE application, if we want to get more specific, then we need a procedure!
    This is the message procedure for our main window, hWnd. As far as I can tell this switch applies only to my openGL window hWnd.

    My question is on the differences of this procedure function versus the message checks in WinMain?
    Code:
    LRESULT CALLBACK WndProc(	HWND	hWnd,			// Handle For This Window
    							UINT	uMsg,			// Message For This Window
    							WPARAM	wParam,			// Additional Message Information
    							LPARAM	lParam)			// Additional Message Information
    {
    	switch (uMsg)									// Check For Windows Messages
    	{
    		case WM_ACTIVATE:							// Watch For Window Activate Message
    		{
    			if (!HIWORD(wParam))					// Check Minimization State
    			{
    				active=TRUE;						// Program Is Active
    			}
    			else
    			{
    				active=FALSE;						// Program Is No Longer Active
    			}
    
    			return 0;								// Return To The Message Loop
    		}
    
    		case WM_SYSCOMMAND:							// Intercept System Commands
    		{
    			switch (wParam)							// Check System Calls
    			{
    				case SC_SCREENSAVE:					// Screensaver Trying To Start?
    				case SC_MONITORPOWER:				// Monitor Trying To Enter Powersave?
    				return 0;							// Prevent From Happening
    			}
    			break;									// Exit
    		}
    
    		case WM_CLOSE:								// Did We Receive A Close Message?
    		{
    			PostQuitMessage(0);						// Send A Quit Message
    			return 0;								// Jump Back
    		}
    
    		case WM_KEYDOWN:							// Is A Key Being Held Down?
    		{
    			keys[wParam] = TRUE;					// If So, Mark It As TRUE
    			return 0;								// Jump Back
    		}
    
    		case WM_KEYUP:								// Has A Key Been Released?
    		{
    			keys[wParam] = FALSE;					// If So, Mark It As FALSE
    			return 0;								// Jump Back
    		}
    
    		case WM_SIZE:								// Resize The OpenGL Window
    		{
    			ReSizeGLScene(LOWORD(lParam),HIWORD(lParam));  // LoWord=Width, HiWord=Height
    			return 0;								// Jump Back
    		}
    	}
    
    	// Pass All Unhandled Messages To DefWindowProc
    	return DefWindowProc(hWnd,uMsg,wParam,lParam);
    }
    Now, the process of creating a window, an openGL window to be exact.

    Looks like the first thing we do is create a WNDCLASS, then we define the attributes of the WNDCLASS. Then we register it. What exactly are we creating here? I see that eventually we create a window with a windows API function, but is this really the only thing having to do with the window? I guess I didn't get enough explanation of this process (well not this one specifically, but the act of creating a window and how you can do it) in the book I read.
    Code:
    BOOL CreateGLWindow(char* title, int width, int height, int bits, bool fullscreenflag)
    {
    	GLuint		PixelFormat;			// Holds The Results After Searching For A Match
    	WNDCLASS	wc;						// Windows Class Structure
    	DWORD		dwExStyle;				// Window Extended Style
    	DWORD		dwStyle;				// Window Style
    	RECT		WindowRect;				// Grabs Rectangle Upper Left / Lower Right Values
    	WindowRect.left=(long)0;			// Set Left Value To 0
    	WindowRect.right=(long)width;		// Set Right Value To Requested Width
    	WindowRect.top=(long)0;				// Set Top Value To 0
    	WindowRect.bottom=(long)height;		// Set Bottom Value To Requested Height
    	fullscreen=fullscreenflag;			// Set The Global Fullscreen Flag
    
    	hInstance			= GetModuleHandle(NULL);				// Grab An Instance For Our Window
    	wc.style			= CS_HREDRAW | CS_VREDRAW | CS_OWNDC;	// Redraw On Size, And Own DC For Window.
    	wc.lpfnWndProc		= (WNDPROC) WndProc;					// WndProc Handles Messages
    	wc.cbClsExtra		= 0;									// No Extra Window Data
    	wc.cbWndExtra		= 0;									// No Extra Window Data
    	wc.hInstance		= hInstance;							// Set The Instance
    	wc.hIcon			= LoadIcon(NULL, IDI_WINLOGO);			// Load The Default Icon
    	wc.hCursor			= LoadCursor(NULL, IDC_ARROW);			// Load The Arrow Pointer
    	wc.hbrBackground	= NULL;									// No Background Required For GL
    	wc.lpszMenuName		= NULL;									// We Don't Want A Menu
    	wc.lpszClassName	= "OpenGL";								// Set The Class Name
    
    	if (!RegisterClass(&wc))									// Attempt To Register The Window Class
    	{
    		MessageBox(NULL,"Failed To Register The Window Class.","ERROR",MB_OK|MB_ICONEXCLAMATION);
    		return FALSE;											// Return FALSE
    	}
    	
    	if (fullscreen)												// Attempt Fullscreen Mode?
    	{
    		DEVMODE dmScreenSettings;								// Device Mode
    		memset(&dmScreenSettings,0,sizeof(dmScreenSettings));	// Makes Sure Memory's Cleared
    		dmScreenSettings.dmSize=sizeof(dmScreenSettings);		// Size Of The Devmode Structure
    		dmScreenSettings.dmPelsWidth	= width;				// Selected Screen Width
    		dmScreenSettings.dmPelsHeight	= height;				// Selected Screen Height
    		dmScreenSettings.dmBitsPerPel	= bits;					// Selected Bits Per Pixel
    		dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;
    
    		// Try To Set Selected Mode And Get Results.  NOTE: CDS_FULLSCREEN Gets Rid Of Start Bar.
    		if (ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL)
    		{
    			// If The Mode Fails, Offer Two Options.  Quit Or Use Windowed Mode.
    			if (MessageBox(NULL,"The Requested Fullscreen Mode Is Not Supported By\nYour Video Card. Use Windowed Mode Instead?","NeHe GL",MB_YESNO|MB_ICONEXCLAMATION)==IDYES)
    			{
    				fullscreen=FALSE;		// Windowed Mode Selected.  Fullscreen = FALSE
    			}
    			else
    			{
    				// Pop Up A Message Box Letting User Know The Program Is Closing.
    				MessageBox(NULL,"Program Will Now Close.","ERROR",MB_OK|MB_ICONSTOP);
    				return FALSE;									// Return FALSE
    			}
    		}
    	}
    
    	if (fullscreen)												// Are We Still In Fullscreen Mode?
    	{
    		dwExStyle=WS_EX_APPWINDOW;								// Window Extended Style
    		dwStyle=WS_POPUP;										// Windows Style
    		ShowCursor(TRUE);										// Hide Mouse Pointer
    	}
    	else
    	{
    		dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;			// Window Extended Style
    		dwStyle=WS_OVERLAPPEDWINDOW;							// Windows Style
    	}
    
    	AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle);		// Adjust Window To True Requested Size
    
    	// Create The Window
    	if (!(hWnd=CreateWindowEx(	dwExStyle,							// Extended Style For The Window
    								"OpenGL",							// Class Name
    								title,								// Window Title
    								dwStyle |							// Defined Window Style
    								WS_CLIPSIBLINGS |					// Required Window Style
    								WS_CLIPCHILDREN,					// Required Window Style
    								0, 0,								// Window Position
    								WindowRect.right-WindowRect.left,	// Calculate Window Width
    								WindowRect.bottom-WindowRect.top,	// Calculate Window Height
    								NULL,								// No Parent Window
    								NULL,								// No Menu
    								hInstance,							// Instance
    								NULL)))								// Dont Pass Anything To WM_CREATE
    	{
    		KillGLWindow();								// Reset The Display
    		MessageBox(NULL,"Window Creation Error.","ERROR",MB_OK|MB_ICONEXCLAMATION);
    		return FALSE;								// Return FALSE
    	}
    
    	static	PIXELFORMATDESCRIPTOR pfd=				// pfd Tells Windows How We Want Things To Be
    	{
    		sizeof(PIXELFORMATDESCRIPTOR),				// Size Of This Pixel Format Descriptor
    		1,											// Version Number
    		PFD_DRAW_TO_WINDOW |						// Format Must Support Window
    		PFD_SUPPORT_OPENGL |						// Format Must Support OpenGL
    		PFD_DOUBLEBUFFER,							// Must Support Double Buffering
    		PFD_TYPE_RGBA,								// Request An RGBA Format
    		bits,										// Select Our Color Depth
    		0, 0, 0, 0, 0, 0,							// Color Bits Ignored
    		0,											// No Alpha Buffer
    		0,											// Shift Bit Ignored
    		0,											// No Accumulation Buffer
    		0, 0, 0, 0,									// Accumulation Bits Ignored
    		16,											// 16Bit Z-Buffer (Depth Buffer)  
    		0,											// No Stencil Buffer
    		0,											// No Auxiliary Buffer
    		PFD_MAIN_PLANE,								// Main Drawing Layer
    		0,											// Reserved
    		0, 0, 0										// Layer Masks Ignored
    	};
    	
    	if (!(hDC=GetDC(hWnd)))							// Did We Get A Device Context?
    	{
    		KillGLWindow();								// Reset The Display
    		MessageBox(NULL,"Can't Create A GL Device Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);
    		return FALSE;								// Return FALSE
    	}
    
    	if (!(PixelFormat=ChoosePixelFormat(hDC,&pfd)))	// Did Windows Find A Matching Pixel Format?
    	{
    		KillGLWindow();								// Reset The Display
    		MessageBox(NULL,"Can't Find A Suitable PixelFormat.","ERROR",MB_OK|MB_ICONEXCLAMATION);
    		return FALSE;								// Return FALSE
    	}
    
    	if(!SetPixelFormat(hDC,PixelFormat,&pfd))		// Are We Able To Set The Pixel Format?
    	{
    		KillGLWindow();								// Reset The Display
    		MessageBox(NULL,"Can't Set The PixelFormat.","ERROR",MB_OK|MB_ICONEXCLAMATION);
    		return FALSE;								// Return FALSE
    	}
    
    	if (!(hRC=wglCreateContext(hDC)))				// Are We Able To Get A Rendering Context?
    	{
    		KillGLWindow();								// Reset The Display
    		MessageBox(NULL,"Can't Create A GL Rendering Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);
    		return FALSE;								// Return FALSE
    	}
    
    	if(!wglMakeCurrent(hDC,hRC))					// Try To Activate The Rendering Context
    	{
    		KillGLWindow();								// Reset The Display
    		MessageBox(NULL,"Can't Activate The GL Rendering Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);
    		return FALSE;								// Return FALSE
    	}
    
    	ShowWindow(hWnd,SW_SHOW);						// Show The Window
    	SetForegroundWindow(hWnd);						// Slightly Higher Priority
    	SetFocus(hWnd);									// Sets Keyboard Focus To The Window
    	ReSizeGLScene(width, height);					// Set Up Our Perspective GL Screen
    
    	if (!InitGL())									// Initialize Our Newly Created GL Window
    	{
    		KillGLWindow();								// Reset The Display
    		MessageBox(NULL,"Initialization Failed.","ERROR",MB_OK|MB_ICONEXCLAMATION);
    		return FALSE;								// Return FALSE
    	}
    
    	return TRUE;									// Success
    }
    Questions:

    Is WNDCLASS just a data structure we pass to the window creation function to give it a set of attributes?
    I see we are using an OpenGL device context, is there any way to use openGL AND windows API in the same window? Or do I need to start adding children and whatnot?

    School me please!
    Sometimes I forget what I am doing when I enter a room, actually, quite often.

  2. #2
    Absent Minded Programmer
    Join Date
    May 2005
    Posts
    968
    I guess the general advice is to reread and reread the chapter again? :d
    Sometimes I forget what I am doing when I enter a room, actually, quite often.

  3. #3
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Err, yes, I think I can agree?
    OpenGL is a Graphics API used for 3D graphics and not for common applications (this is more of a game rather than a normal win32 app). And this is pure Win32, not MFC
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  4. #4
    Absent Minded Programmer
    Join Date
    May 2005
    Posts
    968
    Yeah, I'm trying to ignore the OpenGL part for now and am trying to focus on the messaging/callback system. I know that opengl is a graphics api and has nothing to do with windows in general.

    My question is, how does the WNDCLASS object interact with the actual hWnd ? The way my code is set up it looks like the WNDCLASS actually determines alot of things about the nature of the hWnd.

    It looks like when we give hWnd a value we need to specify the WNDCLASS it uses, in my case the WNDCLASS is "OpenGL".

    What if I made another WNDCLASS, and added a child window for a menu bar along the right side of the main window. Also to note would be the device context, I would have to change it to something, my main window's device context is opengl, does that go recursively for all child windows?

    Also to note, do I need more than one hWnd? My assumption is yes, we need a handle for each window and each child window.

    And then I need to write wndprocs for each hWnd. Right?
    Last edited by Shamino; 02-20-2008 at 02:08 PM.
    Sometimes I forget what I am doing when I enter a room, actually, quite often.

  5. #5
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by Shamino View Post
    My question is, how does the WNDCLASS object interact with the actual hWnd ? The way my code is set up it looks like the WNDCLASS actually determines alot of things about the nature of the hWnd.
    First, hWnd is a handle to a window. An identifier of which Windows uses to identify your window. To create a window, you first need to register a class. The class determines some properties of your window. Exactly what I'm not sure since I'm an MFC programmer and MFC doesn't use classes, it only creates windows.
    Anyway, that class is then associated with your window as you create it. As noted, it determines some properties of your window, such as the icon.

    It looks like when we give hWnd a value we need to specify the WNDCLASS it uses, in my case the WNDCLASS is "OpenGL".
    Yes, all windows needs to be associated with a certain class. The "OpenGL" class is probably a class designed to be suitable for OpenGL to draw on the window.

    What if I made another WNDCLASS, and added a child window for a menu bar along the right side of the main window. Also to note would be the device context, I would have to change it to something, my main window's device context is opengl, does that go recursively for all child windows?
    I'm not 100% sure if I understand that question. But I think you meant to ask if a class is recursively applied to windows? The answer to that is no since you must specify what class you want to use when creating the actual window.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  6. #6
    Absent Minded Programmer
    Join Date
    May 2005
    Posts
    968
    Okay, So each windows needs a WNDCLASS.

    So we have our main window; to have menu bars (perhaps some kind of interface with buttons to control a blackjack game (using the windows API)), would we add a child to the main window with the new WNDCLASS??

    Or would we do something else entirely?

    I suppose I could define a WNDCLASS gui and apply it to the child window.

    I unfortunately have an MFC book in my hands and not a C++ win32 book. So I don't think it's going to tell me how to create a WNDCLASS suitable for drawing a gui with win32, perhaps maybe you could give me some insight into this?
    Sometimes I forget what I am doing when I enter a room, actually, quite often.

  7. #7
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by Shamino View Post
    Okay, So each windows needs a WNDCLASS.
    Well, not exactly. Each window needs a class. A WNDCLASS struct is used to register a class. Once a class is registered, it can be used in your Windows. So you only need to do it once.

    So we have our main window; to have menu bars (perhaps some kind of interface with buttons to control a blackjack game (using the windows API)), would we add a child to the main window with the new WNDCLASS??
    When working with controls, you would typically use a pre-defined window class. What one to use, I don't know.

    I unfortunately have an MFC book in my hands and not a C++ win32 book. So I don't think it's going to tell me how to create a WNDCLASS suitable for drawing a gui with win32, perhaps maybe you could give me some insight into this?
    Well, as I said, I'm an MFC dev so I know little about window classes. But there's nothing wrong in using MFC either, if you have Visual Studio Pro edition.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  8. #8
    Absent Minded Programmer
    Join Date
    May 2005
    Posts
    968
    SOO MANY FUNCTIONSSSS SO MANY CLASSESSSSSS

    Windows API is actually something I enjoy learning about.
    But in terms of MFC, I think it's faulty logic to think that you can make a framework for any application. (EDIT), well you can if windows was the only OS on earth, but I guess it's kinda pointless to use the windows API without MFC, wouldn't be losing anything.

    Okay, so I'm reading the msdn here and I saw a few of these predefined classes you were talking about.

    There is a button, dialog box, etc etc.... also a static....

    My guess is that I'd have to make a static window with a bunch of buttons for children.

    Code:
        hwnd = CreateWindow( 
            "MainWClass",        // name of window class 
            "Sample",            // title-bar string 
            WS_OVERLAPPEDWINDOW, // top-level window 
            CW_USEDEFAULT,       // default horizontal position 
            CW_USEDEFAULT,       // default vertical position 
            CW_USEDEFAULT,       // default width 
            CW_USEDEFAULT,       // default height 
            (HWND) NULL,         // no owner window 
            (HMENU) NULL,        // use class menu 
            hinstance,           // handle to application instance 
            (LPVOID) NULL);      // no window-creation data
    I could replace that MainWClass with like a something... not sure on this syntax.
    Last edited by Shamino; 02-20-2008 at 02:57 PM.
    Sometimes I forget what I am doing when I enter a room, actually, quite often.

  9. #9
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by Shamino View Post
    SOO MANY FUNCTIONSSSS SO MANY CLASSESSSSSS
    Welcome to win32

    But in terms of MFC, I think it's faulty logic to think that you can make a framework for any application. (EDIT), well you can if windows was the only OS on earth, but I guess it's kinda pointless to use the windows API without MFC, wouldn't be losing anything.
    But MFC does a really good job at hiding these complexities while still retaining a powerful framework that does pretty much about everything you'd want to do with win32.
    In MFC, there's no need to remember classes. Just add an appropriate control to your dialog and add a member through the wizard. So easy.

    My guess is that I'd have to make a static window with a bunch of buttons for children.

    Code:
        hwnd = CreateWindow( 
            "MainWClass",        // name of window class 
            "Sample",            // title-bar string 
            WS_OVERLAPPEDWINDOW, // top-level window 
            CW_USEDEFAULT,       // default horizontal position 
            CW_USEDEFAULT,       // default vertical position 
            CW_USEDEFAULT,       // default width 
            CW_USEDEFAULT,       // default height 
            (HWND) NULL,         // no owner window 
            (HMENU) NULL,        // use class menu 
            hinstance,           // handle to application instance 
            (LPVOID) NULL);      // no window-creation data
    I could replace that MainWClass with like a something... not sure on this syntax.
    Well, the main window should be of your custom registered class and all controls should use pre-defined window classes and their parent set to your main window.
    You should replace the MainWClass argument with a string to the class of the controls, such as "STATIC". This is IIRC.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  10. #10
    Absent Minded Programmer
    Join Date
    May 2005
    Posts
    968
    Lets see here, we have this one:

    STATIC Designates a simple text field, box, or rectangle used to label, box, or separate other controls. Static controls take no input and provide no output. For more information, see Static Controls.

    For a table of the static control styles you can specify in the dwStyle parameter, see Static Control Styles.


    Cool, so I do need a static to group together all the buttons for playing a blackjack game.

    and then I need BUTTON!

    BUTTON Designates a small rectangular child window that represents a button the user can click to turn it on or off. Button controls can be used alone or in groups, and they can either be labeled or appear without text. Button controls typically change appearance when the user clicks them. For more information, see Buttons.

    For a table of the button styles you can specify in the dwStyle parameter, see Button Styles.


    Mhmmmmm

    EDIT: there is a trick though, I have to make the OpenGL window only draw to where the new static window starts on the x axis.
    Last edited by Shamino; 02-20-2008 at 03:11 PM.
    Sometimes I forget what I am doing when I enter a room, actually, quite often.

  11. #11
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    Each window requires a WNDCLASS, but can share one already created. WNDCLASS is used to hold the settings/styles etc, so windows sharing common functionality and/or style can use the same WNDCLASS.

    You want a WIN32 main window with a child OpenGL frame (DC) inside.

    Your message pump should 'catch' WIN32 messages from the menu / buttons and pass them to your callback. If there are no messages your app will draw the next frame.

    I don't see why you would want to complicate BlackJack with OpenGL. BJ is not a game that requires serious graphic rendering. I see so many people fail because they over complicate thier first apps, get frustrated and quit. KEEP IT SIMPLE! Build up complexity as you gain in confidence.

    Simple GDI would do the job, if double buffered and you can use the WIN32 card class CARDS.DLL (ie the cards used in the windows games Hearts etc).

    I would create a main window with a menu built in the resource editor.
    I would also create a toolbar in the resource editor, though this is MUCH harder in WIN32 than MFC. (something for v2?)
    In the WM_CREATE handler I would work out the size of the screen and create my memory HDC.
    I would then create the controls (buttons) needed directly on the main screen (adding handlers into the callback).

    Respond to the buttons to determine the action required (new game, draw card etc)

    I would use cards.dll to draw the cards to the memory DC as required and then call for a paint (InvalidateRect and UpdateWindow).

    In the paint I would BitBlt the memory DC to the HDC (using the rect) in the PAINTSTRUCT.



    Quote Originally Posted by Elysia View Post
    Well, as I said, I'm an MFC dev so I know little about window classes. But there's nothing wrong in using MFC either, if you have Visual Studio Pro edition.
    I thought you knew everything? ("I am not young enough to know everything." Oscar Wilde)

    MFC's message pump is incompatible with the game style message pump.

    MFC's use of two PeekMessages and GetMessage is too much overhead for fast rendering And you do not have the ability to 'hack' this message pump (as you do in WIN32).

    You can process using the MFC OnIdle() handler but will not be as responsive as the message pump you are currently using.
    "Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
    Friedrich Nietzsche

    "I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
    George Best

    "If you are going through hell....keep going."
    Winston Churchill

  12. #12
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by novacain View Post
    I thought you knew everything? ("I am not young enough to know everything." Oscar Wilde)
    No, no, no... That's what others have said, not I. I've never claimed to know everything. I've been corrected countless times and others have filled the void where my knowledge was lacking also countless times. No one knows everything...
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  13. #13
    Absent Minded Programmer
    Join Date
    May 2005
    Posts
    968
    I already have cards and a deck and a working engine, all I need is an input/output interface that isn't poopy like the console.

    Code:
    class Card_Game
    {
    public:
    	Card_Game(){}
    	~Card_Game(){}
    	virtual void init(){}
    	virtual void cleanup(){}
    	virtual void turn_logic(std::string player_id);
    	std::vector<std::string> m_vPlayer_List;
    	int get_setting(std::string name);
    protected:
    	int calculate_winnings();
    	void new_setting(std::string name, Setting * new_setting);
    	void initialize_players();
    	// Give player id a new hand
    	void give_player_hand(std::string player_id);
    	void shuffle_deck(int deck_id);
    	// Draw how_many cards to player id's hand_id from deck_idntyd
    	void draw_card(std::string player_id, int hand_id, int deck_id, int how_many);
    	void place_bet(std::string player_id, int bet);
    	// Split player's active hand
    	void split_hand(std::string player_id, int hand_id);
    	// check if hand value > check_value
    	bool check_hand_value(std::string player_id, int hand_id, int check_value);	
    
    	Resource_Manager< Player > m_rPlayers;
    	Resource_Manager< std::vector<Hand*> > m_rHands;
    	Resource_Manager< int* > m_rBets;
    	Resource_Manager< Deck* > m_rDecks;
    	Resource_Manager< Setting > m_rSettings;
    	std::vector< Deck* > m_vDeck;	
    
    };
    The idea I'm trying to grasp right now is how to work windows into my state manager. This is how I update my game logic:
    Code:
    				srand ( unsigned(time(NULL)) );
    				Blackjack_Game * game = new Blackjack_Game();
    				game->init();
    
    				State_Manager * state_manager = new State_Manager;
    				state_manager->change_state(new Play_State(state_manager, game) );
    				*/
    
    				/*
    				while ( state_manager->running() )
    				{
    					state_manager->update();
    					state_manager->print();
    					state_manager->handle_events();
    				}
    
    				game->cleanup();
    I want to integrate the windows messaging system into my state manager.
    They will be responsible for the creation of certain windows and buttons and such, and also accept messages from Win32 and handle them, like a WM_COMMAND I suppose.
    Sometimes I forget what I am doing when I enter a room, actually, quite often.

  14. #14
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Well, in your handle_events function, call PeekMessage repeatedly to handle any messages for your windows. All messages will automatically go to your windowproc function. That's how win32 works.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  15. #15
    Absent Minded Programmer
    Join Date
    May 2005
    Posts
    968
    whoah, thats almost so easy its weeiiird.
    Sometimes I forget what I am doing when I enter a room, actually, quite often.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 6
    Last Post: 01-01-2007, 07:36 AM
  2. Script errors - bool unrecognized and struct issues
    By ulillillia in forum Windows Programming
    Replies: 10
    Last Post: 12-18-2006, 04:44 AM
  3. Question..
    By pode in forum Windows Programming
    Replies: 12
    Last Post: 12-19-2004, 07:05 PM
  4. IE 6 status bar
    By DavidP in forum Tech Board
    Replies: 15
    Last Post: 10-23-2002, 05:31 PM
  5. Manipulating the Windows Clipboard
    By Johno in forum Windows Programming
    Replies: 2
    Last Post: 10-01-2002, 09:37 AM