1

注意:目标是创建一个带有丙烯酸背景的窗口,可以由 OpenGL 绘制。欢迎任何可以实现这一目标的方法。

我已经能够按照教程成功创建一个合成器。并打算根据本文档中给出的示例代码添加高斯模糊

这篇文章之后,我从 Nuget 安装了 Win2D 并将文件复制Generated Files/winrt到包含目录。(也尝试cppwinrt.exe.winmd文件上运行。找不到答案中提到的“Win2D dll”)

这是我目前正在运行的代码:

void CompositionHost::BlurBackground() {
    if (m_target.Root()) {

        GaussianBlurEffect blurEffect{};
        blurEffect.Name(L"Blur");
        blurEffect.BlurAmount(1.0f);
        blurEffect.BorderMode(EffectBorderMode::Hard);
        blurEffect.Optimization(EffectOptimization::Balanced);

        CompositionEffectSourceParameter sourceParameter = CompositionEffectSourceParameter(L"source");
        blurEffect.Source(sourceParameter);

        CompositionEffectFactory blurEffectFactory = m_compositor.CreateEffectFactory(blurEffect);
        CompositionEffectBrush blurBrush = blurEffectFactory.CreateBrush();

        CompositionBackdropBrush backDropBrush = m_compositor.CreateBackdropBrush();
        blurBrush.SetSourceParameter(L"source", backDropBrush);

        auto visuals = m_target.Root().as<ContainerVisual>().Children();
        auto visual = m_compositor.CreateSpriteVisual();
        auto element = m_compositor.CreateSpriteVisual();

        element.Brush(blurBrush);
        visuals.InsertAtTop(element);

        visuals.InsertAtTop(visual);
    }
}

执行时的错误GaussianBlurEffect blurEffect{};

Microsoft C++ exception: winrt::hresult_class_not_registered at memory location 0x00000076EEF8E248.

调用堆栈

>   Project2.exe!winrt::throw_hresult(const winrt::hresult result) Line 4941    C++
    Project2.exe!winrt::check_hresult(const winrt::hresult result) Line 5038    C++
    Project2.exe!winrt::get_activation_factory<winrt::Windows::Foundation::IActivationFactory>(const winrt::param::hstring & name) Line 6078    C++
    Project2.exe!winrt::impl::factory_cache_entry<winrt::Microsoft::Graphics::Canvas::Effects::GaussianBlurEffect,winrt::Windows::Foundation::IActivationFactory>::call<winrt::Microsoft::Graphics::Canvas::Effects::GaussianBlurEffect (__cdecl*)(winrt::Windows::Foundation::IActivationFactory const &)>(winrt::Microsoft::Graphics::Canvas::Effects::GaussianBlurEffect(*)(const winrt::Windows::Foundation::IActivationFactory &) && callback) Line 6308   C++
    Project2.exe!winrt::impl::call_factory_cast<winrt::Microsoft::Graphics::Canvas::Effects::GaussianBlurEffect (__cdecl*)(winrt::Windows::Foundation::IActivationFactory const &),winrt::Microsoft::Graphics::Canvas::Effects::GaussianBlurEffect,winrt::Windows::Foundation::IActivationFactory,winrt::Microsoft::Graphics::Canvas::Effects::GaussianBlurEffect <lambda>(const winrt::Windows::Foundation::IActivationFactory &)>(winrt::Microsoft::Graphics::Canvas::Effects::GaussianBlurEffect::winrt::Microsoft::Graphics::Canvas::Effects::GaussianBlurEffect <lambda>(const winrt::Windows::Foundation::IActivationFactory &) && callback) Line 6369    C++
    Project2.exe!winrt::Microsoft::Graphics::Canvas::Effects::GaussianBlurEffect::GaussianBlurEffect() Line 9041    C++

完整代码:

#pragma once
#ifndef UNICODE
#define UNICODE
#endif 

#define BTN_ADD 1000

#include <SDKDDKVer.h>

#define WIN32_LEAN_AND_MEAN  
#include <windows.h>
//#include <D2d1_1.h>
//#include <D3d11_4.h>
//#include <Dwrite.h>
#include <Windows.Graphics.DirectX.Direct3D11.interop.h>
#include <Windows.ui.composition.interop.h>
#include <unknwn.h>
#include <DispatcherQueue.h>

#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <tchar.h>

