Windows 使用DrawText或类似函数呈现下标

Windows 使用DrawText或类似函数呈现下标,windows,delphi,fonts,rendering,c++builder,Windows,Delphi,Fonts,Rendering,C++builder,问题很简单。如何在TStringGrid单元格中绘制以下文本 操作系统是Windows XP(或Windows Vista或Windows 7)。首选开发环境是C++ Builder 6,但我也接受Delphi的C++ Builder XE的解决方案。首选的API函数是DrawText,但如果存在比此更好的函数,则没有问题。字体名称为《泰晤士报新罗马版》,字体大小为11。目前我正在使用此方法渲染单元格内容(简化): void\uuuuFastCall TForm\uMain::StringGr

问题很简单。如何在TStringGrid单元格中绘制以下文本

操作系统是Windows XP(或Windows Vista或Windows 7)。首选开发环境是C++ Builder 6,但我也接受Delphi的C++ Builder XE的解决方案。首选的API函数是
DrawText
,但如果存在比此更好的函数,则没有问题。字体名称为《泰晤士报新罗马版》,字体大小为11。目前我正在使用此方法渲染单元格内容(简化):

void\uuuuFastCall TForm\uMain::StringGrid\uDrawCell(TObject*发送方,
int ACol、int ARow、TRect和Rect、TGRIDRAWSTATE)
{
TStringGrid*网格=(TStringGrid*)发送方;
if(grid==NULL)返回;
//1.背景
网格->画布->画笔->颜色=网格->颜色;
网格->画布->填充矩形(矩形);
//2.文本
网格->画布->字体->分配(网格->字体);//泰晤士报新罗马版,第11页
//水平定心
RECT RText=静态_转换(RECT);
AnsiString text=grid->Cells[ACol][ARow];
如果(!text.IsEmpty()){
int text_len=strlen(text.c_str());
大小;
memset(&size,0,sizeof(size));
GetTextExtentPoint32(网格->画布->句柄,text.c_str(),text_len,&size);
int offset_x=(Rect.Width()-size.cx)>>1;
RText.left+=offset\ux;RText.right+=offset\ux;
//渲染
DrawText(网格->画布->句柄,text.c_str(),text_len,&RText,DT_LEFT | DT_VCENTER | DT|u SINGLELINE);
}
}

有些字符的下标符号是特殊的unicode字符(例如,代码0x2081被指定为下标字符),但不幸的是,大写字母U并非如此。此外,并非所有字体都支持这些字符(例如,Times New Roman字体不支持代码范围0x2070-209F),请参阅Wikipedia文章。我正在寻找一个更通用的解决方案,就像那些由Microsoft Word实现的解决方案一样。MS Word可以使用Times New Roman字体将大写字母U作为下标。

如果要将某些字符作为上标,则必须在其前面加上^。同样,下标字符的前缀也必须为x

