title: Win32: UpdateLayeredWindow failing sometimes (error 317)
body: <p>I have a bizarre issue here.  I'm displaying a semi-transparent splash screen (a .png file) using layered windows.  It works on some machines but not others.  On the machines where it doesn't work, the GetLastError returns 317 (which isn't very helpful).  Has anyone experienced this before?  Here are my relevant functions.  The incoming parameters for CreateAsPNG are WS_VISIBLE|WS_POPUP (dwStyle), 0 (dwExStyle), and the handle to a hidden tool window for the parent so no taskbar entry is created.  I've verified that I can load an embedded PNG resource into CImage and that the size of the image is correct.</p>
  
  <p>Thanks in advance for any help!</p>
  
  <pre><code>BOOL MySplashWnd::CreateAsPNG( DWORD dwStyle, DWORD dwExStyle, const CString&amp; sTitle, HWND hWndParent )
  {
      ATL::CImage img;
      CreateStreamOnResource( m_nBitmapID, img );
  
      m_nWndWidth = img.GetWidth();
      m_nWndHeight = img.GetHeight();
  
      int nTop = 0;
      int nLeft = 0;
      GetTopLeft( nTop, nLeft );
  
      dwExStyle |= WS_EX_LAYERED;
  
      // Create the Splash Window
      BOOL bRetVal = CWnd::CreateEx( dwExStyle, AfxRegisterWndClass( CS_CLASSDC ), sTitle,
                                    dwStyle, nLeft, nTop, m_nWndWidth, m_nWndHeight, hWndParent, NULL );
  
      //Couldn't create the window for some unknown reason...
      X_ASSERT( bRetVal != FALSE );
  
      if ( bRetVal )
      {
          HDC hScreenDC = ::GetDC( m_hWnd );
          HDC hDC = ::CreateCompatibleDC( hScreenDC );
          HBITMAP hBmp = ::CreateCompatibleBitmap( hScreenDC, m_nWndWidth, m_nWndHeight );
          HBITMAP hBmpOld = ( HBITMAP ) ::SelectObject( hDC, hBmp );
  
          img.Draw( hDC, 0, 0, m_nWndWidth, m_nWndHeight, 0, 0, m_nWndWidth, m_nWndHeight );
  
          BLENDFUNCTION blend = { 0 };
          blend.BlendOp = AC_SRC_OVER;
          blend.BlendFlags = 0;
          blend.SourceConstantAlpha = 255;
          blend.AlphaFormat = AC_SRC_ALPHA;
  
          POINT ptPos = { nLeft, nTop };
          SIZE sizeWnd = { m_nWndWidth, m_nWndHeight };
          POINT ptSource = { 0, 0 };
  
          if ( ::UpdateLayeredWindow( m_hWnd, hScreenDC, &amp;ptPos, &amp;sizeWnd, hDC, &amp;ptSource, 0, &amp;blend, ULW_ALPHA ) )
          {
          }
          else
          {
              // The last error value is 317 on some Win7 machines.
              TRACE( _T( "*** Last error: %d\n" ), ::GetLastError() );
          }
  
          ::SelectObject( hDC, hBmpOld );
          ::DeleteObject( hBmp );
          ::DeleteDC( hDC );
          ::ReleaseDC( NULL, hScreenDC );
      }
  
      return bRetVal;
  }
  
  void MySplashWnd::CreateStreamOnResource( UINT nIDRes, ATL::CImage&amp; img )
  {
      HINSTANCE hInstance = ::GetMUIResourceInstance();
      if ( hInstance == NULL )
      {
          return;
      }
  
      HRSRC hResource = ::FindResource( hInstance, MAKEINTRESOURCE( nIDRes ), "PNG" );
      if ( hResource == NULL )
      {
          return;
      }
  
      DWORD dwResourceSize = ::SizeofResource( hInstance, hResource );
      if ( dwResourceSize == 0 )
      {
          return;
      }
  
      HGLOBAL hImage = ::LoadResource( hInstance, hResource );
      if ( hImage == NULL )
      {
          return;
      }
  
      LPVOID pvImageResourceData = ::LockResource( hImage );
      if ( pvImageResourceData == nullptr )
      {
          return;
      }
  
      HGLOBAL hImageData = ::GlobalAlloc( GMEM_MOVEABLE, dwResourceSize );
      if ( hImageData == NULL )
      {
          return;
      }
  
      LPVOID pvImageBuffer = ::GlobalLock( hImageData );
      if ( pvImageBuffer != nullptr )
      {
          ::CopyMemory( pvImageBuffer, pvImageResourceData, dwResourceSize );
          ::GlobalUnlock( hImageData );
  
          IStream* pStream = nullptr;
  
          if ( SUCCEEDED( ::CreateStreamOnHGlobal( hImageData, TRUE, &amp;pStream ) ) )
          {
              img.Load( pStream );
              pStream-&gt;Release();
          }
  
          ::GlobalUnlock( hImageData );
      }
  
      ::GlobalFree( hImageData );
  } // CTTSplashWnd::CreateStreamOnResource
  </code></pre>
  
  <p>UPDATE: I've found that even on the same machine, sometimes UpdateLayeredWindow succeeds and other time it fails (but always with code 317 if it does fail).  Another piece of info is that this splash is being run on a separate UI thread.  It always works on my machine though...</p>