Native Window background color issue


#1

We experienced an issue with window creation on Windows, which is that as a window is created, it's always created with a white background colour which only changes after the contents of the window are loaded. For us this creates a disturbing effect of white flickering. 

To set the correct background colour immediately when the window is created, we modified the code in juce_win32_Windowing.cpp. In HWNDComponentPeer we defined a method paintBackground as follows:

    void paintBackground()
    {
        //SetClassLongPtr(hwnd, GCLP_HBRBACKGROUND, (LONG)brush);
        ResizableWindow* juceWindow = dynamic_cast<juce::ResizableWindow*>(&component);
        if (juceWindow != nullptr)
        {
            RECT rect;
            GetClientRect(hwnd, &rect);
            HDC hdc = GetDC(hwnd);
            Colour backgroundColour = juceWindow->getBackgroundColour();
            HBRUSH bgBrush = CreateSolidBrush(RGB(backgroundColour.getRed(), backgroundColour.getGreen(), backgroundColour.getBlue()));
            FillRect((HDC)hdc, &rect, bgBrush);
            DeleteObject(bgBrush);
            ReleaseDC(hwnd, hdc);
        }
    }

HWNDComponentPeer::peerWindowProc() we call this method right under the case label WM_ERASEBKGND, effectively changing the code there from

            case WM_ERASEBKGND:
            case WM_NCCALCSIZE:

to 

            case WM_ERASEBKGND:
#pragma mark BEGIN_MODIFIED_BY_US
                paintBackground();
#pragma mark END_MODIFIED_BY_US
            case WM_NCCALCSIZE:

We did not add a break, to make sure the code under the label WM_NCCALCSIZE is still executed as it was before. 

We would like to hear whether we can safely modify the code this way. In addition to that, we hope to help out other users who are suffering the same issue.


#2

Interesting.. We haven't seen that in our apps, but perhaps yours does some initialisation that takes a long time or something.. Thanks for the heads-up and the suggested fix, which seems pretty sensible, we'll take a look!


#3

..no, hang on, I remember now why it doesn't already do this! Things may be different nowadays since Windows Vista, but I'm pretty sure that in the old days, this would cause nasty flickering issues in older versions of Windows. Unless the OS definitely double-buffers things, then clearing the window before it gets drawn will certainly cause some glitching, and I wouldn't trust it to always work. Don't think I could add a change like this without some extensive testing, as it could mess things up for other users..


#4

Hi Jules,

After testing we noticed the same flickering, esepcially when resizing the window. So we tried registering a background color for the window when registering it but that yields the same results. So we added a nasty hack, which i don't think is suitable for inclusion in the Juce framework for all.

Our app has some heavy initialization and thus shows a white window briefly before it get's painted by Juce, the same happens (but very briefly) when we create another window at runtime with an opengl context on a secondary screen. Which is something we don't want because we make a live video performance tool. So we are trying to prevent the white flash.

 


#5

Ideally you'd be doing your initialisation in a background thread, but if for some reason you can't do that, why not just do it a second after the window is first show (using a Timer) so that the window is in a decent state before you block things?


#6

I also have this problem.  I'm using Windows 7, and any time I create a native window with an OpenGL context, it flashes white before the context (with a black background) finishes initializing.  It's not a complicated window, so it seems like it should initialize pretty quickly.

I've tried a few different things to get around this but nothing works.

Really all I'm after is to have the default Win32 background color be black.  Any suggestions?

 

*Edit: Interestingly, I notice it also happens when I destroy the window.  The OpenGL black background goes away, and it flashes white for a second before the window disappears.

 

*Edit 2: It happens with all components in native windows, not just OpenGL-related.  It's just more noticeable in OpenGL.