[SDL] WM_PAINT patch for foreign windows

Mason Wheeler masonwheeler at yahoo.com
Fri Aug 7 05:59:03 PDT 2009


It's pretty simple.  I built a control that wraps an SDL_Window and embeds
it on a Delphi form.  In Delphi, forms are constructed in one pass, and then
shown after construction is complete.  Sometimes quite a bit after; forms
can be constructed at startup time and cached in memory until they're
needed.

The TSDLFrame constructor calls the inherited constructors (in Delphi,
construction order is from the actual object type down to the base class,
not from the base up like in C++) to set up a generic rectangle with a
HWND handle, then passes that handle to SDL_CreateWindowFrom.
Unfortunately, that's as far as it can go, since it's quite possible at this
point for the component to be offscreen.  If I try to call SDL_CreateRenderer
while the window's offscreen, the call will fail.  I need to delay that call
until the moment when the window is displayed onscreen.

Fortunately, Windows makes it very easy to know when something is
displayed onscreen:  It sends a WM_PAINT message.  But if I never
receive it because SDL_win32events.c is swallowing it internally, I
can't finish setting up the control, and it becomes useless.

Other external systems are likely to have the same problem.  If SDL
really needs to do that SDL_SendWindowEvent call, then go ahead
and do it, but don't Return(0) at the end unless you know there's no
one else who needs that message.


From: Sam Lantinga <slouken at libsdl.org>
Subject: Re: [SDL] WM_PAINT patch for foreign windows

This is a little tricky in that right now SDL assumes that for foreign windows it owns the graphics but the application owns the input.

Can you tell a little more about how you're trying to use it?


On Mon, Jul 6, 2009 at 10:47 AM, Mason Wheeler <masonwheeler at yahoo.com> wrote:

I just spent the last several hours digging through Delphi's message-handling system, trying to find out why my SDL wrapper component wouldn't display properly under certain circumstances.  Eventually I tracked it to the fact that it was never receiving the WM_PAINT message.  Turns out SDL was swallowing it to handle internally.
>
>That's perfectly acceptable when you have a window that SDL created and is managing, but when it's a foreign window created by SDL_CreateWindowFrom, someone else owns the window handle and needs to be able to respond to paint requests in its own fashion.
>
>This patch fixes it.  It's Windows only, of course.  Not sure if the same problem exists on other platforms, but it wouldn't surprise me.  If so, they'll need platform-specific
> fixes.
>
>Index: SDL_win32events.c
>===================================================================
>--- SDL_win32events.c    (revision 4599)
>+++ SDL_win32events.c    (working copy)
>@@ -587,15 +587,18 @@
>> 
>         /* We were occluded, refresh our display */
>     case WM_PAINT:
>-        {
>-            RECT rect;
>-            if (GetUpdateRect(hwnd, &rect, FALSE)) {
>-                ValidateRect(hwnd, &rect);
>>-                SDL_SendWindowEvent(data->windowID,
> SDL_WINDOWEVENT_EXPOSED,
>-                                    0, 0);
>-            }
>-        }
>-        return (0);
>+        {
>+            if (!(SDL_GetWindowFlags(data->windowID) & SDL_WINDOW_FOREIGN)) {
>>+                RECT rect;
>+                if (GetUpdateRect(hwnd, &rect, FALSE)) {
>+                    ValidateRect(hwnd,
> &rect);
>+                    SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_EXPOSED,
>+                                        0, 0);
>+                }
>+                return (0);
>+            }
>>+            else break;
>+        }
> 
>         /* If this isn't our window, we don't need to repaint the frame.
>            This fixes a reentrancy issue that can
> cause stack overflows with foreign windows.
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.libsdl.org/pipermail/sdl-libsdl.org/attachments/20090807/515cbb2b/attachment.htm>


More information about the SDL mailing list