void\uu fastcall TForm\u Main::StringGrid\u DrawCell(TObject*发送方、int-ACol、int-ARow、TRect&Rect、TGridDrawState)
{
TStringGrid*网格=(TStringGrid*)发送方;
if(grid==NULL)
{
返回;
}
宽管柱wtext=L“φ_=120”;
if(wtext.IsEmpty())返回;
//布局
大小;
memset(&size,0,sizeof(size));
SSGetTextExtentPoint(网格->画布,wtext,大小);
int offset_x=(Rect.Width()-size.cx+1)>>1;//水平居中
RECT RText=静态_转换(RECT);
RText.left+=偏移量_x;
RText.right+=偏移量_x;
//渲染
SetBkMode(网格->画布->句柄,透明);
SSDrawText(网格->画布、wtext、RText、DT_左);
}
int-TForm_Main::SSGetTextExtentPoint(TCAVAS*画布、宽字符串文本、大小和大小)
{
//资料来源:http://www.codeproject.com/Articles/12660/Using-Subscripts-and-Superscripts-When-Showing-Tex
SaveDC(画布->句柄);
尺寸sz;
直截了当=
{0, 0, 0, 0};
HFONT oldFont;
LOGFONT-lf;
GetObject(画布->字体->句柄,大小(LOGFONT),&lf);
点接头、辅助接头、辅助接头、辅助接头;
//计算下标/上标大小和偏移量
bool use_pixel_unit=false;
如果(左前高度<0)
{
lf.lfHeight=MulDiv(-lf.lfHeight,72,GetDeviceCaps(canvas->Handle,LOGPIXELSY));
使用像素单位=真;
}
sub.x=lf.lf宽度/2;
sup.x=lf.lf宽度/2;
sub.y=lf.lf高度/3*2;
辅助y=lf.lf高度/3*2;
subofs.x=lf.lfWidth/2;
supofs.x=lf.lfWidth/2;
subofs.y=lf.lf高度/6;
supofs.y=lf.lf高度/3;
lf.lfWidth=sub.x;
lf.lfHeight=sub.y;
如果(使用像素单位)
{
lf.lfHeight=-MulDiv(lf.lfHeight,GetDeviceCaps(canvas->Handle,LOGPIXELSY),72);
}
HFONT子字体;
子字体=CreateFontIndirect(&lf);
lf.lfWidth=sup.x;
lf.lfHeight=sup.y;
HFONT-SupFont;
如果(使用像素单位)
{
lf.lfHeight=-MulDiv(lf.lfHeight,GetDeviceCaps(canvas->Handle,LOGPIXELSY),72);
}
SupFont=createfontfindirect(&lf);
宽字符串温度=文本;
tcharc;
//计算需要显示的文本的大小
做
{
int-x1=1,x2=1,x=1;
宽字符串s=“”;
c='';
bool bFind=true;
//查找第一个“^”或“389;”,表示子或上标
while(bFind)
{
x1=文本位置(L“^”);
x2=文本位置(L“”);
如果((x1==0)和&(x2==0))
{
x=0;
}
否则如果((x1>0)和&(x2>0))
{
x=最小值(x1,x2);
}
如果(x1>0),则为else
{
x=x1;
}
其他的
{
x=x2;
}
如果(x==0)
{
bFind=false;
x=文本长度()+1;
}
else if(x==text.Length())
{
bFind=false;
}
else if(text[x]!=text[x+1])
{
bFind=false;
c=文本[x];
}
其他的
{
x++;
}
s=s+text.SubString(1,x-1);
text.Delete(1,min(x,text.Length());
}
sz=画布->文本范围;
outRect.right+=sz.cx;
if((outRect.bottom-outRect.top)句柄,SupFont);
GetTextExtentPoint32W(canvas->Handle,text.c_bstr(),1,&sz);
outRect.right+=sz.cx+supofs.x;
删除(1,1);
选择对象(画布->手柄,旧字体);
打破
案例‘‘
oldFont=(HFONT)选择对象(画布->句柄,子字体);
GetTextExtentPoint32W(canvas->Handle,text.c_bstr(),1,&sz);
outRect.right+=sz.cx
var
  i,
  h,
  h3: integer;
  sup,
  sub: boolean;
begin
  with ACanvas, ARect do begin
    h:= textHeight('H');
    h3:= h div 3;
    brush.Style:= bsClear;
    moveTo(Left +1, Top +1);
    i:= 1;
    while i < Length(s) +1 do begin
      if s[i] = '^' then
        begin
          Inc(i);
          font.Height:= MulDiv(font.Height, 8, 10);
          textOut(penPos.X, penPos.Y -h3, s[i]);
          moveTo(penPos.X +1, penPos.Y +h3);
          font.Height:= h;
          Inc(i);
        end
      else if s[i] = '_' then
        begin
          Inc(i);
          font.Height:= MulDiv(font.Height, 8, 10);
          textOut(penPos.X, penPos.Y +h3, s[i]);
          moveTo(penPos.X +1, penPos.Y -h3);
          font.Height:= h;
          Inc(i);
        end
      else
        begin
          textOut(penPos.X, penPos.Y, s[i]);
          Inc(i);
          moveTo(penPos.X +1, penPos.Y);
        end;
    end;//  while
  end;
  sup:= Pos('^', S) > 0;
  sub:= Pos('_', S) > 0;
  if sup and sub then
    result:= MulDiv(h, 5, 3)
  else if sup or sub then
    result:= h +h3
  else
    result:= h;
end;//  SSTextLeft