Problems with client coordinates in windowed mode.

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
scippie
Posts: 26
Joined: Sat Oct 13, 2007 3:35 pm
Location: Belgium
Contact:

Problems with client coordinates in windowed mode.

Post 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.
Namek Kural
Posts: 81
Joined: Sun Sep 09, 2007 7:01 pm
Location: BW, Germany

Post 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"); 
Sylence
Posts: 725
Joined: Sat Mar 03, 2007 9:01 pm
Location: Germany
Contact:

Post by Sylence »

they do both exactly the same...
s32 is just a typedef for int
Software documentation is like sex. If it's good you want more. If it's bad it's better than nothing.
Ico
Posts: 289
Joined: Tue Aug 22, 2006 11:35 pm

Post 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.
scippie
Posts: 26
Joined: Sat Oct 13, 2007 3:35 pm
Location: Belgium
Contact:

Post 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.
Sylence
Posts: 725
Joined: Sat Mar 03, 2007 9:01 pm
Location: Germany
Contact:

Post by Sylence »

You can get the Window handle by calling IVideoDriver::getExposedVideoData()
Software documentation is like sex. If it's good you want more. If it's bad it's better than nothing.
scippie
Posts: 26
Joined: Sat Oct 13, 2007 3:35 pm
Location: Belgium
Contact:

Post by scippie »

Sylence wrote:You can get the Window handle by calling IVideoDriver::getExposedVideoData()
Ah... Thanks!
scippie
Posts: 26
Joined: Sat Oct 13, 2007 3:35 pm
Location: Belgium
Contact:

Post 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?
Ico
Posts: 289
Joined: Tue Aug 22, 2006 11:35 pm

Post by Ico »

Irrlicht has got its own device->isWindowActive(); that should be enough afaik.
scippie
Posts: 26
Joined: Sat Oct 13, 2007 3:35 pm
Location: Belgium
Contact:

Post 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 :)
Post Reply