Sign in to follow this  

Window Creation Problem

This topic is 4271 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 am writing a new window wrapper class and everything compiles okay (except for two warnings) but when I run it I get a messagebox saying that I'm stupid. What I am doing wrong? the warnings: c:\documents and settings\daniel\my documents\visual studio 2005\projects\directx\directx\window.cpp(48) : warning C4244: 'argument' : conversion from 'LONG_PTR' to 'LONG', possible loss of data c:\documents and settings\daniel\my documents\visual studio 2005\projects\directx\directx\window.cpp(57) : warning C4312: 'type cast' : conversion from 'LONG' to 'cWindow *' of greater size
LRESULT CALLBACK cWindow::StaticMsgProc(HWND hwnd, UINT msg, 
										WPARAM wParam, LPARAM lParam)
{
	cWindow* wnd = 0;

	if(msg == WM_NCCREATE)
	{
 	    // retrieve Window instance from window creation data and associate
	    wnd = (cWindow*)((CREATESTRUCT*)lParam)->lpCreateParams;
	    SetWindowLongPtr(hwnd, GWL_USERDATA, (LONG_PTR)wnd);
	
		// save window handle
	    wnd->SetHWND(hwnd);
		
	}
	else
	{
	    // retrieve associated Window instance
	    wnd = (cWindow*)GetWindowLongPtr(hwnd, GWL_USERDATA);
	}

	if (wnd)
		return wnd->MsgProc( hwnd, msg, wParam, lParam );
	else
		return DefWindowProc( hwnd, msg, wParam, lParam );

	return 0;
}

HRESULT cWindow::CreateApplicationWindow(HINSTANCE hInst)
{
	m_hInst = hInst;
 
	WNDCLASSEX wc;

	wc.cbSize			= sizeof(WNDCLASSEX);
	wc.cbClsExtra		= 0;
	wc.cbWndExtra		= sizeof(cWindow*);
	wc.hbrBackground	= NULL;
	wc.hCursor			= NULL;
	wc.hIcon			= LoadIcon( hInst, IDI_WINLOGO );
	wc.hIconSm			= LoadIcon( hInst, IDI_WINLOGO );
	wc.hInstance		= m_hInst;
	wc.lpfnWndProc		= StaticMsgProc;
	wc.lpszClassName	= L"GameClass"; 
	wc.lpszMenuName		= NULL;
	wc.style			= CS_HREDRAW | CS_VREDRAW;

	if ( ! ( RegisterClassEx( &wc ) ) )
		throw GameError(L"Blahladadada! (DOH!)");

	if ( NULL == ( m_hwnd = CreateWindowEx( NULL, L"GameClass", L"Dan's (not so)Awesome (not)Game window",
		WS_OVERLAPPED | WS_VISIBLE, m_nX, m_nY, m_nWidth, m_nHeight, NULL,
		NULL, m_hInst, this ) ) )	
	{
		throw GameError(L"Error: You did something wrong, stupid!");
	}

	return S_OK;
}

Thanks. P.S. Initially, I tried using Oluseyi's article but I couldn't get it to compile for some reason so I tried it this way instead.

Share this post


Link to post
Share on other sites

if(msg == WM_NCCREATE)
{
// your code

// return TRUE!!!
return (LRESULT)TRUE;
}

// this is returning FALSE, and for WM_NCCREATE
// terminates window creation
return 0;
}

Share this post


Link to post
Share on other sites
actually nevermind, i didn't see at the bottom of your
code


if(wnd)
return wnd->MsgProc( hwnd, msg, wParam, lParam );


which should still be called for WM_NCCREATE. you should however,
check your class MsgProc function to make sure FALSE isn't being
returned for WM_NCCREATE or -1 for WM_CREATE. other than that your
code seems fine to me.

Share this post


Link to post
Share on other sites
When I wrote my wrapper I had to move everything from NCCREATE to CREATE and it worked. To this day I have no idea why but it works perfectly so I don't question it. If nothing else works, try removing 2 letters and see if it fixes ;-)

Share this post


Link to post
Share on other sites
The wrapper stuff looks ok.

What does your MsgProc look like?
Does it pass unhandled messages on to DefWindowProc?
Does it accidentally return 0 or 1 for every handled message? (e.g. the stupid switch case that calls DefWindowProc only for the default-case).

Addon for Mike2343: Never rely on a specific windows message to be the first to be sent to your window. Not even WM_NCCREATE may be the first message, there can be a WM_GETMINMAXINFO coming before that. It depends on the Windows version you're running (9x line is a bit different). Just pass on the messages to DefWindowProc if you don't have the handler set up yet.

If you really "need" all messages caught you have to go the MFC way and use the CBT_HOOK. This allows you to set up the wrapper on the true window creation.

Share this post


Link to post
Share on other sites
Quote:
Original post by Endurion
The wrapper stuff looks ok.

What does your MsgProc look like?
Does it pass unhandled messages on to DefWindowProc?
Does it accidentally return 0 or 1 for every handled message? (e.g. the stupid switch case that calls DefWindowProc only for the default-case).

Addon for Mike2343: Never rely on a specific windows message to be the first to be sent to your window. Not even WM_NCCREATE may be the first message, there can be a WM_GETMINMAXINFO coming before that. It depends on the Windows version you're running (9x line is a bit different). Just pass on the messages to DefWindowProc if you don't have the handler set up yet.

If you really "need" all messages caught you have to go the MFC way and use the CBT_HOOK. This allows you to set up the wrapper on the true window creation.
Yes, unhandled msg's are sent to DefWindowProc.
It doesn't return 0 or 1 at every message. Should it? I have seen it this way. So should my WndProc return DefWindowProc instead of 0 or 1?

Share this post


Link to post
Share on other sites
This is what MSDN has to say:

If an application processes this message (WM_NCCREATE), it should return TRUE to continue creation of the window. If the application returns FALSE, the CreateWindow or CreateWindowEx function will return a NULL handle.

Here is what my static WinProc looks like:

LRESULT CALLBACK CBaseWindow::MessageRouter( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
CBaseWindow* pWindow;

if( uMsg == WM_NCCREATE )
{
pWindow = (CBaseWindow*) ((LPCREATESTRUCT)lParam)->lpCreateParams;
SetWindowLongPtr( hWnd, GWL_USERDATA, (LONG_PTR) pWindow );
return TRUE;
}
else
{
pWindow = (CBaseWindow*) GetWindowLongPtr( hWnd, GWL_USERDATA );

if( pWindow == NULL )
{
return DefWindowProc( hWnd, uMsg, wParam, lParam );
}
}

pWindow->m_hWnd = hWnd;
return pWindow->WindowProcedure( uMsg, wParam, lParam );
}

Share this post


Link to post
Share on other sites
This is my static WinProc looks like:


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

if (pWnd == NULL)
return (DefWindowProc(hwnd, msg, wParam, lParam));

return pWnd->WndProc(msg, wParam, lParam);

}

Share this post


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