Advertisement

Creating a window with a class -> error [win32 c++]

Started by February 15, 2004 04:01 AM
14 comments, last by Ruudje 21 years ago
Hi all, im trying to write wrappers for all the basic stuff such as creating a window, opengl, sounds blablabla. My first class is CWindowFactory and should basically handle creating and destroying a window much like the ones used in the nehe-tutorials. This class also holds all information on the window, such as the handle, key- and mousestate etc. My problem? Everyone probably recognises this line: wc.lpfnWndProc = (WNDPROC) WndProc; Normally (when not using a class) this is no problem, but the windowprocedure is also part of the class. The above line gives me the error : e:\Baseclasses\CWindowFactory.cpp(34): error C2440: ''type cast'' : cannot convert from ''overloaded-function'' to ''WNDPROC'' How can I fix this? The line: LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); is a private member of the class. tnx
The probem is, is that the lpfnWndProc in the WNDCLASS structure calls for a GLOBAL function of type LRESULT CALLBACK (*ptr)(HWND, UINT, WPARAM, LPARAM). But your CWindowFactory classes WndProc is type LRESULT CALLBACK (CWindowFactor:: (*ptr))(HWND, UINT, WPARAM, LPARAM), and the compiler cannot cast from the global type to the function type. I have managed to get around this by having a pointer to a static global variable of CWinApp, or CWindowFactory in your case, and a static global WndProc. Then in the CWindowFactory constructor make the global pointer point to this, and make the global window procedure handle the messages throught the global pointer. Ill put it into code, I dont think I explained it very well.

class CWindowFactory {public:  CWindowFactory() {    g_pWndFactory = (this);  }    LRESULT CALLBACK WndProc(HWND ...);};static CWindowFactory*    g_pWndFactory=NULL;static LRESULT CALLBACK GlobalWndProc(HWND ...) {  if(g_pWndFactory)    m_pWndFactory->WndProc(hWnd, ...);}


Hope this helps

ps: if you have any problems, email me at chatterbox@xtra.co.nz

- Ratterbox

[edited by - Ratterbox on February 15, 2004 5:31:13 AM]
Advertisement
Im sorry but you kindof lose me at the end there I found something on google btw about making my windowproc static, but then I cant use my keys[256] array anymore

Anyways. The goal of this class is being completely independant from the application itself, so it should be able to work without any global variables/declarations

Im sorry, guess im still a win32 n00b :D
Windows needs a single WndProc function that it can call whenever a window message is generated for your application. Windows knows nothing about your CWindow or CWindowFactory classes, so it can''t call one of their member functions. The solution is to declare a static member function WndProc in one of your classes and have it forward the call to the correct window. This can be achieved by maintaining a map of window handles to window instances and looking up the window handle in WndProc, i.e.:
class Window{	public:		Window()		{			// stuff			windows.insert(std::make_pair(windowHandle, this));		}		~Window()		{			windows.erase(windowHandle);			// stuff		}		void memberWndProc(...)		{			// stuff		}		static void WndProc(HWND hWnd, ...)		{			if (windows.find(hWnd) != windows.end())			{				windows[hWnd]->memberWndProc(...);			}		}	private:		static std::map<HWND, Window*> windows;}; 


Enigma
your reply is, as always, awesome

but after implementing this, 1 problem remains:

Baseclasses error LNK2001: unresolved external symbol "private: static class std::map,class std::allocatorair > > CWindowFactory::windows" (?windows@CWindowFactory@@0V?$map@PAUHWND__@@PAVCWindowFactory@@U?$less@PAUHWND__@@@std@@V?$allocator@U?$pair@QAUHWND__@@PAVCWindowFactory@@@std@@@4@@std@@A)

Can you explain to me what is wrong?
You need to actually define static members as well as declaring them. In your Window.cpp (or equivalent) add:
std::map<HWND, Window*> Window::windows; 


Enigma
Advertisement
tnx. now if I try to use the class/code i get

Baseclasses error LNK2005: "private: static class std::map,class std::allocatorair > > CWindowFactory::windows" (?windows@CWindowFactory@@0V?$map@PAUHWND__@@PAVCWindowFactory@@U?$less@PAUHWND__@@@std@@V?$allocator@U?$pair@QAUHWND__@@PAVCWindowFactory@@@std@@@4@@std@@A) already defined in Baseclasses.obj


i guess its a little out of my league
You have the definition in a cpp file and you''re not including that cpp file anywhere?

Enigma
nopers... i have the class, structure and std definitions in a .h file. Ive also added the cpp-file and h-file to the project and include the .h file in the main .cpp file of the program.

I''ll post my code this evening (its 8:24 here right now).
#include "stdafx.h"#ifndef WindowFactoryHeader#define WindowFactoryHeader#include <map>using namespace std;struct s_Windowsettings{	int width, height, bits;	bool fullscreen;};class CWindowFactory{public:	CWindowFactory(s_Windowsettings Settings);	~CWindowFactory();	HWND* GetHandle(void);	bool Create(void);	void Kill(void);	static void CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);	LRESULT CALLBACK MemberWndProc(HWND, UINT, WPARAM, LPARAM);private:	HWND				hWnd;	HINSTANCE			hInstance;	s_Windowsettings	s_Settings;	bool				keys[256];	char *				title;	static std::map<HWND, CWindowFactory*> windows;protected:};std::map<HWND, CWindowFactory*> CWindowFactory::windows; #endif

This topic is closed to new replies.

Advertisement