HRESULT _IFUNC BOleInProcHandler::Draw (DWORD dwDrawAspect, LONG lindex, void FAR* pvAspect, DVTARGETDEVICE FAR * ptd, HDC hicTargetDev, HDC hdcDraw, LPCRECTL lprcBounds, LPCRECTL lprcWBounds, BOOL(CALLBACK * pfnContinue)(DWORD), DWORD dwContinue) { HRESULT hr = ResultFromScode(VIEW_E_DRAW); // Let provider Draw // unless its iconic which the handler does for us // if (dwDrawAspect != DVASPECT_ICON) { if (SUCCEEDED(pProvider->Draw(hdcDraw, lprcBounds, // lprcWBounds is NULL unless this is a metafile // lprcWBounds ? lprcWBounds : lprcBounds, (BOleAspect) dwDrawAspect))) { hr = NOERROR; } } // If this failed let the default handler render the Metafile // if (!SUCCEEDED(hr)) { IViewObject *pVO; if (SUCCEEDED(pDefHandler->QueryInterface(IID_IViewObject, &(LPVOID)pVO))) { hr = pVO->Draw(dwDrawAspect, lindex, pvAspect, ptd, hicTargetDev, hdcDraw, lprcBounds, lprcWBounds, pfnContinue, dwContinue); pVO->Release(); } } return hr; }
STDMETHODIMP CActiveXCtrl::ShowObject(void) { TRACE(_T("AX: CActiveXCtrl::ShowObject")); if( m_pOwner == NULL ) return E_UNEXPECTED; HDC hDC = ::GetDC(m_pOwner->m_hwndHost); if( hDC == NULL ) return E_FAIL; if( m_pViewObject != NULL ) m_pViewObject->Draw(DVASPECT_CONTENT, -1, NULL, NULL, NULL, hDC, (RECTL*) &m_pOwner->m_rcItem, (RECTL*) &m_pOwner->m_rcItem, NULL, NULL); ::ReleaseDC(m_pOwner->m_hwndHost, hDC); return S_OK; }
//--------------------------------------------------------------------- void CFlashDXPlayer::DrawFrame(HDC dc) { if (m_dirtyFlag) { IViewObject* pViewObject = NULL; m_flashInterface->QueryInterface(IID_IViewObject, (LPVOID*) &pViewObject); if (pViewObject != NULL) { // Combine regions HRGN unionRgn, first, second = NULL; unionRgn = CreateRectRgnIndirect(&m_dirtyRects[0]); if (m_dirtyRects.size() >= 2) second = CreateRectRgn(0, 0, 1, 1); for (std::vector<RECT>::iterator it = m_dirtyRects.begin() + 1; it != m_dirtyRects.end(); ++it) { // Fill combined region first = unionRgn; SetRectRgn(second, it->left, it->top, it->right, it->bottom); unionRgn = CreateRectRgn(0, 0, 1, 1); CombineRgn(unionRgn, first, second, RGN_OR); DeleteObject(first); } if (second) DeleteObject(second); RECT clipRgnRect; GetRgnBox(unionRgn, &clipRgnRect); RECTL clipRect = { 0, 0, m_width, m_height }; // Fill background if (m_transpMode != TMODE_FULL_ALPHA) { // Set clip region SelectClipRgn(dc, unionRgn); COLORREF fillColor = GetBackgroundColor(); HBRUSH fillColorBrush = CreateSolidBrush(fillColor); FillRgn(dc, unionRgn, fillColorBrush); DeleteObject(fillColorBrush); // Draw to main buffer HRESULT hr = pViewObject->Draw(DVASPECT_TRANSPARENT, 1, NULL, NULL, NULL, dc, &clipRect, &clipRect, NULL, 0); assert(SUCCEEDED(hr)); } else { if (m_alphaBlackDC == NULL) { // Create memory buffers BITMAPINFOHEADER bih = {0}; bih.biSize = sizeof(BITMAPINFOHEADER); bih.biBitCount = 32; bih.biCompression = BI_RGB; bih.biPlanes = 1; bih.biWidth = LONG(m_width); bih.biHeight = -LONG(m_height); m_alphaBlackDC = CreateCompatibleDC(dc); m_alphaBlackBitmap = CreateDIBSection(m_alphaBlackDC, (BITMAPINFO*)&bih, DIB_RGB_COLORS, (void**)&m_alphaBlackBuffer, 0, 0); SelectObject(m_alphaBlackDC, m_alphaBlackBitmap); m_alphaWhiteDC = CreateCompatibleDC(dc); m_alphaWhiteBitmap = CreateDIBSection(m_alphaWhiteDC, (BITMAPINFO*)&bih, DIB_RGB_COLORS, (void**)&m_alphaWhiteBuffer, 0, 0); SelectObject(m_alphaWhiteDC, m_alphaWhiteBitmap); } HRESULT hr; HBRUSH fillColorBrush; // Render frame twice - against white and against black background to calculate alpha SelectClipRgn(m_alphaBlackDC, unionRgn); COLORREF blackColor = 0x00000000; fillColorBrush = CreateSolidBrush(blackColor); FillRgn(m_alphaBlackDC, unionRgn, fillColorBrush); DeleteObject(fillColorBrush); hr = pViewObject->Draw(DVASPECT_TRANSPARENT, 1, NULL, NULL, NULL, m_alphaBlackDC, &clipRect, &clipRect, NULL, 0); assert(SUCCEEDED(hr)); // White background SelectClipRgn(m_alphaWhiteDC, unionRgn); COLORREF whiteColor = 0x00FFFFFF; fillColorBrush = CreateSolidBrush(whiteColor); FillRgn(m_alphaWhiteDC, unionRgn, fillColorBrush); DeleteObject(fillColorBrush); hr = pViewObject->Draw(DVASPECT_TRANSPARENT, 1, NULL, NULL, NULL, m_alphaWhiteDC, &clipRect, &clipRect, NULL, 0); assert(SUCCEEDED(hr)); // Combine alpha for (LONG y = clipRgnRect.top; y < clipRgnRect.bottom; ++y) { int offset = y * m_width * 4 + clipRgnRect.left * 4; for (LONG x = clipRgnRect.left; x < clipRgnRect.right; ++x) { BYTE blackRed = m_alphaBlackBuffer[offset]; BYTE whiteRed = m_alphaWhiteBuffer[offset]; m_alphaBlackBuffer[offset + 3] = 255 - (whiteRed - blackRed); offset += 4; } } // Blit result to target DC BitBlt(dc, clipRgnRect.left, clipRgnRect.top, clipRgnRect.right - clipRgnRect.left, clipRgnRect.bottom - clipRgnRect.top, m_alphaBlackDC, clipRgnRect.left, clipRgnRect.top, SRCCOPY); } DeleteObject(unionRgn); pViewObject->Release(); } m_dirtyFlag = false; m_dirtyRects.clear(); m_dirtyUnionRect.left = m_dirtyUnionRect.top = LONG_MAX; m_dirtyUnionRect.right = m_dirtyUnionRect.bottom = -LONG_MAX; } }