LoginSignup
0
1

More than 1 year has passed since last update.

CRenderTarget::DrawText と CD2DTextLayout::CD2DTextLayout のバグ

Last updated at Posted at 2022-07-13

1.環境など
Visual Studio 2022/2019/2017(それ以前は未確認)
MFC
マルチバイト文字セット

2.現象
MFC の Direct2D ラッパークラス、CRenderTarget と CD2DTextLayout ですが、マルチバイト文字セットで正しく動きません

3.詳細
MFCの実装ファイル、afxrendertarget.cpp

場所は環境によりますが、わたしの環境では以下のあたり
【Visual Studio 2022】
C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.32.31326\atlmfc\src\mfc
【Visual Studio 2019】
C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\MSVC\14.29.30133\atlmfc\src\mfc
【Visual Studio 2017】
C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Tools\MSVC\14.16.27023\atlmfc\src\mfc

で確認したところ、CRenderTarget::DrawText では

m_pRenderTarget->DrawText(T2CW(strText), strText.GetLength(), textFormat->m_pTextFormat, &rect, *pForegroundBrush, options, measuringMode);

などとなっています。バッファだけUnicodeへ変換して、文字数は変換前のバイト数を渡しています。なので、全角文字を渡すとUnicode文字数より大きな文字数を渡してしまい、文字化けします。CD2DTextLayoutのコンストラクタも同様です。

4.対策
【CRenderTarget::DrawText】
CHwndRenderTarget の 派生クラスを用意し、同じ DrawText を宣言し、定義部分は afxrendertarget.cpp からコピーしてきて

m_pRenderTarget->DrawText(T2CW(strText), strText.GetLength(), textFormat->m_pTextFormat, &rect, *pForegroundBrush, options, measuringMode);

のところを

CStringW strTextW(strText);
m_pRenderTarget->DrawText(strTextW, strTextW.GetLength(), textFormat->m_pTextFormat, &rect, *pForegroundBrush, options, measuringMode);

と修正し、CHwndRenderTarget の代わりに使います。

【CD2DTextLayout::CD2DTextLayout】
このラッパークラスは使わず
IDWriteFactory* pDWFactory = AfxGetD2DState()->GetWriteFactory();
であれこれします。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1