method override not being called

Started by
1 comment, last by cptrnet 18 years, 8 months ago
Before I mention anything I have checked the spelling and method declaration so don't reply saying check those things. I am using c++ in vs2003. I have an Application class that uses a static window procedure. In my window procedure the WM_CREATE calls an OnLoad method. In my derived class I override the method. The weird thing is that the base class's method gets called instead of the derived class. I also have an OnPaint and OnClose method that work fine. I have checked the spelling and declaration so many times. I have used break points to figure whats happening and this is where I am now. I don't understand why.


                class IApplication
		{

		private:

			HINSTANCE	m_hInst;
			HWND		m_hWnd;
			std::string m_strClassName;

		public:

			IApplication(HINSTANCE hInst, std::string strClassName, std::string strTitle = "Default");
			~IApplication(void);

			HINSTANCE GethInst(void);
			HWND GethWnd(void);

			void Run(void);
			void Show(bool bShow = true);
			void SetFont(HFONT hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT));

		protected:

			static LRESULT CALLBACK StaticWndProc(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam);
			inline static IApplication* GetObjectFromWindow(HWND hWnd);

			LRESULT CALLBACK WndProc(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam);

			virtual void OnLoad(void);
			virtual void OnClose(void);
			virtual void OnPaint(void);

		};





IApplication::IApplication(HINSTANCE hInst, std::string strClassName, std::string strTitle)
		{

			m_hInst = hInst;

			WNDCLASSEX wcex;

			wcex.cbClsExtra		= 0;
			wcex.cbSize			= sizeof(WNDCLASSEX);
			wcex.cbWndExtra		= 0;
			wcex.hbrBackground	= (HBRUSH)GetStockObject(0);
			wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
			wcex.hIcon			= LoadIcon(NULL, IDI_APPLICATION);
			wcex.hIconSm		= LoadIcon(NULL, IDI_APPLICATION);
			wcex.hInstance		= g_hInst;
			wcex.lpfnWndProc	= StaticWndProc;
			wcex.lpszClassName	= strClassName.c_str();
			wcex.lpszMenuName	= NULL;
			wcex.style			= CS_CLASSDC;

			if(!RegisterClassEx(&wcex))
			{
				//Log Error
			}

			m_hWnd = CreateWindow(strClassName.c_str(), strTitle.c_str(), 
				WS_OVERLAPPEDWINDOW, 0, 0, 300, 300, NULL, NULL, g_hInst, (void*)this);

			if(!m_hWnd)
			{
				//Log Error
			}

			//Set Globals
			g_hWnd = m_hWnd;
			g_hInst = m_hInst;

			UpdateWindow(m_hWnd);

		}

		IApplication::~IApplication(void)
		{
			UnregisterClass("DEFAULT", g_hInst);
		}

		HINSTANCE IApplication::GethInst(void)
		{
			return m_hInst;
		}

		HWND IApplication::GethWnd(void)
		{
			return m_hWnd;
		}

		void IApplication::Run(void)
		{

			MSG msg;

			ZeroMemory(&msg, sizeof(MSG));

			while(msg.message != WM_QUIT)
			{
				if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
				{
					TranslateMessage(&msg);
					DispatchMessage(&msg);
				}
			}

		}

		void IApplication::Show(bool bShow)
		{
			if(bShow)
			{
				ShowWindow(m_hWnd, SW_SHOW);
			}
			else 
			{
				ShowWindow(m_hWnd, SW_HIDE);
			}
		}

		void IApplication::SetFont(HFONT hFont)
		{
			SendMessage(m_hWnd, WM_SETFONT, (WPARAM)hFont, MAKELPARAM(FALSE, 0));
		}

		LRESULT CALLBACK IApplication::StaticWndProc(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
		{

			IApplication *app = NULL;

			if(iMsg == WM_NCCREATE)
			{
				SetWindowLongPtr(hWnd, GWL_USERDATA, reinterpret_cast<long>((LPCREATESTRUCT(lParam))->lpCreateParams));
			}

			app = GetObjectFromWindow(hWnd);

			if(app)
			{
				return app->WndProc(hWnd, iMsg, wParam, lParam);
			}
			else
			{
				return DefWindowProc(hWnd, iMsg, wParam, lParam);
			}

		}

		IApplication* IApplication::GetObjectFromWindow(HWND hWnd)
		{
			return reinterpret_cast<IApplication*>(GetWindowLongPtr(hWnd, GWL_USERDATA));
		}

		LRESULT CALLBACK IApplication::WndProc(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
		{

			switch(iMsg)
			{

				case WM_CREATE:	 
					OnLoad();  
				break;

				case WM_DESTROY: 
					OnClose(); 
					PostQuitMessage(0);
				break;

				case WM_PAINT:
					OnPaint();
				break;

			}

			return DefWindowProc(hWnd, iMsg, wParam, lParam);

		}

		void IApplication::OnLoad(void)
		{
			MessageBox(NULL, "Load", "", MB_OK);
		}

		void IApplication::OnClose(void)
		{
		}

		void IApplication::OnPaint(void)
		{
		}



class Application : public IApplication
{

public:

	Application(HINSTANCE hInst, std::string strClassName, std::string strTitle);
	~Application(void);

protected:

	void OnLoad(void);
	void OnPaint(void);
	void OnClose(void);

};


Application::Application(HINSTANCE hInst, std::string strClassName, 
	std::string strTitle = "Default") : IApplication(hInst, strClassName, strTitle)
{
}

Application::~Application()
{
}

void Application::OnLoad(void)
{
	Show(true);
}

void Application::OnPaint(void)
{
	
	HDC hdc;

	hdc = GetDC(g_hWnd);

	TextOut(hdc, 100, 100, "Hello World!", 12);

}

void Application::OnClose(void)
{
	//MessageBox(NULL, "Close", "", MB_OK);
}

If you insist on saying "DUH", try to make a post that makes a little more sense
Advertisement
because in IApplication :: IApplication, the this pointer will be of type IApplication, and thus, at CreateWindow, you'll pass an IApplication object, and this gets into WM_CREATE..

afterwards, the IApplication constructor ends, and the pointer gets converted to type Application, and Application :: Application starts running. at this point, all further windows messages will see and use the Application object.


internally, what happens is, first an IApplication object gets created, with a vtable pointing to the IApplication methods.
after the IApplication constructor, the vtable gets overwritten by the Application constructor.

solution? hm.. I'd suggest to write a IApplication :: createWindow(..) method, and call it manually in the constructor of Application. I "think" thats the only clean way, but i haven't worked with c++ for quite a long time.
If that's not the help you're after then you're going to have to explain the problem better than what you have. - joanusdmentia

My Page davepermen.net | My Music on Bandcamp and on Soundcloud

Yah I believe thats the problem, when using breakpoints I saw something like that I just wasn't sure and I thought it was supposed to be that way. Thanks for the reply, I will try the create window method.
If you insist on saying "DUH", try to make a post that makes a little more sense

This topic is closed to new replies.

Advertisement