【问题标题】:IDWriteFactory::CreateTextLayout method causes window to suddenly closeIDWriteFactory::CreateTextLayout 方法导致窗口突然关闭
【发布时间】:2023-03-19 17:52:01
【问题描述】:

在我使用 Windows API 构建的应用程序中,我目前正在将文本写入屏幕。我正在尝试使用CreateTextLayout 方法,但是使用该特定功能时,我遇到了无法解决的问题。当我刚刚运行我的应用程序时,我开始正常,并且刚刚退出,没有任何类型的错误警告。使用断点,我将问题追溯到该函数。这是我用来调用它的代码:

IDWriteFactory* writeFactory;
IDWriteTextFormat* writeTextFormat;
IDWriteTextLayout* writeTextLayout;

 HRESULT App::CreateDeviceIndependentResources()
{
    HRESULT hr;
// Create a Direct2D factory.
hr = D2D1CreateFactory(
    D2D1_FACTORY_TYPE_SINGLE_THREADED,
    &writeFactory
);


if (SUCCEEDED(hr))
{
    hr = DWriteCreateFactory(
        DWRITE_FACTORY_TYPE_SHARED,
        __uuidof(writeFactory),
        reinterpret_cast<IUnknown**>(&writeFactory)
    );

}

if (writeFactory == NULL)
        OutputDebugStringA("NULL\n");

if (SUCCEEDED(hr))
{
    hr =  writeFactory->CreateTextFormat(
        L"Times New Roman",
        NULL,
        DWRITE_FONT_WEIGHT_NORMAL,
        DWRITE_FONT_STYLE_NORMAL,
        DWRITE_FONT_STRETCH_NORMAL,
        14.0f,
        L"EN-US",
        &writeTextFormat
    );
}
if (SUCCEEDED(hr))
{
    // Create a DirectWrite text format object.
    hr = writeFactory->CreateTextLayout(
        L"Projects",      // The string to be laid out and formatted.
        8,  // The length of the string.
        writeTextFormat,  // The text format to apply to the string (contains font information, etc).
        10.0f,         // The width of the layout box.
        10.0f,        // The height of the layout box.
        &writeTextLayout  // The IDWriteTextLayout interface pointer.
    );
}
}

我觉得这很基本,因为我只是按照 Microsoft.com 上的教程进行操作;但是,有些地方显然是错误的。我的猜测是它可能与writeTextFormat 有关。它是一个IDWriteTextFormat 对象。此外,所有这些对象都在 CreateDeviceIndependentResources() 函数中初始化。我应该在其他地方初始化它们吗?

【问题讨论】:

  • 你检查过writeTextFormat的值吗?您首先需要使用IDWriteFactory::CreateTextFormat 方法创建一个IDWriteTextFormat 接口对象。如果还是不行,请提供a Minimal, Reproducible Example
  • 还要检查CreateTextLayout的返回值。
  • 我刚刚检查过,writeTextFactory 为 NULL。

标签: c++ windows user-interface winapi


【解决方案1】:

您混淆了D2D1CreateFactoryDWriteCreateFactory 的使用。

D2D1CreateFactory用于创建ID2D1Factory接口,用于创建ID2D1HwndRenderTargetID2D1SolidColorBrush来渲染文本。

DWriteCreateFactory 用于创建IDWriteFactory 接口,它是所有DirectWrite 对象的根工厂接口。 DirectWrite 对象用于格式化文本。

如:

ID2D1HwndRenderTarget* pRT_;
...

pRT_->DrawText(
    wszText_,        // The string to render.
    cTextLength_,    // The string's length.
    pTextFormat_,    // The text format.
    layoutRect,       // The region of the window where the text will be rendered.
    pBlackBrush_     // The brush used to draw the text.
    );

也许你可以从Part 2: Create Device Independent Resources开始。

一些代码:

IDWriteFactory* pDWriteFactory_;

hr = DWriteCreateFactory(
       DWRITE_FACTORY_TYPE_SHARED,
       __uuidof(IDWriteFactory),
       reinterpret_cast<IUnknown**>(&pDWriteFactory_)
       );
...

if (SUCCEEDED(hr))
{
    // Create a DirectWrite text format object.
    hr = pDWriteFactory_->CreateTextLayout(
        L"Projects",      // The string to be laid out and formatted.
        8,  // The length of the string.
        writeTextFormat,  // The text format to apply to the string (contains font information, etc).
        10.0f,         // The width of the layout box.
        10.0f,        // The height of the layout box.
        &writeTextLayout  // The IDWriteTextLayout interface pointer.
    );
}

官方示例:HelloWorld

【讨论】:

  • 感谢您的建议。在相关的说明中,您是否有任何猜测为什么 m_pRenderTarget-&gt;DrawTextLayout(origin, writeTextLayout, m_pBlackBrush, D2D1_DRAW_TEXT_OPTIONS_NONE) 函数什么都不做?
  • @johndoe DrawTextLayout 适合我。你检查了DrawTextLayout?中的所有参数注意:Drawing operations只能在BeginDrawEndDraw调用之间发出。
  • 谢谢!问题是我忘记了BeginDraw
猜你喜欢
  • 2022-10-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多