Public Group

# problems with my win32 class

This topic is 4757 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I'm trying to create a simple class in C++ so that all I'd have to do is include this file in future files and call a few functions to setup a window, but I have one error so far that I cannot understand. This is the line... winclass.lpfnWndProc = WindowProc; and this is the error... error C2440: '=' : cannot convert from 'long (__stdcall initwin::*)(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 I see that the main problem is (_stdcall initwin::*) to (_stdcall *), and it looks to me like the only way to get rid of this is to leave something out of my class. What do I have to do to be able to keep all variables/struct declarations and functions inside of a class declaration so I can avoid using globals? Here's the (incomplete) code as it is now:
#define WIN32_LEAN_AND_MEAN

#include <windows.h>
#include <windowsx.h>
#include <mmsystem.h>
#include <stdlib.h>
#include <stdio.h>
#include <ddraw.h>
#include <math.h>

class initwin
{
private:
HWND				hwindow;		UINT		msg2;
HINSTANCE			hinst;			WPARAM		wparam;
WNDCLASSEX			winclass;		LPARAM		lparam;
MSG					msg;
public:
initwin();
LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
WNDCLASSEX SetWinclass(WNDCLASSEX winclass);
};

initwin::initwin()
{
hwindow = NULL;
hinst = NULL;
}

LRESULT CALLBACK initwin::WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
PAINTSTRUCT		ps;
HDC				hdc;

switch(msg)
{
case WM_CREATE:
{
return(0);
} break;

case WM_PAINT:
{
hdc = BeginPaint(hwnd,&ps);
EndPaint(hwnd,&ps);
return(0);
} break;

case WM_DESTROY:
{
PostQuitMessage(0);
return(0);
} break;

default:break;

} // end switch

return (DefWindowProc(hwnd, msg, wparam, lparam));

} // end WinProc

WNDCLASSEX initwin::SetWinclass(WNDCLASSEX winclass)
{
winclass.cbSize         = sizeof(WNDCLASSEX);
winclass.style			= CS_DBLCLKS | CS_OWNDC |
CS_HREDRAW | CS_VREDRAW;
winclass.lpfnWndProc	= WindowProc;
winclass.cbClsExtra		= 0;
winclass.cbWndExtra		= 0;
winclass.hInstance		= hinst;
winclass.hbrBackground	= (HBRUSH)GetStockObject(BLACK_BRUSH);
winclass.lpszClassName	= "C++ window class";
return winclass;
}

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nShowCmd)
{
return 0;
}


##### Share on other sites
I don't know if this will work (just a shot in the dark here), but trying putting:

winclass.lpfnWndProc = this.WindowProc;

If that doesn't work, then just remove WindowProc from the class and make it an external function. It doesn't hurt to have a couple of globals, just make sure that you don't overdo them. Same with classes.

##### Share on other sites
The function can be in your class but you have to declare it to be static.

##### Share on other sites
Every function inside a class has a hidden last parameter where this (the pointer to the class) is passed. That's why the compiler complains. The line:

winclass.lpfnWndProc = WindowProc;

expects to see a WNDPROC function pointer and you assign it something which is not a WNDPROC function pointer because of the hidden parameter.

There are a few ways to get around this problem. My favorite is to have the WndProc function outside the class and pass it as a parameter to an Init function of my class. It can then be assigned to the lpfnWndProc without the compiler complaining.

You can always have all the initialisation and windows creation/message handling stuff in a separate file and just add it to your workspace everytime you start a new project, without using classes. All you have to do is call the Init function if all you need a window class for is initialisation.

##### Share on other sites
I guess I'll have to go with the suggestion to leave it out of a class, since declaring the function as static inside a class causes another error. Now that I think of it, I could just use a "initwin.cpp" file to put all of my initialization functions into.

Now since that's apparently it, could anyone tell me if I could use this kind of code in unmanaged C++.net? I've googled for tutorials, but couldn't really find something besides using C++.net for managed code or for sample applications. I had asked this type of question before and didn't really get an answer...

##### Share on other sites
I think I've found a solution for the time being that cuts down on the number of lines of code in the WinMain function. All it requires are for the same variable/struct declarations within WinMain as in the globals.

