0

I am doing a program with Direct2D and I want to paint a flower on the window. However, I could only see a white window with nothing except the menu. I tested, and then I found that the code which deal with the message WM_PAINT didn't work. I added a piece of code that show a message box, but I only heard the sound, and didn't see the box.

The main code:

// other code omitted
ID2D1Factory* pFactory = nullptr;
ID2D1HwndRenderTarget* pRenderTarget = nullptr;
ID2D1SolidColorBrush* pBrush = nullptr;
IWICImagingFactory* pImagingFactory = nullptr;
IWICBitmapDecoder* pBitmapDecoder = nullptr;
IWICFormatConverter* pConverter = nullptr;
ID2D1Bitmap* pBitmap = nullptr;
IWICBitmapFrameDecode* pDecode = nullptr;

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
        // other messages omitted
    case WM_CREATE:
    {
        D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &pFactory);
        pFactory->CreateHwndRenderTarget(D2D1::RenderTargetProperties(),
            D2D1::HwndRenderTargetProperties(hWnd, D2D1::SizeU(rect.right - rect.left, rect.top - rect.bottom)),
            &pRenderTarget);
        HRESULT hr = CoCreateInstance(CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pImagingFactory));
        pImagingFactory->CreateDecoderFromFilename(L".\\flower.png", nullptr, GENERIC_READ,
            WICDecodeMetadataCacheOnLoad, &pBitmapDecoder);
        pBitmapDecoder->GetFrame(0, &pDecode);
        pImagingFactory->CreateFormatConverter(&pConverter);
        pConverter->Initialize(pDecode, GUID_WICPixelFormat32bppPBGRA, WICBitmapDitherTypeNone,
            nullptr, 0.F, WICBitmapPaletteTypeCustom);
        pRenderTarget->CreateBitmapFromWicBitmap(pConverter, nullptr, &pBitmap);
    }
        break;
    

    case WM_PAINT:
    {
        MessageBox(hWnd, L"WM_PAINT", L"flower", MB_OK | MB_ICONEXCLAMATION);  // the test code

        PAINTSTRUCT ps;
        HDC hdc = BeginPaint(hWnd, &ps);

        pRenderTarget->BeginDraw();
        pRenderTarget->Clear(D2D1::ColorF(D2D1::ColorF::Red));
        if (pBitmap != nullptr)
            pRenderTarget->DrawBitmap(pBitmap, D2D1::RectF(500, 500, 572, 572));
        pRenderTarget->EndDraw();

        EndPaint(hWnd, &ps);
    }
        break;
    }
}
Simon Mourier
  • 132,049
  • 21
  • 248
  • 298
Sam-zhuang
  • 24
  • 5
  • 2
    We cannot see where your render target dimensions are coming from, but `rect.top - rect.bottom` is probably wrong. In Windows' native coordinate system, this expression yields a negative value. Once that gets converted to an unsigned value it turns huge. `CreateHwndRenderTarget` subsequently likely fails, but you're ignoring its return value. Step one towards a solution: Make sure to observe results from **all** operations that can fail. – IInspectable Mar 23 '22 at 10:24
  • @IInspectable I checked that the results from **all** operations are all **S_OK** – Sam-zhuang Mar 23 '22 at 10:37
  • Put the complete reproducing sample somewhere or here if it's not too big. – Simon Mourier Mar 23 '22 at 10:38
  • https://anonfiles.com/R6M1tfQ1xe/flower_cpp – Sam-zhuang Mar 23 '22 at 10:47
  • 1
    As IInspectable suspected, you create an empty render target, rect is empty at that moment. – Simon Mourier Mar 23 '22 at 11:04
  • But now I change it: `D2D1::HwndRenderTargetProperties(hWnd, D2D1::SizeU(rect.right - rect.left, rect.bottom - rect.top))`, it still doesn't work. – Sam-zhuang Mar 23 '22 at 11:12
  • 1
    rect is empty means right-left = bottom - top = 0 – Simon Mourier Mar 23 '22 at 11:37
  • @SimonMourier Thank you for the tip. I forgot to write `GetClientRect(hWnd, &rect)`. – Sam-zhuang Mar 23 '22 at 11:46

0 Answers0