#include <winrt/base.h>
#include <winrt/Windows.ApplicationModel.Core.h>
//#include <winrt/Windows.Foundation.h>
//#include <winrt/Windows.Graphics.h>
//#include <winrt/Windows.Graphics.DirectX.h>
#include <winrt/Windows.Graphics.DirectX.Direct3D11.h>


#include <winrt/Windows.UI.Composition.Desktop.h>
//#include <winrt/Windows.UI.Core.h>
//#include <winrt/Windows.UI.Input.h>
#include <winrt/Windows.Graphics.Effects.h>

#include <winrt/Microsoft.Graphics.Canvas.Effects.h>
#include <winrt/Windows.Graphics.Effects.h>

using namespace winrt;
//using namespace winrt::Windows::ApplicationModel::Core;
using namespace winrt::Windows::Foundation;
using namespace winrt::Windows::Foundation::Numerics;
//using namespace winrt::Windows::Graphics::DirectX;
//using namespace winrt::Windows::Graphics::DirectX::Direct3D11;
using namespace winrt::Windows::UI;
using namespace winrt::Windows::UI::Composition;
using namespace winrt::Windows::UI::Composition::Desktop;
using namespace winrt::Windows::UI::Core;
using namespace winrt::Windows::System;
using namespace winrt::Microsoft::Graphics::Canvas::Effects;



namespace abi
{
    using namespace ABI::Windows::Foundation;
    using namespace ABI::Windows::Graphics::DirectX;
    using namespace ABI::Windows::UI::Composition;
}

class CompositionHost
{
public:
    ~CompositionHost();
    static CompositionHost* GetInstance();
    void Initialize(HWND hwnd);
    void AddElement(float size, float x, float y);
    void BlurBackground();
private:
    CompositionHost();
    void EnsureDispatcherQueue();
    void CreateDesktopWindowTarget(HWND window);
    void CreateCompositionRoot();

    winrt::Windows::UI::Composition::Compositor m_compositor{ nullptr };
    winrt::Windows::System::DispatcherQueueController m_dispatcherQueueController{ nullptr };
    winrt::Windows::UI::Composition::Desktop::DesktopWindowTarget m_target{ nullptr };

};

CompositionHost* CompositionHost::GetInstance()
{
    static CompositionHost instance;
    return &instance;
}

void CompositionHost::Initialize(HWND hwnd)
{
    EnsureDispatcherQueue();
    m_compositor = Compositor();

    CreateDesktopWindowTarget(hwnd);
    CreateCompositionRoot();
}

void CompositionHost::EnsureDispatcherQueue()
{
    namespace abi = ABI::Windows::System;

    //if (m_dispatcherQueueController == nullptr)
    {
        DispatcherQueueOptions options
        {
            sizeof(DispatcherQueueOptions), /* dwSize */
            DQTYPE_THREAD_CURRENT,          /* threadType */
            DQTAT_COM_ASTA                  /* apartmentType */
        };

        winrt::Windows::System::DispatcherQueueController controller{ nullptr };
        //auto test1 = &m_dispatcherQueueController;
        //int t = CreateDispatcherQueueController(options, (abi::IDispatcherQueueController **)&test1);
        int t = CreateDispatcherQueueController(options, reinterpret_cast<abi::IDispatcherQueueController**>(put_abi(controller)));
        m_dispatcherQueueController = controller;
        int p = 1;
    }
}

void CompositionHost::CreateDesktopWindowTarget(HWND window)
{
    namespace abi = ABI::Windows::UI::Composition::Desktop;

    auto interop = m_compositor.as<abi::ICompositorDesktopInterop>();
    DesktopWindowTarget target{ nullptr };
    check_hresult(interop->CreateDesktopWindowTarget(window, false, reinterpret_cast<abi::IDesktopWindowTarget**>(put_abi(target))));
    m_target = target;
}

void CompositionHost::CreateCompositionRoot()
{
    auto root = m_compositor.CreateContainerVisual();
    root.RelativeSizeAdjustment({ 1.0f, 1.0f });
    root.Offset({ 124, 12, 0 });
    m_target.Root(root);
}

