1

我有一个标准的 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 知识几乎为零,所以这可能与它有关,但这是我想要做的。也许有人可以看到我做错了什么并将我带到我需要去的地方(请注意,我只是在玩耍,这就是为什么没有错误处理的原因):

  1. 我创建了我的分层窗口

    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 );
    
  2. 我初始化 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);
    
  3. 类似于我的初始实现,每当控件调用 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);
    

不知道我做错了什么,我基本上被卡住了。任何帮助,将不胜感激。

4

0 回答 0