#define WIN32_LEAN_AND_MEAN#include <windows.h>#include <windowsx.h>#include <mmsystem.h>#include <stdlib.h>#include <stdio.h>#include <ddraw.h>#include <math.h>HINSTANCE				hinst;WNDCLASSEX				winclass;HWND					hwnd;MSG						msg;HDC						hdc;int x = 0;				int w = 400;int y = 0;				int h = 300;const char *wcname = "C++ window class";const char *wtitle = "Test window...";LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam){PAINTSTRUCT		ps;HDC				hdc;switch(msg)	{		case WM_CREATE:         {		return(0);		} break;  	case WM_PAINT: 		{		hdc = BeginPaint(hwnd,&ps);	         EndPaint(hwnd,&ps);		return(0);   		} break;	case WM_DESTROY: 		{		PostQuitMessage(0);		return(0);		} break;	default:break;    }return (DefWindowProc(hwnd, msg, wparam, lparam));}void SetWinclass(WNDCLASSEX &winclass, HINSTANCE &hinst, HWND &hwnd){	winclass.cbSize         = sizeof(WNDCLASSEX);	winclass.style			= CS_DBLCLKS | CS_OWNDC | 							  CS_HREDRAW | CS_VREDRAW;	winclass.lpfnWndProc	= WindowProc;	winclass.cbClsExtra		= 0;	winclass.cbWndExtra		= 0;	winclass.hInstance		= hinst;	winclass.hIcon			= LoadIcon(NULL, IDI_APPLICATION);	winclass.hCursor		= LoadCursor(NULL, IDC_ARROW); 	winclass.hbrBackground	= (HBRUSH)GetStockObject(BLACK_BRUSH);	winclass.lpszMenuName	= NULL;	winclass.lpszClassName	= wcname;	winclass.hIconSm        = LoadIcon(NULL, IDI_APPLICATION);	RegisterClassEx(&winclass);	hwnd = CreateWindowEx(NULL, wcname, wtitle, WS_OVERLAPPEDWINDOW | WS_VISIBLE,		x, y, w, h, NULL, NULL, hinst, NULL);	hdc = GetDC(hwnd);}int HandleMsg(MSG &msg){	if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))	   {        if (msg.message == WM_QUIT)           return 1;			   TranslateMessage(&msg);	   DispatchMessage(&msg);	   }	return 0;}int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,					LPSTR lpCmdLine, int nShowCmd){	HWND			hWnd = NULL;			HDC				hDC = NULL;	WNDCLASSEX		winClass;	HINSTANCE		hInst;	MSG				mSg;	SetWinclass(winClass, hInst, hWnd);	while(TRUE)	{		if(HandleMsg(mSg)==1)			break;		SetTextColor(hdc, RGB(rand()%256,rand()%256,rand()%256));		SetBkColor(hdc, RGB(0,0,0));		SetBkMode(hdc, TRANSPARENT);		TextOut(hdc,rand()%400,rand()%400, "GDI Text Demo!", strlen("GDI Text Demo!"));		Sleep(10);	}	ReleaseDC(hWnd, hDC);	return (msg.wParam);}

##### Share on other sites
Another option would be to pass a pointer of the WNDPROC to your original class

void initwin::SetWinclass(WNDPROC proc){	hinst =GetModuleHandle(NULL);	winclass.cbSize         = sizeof(WNDCLASSEX);	winclass.style			= CS_DBLCLKS | CS_OWNDC | 							  CS_HREDRAW |   CS_VREDRAW;	winclass.lpfnWndProc	= proc;	winclass.cbClsExtra		= 0;	winclass.cbWndExtra		= 0;	winclass.hInstance		= hinst;	winclass.hIcon			= LoadIcon(NULL, IDI_APPLICATION);	winclass.hCursor		= LoadCursor(NULL, IDC_ARROW); 	winclass.hbrBackground	= (HBRUSH)GetStockObject(BLACK_BRUSH);	winclass.lpszMenuName	= NULL;	winclass.lpszClassName	= "C++ window class";	winclass.hIconSm        = LoadIcon(NULL, IDI_APPLICATION);}

Hmm had to fix that a bit hope that doesn't have to many errors [lol]
This is as long as you don't mind having the window procedure outside your class of course [smile]

• 9
• 13
• 41
• 15
• 13