• Advertisement
Sign in to follow this  

Creating a window using a class in C++

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

If you intended to correct an error in the post then please contact us.

Recommended Posts

I can already create a window and initialize DirectX and everything when I am doing everything with global functions and variables. Problems arise when I try to do this from within a class though. I am getting the following errors when I try to compile with Microsoft Visual C++ 2005...
nhsWindow.cpp
c:\blahblahblah\projects\nhs2d\nhs2d\nhswindow.cpp(65) : error C2664: 'SetWindowLongA' : cannot convert parameter 3 from 'LPVOID' to 'LONG'
        There is no context in which this conversion is possible
c:\blahblahblah\projects\nhs2d\nhs2d\nhswindow.cpp(70) : error C2440: '=' : cannot convert from 'LONG' to 'nhsWindow *'
        Conversion from integral type to pointer type requires reinterpret_cast, C-style cast or function-style cast
The part of the program that these errors are coming from contains the following code:
LRESULT CALLBACK nhsWindow::WndProc (HWND hWindow, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
	nhsWindow * pkWindow = NULL;
	nhsBool32 bProcessed = nhsFalse;

	switch (iMessage)
	{
	
	//Windows is creating the window, send custom information
	case WM_NCCREATE:
		SetWindowLong (hWindow, GWL_USERDATA, ((LPCREATESTRUCT(lParam))->lpCreateParams));
		break;
	
	//Windows message, let the message handler handle it
	default:
		pkWindow = GetWindowLong (hWindow, GWL_USERDATA);
		if (NULL != pkWindow)
		{
			bProcessed = pkWindow->MessageHandler (iMessage, wParam, lParam);
		}
		break;
	}

	//The message wasn't processed, pass it to windows...
	if (nhsFalse == bProcessed)
	{
		return DefWindowProc (hWindow, iMessage, wParam, lParam);
	}
	
	return 0;
}

If you need any more information to help me fix this, just ask and I will be happy to provide you with it. Thanks in advance.

Share this post


Link to post
Share on other sites
Advertisement
Your WndProc function is static correct?

http://www.gamedev.net/community/forums/topic.asp?topic_id=359217

Good overview of the issue.

Share this post


Link to post
Share on other sites
Yea, the WndProc is static. The program compiles with no errors or anything now but the second I try to run it I get the following error (which I nabbed from the debug mode):


Unhandled exception at 0x102308cf (msvcr80d.dll) in NHS2D.exe: 0xC0000005: Access violation writing location 0xcccccccc.


EDIT:
Also, if anyone needs to take a look at the full code to try to find the error, just tell me and I will zip it up and stick it on my website for you to take a look at.

Share this post


Link to post
Share on other sites
First, you might want to look into using SetWindowLongPtr/GetWindowLongPtr for 64-bit compliance. You will also want to:


YourObject* TheObject = (YourObject*)(DWORD_PTR)GetWindowLongPtr( ... )

Share this post


Link to post
Share on other sites
Okay so I went and looked through some of the stuff you people showed me, and I re-wrote the class. The thing is it seems like it is only processing around 1 out of 30 messages through WndProc, if even that. By this I mean I can place my mouse over the little red X in the top right corner, and click on it really fast, and many times, and it will eventually close the window (sometimes). Something that I thought was kind of wierd though was that I can close the window perfectly if I minimize the window, and use the right click menu to close it. Anyways, here is my code:

nhsWindow.h

//Includes
#include <windows.h> //windows header

#pragma once //only include this file once

class nhsWindow
{
public:
nhsWindow();
~nhsWindow();

private:
static LRESULT CALLBACK StaticWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
bool WndProc(UINT uMsg, WPARAM wParam, LPARAM lParam);

public:
void Create(HINSTANCE hInstance, LPCWSTR lpWndTitle);
void Destroy();
void Run();
void Frame();

inline HWND getHWND() { return hWnd; }
inline void setHWND(HWND hwnd) { this->hWnd = hwnd; }

//Window size and positioning functions
void SetPosition (int iX, int iY);
void GetPosition (POINT * pkPosition);
void SetSize (int iWidth, int iHeight);
void GetSize (POINT * pkSize);

private:
HWND hWnd; // window handle
HINSTANCE hInstance; // application instance handle
MSG msg; // windows message
WNDCLASSEX m_wClass; // wndclass struct
LPCWSTR m_lpClassName; // window classname
LPCWSTR m_lpWindowName; // window title
DWORD m_dwStyle; // window style
int m_iXPos; // horizontal position of window
int m_iYPos; // vertical position of window
int m_iWidth; // window width
int m_iHeight; // window height
};



nhsWindow.cpp

//includes
#include "nhsWindow.h" //nhsWindow class header

nhsWindow::nhsWindow()
{
hWnd = NULL; // window handle
hInstance = NULL; // application instance handle
m_lpClassName = L"NHS2DWnd"; // window classname
m_lpWindowName = L"NHS2D Game Engine"; // window title
m_dwStyle = WS_OVERLAPPEDWINDOW; // window style
m_iXPos = 0; // horizontal position of window
m_iYPos = 0; // vertical position of window
m_iWidth = 640; // window width
m_iHeight = 480; // window height
}

nhsWindow::~nhsWindow()
{
//do nothing
}

LRESULT CALLBACK nhsWindow::StaticWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
nhsWindow *wnd = 0;
bool bProcessed = false;

