[fixed] External window events & CIrrDeviceWin32::run()

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
Strong99
Admin
Posts: 687
Joined: Fri Mar 31, 2006 7:06 pm
Location: Netherlands
Contact:

[fixed] External window events & CIrrDeviceWin32::run()

Post by Strong99 »

Details
IrrVersion: 1.7.2
Device: Win32
Method: run()
Class: CIrrDeviceWin32

The issue:
When I was working with windows api for GUI and in particular C Com objects I had a problem that the com objects didn't receive any ASCII (mostly WM_CHAR/WM_SYSCHAR) input for most winapi com and custom elements.

The problem:
After looking through CIrrDeviceWin32 run method I noticed that TranslateMessage() is missing in the PeekMessage loop. When looking in the CIrrDeviceWinCE still does implement this method.

While using Irrlicht as the main window there is no reason to use WM_CHAR and it isn't implemented because of the deadkey handling. Though, when working with an ExternalWindow its useful and other non-irrlicht components they can be useful.
It is removed after this bug report: http://irrlicht.sourceforge.net/forum/v ... p?p=212664

Possible workaround
A fast work-around is a custom "run()" method which handles incoming events rather than using Irrlichts device method run(). But that breaks the default event receiving from irrlicht itself since CIrrDeviceWin32 WndProc method is not available.

Fix
TranslateMessage() should be added to the PeekMessage loop in CIrrDeviceWin32::run(). The TranslateMessage() translates ASCII keys into a new message with the signature WM_CHAR. TranslateMessage() does not alter the current message in anyway, instead it adds a new message to the list for PeekMessage to pick up. Though WM_CHAR would intervene with the Deadkey handling. To handle this, we need to be sure that the message does not come from irrlichts window itself.


The current CIrrDeviceWin32::Run() code

Code: Select all

while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
        // No message translation because we don't use WM_CHAR and it would conflict with our
        // deadkey handling.
 
        if (ExternalWindow)
                WndProc(HWnd, msg.message, msg.wParam, msg.lParam);
        else
                DispatchMessage(&msg);
 
        if (msg.message == WM_QUIT)
                Close = true;
}
A possible fix to obtain the expected behavoir:

Code: Select all

while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
        // No message translation because we don't use WM_CHAR and it would conflict with our
        // deadkey handling.
 
        if (ExternalWindow)
        {
                if (msg.hwnd == HWnd)
                {
                        WndProc(HWnd, msg.message, msg.wParam, msg.lParam);
                }
                else
                {
                        TranslateMessage(&msg)
                        DispatchMessage(&msg);
                }
        }
        else
        {
                DispatchMessage(&msg);
        }
 
        if (msg.message == WM_QUIT)
                Close = true;
}
This seems to work good enough. But it does not feel as the right solution.
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: [fixed] External window events & CIrrDeviceWin32::run()

Post by CuteAlien »

Just added that to trunk (r4742) (run into this post while working on this stuff on X11).
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Post Reply