ある一定の文字数を超えると、行頭からダブって表示される問題ですが、どうもExtTextOutの制限に引っかかっている様子でした。
ウィンドウの左右にあふれている文字のクリッピングをExtTextOutに一任していたものを、動作に支障が出ない程度に自前でクリッピングするようにしました。
そしたら、不思議なことに行頭からダブって表示される問題は発生しなくなったように見えます。
ExtTextOutについて詳しくは、
http://www.microsoft.com/japan/developer/library/jpgdipf/_win32_exttextout.htmで、結局DispTextを次のように変更しました。
int CEditView::DispText( HDC hdc, int x, int y, const unsigned char* pData, int nLength )
{
if( 0 >= nLength ){
return 0;
}
RECT rcClip;
int nLineHeight = m_nCharHeight + m_pcEditDoc->GetDocumentAttribute().m_nL
ineSpace;
int nCharWidth = m_nCharWidth + m_pcEditDoc->GetDocumentAttribute().m_nC
olmSpace;
UINT fuOptions = ETO_CLIPPED | ETO_OPAQUE;
rcClip.left = x;
rcClip.right = rcClip.left + ( nCharWidth ) * nLength;
rcClip.top = y;
if( rcClip.left < m_nViewAlignLeft ){
rcClip.left = m_nViewAlignLeft;
}
if( rcClip.left < rcClip.right
&& rcClip.left < m_nViewAlignLeft + m_nViewCx && rcClip.right > m_nViewAlignLeft
&& rcClip.top >= m_nViewAlignTop
){
rcClip.bottom = y + nLineHeight;
/* if( rcClip.right - rcClip.left > 3000 ){
rcClip.right = rcClip.left + 3000;
}
::ExtTextOut( hdc, x, y, fuOptions, &rcClip, (const char *)pData, nLength, m_pnDx );
*/
if( rcClip.right - rcClip.left > m_nViewCx ){
rcClip.right = rcClip.left + m_nViewCx;
}
int nBefore = 0; // ウィンドウの左にあふれた文字数
int nAfter = 0; // ウィンドウの右にあふれた文字数
if ( x < 0 ){
nBefore = ( 0 - x ) / nCharWidth;
}
if ( rcClip.right < x + nCharWidth * nLength ){
nAfter = (x + nCharWidth * nLength - rcClip.right) / nCharWidth;
}
::ExtTextOut( hdc, x + nBefore * nCharWidth, y, fuOptions, &rcClip, (const char *)&pData[nBefore], nLength - nBefore - nAfter, m_pnDx );
}
return nLength;
}