if (uMsg == WM_NCCREATE)
{
LPCREATESTRUCT lpcs = reinterpret_cast<LPCREATESTRUCT>(lParam);
wnd = reinterpret_cast<nhsWindow *>((LPCREATESTRUCT)lParam)->lpCreateParams;
SetWindowLongPtr(hWnd, GWLP_USERDATA, reinterpret_cast<long>(wnd));

// save window handle
wnd->SetHWND(hwnd);
}
else
{
wnd = (nhsWindow*)(LONG_PTR)GetWindowLongPtr(hWnd, GWLP_USERDATA);
}

if (NULL != wnd)
{
bProcessed = wnd->WndProc(uMsg, wParam, lParam);
}

if(bProcessed == false){
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

return 0;
}

bool nhsWindow::WndProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_KEYDOWN:
if (wParam == VK_ESCAPE)
{
PostQuitMessage(0);
}
return true;
break;

case WM_CLOSE:
PostQuitMessage(0);
return true;
break;

//The message isn't handled, send it to windows...
default:
return false;
break;
}
}

void nhsWindow::Create(HINSTANCE hInstance, LPCWSTR lpWndTitle)
{
//Set window name
m_lpWindowName = lpWndTitle;


ZeroMemory(&m_wClass, sizeof(m_wClass));

//Visual window properties
m_wClass.hCursor = LoadCursor (NULL, IDC_ARROW);
m_wClass.hIcon = LoadIcon (NULL, IDI_APPLICATION);
m_wClass.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
m_wClass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);

//System properties
m_wClass.hInstance = hInstance;
m_wClass.lpfnWndProc = StaticWndProc;
m_wClass.lpszClassName = m_lpClassName;
m_wClass.cbSize = sizeof(WNDCLASSEX);

//Additional properties
m_wClass.lpszMenuName = NULL;

m_wClass.cbClsExtra = NULL;
m_wClass.cbWndExtra = NULL;
m_wClass.style = NULL;

//Register the window class
if (!RegisterClassEx (&m_wClass))
{
MessageBox(hWnd, L"Couldn't Register Windows Class", 0, 0);
}

// Create the window...

hWnd = CreateWindowEx(
0, // extended style
m_lpClassName, // class
m_lpWindowName, // title
m_dwStyle, // style
m_iXPos, m_iYPos, // position x and y
m_iWidth, // width
m_iHeight, // height
0, // handle to parent
0, // handle to menu
hInstance, // instance of the application
this // This will be passed when the message loop is created
);

//Make sure that the window title gets set
SetWindowText (hWnd, m_lpWindowName);

ShowWindow(hWnd, SW_SHOW);
}

void nhsWindow::Destroy()
{
// Destroy your window
}

void nhsWindow::Run()
{

while (1)
{
//Are there any messages in the cue?
if (PeekMessage (&msg, hWnd, 0, 0, PM_REMOVE))
{
//See if the user is trying to quit the application
if (WM_QUIT == msg.message)
{
MessageBox(hWnd, L"Quit message recieved", 0, 0);
break;
}
//Process the windows message
else
{
TranslateMessage (&msg);
DispatchMessage (&msg);
}
}
//There are no messages, run a frame
else
{
Frame();
}
}
}

void nhsWindow::Frame()
{
// do nothing yet
}

//Window size and position functions
void nhsWindow::SetPosition(int iX, int iY)
{
SetWindowPos(hWnd, HWND_TOP, iX, iY, 0, 0, SWP_NOSIZE);
}

void nhsWindow::GetPosition(POINT *pkPosition)
{
RECT rcWindow;
POINT pPosition;

//Get window position
GetWindowRect (hWnd, &rcWindow);
pPosition.x = rcWindow.left;
pPosition.y = rcWindow.top;
memcpy (pkPosition, &pPosition, sizeof (POINT));
}

void nhsWindow::SetSize(int iWidth, int iHeight)
{
SetWindowPos(hWnd, HWND_TOP, 0, 0, iWidth, iHeight, SWP_NOMOVE);
}

void nhsWindow::GetSize(POINT *pkSize)
{
RECT rcWindow;
POINT pSize;

//Get window position
GetWindowRect (hWnd, &rcWindow);
pSize.x = rcWindow.right - rcWindow.left;
pSize.y = rcWindow.bottom - rcWindow.top;
memcpy (pkSize, &pSize, sizeof (POINT));
}



programMain.cpp

//includes
#include "nhsWindow.h" //Window managing class header

//WinMain function
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nShowCmd)
{
nhsWindow appWindow;

appWindow.Create(hInstance, L"NHS2D Game Engine DEV");
appWindow.SetPosition(50, 50);
appWindow.SetSize(640, 480);

appWindow.Run();

return 0;
}



Sorry for the long post, and again, thanks for the help.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
I also have problem too. the problem is WndProc won't recieve any message.


LRESULT CALLBACK Window::MainWndProc(HWND hwnd, UINT msg,
WPARAM wParam, LPARAM lParam)
{
Window* pWnd = NULL;

if (msg == WM_NCCREATE)
{
SetWindowLong(hwnd, GWL_USERDATA,
(long)((LPCREATESTRUCT(lParam))->lpCreateParams));
}

pWnd = (Window*)(GetWindowLong(hwnd, GWL_USERDATA));

if (pWnd)
return pWnd->WndProc(msg, wParam, lParam);
else
return DefWindowProc (hwnd, msg, wParam, lParam);

}

LRESULT CALLBACK Window::WndProc(UINT msg, WPARAM wParam,
LPARAM lParam)
{
switch(msg)
{
case WM_DESTROY:
PostQuitMessage(0); // send quit message
break;

case WM_KEYDOWN:
MessageBox(NULL, "COME HERE!", "Note", MB_OK);
break;

default:
return DefWindowProc (hWnd, msg, wParam, lParam);
}

return 0;

}

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement