Thread: Just starting Windows Programming, School me!

Hybrid View

Previous Post Previous Post   Next Post Next Post
  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
    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.

  9. #9
    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.

  10. #10
    Absent Minded Programmer
    Join Date
    May 2005
    Posts
    968
    Okay, so here is my first attempt at a main window.

    Code:
    BOOL CreateMainWindow(char* title, int width, int height)
    {
    
    	DWORD    dwExStyle;
    	DWORD    dwStyle;
    	RECT     WindowRect;
    	WindowRect.left =(long)0;
    	WindowRect.right=(long)width;
    	WindowRect.top=(long)0;
    	WindowRect.bottom=(long)height;
    
    	hInstance = GetModuleHandle(NULL);
    	
    	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
    
    	if (!(hWnd=CreateWindowEx(	dwExStyle,							// Extended Style For The Window
    								WC_DIALOG,					// 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
    	{
    		MessageBox(NULL,"Window Creation Error.","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
    	return TRUE;
    }
    The only issue with this, is that the X button at the top right doesn't work! Why?

    Also, Can someone explain more to me about the device context? Do I need one for this main window? Or do I only need a device context when I'm drawing things, like in our OpenGL frame I want to create.
    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
    WM_CLOSE should call DestroyWindow() [WM_DESTROY] which will clean up and call PostQuitMessage().

    As you have no processing in these handlers I would pass them on to the DefWindowProc(). ie remove the WM_CLOSE and I think it will work.

    As you have not followed correct switch/case/break syntax there are probably other errors (where DefWindowProc() is/ is not called after the message is/is not processed).

    DCs and OpenGL......

    Seen these?

    http://nehe.gamedev.net/data/lessons....asp?lesson=01
    "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
    Absent Minded Programmer
    Join Date
    May 2005
    Posts
    968
    Definately, I used those to get a milkshape model loader and such running. They don't really explain the win32 part too much, but I'll look again at it.
    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