locked
how to write a function with in LPCWSTR and return ID2D1Bitmap

    Question

  • Hi, I'm new to c++ and directx. I'm studing with a book of c++ stl, but when I try directx I don't understand many things.

    I'm working on ID2D1Bitmap a function and i can't get it right.

    Could any one show me some code to write a function that takes as in parameter a LPCWSTR and returns a comptr<LPCWSTR>

    I want to encapsulate de functionaliti of loading an image for d2d in this function.

    Thanx.


    P.D:By the way any book recomendations on c++ winrt for rookies?

    Wednesday, February 27, 2013 10:39 PM

Answers

  • LPCWSTR is just a fancy typedef for "const wchar_t*" which is a pointer to a constant wide-character string.

    "const wchar_t*" is not a COM object, and therefore has no reference counting methods AddRef or Release that are used by the ComPtr smart-pointer class. That's why it won't work.

    So you want a C++ function that takes a wide-character string (which you don't modify) and then return a new wide-character string, correct?

    You don't need to use any fancy WinRT to make this happen unless you are actually writing a WinRT interface for use by JavaScript or C#. You can write it very simply in C as:

    void Function( LPCWSTR* input, LPWSTR* output, size_t max );

    You need to know the maximum size of the output buffer so you can pass it along to the Secure CRT string functions.

    Alternatively you can make use of the STL and use the wstring wide-character string container class.

    std::wstring Function( LPWCSTR* input );

    or if you are being a heavy user of STL

    void Function( const std::wstring& input, std::wstring& output );



    Friday, March 1, 2013 12:01 AM
  • Thanks for your replay.

    It was usfull in the sense that I figures how to convert a Platform::String to a LPWCSTR string in order to get my ID2DBitmap.

    But what I ment is how to "return" a ID2DBitmap, my problems was the Access modifier of my method, it was public, and it needed to be internal.

    So I finally came up with this:

    void LayeredRenderer::Load(Platform::String^ fileName, _Out_opt_ ID2D1Bitmap** outBitmap){
     auto filename=fileName->Data();
     if(m_D2Dcontext!=NULL && m_wicFactory!=NULL){
      ComPtr<IWICBitmapDecoder> wicBitmapDecoder;
      DX::ThrowIfFailed(
       m_wicFactory->CreateDecoderFromFilename(
        filename,
        nullptr,
        GENERIC_READ,
        WICDecodeMetadataCacheOnDemand,
        &wicBitmapDecoder
        )
       );
      ComPtr<IWICBitmapFrameDecode> wicBitmapFrame;
      DX::ThrowIfFailed(
       wicBitmapDecoder->GetFrame(0, &wicBitmapFrame)
       );
      ComPtr<IWICFormatConverter> wicFormatConverter;
      DX::ThrowIfFailed(
       m_wicFactory->CreateFormatConverter(&wicFormatConverter)
       );
      DX::ThrowIfFailed(
       wicFormatConverter->Initialize(
        wicBitmapFrame.Get(),
        GUID_WICPixelFormat32bppPBGRA,
        WICBitmapDitherTypeNone,
        nullptr,
        0.0,
        WICBitmapPaletteTypeCustom  // the BGRA format has no palette so this value is ignored
        )
       );
      double dpiX = 96.0f;
      double dpiY = 96.0f;
      DX::ThrowIfFailed(
       wicFormatConverter->GetResolution(&dpiX, &dpiY)
       );
      DX::ThrowIfFailed(
       
       m_D2Dcontext->CreateBitmapFromWicBitmap(
        wicFormatConverter.Get(),
        D2D1::BitmapProperties(
         D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED),
         static_cast<float>(dpiX),
         static_cast<float>(dpiY)
         ),
        outBitmap  //D2Dbitmap
        )
       );
       
     }

    Being the declaration of this method internal and it worked.

    Thanks again for your help


    • Marked as answer by adrifre7 Tuesday, March 5, 2013 2:09 PM
    • Edited by adrifre7 Tuesday, March 5, 2013 2:11 PM
    Monday, March 4, 2013 8:59 PM

All replies

  • LPCWSTR is just a fancy typedef for "const wchar_t*" which is a pointer to a constant wide-character string.

    "const wchar_t*" is not a COM object, and therefore has no reference counting methods AddRef or Release that are used by the ComPtr smart-pointer class. That's why it won't work.

    So you want a C++ function that takes a wide-character string (which you don't modify) and then return a new wide-character string, correct?

    You don't need to use any fancy WinRT to make this happen unless you are actually writing a WinRT interface for use by JavaScript or C#. You can write it very simply in C as:

    void Function( LPCWSTR* input, LPWSTR* output, size_t max );

    You need to know the maximum size of the output buffer so you can pass it along to the Secure CRT string functions.

    Alternatively you can make use of the STL and use the wstring wide-character string container class.

    std::wstring Function( LPWCSTR* input );

    or if you are being a heavy user of STL

    void Function( const std::wstring& input, std::wstring& output );



    Friday, March 1, 2013 12:01 AM
  • Thanks for your replay.

    It was usfull in the sense that I figures how to convert a Platform::String to a LPWCSTR string in order to get my ID2DBitmap.

    But what I ment is how to "return" a ID2DBitmap, my problems was the Access modifier of my method, it was public, and it needed to be internal.

    So I finally came up with this:

    void LayeredRenderer::Load(Platform::String^ fileName, _Out_opt_ ID2D1Bitmap** outBitmap){
     auto filename=fileName->Data();
     if(m_D2Dcontext!=NULL && m_wicFactory!=NULL){
      ComPtr<IWICBitmapDecoder> wicBitmapDecoder;
      DX::ThrowIfFailed(
       m_wicFactory->CreateDecoderFromFilename(
        filename,
        nullptr,
        GENERIC_READ,
        WICDecodeMetadataCacheOnDemand,
        &wicBitmapDecoder
        )
       );
      ComPtr<IWICBitmapFrameDecode> wicBitmapFrame;
      DX::ThrowIfFailed(
       wicBitmapDecoder->GetFrame(0, &wicBitmapFrame)
       );
      ComPtr<IWICFormatConverter> wicFormatConverter;
      DX::ThrowIfFailed(
       m_wicFactory->CreateFormatConverter(&wicFormatConverter)
       );
      DX::ThrowIfFailed(
       wicFormatConverter->Initialize(
        wicBitmapFrame.Get(),
        GUID_WICPixelFormat32bppPBGRA,
        WICBitmapDitherTypeNone,
        nullptr,
        0.0,
        WICBitmapPaletteTypeCustom  // the BGRA format has no palette so this value is ignored
        )
       );
      double dpiX = 96.0f;
      double dpiY = 96.0f;
      DX::ThrowIfFailed(
       wicFormatConverter->GetResolution(&dpiX, &dpiY)
       );
      DX::ThrowIfFailed(
       
       m_D2Dcontext->CreateBitmapFromWicBitmap(
        wicFormatConverter.Get(),
        D2D1::BitmapProperties(
         D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED),
         static_cast<float>(dpiX),
         static_cast<float>(dpiY)
         ),
        outBitmap  //D2Dbitmap
        )
       );
       
     }

    Being the declaration of this method internal and it worked.

    Thanks again for your help


    • Marked as answer by adrifre7 Tuesday, March 5, 2013 2:09 PM
    • Edited by adrifre7 Tuesday, March 5, 2013 2:11 PM
    Monday, March 4, 2013 8:59 PM