我有一个标准的 GDI win32 应用程序。我有一个组件,它可以通过使用 IOleInPlaceSiteWindowless/IOleInPlaceObjectWindowless 接口对来托管无窗口 ActiveX 控件(我们通常将其用于 Flash),因此每当托管控件回调到 InvalidateRect 时调用 IViewObject::Draw。该组件一般仿照本文: http: //www.codeguru.com/cpp/com-tech/activex/controls/article.php/c12229/Transparent-Flash-Control-in-Plain-C.htm
现在,我的应用程序针对一些较旧的硬件,并且在 Internet Explorer 中运行相同的 ActiveX 控件时,我发现这种方法存在一些性能问题。事实上,使用进程监视器,我可以看到 IE 在某种程度上使用 GPU 进行渲染,而我的应用程序没有。这让我发现 IE 很可能在幕后使用 DirectDraw 以获得更好的性能。
因此,我尝试在我的应用程序中执行此操作,但我没有看到屏幕上绘制的任何内容。我的 DirectX/DirectDraw 知识几乎为零,所以这可能与它有关,但这是我想要做的。也许有人可以看到我做错了什么并将我带到我需要去的地方(请注意,我只是在玩耍,这就是为什么没有错误处理的原因):
我创建了我的分层窗口
ivhWnd = CreateWindowEx(WS_EX_LAYERED, L"MyWndClass", NULL, WS_POPUP | WS_VISIBLE | WS_CLIPSIBLINGS, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, ivhParentWindow, ( HMENU )NULL, ivhAppInstance, ( LPVOID )NULL );
我初始化 DirectDraw 并创建一个离屏表面:
DirectDrawCreateEx(NULL, (LPVOID*)&pivDD, IID_IDirectDraw7, NULL); pivDD->SetCooperativeLevel(NULL, DDSCL_NORMAL); DDSURFACEDESC2 tvSurfDesc; ZeroMemory(&tvSurfDesc, sizeof(DDSURFACEDESC2)); tvSurfDesc.dwSize = sizeof(DDSURFACEDESC2); tvSurfDesc.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH; tvSurfDesc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY; tvSurfDesc.dwWidth = 320; tvSurfDesc.dwHeight = 340; HRESULT tvHR = pivDD->CreateSurface((LPDDSURFACEDESC)&tvSurfDesc, (LPDIRECTDRAWSURFACE*)&pivPrimarySurface, NULL); LPDIRECTDRAWCLIPPER ptvClipper; pivDD->CreateClipper(0, &ptvClipper, NULL); ptvClipper->SetHWnd(0, ivhInternalMsgWindow); pivPrimarySurface->SetClipper(ptvClipper);
类似于我的初始实现,每当控件调用 InvalidateRect 时,我都会调用 IViewObject::Draw;我现在做的基本相同,但将 DC 用于我的 DDraw 表面而不是兼容的位图:
RECT rTotal; ::GetClientRect(ivhWnd, &rTotal); HDC tvhDC; pivPrimarySurface->GetDC(&tvhDC); HRESULT tvHR = OleDraw(ivViewObject, DVASPECT_TRANSPARENT, tvhDC, &rTotal); BLENDFUNCTION bf; bf.BlendOp = AC_SRC_OVER; bf.AlphaFormat = AC_SRC_ALPHA; bf.BlendFlags = 0; bf.SourceConstantAlpha = 255; UpdateLayeredWindow(ivhWnd, NULL, NULL, NULL, tvhDC, NULL, 0, &bf, ULW_ALPHA);
不知道我做错了什么,我基本上被卡住了。任何帮助,将不胜感激。