direct 2d и api WIC ошибка нулевого указателя

Рейтинг: 0Ответов: 1Опубликовано: 11.04.2023

Создаю игру на direct 2d с использованием компонента обработки изображений windows (api WIC), но столкнулся с проблемой. По какой-то причине img_decoder (интерфейс IWICImagingFactory) при запуске программы является нулевым указателем (img_decoder->CreateDecoderFromFilename(L"C:\Users\Rak\source\repos\Game\x64\Debug\ft.png", 0, GENERIC_READ, WICDecodeMetadataCacheOnLoad, &bitmap_decoder) - вот здесь она проявляется). Я совершенно не понимаю, что с ним не так. В коде на MSDN (https://learn.microsoft.com/ru-ru/windows/win32/direct2d/how-to-load-a-direct2d-bitmap-from-a-file) никакой инициализации этого интерфейса нет, его просто объявили и уже используют. Помогите пожалуйста!

#include <Windows.h>
#include <wincodec.h>
#include <d2d1.h>
#pragma comment(lib, "d2d1.lib")

using namespace D2D1;

ID2D1Factory* fc = 0;
IWICImagingFactory* img_decoder;
IWICBitmapDecoder* bitmap_decoder = 0;
IWICBitmapFrameDecode* decoded_frame = 0;
IWICFormatConverter* img_converter;
ID2D1HwndRenderTarget* rTarg = 0;
ID2D1SolidColorBrush* pBrush = 0;
ID2D1Bitmap* png = 0;
RECT rc;
HWND hwin;

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow) {
    WNDCLASSW wcw = {};
    wcw.hInstance = hInstance;
    wcw.lpfnWndProc = WindowProc;
    wcw.lpszClassName = L"Priv";
    RegisterClassW(&wcw);
    hwin = CreateWindowExW(0, L"Priv", L"Hi", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, hInstance, 0);
    ShowWindow(hwin, nCmdShow);
    GetClientRect(hwin, &rc);
    D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &fc);
    fc->CreateHwndRenderTarget(RenderTargetProperties(), HwndRenderTargetProperties(hwin, SizeU(rc.right - rc.left, rc.bottom - rc.top)), &rTarg);
    rTarg->CreateSolidColorBrush(ColorF(ColorF::BlueViolet), &pBrush);
    img_decoder->CreateDecoderFromFilename(L"C:\\Users\\Rak\\source\\repos\\Game\\x64\\Debug\\ft.png", 0, GENERIC_READ, WICDecodeMetadataCacheOnLoad, &bitmap_decoder);
    bitmap_decoder->GetFrame(0, &decoded_frame);
    img_converter->Initialize(decoded_frame, GUID_WICPixelFormat32bppPBGRA, WICBitmapDitherTypeNone, 0, 0, WICBitmapPaletteTypeMedianCut);
    rTarg->CreateBitmapFromWicBitmap(img_converter, 0, &png);
    MSG msg = {};
    while (GetMessage(&msg, NULL, 0, 0) > 0)
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
}

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
    case WM_DESTROY:
    {
        return 0;
    }
    case WM_PAINT:
    {
        rTarg->BeginDraw();
        rTarg->CreateSolidColorBrush(ColorF(ColorF::White), &pBrush);
        rTarg->FillRectangle(RectF(rc.left, rc.top, rc.right, rc.bottom), pBrush);
        rTarg->CreateSolidColorBrush(ColorF(ColorF::BlueViolet), &pBrush);
        rTarg->DrawRectangle(D2D1::RectF(rc.left + 100.0f, rc.top + 100.0f, rc.right - 100.0f, rc.bottom - 100.0f), pBrush);
        rTarg->EndDraw();
        return 0;
    }
    return 0;
    }
    return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

Ответы

▲ 0

Проблема заключается в том, что вы объявили указатель на интерфейс IWICImagingFactory, но не создали экземпляр этого интерфейса. Поэтому, когда вы вызываете метод img_decoder->CreateDecoderFromFilename(), программа пытается обратиться к несуществующему объекту и вызывает ошибку. Чтобы исправить это, вам нужно создать экземпляр IWICImagingFactory, используя функцию CoCreateInstance(). Попробуйте заменить строку

IWICImagingFactory* img_decoder;

на

CoCreateInstance(CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&img_decoder));

Это должно создать экземпляр IWICImagingFactory и присвоить его указателю img_decoder.