void CompositionHost::AddElement(float size, float x, float y)
{
    if (m_target.Root())
    {
        auto visuals = m_target.Root().as<ContainerVisual>().Children();
        auto visual = m_compositor.CreateSpriteVisual();

        auto element = m_compositor.CreateSpriteVisual();
        uint8_t r = (double)(double)(rand() % 255);;
        uint8_t g = (double)(double)(rand() % 255);;
        uint8_t b = (double)(double)(rand() % 255);;

        element.Brush(m_compositor.CreateColorBrush({ 255, r, g, b }));
        element.Size({ size, size });
        element.Offset({ x, y, 0.0f, });

        auto animation = m_compositor.CreateVector3KeyFrameAnimation();
        auto bottom = (float)600 - element.Size().y;
        animation.InsertKeyFrame(1, { element.Offset().x, bottom, 0 });

        using timeSpan = std::chrono::duration<int, std::ratio<1, 1>>;

        std::chrono::seconds duration(2);
        std::chrono::seconds delay(3);

        animation.Duration(timeSpan(duration));
        animation.DelayTime(timeSpan(delay));
        element.StartAnimation(L"Offset", animation);
        visuals.InsertAtTop(element);

        visuals.InsertAtTop(visual);
    }
}

void CompositionHost::BlurBackground() {
    if (m_target.Root()) {


        GaussianBlurEffect blurEffect;
        winrt::hstring blurStr = winrt::hstring(L"Blur");
        blurEffect.Name(blurStr);
        blurEffect.BlurAmount(1.0f);
        blurEffect.BorderMode(EffectBorderMode::Hard);
        blurEffect.Optimization(EffectOptimization::Balanced);

        CompositionEffectSourceParameter sourceParameter = CompositionEffectSourceParameter(L"source");
        blurEffect.Source(sourceParameter);



        CompositionEffectFactory blurEffectFactory = m_compositor.CreateEffectFactory(blurEffect);
        CompositionEffectBrush blurBrush = blurEffectFactory.CreateBrush();

        CompositionBackdropBrush backDropBrush = m_compositor.CreateBackdropBrush();
        blurBrush.SetSourceParameter(L"source", backDropBrush);

        auto visuals = m_target.Root().as<ContainerVisual>().Children();
        auto visual = m_compositor.CreateSpriteVisual();
        auto element = m_compositor.CreateSpriteVisual();

        element.Brush(blurBrush);
        visuals.InsertAtTop(element);

        visuals.InsertAtTop(visual);
    }
}

CompositionHost::CompositionHost()
{
}

CompositionHost::~CompositionHost()
{
}


CompositionHost* compHost = CompositionHost::GetInstance();
HWND hwnd;
LRESULT CALLBACK    WindowProc(HWND, UINT, WPARAM, LPARAM);

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow)
{
    // Register the window class.
    const wchar_t CLASS_NAME[] = L"Sample Window Class";

    WNDCLASS wc = { };


    {
    wc.lpfnWndProc = WindowProc;
    wc.hInstance = hInstance;
    wc.lpszClassName = CLASS_NAME;

    RegisterClass(&wc);

    // Create the window.

    hwnd = CreateWindowEx(
        WS_EX_NOREDIRECTIONBITMAP,                              // Optional window styles.
        CLASS_NAME,                     // Window class
        L"Learn to Program Windows",    // Window text
        WS_OVERLAPPEDWINDOW,             // Window style

        // Size and position
        CW_USEDEFAULT, CW_USEDEFAULT, 900, 672,

        NULL,       // Parent window    
        NULL,       // Menu
        hInstance,  // Instance handle
        NULL        // Additional application data
    );

    if (hwnd == NULL)
    {
        return 0;
    }
    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);
    }

    compHost = CompositionHost::GetInstance();


    MSG msg = { };
    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return 0;
}

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
    case WM_CREATE:
    {
        compHost->Initialize(hwnd);
        srand(time(nullptr));

        CreateWindow(TEXT("button"), TEXT("Add element"),
            WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON,
            12, 12, 100, 50,
            hwnd, (HMENU)BTN_ADD, nullptr, nullptr);
    }
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;

    case WM_PAINT:
        {
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hwnd, &ps);



            //FillRect(hdc, &ps.rcPaint, (HBRUSH) (COLOR_WINDOW+1));

            EndPaint(hwnd, &ps);
        }
        break;
    case WM_COMMAND: // on Button click
    {
        //double size = (double)(rand() % 150 + 50);
        //double x = (double)(rand() % 600);
        //double y = (double)(rand() % 200);
        //compHost->AddElement(size, x, y);
        compHost->BlurBackground();
        break;
    }
    }
    return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
4

0 回答 0