Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

ANSI2000

Win32 Windows and classes again. Something wrong...

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

We talked about this a while back... I have managed to wrap the win32 code that wraps up the window creation within classes.. But i thought I should give it a try to clean it up a bit a or rearange things they way "I think" they should be.... Of course this failed miserably, can some one look and tell me what is wrong? I want to implement the constructor and create() function as I have them shown, of course this might not be possible... It doesnt seem that the WM_CREATE ever happens....
// g3dgui.h
#ifndef G3DGUI_H
#define G3DGUI_H

// Required include files.
#include <windows.h>
#include <windowsx.h>

namespace G3DGUI
{
	class Object
	{
	public:

		Object(HINSTANCE pInstance, HWND pParent) : instance(pInstance), parent(pParent) {}
		virtual ~Object() {}

		const HINSTANCE getInstance() const { return(instance); }
		const HWND getParent() const { return(parent); }
		const HWND getHandle() const { return(handle); }
		const char* getClassName() const { return(className); }
		const getX() const { return(x); }		
		const getY() const { return(y); }		
		const getWidth() const { return(width); }		
		const getHeight() const { return(height); }		
		const unsigned int getStyleEx() const { return(styleEx); }
		const unsigned int getStyle() const { return(style); }
		const char* getCaption() const { return(caption); }			

		void create(const char *pClassName, int pX, int pY, int pWidth, int pHeight, unsigned int pStyle, unsigned int pStyleEx, const char *pCaption)
		{
			setClassName(pClassName);
			setX(pX);
			setY(pY);
			setWidth(pWidth);
			setHeight(pHeight);
			setStyle(pStyle);
			setStyleEx(pStyleEx);
			setCaption(pCaption);

			windowClass.lpfnWndProc = defaultProc;
			windowClass.hInstance = getInstance();
			windowClass.lpszClassName = getClassName();
			windowClass.cbSize = sizeof(WNDCLASSEX);
			windowClass.cbClsExtra = 0;
			windowClass.cbWndExtra = 0;
			windowClass.style = 0;
			windowClass.hCursor = LoadCursor(0, IDC_ARROW);
			windowClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
			windowClass.hIcon = LoadIcon(0, IDI_APPLICATION);
			windowClass.hIconSm = LoadIcon(0, IDI_APPLICATION);
			windowClass.lpszMenuName = 0;

			registerClass();
			
			handle = CreateWindowEx(getStyleEx(), getClassName(), getCaption(), getStyle(), 
									getX(), getY(), getWidth(), getHeight(), getParent(), 
									NULL, getInstance(), (LPSTR)this);
			update();
			
			show();
		}
		
		void update() { UpdateWindow(getHandle()); }
		void show()	{ ShowWindow(getHandle(), SW_SHOW); }
		void hide()	{ ShowWindow(getHandle(), SW_HIDE); }
		void focus() { SetFocus(getHandle()); }

		static LRESULT CALLBACK defaultProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
		{
			Object *thisObject = (Object*)GetWindowLong(hWnd, GWL_USERDATA);
			
			if(!thisObject)
			{
				if(Msg == WM_CREATE)
				{
					MessageBox(NULL, "WM_CREATE", "WM_CREATE", 0);
					LPCREATESTRUCT lpcs = (LPCREATESTRUCT)lParam;
					thisObject = (Object*)lpcs->lpCreateParams;
					SetWindowLong(hWnd, GWL_USERDATA, (LONG)thisObject);
					return thisObject->winProc(Msg, wParam, lParam);
				}
				else
					return DefWindowProc(hWnd, Msg, wParam, lParam); // should never be called
			}
			else
			{
				MessageBox(NULL, "winProc", "winProc", 0);
				return thisObject->winProc(Msg, wParam, lParam);
			}
		}
	
		virtual LRESULT winProc(UINT Msg, WPARAM wParam, LPARAM lParam) = 0;

	protected:

		void setClassName(const char *pClassName) { className = pClassName; }
		void setX(int pX) { x = pX; }		
		void setY(int pY) { y = pY; }		
		void setWidth(int pWidth) { width = pWidth; }		
		void setHeight(int pHeight) { height = pHeight; }		
		void setStyle(unsigned int pStyle) { style |= pStyle; }
		void setStyleEx(unsigned int pStyleEx) { styleEx |= pStyleEx; }
		void setCaption(const char *pCaption) { caption = pCaption; }

