[not a bug] Creating Device with custom window

You discovered a bug in the engine, and you are sure that it is not a problem of your code? Just post it in here. Please read the bug posting guidelines first.
Post Reply
Night_Wulfe
Posts: 1
Joined: Sat Oct 08, 2005 2:58 am

[not a bug] Creating Device with custom window

Post by Night_Wulfe »

Hello all. I think I found a small bug in v0.12 with custom windows. I dug around on the forum trying to figure this one out, and couldn't find it. So eventually I started poking around in Irrlicht's engine itself. I've found what I believe is a bug in the CIrrDeviceWin32.cpp file.

The problem:

I created a custom Win32 window and set the windowId appropriately. From here, I used the GUI stuff to display a browse file dialog. Here's the two used functions:

Code: Select all


bool window::initialize(irr::video::E_DRIVER_TYPE driverType,
                        irr::core::dimension2d<irr::s32> dimensions,
                        irr::u32 nBits)
{
    WNDCLASSEX wcx;
    ZeroMemory(&wcx, sizeof(WNDCLASSEX));

    wcx.cbSize = sizeof(WNDCLASSEX);
    wcx.hInstance = GetModuleHandle(NULL);
    wcx.style = CS_HREDRAW|CS_VREDRAW|CS_OWNDC;
    wcx.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
    wcx.lpszClassName = "FrEdMainWnd";
    wcx.lpfnWndProc = windowProc;
    wcx.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wcx.hCursor = LoadCursor(NULL, IDC_ARROW);

    if (RegisterClassEx(&wcx) == 0)
    {
        return false;
    }

    m_bRegistered = true;

    RECT r;
    DWORD dwStyle = WS_SYSMENU|WS_CAPTION|WS_BORDER|WS_CLIPCHILDREN|WS_CLIPSIBLINGS;

    r.left = 0;
    r.top = 0;
    r.right = dimensions.Width;
    r.bottom = dimensions.Height;

    AdjustWindowRect(&r, dwStyle, FALSE);

    // Pulled from Irrlicht, for auto-centering window
    irr::s32 realWidth = r.right - r.left;
    irr::s32 realHeight = r.bottom - r.top;
    irr::s32 windowLeft = (GetSystemMetrics(SM_CXSCREEN) - realWidth) / 2;
    irr::s32 windowTop = (GetSystemMetrics(SM_CYSCREEN) - realHeight) / 2;

    // Create the window
    m_hWnd = CreateWindow("FrEdMainWnd", "FrEd", dwStyle, windowTop, windowLeft, realWidth, realHeight, NULL,
        NULL, GetModuleHandle(NULL), NULL);

    if (m_hWnd == NULL)
    {
        destroy();
        return false;
    }

    ShowWindow(m_hWnd, SW_SHOW);
    UpdateWindow(m_hWnd);

    // Pulled from Irrlicht. Something to do with an ATI Driver Bug
    MoveWindow(m_hWnd, windowLeft, windowTop, realWidth, realHeight, TRUE);

    irr::SIrrlichtCreationParameters sicp;
    ZeroMemory(&sicp, sizeof(irr::SIrrlichtCreationParameters));

    sicp.SDK_version_do_not_use = IRRLICHT_SDK_VERSION;
    sicp.DriverType = driverType;
    sicp.Bits = nBits;
    sicp.WindowId = reinterpret_cast<irr::s32>(m_hWnd);

    m_pDev = irr::createDeviceEx(sicp);

    if (m_pDev == NULL)
    {
        destroy();
        return false;
    }

    m_pDev->setWindowCaption(L"Irrlicht Window");
    return true;

}

// This is called in my main routine
bool window::buildUIWindow()
{
    irr::gui::IGUIEnvironment* pEnv = m_pDev->getGUIEnvironment();
    irr::gui::IGUIFileOpenDialog* pOpenDialog = pEnv->addFileOpenDialog(L"Open Map", true);

    return true;
}
What I noticed was that the File Browse dialog was scrunched vertically. The font was difficult to read. The biggest thing I noticed was that anywhere I clicked on the dialog, the action happend about 15 or so pixels above the mouse pointer. I had to click below the cancel button to dismiss the dialog.

I comented out all my window creation code, and had Irrlicht create it, not full screen. The problem did not exist in this case. The only difference between my window and Irrlicht's was the style. So I tried Irrlicht's window style in my code. I again, had the problems described above.

From here, I started digging around to determine why my window acted differently from the one Irrlicht would create. I finally saw it.

Irrlicht Version: 0.12
File: CIrrDeviceWin32.cpp
Line: 352

You should see this:

Code: Select all

	if (externalWindow)
	{
		HWnd = externalWindow;
		RECT r;
		GetWindowRect(HWnd, &r);
		windowSize.Width = r.right - r.left;
		windowSize.Height = r.bottom - r.top;
		fullscreen = false;
		ExternalWindow = true;
	}
Change the line

Code: Select all

GetWindowRect(HWnd, &r);
to

Code: Select all

GetClientRect(HWnd, &r);
What was happening was Irrlicht was using the full window size when given a custom window. This did not take into account borders, title bars, etc. Irrlicht was not doing this in it's own windows creation code. Although Irrlicht would create a say a 650px window, it would pass 640 as the window.Width. GetClientRect returns the size of the client area of the window, which should always be the correct dimensions Irrlicht should use.

I don't think I'm explaining this very well, but I had to give it a shot. Please let me know if this was the intended behavior, and there's some other method I should be calling instead.
ck123
Posts: 5
Joined: Wed May 24, 2006 5:50 am

Post by ck123 »

create your Irrlicht render window as a child of the main window. I thought this was a bug also, until I took a closer look at the windows tutorial.
Post Reply