Click to See Complete Forum and Search --> : Problems making a Windows class


Drb2k2
September 25th, 2003, 08:02 AM
HI all,
I'm trying to write a simple class so that when I want a window to appear I won't have to register it etc. The class should take care of this for me. I have taken the code from a book called "Special Effects Programming with DirectX" and know that it compiles in its raw state. My problem is that .NET complains about this:

EASYWINDOW.cpp(73): error C2440: '=' : cannot convert from 'LRESULT (__stdcall CEASYWINDOW::* )(HWND,UINT,WPARAM,LPARAM)' to 'WNDPROC'

But this its meant to return an LRESULT. I guess there is an error somewhere within the definition for WindowProc, but I don't know what. Any help would be appreciated. Below are all the files I'm currently using

<HEADER FILE>
#pragma once
#include <windows.h>

class CEASYWINDOW
{
public:
CEASYWINDOW(void);
~CEASYWINDOW(void);
HWND InitWindow(HINSTANCE &hInst, int nCmdShow);
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
void PaintWindow(HWND hwnd);
};


<CLASS FILE>
#include "easywindow.h"

CEASYWINDOW::CEASYWINDOW(void)
{
}

CEASYWINDOW::~CEASYWINDOW(void)
{
}

void PaintWindow(HWND hwnd)
{
PAINTSTRUCT ps;

BeginPaint(hwnd, &ps);
HDC hdc = ps.hdc;
char buf[] = "Press a key to exit.";

TextOut(hdc, 0, 0, buf, strlen(buf));
EndPaint(hwnd, &ps);
}

/****************************************************************************

WindowProc: callback function for our window.

****************************************************************************/
LRESULT CALLBACK WindowProc(
HWND hwnd, // handle to window
UINT uMsg, // message identifier
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
)
{
switch(uMsg) {

// we get the WM_CLOSE message when our close (X) box has been clicked.
// we need to respond to it to make sure our program stops when its window
// is closed.

case WM_PAINT: // we get this message when we're supposed to paint.
PaintWindow(hwnd);
return(0);

case WM_CHAR: // we get this message when a key is pressed.
PostQuitMessage(0);
return(0);

case WM_CLOSE: // we get this message when our window is closed.
PostQuitMessage(0);
return(0);
}

// all the other messages, we don't care about, so we let DefWindowProc
// handle them.
return(DefWindowProc(hwnd, uMsg, wParam, lParam));
}

/****************************************************************************

InitWindow: creates a window class and a window.

****************************************************************************/
HWND CEASYWINDOW::InitWindow(HINSTANCE& hinst, int nCmdShow)
{
HWND hwnd;
WNDCLASSEX wc;

// set up and register window class
memset(&wc, 0, sizeof(wc));
wc.cbSize = sizeof(wc);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WindowProc; // change this to NULL and crash!
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hinst;
wc.hIcon = NULL;
wc.hIconSm = NULL;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = reinterpret_cast<HBRUSH>(COLOR_WINDOW); // this can be changed for different colors
wc.lpszMenuName = NULL;
wc.lpszClassName = "MyCoolWindow";
RegisterClassEx(&wc);

// create a window that's 200 pixels wide, 100 tall.

// NOTE: You can change the window's style slightly by adding or removing WS_ styles.
// see what happens when you take out WS_MINIMIZEBOX, WS_MAXIMIZEBOX, WS_SYSMENU, and/or
// WS_THICKFRAME.
//
// notice how the window changes?
//
// another fun one to play with is WS_EX_TOOLWINDOW, which goes in the 1st parameter, because
// it's an extended style.

// ||
// VV WS_EX_TOOLWINDOW goes here!

hwnd = CreateWindowEx(0, "MyCoolWindow", "Paint, Wait, and Exit v1.00",
WS_POPUP | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME,
50, 50, 200, 100, NULL, NULL, hinst, NULL);

if (!hwnd) {
::MessageBox(NULL, "CreateWindow failed!", "Paint, Wait, and Exit v1.00", MB_ICONSTOP);
exit(-1);
}

ShowWindow(hwnd, nCmdShow);
return(hwnd);
}

<MAIN FILE>
#include "EASYWINDOW.h"
#include <windows.h>


int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
CEASYWINDOW MyWindow;
HWND hwnd = MyWindow.InitWindow(hInstance, nCmdShow);
//HWND hwnd = InitWindow(hInstance, nCmdShow);

while(1)
{
MSG msg;
if(PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
{
int result = GetMessage(&msg, NULL, 0, 0);
if(!result) return(msg.wParam);

TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return 0;
}


Thanks everyone
Dylan

poccil
September 25th, 2003, 08:57 AM
wc.lpfnWndProc = (WNDPROC)WindowProc;


Every window class must have a window procedure. Be sure to cast to WNDPROC to avoid the error.

Drb2k2
September 25th, 2003, 09:31 AM
Hi Peter O,

Thanks for the speedy reply. I had already given that a go and even used

reinterpret_cast<WNDPROC>

just to be super safe but still to no avail. The compiler now throws the error:

\EASYWINDOW.cpp(73): error C2440: 'type cast' : cannot convert from 'overloaded-function' to 'WNDPROC'

Any more help though would be much appreciated.
Thanks
Dylan

usman999_1
September 26th, 2003, 12:09 PM
You forgot to declare it static ;).
Hope this helps,
Regards,
Usman.

Drb2k2
September 26th, 2003, 12:52 PM
Hi,
Thanks for that but its still not working.
I suppose you meant declare the hwnd and wndclassex as being static. The error is still being thrown. I can't get around it. I dont understand why this is being thrown at all. It is returning exactly what it should. Any more help, pleasde keep hemcoming.
cheers
dylan

vicodin451
September 26th, 2003, 01:17 PM
You tried

static LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
and it still didn't work?

Drb2k2
September 26th, 2003, 01:23 PM
Hi,
Thank you so much for the reply, it appears as though we might be getting close.

The compiler is happy with the WndProc call but now claims:

ClassWindows error LNK2019: unresolved external symbol "public: static void __cdecl CEASYWINDOW::PaintWindow(struct HWND__ *)" (?PaintWindow@CEASYWINDOW@@SAXPAUHWND__@@@Z) referenced in function "public: static long __stdcall CEASYWINDOW::WindowProc(struct HWND__ *,unsigned int,unsigned int,long)" (?WindowProc@CEASYWINDOW@@SGJPAUHWND__@@IIJ@Z)

if I don't make the PaintWindow static i get:

\EASYWINDOW.cpp(42): error C2352: 'CEASYWINDOW::PaintWindow' : illegal call of non-static member function

hmmm, i understand the second call, but don't have a clue what the first one means (unresolved external).

Thanks for your continued help
Dylan

Michello
October 1st, 2003, 08:31 AM
Hi!

Your method PaintWindow( HWND ) is declared as a member of CEASYWINDOW, ok! But you've forgotten the namespace in the implementation.

void CEASYWINDOW::PaintWindow( HWND hwnd )
{
PAINTSTRUCT ps;

::BeginPaint(hwnd, &ps); // :: for global namespace.
HDC hdc = ps.hdc;
char buf[] = "Press a key to exit.";

::TextOut(hdc, 0, 0, buf, strlen(buf));
::EndPaint(hwnd, &ps);
}
Hope that helps.

Drb2k2
October 1st, 2003, 10:59 AM
Thats the ticket,
Thank you very much, that had me stumped for ages.
Cheers
Dylan