Problems in C++ (WIN32 API)

Started by
15 comments, last by santonel 18 years, 6 months ago
Hey, I've been trying to write a set of wrapper classes for the win32 API to make my programs easier to write (I know there are things like MFC but I don't want to learn it right now). Im not too good at OOP so im having a bit of trouble wrapping my head around it. What I have so far is:

class wccwindow  
{
private:
	WNDCLASSEX wnd;			//the actual window class
	LRESULT CALLBACK WinProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam);
public:
	//constructors/destructors
	wccwindow();			//constructor
	virtual ~wccwindow();	//destructor

	//vars
	DWORD exstyle;			//extended styles
	int x,y;				//coords of the window
	HWND parent;			//parent window
	HWND menu;				//menu
	HWND window;			//handle to this window;

	//functions
	void init(LPCTSTR windowname,LPCTSTR windowtitle,DWORD windowstyle,int xlen,int ylen,HINSTANCE instance);  //initialize window
	
};
///////////////////////////////////////////////////////////////////
wccwindow::wccwindow()
{
wnd.cbSize = sizeof(WNDCLASSEX);
wnd.style = CS_VREDRAW | CS_HREDRAW | CS_OWNDC;
wnd.cbClsExtra = 0;
wnd.cbWndExtra = 0;
wnd.hIcon = LoadIcon(NULL,IDI_APPLICATION);
wnd.hCursor = LoadCursor(NULL,IDC_ARROW);
wnd.hbrBackground = (HBRUSH)GRAY_BRUSH;
wnd.lpszMenuName = NULL;
wnd.hIconSm = LoadIcon(NULL,IDI_APPLICATION);
wnd.lpfnWndProc = WinProc;
x = CW_USEDEFAULT;
y = CW_USEDEFAULT;
exstyle = NULL;
parent = NULL;
menu = NULL;
}

wccwindow::~wccwindow()
{

}
///////////////////////////////////////////////////
// Functions
///////////////////////////////////////////////////
void wccwindow::init(LPCTSTR windowname,LPCTSTR windowtitle,DWORD windowstyle,int xlen,int ylen,HINSTANCE instance)
{
wnd.hInstance = instance;
wnd.lpszClassName = windowname;
RegisterClassEx(&wnd);
window = CreateWindowEx(exstyle,windowname,windowtitle,windowstyle,x,y,xlen,ylen,parent,(HMENU)menu,instance,NULL);
}

//LRESULT CALLBACK wccwindow::WinProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam)
//{
//return(0);
//}
The problem I get is with this line: wnd.lpfnWndProc = WinProc; My compiler (VC++ 6) gives me an error: error C2440: '=' : cannot convert from 'long (__stdcall wccwindow::*)(struct HWND__ *,unsigned int,unsigned int,long)' to 'long (__stdcall *)(struct HWND__ *,unsigned int,unsigned int,long)' There is no context in which this conversion is possible Can anybody offer some advice? [Edited by - santonel on October 26, 2005 5:32:01 PM]
Advertisement
IIRC you can't use a member function for a callback. Pointers to member functions are handled differntly to pointers to functions. Check out this arcticle, it might help clear things up, and this may help you overcome the problem.
the rug - funpowered.com
It's because class functions have a hidden parameter, which is called the "this" pointer. This makes the function in your class different from a standard WindowProc function, and that's why the compiler is complaining.
You can't assign a pointer to a non-static member function to a pointer to a normal function. The usual method to handle this is to assign a static or normal function to the windows procedure and use GetWindowLong() or GetWindowLongPtr() to a pointer from the GWL_USERDATA of the windows class. See this article for more details. When you call CreateWindowEx() pass the pointer to the class as parameter.

[Edited by - SiCrane on June 25, 2006 1:05:25 PM]
Thanks for the help but like I said im not very experienced with OOP so I only partly understand those articles. Plus they seem to be about making pointers to member functions from outside the class.

The wnd.lpfnWndProc is a function pointer in a class which is within another class and the function i need it to point to is in the "outer" class. I have no idea how to go about this. Any ideas?

P.s. my brain hurts.
You have to take it out of the class or make it static.
- The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
Ok I got around that problem and realised after reading your articles (thanx for them by the way) that im going to need a static message router to route messages back to an event handler in the instance of the class that generated it.

The problem is figring out which instance sent the messages. In the article the code was this:

wnd = reinterpret_cast<Window *>(::GetWindowLong(hwnd, GWL_USERDATA));

I do not get how this works. What exatcly does GetWIndowLong return and how can it be casted into a totally unrelated type? It sort of flies in the face of everyting I learned about type casting.

Other than that is there other ways to accomplish this?
The 'window long' is just an arbitrary bit of data that the application can set when creating the window. In your case, when you create the window, you cast a pointer to that window to long and store it there. Later, you can retreive it using the handle your message handler receives and cast it back into a pointer.
Quote:Original post by Deyja
The 'window long' is just an arbitrary bit of data that the application can set when creating the window. In your case, when you create the window, you cast a pointer to that window to long and store it there. Later, you can retreive it using the handle your message handler receives and cast it back into a pointer.


Im starting to get it now. Why does this require a reinterpret_cast? I've never seen anyone use one before.

NVM the above. I get it now.
OK thanx for the help everyone my program works now. Now im on to event handling. For this im trying to do it using function pointers. Basically the premise is every event gets its own function pointer.When the event comes up in the wndproc the function pointer is called. The person using the class can then point these function pointers to their own functions so that when an event is triggered the function pointer calls their custom function to handle the event. So far i've implemented this and it compiles without errors but it crashes when the function pointer is called. I created an empty static event function in my class that just returns 0 and set all my function pointers to it by default in the constructor.

Any ideas why it's crashing.

(If you want to see the code just ask.)

This topic is closed to new replies.

Advertisement