参考连接:http://www.codeproject.com/useritems/SSTextOut.asp
示例图:
函数名称为SSTextOut,和ExtTextOut函数功能相似。需要指定设备上下文指针,绘制文本区域的指针,需要显示的字符串以及显示格式。
字符串需要包含特殊格式字符。用'^'代表上标,用'_'代表下标,这样,在'^'和'_'后的字符将分别被显示为上标和下标。如果需要显示的是'^'和'_'字符本身,那么将它们连续显示两次就可以。即分别用'^^'和'__'表示。
调用方法:SSTextOut(pDC,"ms^2/Hz+H_2O-mc^^2__4",&rect,DT_CENTER);
源代码:
void SSTextOut(CDC* pDC, CString data , CRect* drawRect, int justification)
{
//Neccessary initializations
pDC->SaveDC();
CSize sz;
CRect outRect(0,0,0,0);
CFont* pFont = pDC->GetCurrentFont();
CFont* oldFont;
pDC->SetTextAlign(TA_BOTTOM|TA_LEFT);
LOGFONT lf;
pFont->GetLogFont(&lf);
CPoint sub,sup,subofs,supofs;
// Calculate subscript/superscript size and offsets
sub.x=lf.lfWidth/2;
sup.x=lf.lfWidth/2;
sub.y=lf.lfHeight/3*2;
sup.y=lf.lfHeight/3*2;
subofs.x=lf.lfWidth/2;
supofs.x=lf.lfWidth/2;
subofs.y=lf.lfHeight/6;
supofs.y=lf.lfHeight/3;
lf.lfWidth=sub.x;
lf.lfHeight=sub.y;
CFont SubFont;
SubFont.CreateFontIndirect(&lf);
lf.lfWidth=sup.x;
lf.lfHeight=sup.y;
CFont SupFont;
SupFont.CreateFontIndirect(&lf);
CString temp = data;
TCHAR c;
// Calculate the size of the text that needs to be displayed
do
{
int x=0;
CString s = "";
c=' ';
bool bFind=true;
// Find the first "^" or "_", indicating the sub- or superscript
while (bFind)
{
x=data.FindOneOf("^_");
if (x==-1)
{
bFind=false;
x=data.GetLength();
}
else if (x==data.GetLength()-1) bFind=false;
else if (data[x]!=data[x+1])
{
bFind=false;
c=data[x];
}
else x++;
s=s+data.Left(x);
data.Delete(0,min(x+1,data.GetLength()));
}
sz = pDC->GetTextExtent(s);
outRect.right+=sz.cx;
if (outRect.Height()<sz.cy) outRect.top=outRect.bottom-sz.cy;
switch (c)
{
case '^':
oldFont = pDC->SelectObject(&SupFont);
sz = pDC->GetTextExtent(data[0]);
outRect.right+=sz.cx+supofs.x;
data.Delete(0);
pDC->SelectObject(oldFont);
break;
case '_':
oldFont = pDC->SelectObject(&SubFont);
sz = pDC->GetTextExtent(data[0]);
outRect.right+=sz.cx+subofs.x;
data.Delete(0);
pDC->SelectObject(oldFont);
break;
}
}
while (c!=' ');
// Adjust text position
outRect.bottom+=2*subofs.y;
outRect.top-=2*subofs.x;
CPoint Origin;
Origin.y = drawRect->Height()/2+outRect.Height()/2+drawRect->top;
switch (justification)
{
case DT_CENTER:
Origin.x = drawRect->Width()/2-outRect.Width()/2+drawRect->left;
break;
case DT_LEFT:
Origin.x = drawRect->left;
break;
case DT_RIGHT:
Origin.x = drawRect->right-outRect.Width();
}
CPoint pnt = Origin;
data = temp;
// Draw text
do
{
int x=0;
CString s = "";
c=' ';
bool bFind=true;
// Find the first "^" or "_", indicating the sub- or superscript
while (bFind)
{
x=data.FindOneOf("^_");
if (x==-1)
{
bFind=false;
x=data.GetLength();
}
else if (x==data.GetLength()-1) bFind=false;
else if (data[x]!=data[x+1])
{
bFind=false;
c=data[x];
}
else x++;
s=s+data.Left(x);
data.Delete(0,min(x+1,data.GetLength()));
}
// Draw main text
pDC->ExtTextOut(pnt.x,pnt.y,ETO_CLIPPED,drawRect,s,NULL);
sz = pDC->GetTextExtent(s);
pnt.x+=sz.cx;
// Draw subscript or superscript
switch (c)
{
case '^':
oldFont = pDC->SelectObject(&SupFont);
pDC->ExtTextOut(pnt.x+supofs.x,pnt.y-supofs.y,ETO_CLIPPED,drawRect,data[0],NULL);
sz = pDC->GetTextExtent(data[0]);
pnt.x+=sz.cx+supofs.x;
data.Delete(0);
pDC->SelectObject(oldFont);
break;
case '_':
oldFont = pDC->SelectObject(&SubFont);
pDC->ExtTextOut(pnt.x+subofs.x,pnt.y+subofs.y,ETO_CLIPPED,drawRect,data[0],NULL);
sz = pDC->GetTextExtent(data[0]);
pnt.x+=sz.cx+supofs.x;
data.Delete(0);
pDC->SelectObject(oldFont);
break;
}
}
while (c!=' ');
// Done, restoring the device context
pDC->RestoreDC(-1);
}