title: Smooth animations using Win32 API - without controlling the message pump
body: <p>I'm currently trying to integrate some animation drawing code of mine into a third party application, under the form of an external plugin.</p>
  
  <p>This animation code in realtime 3d, based on OpenGL, and is supposed to render as fast as it can, usually at 60 frames per second.</p>
  
  <p>In my base application, where I'm the king of the world, I control the application message pump, so that drawing occurs whenever possible. Like that :</p>
  
  <pre><code>for (;;)
  {
    if (PeekMessage(&amp;msg, NULL, 0, 0, PM_REMOVE))
    {
      do
      {
        if (msg.message == WM_QUIT) break;
        TranslateMessage(&amp;msg);
        DispatchMessage(&amp;msg);
      } 
      while (PeekMessage(&amp;msg, NULL, 0, 0, PM_REMOVE));
    }
  
    draw();
  }
  </code></pre>
  
  <p>Now that I'm no more king in the world, I have to play nice with the application messages, so that it keeps being responsive. To my knowledge, as I'm a plugin, I can't hijack the whole application message pump ; so I tried various things, doing my drawing in <code>WM_PAINT</code> message handler :</p>
  
  <p><li> Use <code>WM_TIMER</code>, which doesn't work :I don't know in advance which time step I need (often not fixed) and the timing in not accurate.
  <li> Call <code>InvalidateRect</code> as soon as I'm done drawing, doesn't work : completely prevents the rest of the application of being responsive and doing its own refreshing.
  <li> Create a 'worker' thread, whose only job is to post a user message to the plugin window. This message is posted as soon as the drawing is finished (signaled by an event). The user message handler, in turn, calls <code>InvalidateRect</code> (see <a href="http://www.medsch.wisc.edu/~milenkvc/pdf/thread2.htm" rel="nofollow noreferrer" title="there">there</a>).
  <br/><br/>
  So far, my last attempt is the better, and sometimes work fine.</p>
  
  <pre><code>DWORD WINAPI PaintCommandThreadProc(LPVOID lpParameter)
  {
    Plugin* plugin = static_cast&lt;Plugin*&gt;(lpParameter);
    HANDLE updateEvent = plugin-&gt;updateEvent();
  
    while (updateEvent == plugin-&gt;updateEvent())
    {
      ::WaitForSingleObject(updateEvent, 100);
      ::Sleep(0);
      if (updateEvent == plugin-&gt;updateEvent())
      {
        ::PostMessage(plugin-&gt;hwnd(), WM_USER+0x10, 0, 0);
      }
    }
    return 0;
  }
  
  ...
  
  LRESULT CALLBACK PluginWinProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
  {
    bool processDefault = true;
    LRESULT result = 0;
  
    Plugin* plugin = reinterpret_cast&lt;Plugin*&gt;( GetWindowLong(hWnd, GWL_USERDATA) );
  
    switch (msg) {
      ...
      case WM_GL_MESSAGE:
        {
          ::InvalidateRect( hWnd, NULL, FALSE );
          processDefault = false;
          result = TRUE;
        }
        break;
  
      case WM_PAINT:
        {
          draw(hWnd);
          ::SetEvent( plugin-&gt;updateEvent() );
          processDefault = false;
          result = TRUE;
        }
        break;
      ...
    }
  
    if (processDefault &amp;&amp; plugin &amp;&amp; plugin-&gt;m_wndOldProc)
      result = ::CallWindowProc(plugin-&gt;m_wndOldProc, hWnd, msg, wParam, lParam);
  
    return result;
  }
  </code></pre>
  
  <p>On some occasions, the host application still seems to miss messages. The main characteristics of the problem are that I have to press the 'Alt' key for modal dialogs to show up ; and I have to move the mouse to give some processing time to the host application !...
  <br/><br/>
  Is there any 'industry standard' solution for this kind of as-often-as-you-can animation repaint problem ?</p>