I'm trying to play a transparent flash movie using layered windows and Qt. I'm not going for per pixel alpha and windowless OLE controls, I want to make the background color (black) to become transparent using the UpdateLayeredWindow call. The problem is that I'm getting a black background (no color-key) on Windows XP altough it works on Vista and 7 (related to DWM composition, surely).

Well, the window to be transparent is QWidget subclass. In the constructor I setup the (I think) the proper flags and the layered window style :

Qt Code:
  1. setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
  2. LONG_PTR exstyle = ::GetWindowLongPtr(winId(), GWL_EXSTYLE);
  3. ::SetWindowLongPtr(winId(), GWL_EXSTYLE, exstyle | WS_EX_LAYERED | WS_EX_TOPMOST );
  4.  
  5. _axWidget = new FlashAxWidget(this, winId());
To copy to clipboard, switch view to plain text mode 

FlashAxWidget is a QAxWidget subclass where I simply put a window subclass,etc (This does not change anything since I've tried without subclassing and SetLayeredWindowAttributes and fails also).

Note that as I've told, I update the layered window manually on every flash frame. So I must subclass the AX control to obtain the WM_PAINT message:

Qt Code:
  1. case WM_PAINT:
  2. PAINTSTRUCT ps;
  3. HDC hdc = BeginPaint(hwnd, &ps);
  4. g_pAxWInstance->DispatchPaint(hwnd, hdc);
  5. EndPaint(hwnd, &ps);
  6. return 0L;
  7. break;
To copy to clipboard, switch view to plain text mode 

This is working well, I catch the paint messages properly.

Now, the painting code where the main window layering is updated:

Qt Code:
  1. void FlashAxWidget::DispatchPaint(HWND hwnd, HDC hdc)
  2. {
  3. RECT r;
  4. ::GetClientRect(hwnd, &r);
  5.  
  6. POINT p = {r.left, r.top};
  7. POINT p0 = {0,0};
  8. SIZE sz = {r.right - r.left, r.bottom - r.top};
  9.  
  10. HDC hdcScr = ::GetDC(0);
  11. HDC _dcBackBuf = ::CreateCompatibleDC(hdcScr);
  12.  
  13. BYTE * pBits;
  14.  
  15. BITMAPINFOHEADER bmi = {0};
  16. bmi.biSize = sizeof(BITMAPINFOHEADER);
  17. bmi.biBitCount = 32;
  18. bmi.biCompression = BI_RGB;
  19. bmi.biPlanes = 1;
  20. bmi.biWidth = sz.cx;
  21. bmi.biHeight = -(sz.cy);
  22.  
  23. HBITMAP _hbmpBackBuf = ::CreateDIBSection(hdc, (BITMAPINFO*)&bmi, DIB_RGB_COLORS,
  24. (void**)&pBits, 0, 0);
  25.  
  26. ::SelectObject(_dcBackBuf, _hbmpBackBuf);
  27.  
  28. unsigned long cDIBits = sz.cx*sz.cy*4;
  29.  
  30. ::RtlZeroMemory(pBits, cDIBits);
  31. ::OleDraw(_pIVO, DVASPECT_TRANSPARENT, _dcBackBuf, &r);
  32.  
  33. ::UpdateLayeredWindow(parentWidget()->winId(), NULL, &p,
  34. &sz, _dcBackBuf, &p0, 0, NULL, ULW_COLORKEY);
  35. ::DeleteDC(_dcBackBuf);
  36. ::DeleteObject(_hbmpBackBuf);
  37. ::ReleaseDC(GetDesktopWindow(), hdcScr);
  38. }
To copy to clipboard, switch view to plain text mode 

The rationale is that I'm creating a 32-bit DIB section, I blit the flash contents with OleDraw (this works since I'm tried putting it with BitBlt to screen DC) and make the black background transparent with the ::UpdateLayeredWindow call.

Well, it does not work.

I'm getting strange results. For example, if I remove the window flags (Qt::FramelessWindowHint,etc) I can resize the window. When I resize the window the flash movie stops or gets clipped in incorrect positions.

Anyone with experience on layered windows and Qt? Consider this is my first serious Qt project.

Thank you very much,