		bool registerClass()
		{
			if(!RegisterClassEx(&windowClass))
				return(false);
			else
				return(true);
		}
		
		void unRegisterClass()
		{
			UnregisterClass(getClassName(), getInstance());
		}

	private:
		HINSTANCE instance;
		HWND parent;
		HWND handle;
		WNDCLASSEX windowClass;
		const char* className;
		const char*	caption;
		int x;
		int	y;
		int	width;
		int	height;
		unsigned int style;
		unsigned int styleEx;
	};
}

#endif

// g3dgui.cpp
//Required include files.

//Application include files.
#include "g3dgui.h"
// Nothing in here all of it is inlined in the g3dgui.h file.

//winmain.cpp
#include <g3dgui.h>

using namespace G3DGUI;

bool running = true;

class TestWindow : public Object
{	
public:
	
	TestWindow(HINSTANCE pInstance, HWND pParent) : Object(pInstance, pParent){}

protected:

	LRESULT winProc(UINT Msg, WPARAM wParam, LPARAM lParam);
};

LRESULT TestWindow::winProc(UINT Msg, WPARAM wParam, LPARAM lParam)
{
	switch (Msg)
	{
	case WM_CREATE:
		MessageBox(NULL, "dood", "doods", 0);
	case WM_DESTROY:
		PostQuitMessage(0);

		running = false;

		break;
	default:
		return DefWindowProc(getHandle(), Msg, wParam, lParam);
	}
	return 0;
}

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
	TestWindow testWindow(hInstance, NULL);

	testWindow.create("My Window", 10, 10, 100, 100, WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, NULL, "My Window");

	while(running)
	{
		MSG msg;

		while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}	
	}


	return(0);
}
 

Share this post


Link to post
Share on other sites
Advertisement
Try removing the condition around the WM_CREATE in Object::defaultProc - do you know that GWL_USERDATA is always going to be 0 at the WM_CREATE stage ?

It''s unnecessary anyway, you are only ever going to get a WM_CREATE once per window instance.

Have you tried stepping through the code with the debugger and seeing where it fails ?

HTH,
t0ne.



Slightly shrimpy smell == unsafe breadbin

Share this post


Link to post
Share on other sites
So, the CreateWindowEx call executes but returns NULL, yea ?
I would check then that the hInstance is valid and that you''ve correctly registered the WNDCLASS amd check your window styles are a correct combination. Also what does GetLastError return after the failure ?

A small point, although it probably works OK in this instance your setClassName and setCaption methods are unsafe. You should allocate some memory and store the contents of the buffers rather than the pointer to it (it could go out of scope, get modified elsewhere etc.).



Slightly shrimpy smell == unsafe breadbin

Share this post


Link to post
Share on other sites
The class does register correctly...

To check if the instance is correct I do what check for a null value?

But you should be able to pass an instance of null and it should work anyways

Share this post


Link to post
Share on other sites
Tone -> having a char* as paramter cant go out of scope : heres an example :

void setCaption(const char* cap)

the calling

wnd.setCaption("hello");

in this case "hello" is static and can never be modified.

Share this post


Link to post
Share on other sites
I think the very ''1st'' few messages that Windows send is not WM_CREATE. I think WM_GETMINMAXINFO or WM_NCCREATE came before WM_CREATE, and the WM_GETMINMAXINFO is the 1st.

I suggest that WM_NCCREATE would be a nice spot for SetWindowLong

Share this post


Link to post
Share on other sites
quote:
Original post by hotdot
Tone -> having a char* as paramter cant go out of scope : heres an example :

void setCaption(const char* cap)

the calling

wnd.setCaption("hello");

in this case "hello" is static and can never be modified.


In this particular case this is true. But how about:

char buffer[256];
strcpy(buffer, "Hello");

setCaption(buffer);

strcpy(buffer, "something else");

or if the above code was done inside a function, buffer would be created on the stack and lost when it went out of scope.




Slightly shrimpy smell == unsafe breadbin

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!