你看看msdn中关于PARAFORMAT2结构的介绍PARAFORMAT2 Structure--------------------------------------------------------------------------------The PARAFORMAT2 structure contains information about paragraph formatting attributes in a rich edit control. PARAFORMAT2 is a Microsoft Rich Edit 2.0 extension of the PARAFORMAT structure. Rich Edit 2.0 allows you to use either structure with the EM_GETPARAFORMAT and EM_SETPARAFORMAT messages. Syntaxtypedef struct _paraformat { UINT cbSize; DWORD dwMask; WORD wNumbering; WORD wEffects; LONG dxStartIndent; LONG dxRightIndent; LONG dxOffset; WORD wAlignment; SHORT cTabCount; LONG rgxTabs[MAX_TAB_STOPS]; LONG dySpaceBefore; LONG dySpaceAfter; LONG dyLineSpacing; SHORT sStyle; BYTE bLineSpacingRule; BYTE bOutlineLevel; WORD wShadingWeight; WORD wShadingStyle; WORD wNumberingStart; WORD wNumberingStyle; WORD wNumberingTab; WORD wBorderSpace; WORD wBorderWidth; WORD wBorders; } PARAFORMAT2; #define wEffects wReserved dyLineSpacin bLineSpacingRule
谢谢几位回复。dyLineSpacing bLineSpacingRule 这两个我都试过,行为和word中所设置的行距一样。 bLineSpacingRule 为4时可以精确控制行距,但遗憾的是这和word的"固定值"一样,即使取值小于一行的高度,上下行之间至少有一个像素的间隔。 自画是最无奈的笨办法,娘希匹,时间来不及啊,有谁最先能搞定这问题,可以将分换成¥,说话算数.mail : surs2002 at msn dot com
在word中试了一下,也不是字体的问题,即使将行距设置小于字体,word哪怕选择割掉字符上面的几个像素,也还是会在下面留一个像素的间隔。
edit和CDC::DrawText会小点, 大致如下:
宋体、lfHeight==12宽高是16*12, 上下相邻行间隔有一个像素
宋体、lfHeight==14则为16*14, 上下相邻行间隔有一个像素
宋体、lfHeight==16则为16*16, 上下相邻行间隔0像素而richedit:
宋体、lfHeight==12宽高是16*16 上下相邻行间隔至少有一个像素!
自己Create一个新的CRichEdit控件,还是比较简单的。
先CreateWindow建立一个窗口,创建字体和字体颜色,背景色等等。输出就使用TextOut或者DrawText。想写在什么地方写在什么地方!
UINT cbSize;
DWORD dwMask;
WORD wNumbering;
WORD wEffects;
LONG dxStartIndent;
LONG dxRightIndent;
LONG dxOffset;
WORD wAlignment;
SHORT cTabCount;
LONG rgxTabs[MAX_TAB_STOPS];
LONG dySpaceBefore;
LONG dySpaceAfter;
LONG dyLineSpacing;
SHORT sStyle;
BYTE bLineSpacingRule;
BYTE bOutlineLevel;
WORD wShadingWeight;
WORD wShadingStyle;
WORD wNumberingStart;
WORD wNumberingStyle;
WORD wNumberingTab;
WORD wBorderSpace;
WORD wBorderWidth;
WORD wBorders;
} PARAFORMAT2;
#define wEffects wReserved
dyLineSpacin
bLineSpacingRule
bLineSpacingRule
这两个我都试过,行为和word中所设置的行距一样。
bLineSpacingRule 为4时可以精确控制行距,但遗憾的是这和word的"固定值"一样,即使取值小于一行的高度,上下行之间至少有一个像素的间隔。
自画是最无奈的笨办法,娘希匹,时间来不及啊,有谁最先能搞定这问题,可以将分换成¥,说话算数.mail : surs2002 at msn dot com
code:(有兴趣可以试用)
/*
自动换行 -- 自动加换行符
CRichEdit::SetSel(),GetLine() -- 汉字等宽字符的index和字母一样,
但CString:: ReleaseBuffer(), GetLength(),Mid()必顺区分单字符和宽字符(MSDN : For multibyte character sets (MBCS), nCount refers to each 8-bit character),
所以M$ TMD SB,CRichEditCtrl::GetLine那个例子就是错的, ReleaseBuffer就不应该加参数
*/
void CRichText::OnDraw(CDC* pDC)
{
int oldBkMode = pDC->SetBkMode(1);
CPoint oldViewportOrg = pDC->SetViewportOrg(m_pTextFrmWnd->m_frmData.xStart
, m_pTextFrmWnd->m_frmData.yStart); CRect rectClip(0, 0 , m_pTextFrmWnd->m_frmData.width, m_pTextFrmWnd->m_frmData.height);
CString strLine('c', 256);
CString strDraw;
int nLineCount = m_richEdit.GetLineCount();
CRect rectDraw(0,0,0,0), rectCalc(0,0,0,0);
int iSelStart = 0;
for (int iLine = 0; iLine < nLineCount; iLine++)
{
int nLineLength = m_richEdit.LineLength(iLine);
if(nLineLength <= 0)
continue;// string str;
// str.resize(nLineLength);
// m_richEdit.GetLine(iLine, &str[0]);
// strLine = str.c_str(); //m_richEdit.GetLine(iLine, strLine); int nGetLine = m_richEdit.GetLine(iLine, strLine.GetBuffer(nLineLength), 1000000);
nLineLength = max(nLineLength, nGetLine);
nLineLength = max(nLineLength, strLine.GetLength());
strLine.ReleaseBuffer();
nLineLength = strLine.GetLength();
// int nGetLine = m_richEdit.GetLine(iLine, strLine.GetBuffer(256));
// strLine.ReleaseBuffer(-1);
// nLineLength = strLine.GetLength(); UINT nLineHeight = 0;
vector<UINT> vWidth(nLineLength, 0); //先计算各文字绘制的宽度,高度 UINT iSelStart2 = iSelStart; //Alignment:
UINT format = DT_SINGLELINE | DT_CALCRECT;
m_richEdit.SetSel(iSelStart2, iSelStart2 + 1);
PARAFORMAT paraFormat;
m_richEdit.GetParaFormat(paraFormat);
switch(paraFormat.wAlignment)
{
case PFA_LEFT:
format |= DT_LEFT;
break;
case PFA_RIGHT:
format |= DT_RIGHT;
break;
case PFA_CENTER:
format |= DT_CENTER;
break;
default:
break;
} for(int i = 0 ; i < nLineLength ; ++i, ++iSelStart)
{
char c = strLine[i];
if(c == '\n')
break;
if(c & 0x80)//汉字
{
if(i + 1 < nLineLength)
{
strDraw = strLine.Mid(i, 2);
m_richEdit.SetSel(iSelStart, iSelStart + 1);
++i;
//++nLineLength;
}
else
break;
}
else
{
strDraw = strLine.Mid(i, 1);
m_richEdit.SetSel(iSelStart, iSelStart + 1);
}
//*
CHARFORMAT cf;
memset(&cf, 0 , sizeof(cf));
cf.dwMask = 0xffffffff;
m_richEdit.GetSelectionCharFormat(cf);
auto_ptr<CFont> font(g_CreateFontFrom(cf));
CFont* pOldFont = pDC->SelectObject(font.get());
COLORREF oldTextColor = pDC->SetTextColor(cf.crTextColor);
pDC->DrawText(strDraw, rectCalc, format);
ASSERT(i < vWidth.size());
vWidth[i] = rectCalc.Width();
nLineHeight = max(nLineHeight, rectCalc.Height());
pDC->SetTextColor(oldTextColor);
pDC->SelectObject(pOldFont);
//*/
} //开始绘制:---------------------------------
//Alignment, 同时设置绘制起点:
format = DT_SINGLELINE | DT_CALCRECT;
m_richEdit.SetSel(iSelStart2, iSelStart2 + 1);
//PARAFORMAT paraFormat;
m_richEdit.GetParaFormat(paraFormat);
rectDraw.left = 00;
switch(paraFormat.wAlignment)
{
case PFA_LEFT:
format |= DT_LEFT;
rectDraw.left = 0;
break;
case PFA_RIGHT:
format |= DT_RIGHT;
rectDraw.left = rectClip.Width() - accumulate(vWidth.begin(), vWidth.end(), 0);
break;
case PFA_CENTER:
format |= DT_CENTER;
rectDraw.left = (rectClip.Width() - accumulate(vWidth.begin(), vWidth.end(), 0)) / 2;
break;
default:
rectDraw.left = 0;
break;
} rectDraw.bottom = rectDraw.top + nLineHeight;
format &= ~DT_CALCRECT;
format |= DT_BOTTOM;
for( i = 0 ; i < nLineLength ; ++i, ++iSelStart2)
{
char c = strLine[i];
if(c == '\n')
break;
if(c & 0x80)//汉字
{
if(i + 1 < nLineLength)
{
strDraw = strLine.Mid(i, 2);
m_richEdit.SetSel(iSelStart2, iSelStart2 + 1);
++i;
//++iSelStart;
}
else
break;
}
else
{
strDraw = strLine.Mid(i, 1);
m_richEdit.SetSel(iSelStart2, iSelStart2 + 1);
} //*
CHARFORMAT cf;
cf.dwMask = 0xffffffff;
m_richEdit.GetSelectionCharFormat(cf);
auto_ptr<CFont> font(g_CreateFontFrom(cf));
CFont* pOldFont = pDC->SelectObject(font.get());
COLORREF oldTextColor = pDC->SetTextColor(cf.crTextColor);
rectDraw.right = rectDraw.left + vWidth[i];
rectDraw.bottom = rectDraw.top + nLineHeight;
pDC->DrawText(strDraw, rectDraw, format);
rectDraw.left = rectDraw.right; pDC->SetTextColor(oldTextColor);
pDC->SelectObject(pOldFont);
//*/
}
rectDraw.top = rectDraw.bottom;
} pDC->SetViewportOrg(oldViewportOrg);
pDC->SetBkMode(oldBkMode);
}
CFont* g_CreateFontFrom(const CHARFORMAT& cf)
{
CFont *pNewFont = new CFont;
if (pNewFont == NULL)
{
return NULL;
}
LOGFONT lf;
memset(&lf, 0, sizeof(lf));
lf.lfHeight = -labs(cf.yHeight / 20 + FONT_Height_Diff);
// lf.lfWeight = cf.wWeight;
lf.lfCharSet = cf.bCharSet;
lf.lfOutPrecision = OUT_TT_PRECIS;//OUT_CHARACTER_PRECIS;
lf.lfPitchAndFamily = cf.bPitchAndFamily ; strcpy(lf.lfFaceName, cf.szFaceName);
if (cf.dwEffects & CFM_BOLD)
{
lf.lfWeight = FW_BOLD;
}
if (cf.dwEffects & CFM_ITALIC)
{
lf.lfItalic = TRUE;
}
if (cf.dwEffects & CFM_UNDERLINE)
{
lf.lfUnderline = TRUE;
}
if(!pNewFont->CreateFontIndirect(&lf))
{
delete pNewFont;
pNewFont = NULL;
}
return pNewFont;
}
#define FONT_Height_Diff 4