Page 1 of 1

Problems with client coordinates in windowed mode.

Posted: Sat Oct 13, 2007 3:44 pm
by scippie
Hello,

I'm trying to pass my windows messages to the irrlicht device using the postEventFromUser function, but when I'm in windowed mode, irrlicht seems to be using the part of the window under the title bar as well giving me confusing mouse coordinate results. I need to move my mouse the title-bar-height under every gui component to activate it and I strongly believe that irrlicht is rendering under the title bar as well.

Here's a simplified version of what I do:

Code: Select all

RECT r;
r.left = 0;
r.top = 0;
r.right = g_resX;
r.bottom = g_resY;

AdjustWindowRect(&r, WS_OVERLAPPEDWINDOW, false);

HWND hWnd = CreateWindow(g_windowClass, g_windowTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, r.right - r.left, r.bottom - r.top, NULL, NULL, hInstance, NULL);
...
SIrrlichtCreationParameters devParms;
devParms.AntiAlias = true;
devParms.Bits = 32;
devParms.DriverType = EDT_OPENGL;
devParms.EventReceiver = &receiver;
devParms.Fullscreen = false;
devParms.HighPrecisionFPU = false;
devParms.SDK_version_do_not_use = IRRLICHT_SDK_VERSION;
devParms.Stencilbuffer = true;
devParms.Vsync = false;
devParms.WindowId = (void*)hWnd;
devParms.WindowSize = dimension2d<s32>(g_resX, g_resY);

g_dev = createDeviceEx(devParms);
...
And

Code: Select all

switch (message) 
{
case WM_MOUSEMOVE:
	ev.EventType = EET_MOUSE_INPUT_EVENT;
	ev.MouseInput.Event = EMIE_MOUSE_MOVED;
	ev.MouseInput.X = GET_X_LPARAM(lParam);
	ev.MouseInput.Y = GET_Y_LPARAM(lParam);
	if (g_dev)
		g_dev->postEventFromUser(ev);
	break;
Now if I add a GUI component on the screen like:

Code: Select all

gui->addWindow(rect<int>(10, g_resY - 150, 320, g_resY), false, L"Fix log");
I notice that the window is a title-bar-height away from the bottom of the window, making me believe that irrlicht is actually rendering under the title bar as well, and not only in the client area of the window.

Can someone help me out with this? How do I handle this correctly?

Cheers,
Dirk.

Posted: Sat Oct 13, 2007 6:35 pm
by Namek Kural
I don't know really if it works, but anyway, try it :D :

Code: Select all

gui->addWindow(rect<s32>(10, g_resY - 150, 320, g_resY), false, L"Fix log"); 
instead of:

Code: Select all

gui->addWindow(rect<int>(10, g_resY - 150, 320, g_resY), false, L"Fix log"); 

Posted: Sat Oct 13, 2007 7:09 pm
by Sylence
they do both exactly the same...
s32 is just a typedef for int

Posted: Sat Oct 13, 2007 10:37 pm
by Ico
That's a problem I also encountered outside of irrlicht - the title bar belongs to the window and you'll also receive event messages for that area etc.

I haven't tried it myself, but I guess Windows uses another origin for it's window coordinates compared to irrlicht. I'm actually not 100% sure if I don't mess both origins too, but I'd guess it's that way:

- Windows' MOUSE_MOVED event uses the top left edge of the content part of the window (without the title bar) as the origin.
- Irrlicht will use the top left corner of the window having that hwnd also including the title bar and borders.
- To solve this, use GetSystemMetrics() to obtain the size of things like the title bar and window borders and add/subtract those to your passed coordinates.

Another solution: Why don't you use irrlicht's built in window creation etc?
Yet another solution: Add a control to your window - static text or a text box or whatever and use those hwnd for your irrlicht engine. This way you can move the origin used by Irrlicht to the top left of the window's content area.

Posted: Sat Oct 13, 2007 10:48 pm
by scippie
Ico wrote:- Irrlicht will use the top left corner of the window having that hwnd also including the title bar and borders.
Yes, I was thinking the same here.
Ico wrote:Why don't you use irrlicht's built in window creation etc?
First, I did, but then I wanted to implement DirectInput for joystick input and I couldn't find out where to get the window handle to forward it to DirectInput. Also, I didn't find how to hook on WM_ACTIVATE messages and the stuff, which is also needed by DirectInput.
Ico wrote:Yet another solution: Add a control to your window - static text or a text box or whatever and use those hwnd for your irrlicht engine. This way you can move the origin used by Irrlicht to the top left of the window's content area.
Yes, I thought of that too, but it feels like overkill :D

I'll check out the GetSystemMetrics, but I'm feeling a bit bad that irrlicht is drawing under my title bar... I mean, there I am, being sure that my rendering resolution is 1024x768 and there is irrlicht drawing on something else. I have the feeling that that will give me trouble someday.

Posted: Sat Oct 13, 2007 11:08 pm
by Sylence
You can get the Window handle by calling IVideoDriver::getExposedVideoData()

Posted: Sun Oct 14, 2007 10:05 am
by scippie
Sylence wrote:You can get the Window handle by calling IVideoDriver::getExposedVideoData()
Ah... Thanks!

Posted: Sun Oct 14, 2007 10:14 pm
by scippie
Sylence wrote:You can get the Window handle by calling IVideoDriver::getExposedVideoData()
True, but that still doesn't give me the capability to handle messages like WM_ACTIVATE (which I need to reacquire a lost input-device). Or is there a way for that too?

Posted: Sun Oct 14, 2007 10:27 pm
by Ico
Irrlicht has got its own device->isWindowActive(); that should be enough afaik.

Posted: Mon Oct 15, 2007 2:37 pm
by scippie
Ico wrote:Irrlicht has got its own device->isWindowActive(); that should be enough afaik.
Hmm... not really... if you want to do it right, you need to intercept WM_ACTIVATE and reacquire all input devices at that moment.

Checking every frame for the isWindowActive() states seems a bit overkill then.

But no worries... my window works great now :)