Winapi 如何使用MFC函数绘制曲线文本?

Winapi 如何使用MFC函数绘制曲线文本?,winapi,mfc,Winapi,Mfc,如何使用MFC函数绘制曲线文本?我想实现如下目标 函数的作用是:只在直线上绘制文本,我不知道如何以特定角度绘制曲线文本。请帮帮我 谢谢。您可以使用GDI+,中有一个用C#编写的示例,我将其翻译成C++: Graphics graphics(hWnd); RECT rect = { 0 }; GetWindowRect(hWnd, &rect); POINT center = { (rect.right - rect.left) / 2,(rect.bo

如何使用MFC函数绘制曲线文本?我想实现如下目标

函数的作用是:只在直线上绘制文本,我不知道如何以特定角度绘制曲线文本。请帮帮我


谢谢。

您可以使用GDI+,中有一个用C#编写的示例,我将其翻译成C++:

    Graphics graphics(hWnd);

    RECT rect = { 0 };
    GetWindowRect(hWnd, &rect);
    POINT center = { (rect.right - rect.left) / 2,(rect.bottom - rect.top) / 2 };
    double radius = min(rect.right - rect.left, (rect.bottom - rect.top)) / 3;
    TCHAR text[] = L"ABCDEFGHIJLKMNOPQRSTUVWXYZ";
    REAL emSize = 24;
    Font* font = new Font(FontFamily::GenericSansSerif(), emSize, FontStyleBold);
    for (int i = 0; i < _tcslen(text); ++i)
    {
        RectF re, in;
        Status result = graphics.MeasureString(&text[i], 1, font, in, &re);;

        double charRadius = radius + re.Height;

        double angle = (((float)i / _tcslen(text)) - 0.25) * 2 * M_PI;

        double x = (int)(center.x + cos(angle) * charRadius);
        double y = (int)(center.y + sin(angle) * charRadius);


        result = graphics.TranslateTransform(x, y);

        result = graphics.RotateTransform((float)(90 + 360 * angle / (2 * M_PI)));
        PointF start(0, 0);
        SolidBrush Red(Color(255, 255, 0, 0));
        result = graphics.DrawString(&text[i], 1, font, start, &Red);

        result = graphics.ResetTransform();

        SolidBrush Green(Color(255, 0, 255, 0));
        Pen* pen = new Pen(&Green, 2.0f);
        result = graphics.DrawArc(pen, (REAL)(center.x - radius), (REAL)(center.y - radius), radius * 2, radius * 2, 0, 360);
    }
结果:

更新:

    Graphics graphics(hWnd);

    RECT rect = { 0 };
    GetWindowRect(hWnd, &rect);
    POINT center = { (rect.right - rect.left) / 2,(rect.bottom - rect.top) / 2 };
    double radius = min(rect.right - rect.left, (rect.bottom - rect.top)) / 3;
    TCHAR text[72][4] = { 0 };
    for (int i = 0; i < 72; i++)
    {
         _itot((i/2)*10, text[i],10);
         i++;
         _tcscpy(text[i],L"");
    }
    REAL emSize = 8;
    Font* font = new Font(FontFamily::GenericSansSerif(), emSize, FontStyleBold);
    for (int i = 0; i < 72; ++i)
    {
        RectF re, in,rel;
        Status result = graphics.MeasureString(text[i], _tcslen(text[i]), font, in, &re);
        result = graphics.MeasureString(L"|", 1, font, in, &rel);
        double charRadius = radius - re.Height;

        double angle = (((float)i / 72) - 0.25) * 2 * M_PI;

        double x = (center.x + cos(angle) * charRadius);
        double y = (center.y + sin(angle) * charRadius);


        result = graphics.TranslateTransform(x, y);

        result = graphics.RotateTransform((float)(90 + 360 * angle / (2 * M_PI)));
        PointF start(0- re.Width/2, 0);
        SolidBrush Red(Color(255, 255, 0, 0));
        result = graphics.DrawString(text[i], _tcslen(text[i]), font, start, &Red);
        result = graphics.ResetTransform();

        x = (int)(center.x + cos(angle) * radius);
        y = (int)(center.y + sin(angle) * radius);
        result = graphics.TranslateTransform(x, y);
        result = graphics.RotateTransform((float)(90 + 360 * angle / (2 * M_PI)));

        PointF start1(0 - rel.Width / 2, 0);
        result = graphics.DrawString(L"|", 1, font, start1, &Red);
        result = graphics.ResetTransform();
    }
    SolidBrush Green(Color(255, 0, 255, 0));
    Pen* pen = new Pen(&Green, 2.0f);
    Status result = graphics.DrawArc(pen, (REAL)(center.x - radius), (REAL)(center.y - radius), radius * 2, radius * 2, 0, 360);
图形(hWnd);
RECT RECT={0};
GetWindowRect(hWnd和&rect);
点中心={(rect.right-rect.left)/2,(rect.bottom-rect.top)/2};
双半径=最小值(右直-左直,(下直-上直))/3;
TCHAR text[72][4]={0};
对于(int i=0;i<72;i++)
{
_itot((i/2)*10,文本[i],10);
i++;
_tcscpy(文本[i],L“);
}
实际emSize=8;
Font*Font=新字体(FontFamily::GenericSansSerif(),emSize,FontStyleBold);
对于(int i=0;i<72;++i)
{
RectF-re,in,rel;
状态结果=graphics.MeasureString(文本[i],_tcslen(文本[i]),字体,输入,&re);
结果=图形.MeasureString(L“|”,1,font,in,&rel);
双半径=半径-再高度;
双角度=((浮动)i/72)-0.25)*2*M_-PI;
双x=(中心x+cos(角度)*半径);
双y=(中心y+sin(角度)*半径);
结果=图形。TranslateTransform(x,y);
结果=图形。旋转变换((浮动)(90+360*角度/(2*M_-PI));
点F开始(0-重新宽度/2,0);
SolidBrush红色(颜色(255,255,0,0));
结果=graphics.DrawString(文本[i]、_tcslen(文本[i])、字体、开始和红色);
结果=graphics.ResetTransform();
x=(int)(中心x+cos(角度)*半径);
y=(int)(中心y+sin(角度)*半径);
结果=图形。TranslateTransform(x,y);
结果=图形。旋转变换((浮动)(90+360*角度/(2*M_-PI));
点F起点1(0-相对宽度/2,0);
结果=graphics.DrawString(L“|”,1,font,start1,&红色);
结果=graphics.ResetTransform();
}
SolidBrush绿色(颜色(255,0,255,0));
钢笔*钢笔=新钢笔(&绿色,2.0f);
状态结果=graphics.DrawArc(笔,(实)(中心x-半径),(实)(中心y-半径),半径*2,半径*2,0,360);
结果:


您可以使用GDI+,中有一个用C#编写的示例,我将其翻译成C++:

    Graphics graphics(hWnd);

    RECT rect = { 0 };
    GetWindowRect(hWnd, &rect);
    POINT center = { (rect.right - rect.left) / 2,(rect.bottom - rect.top) / 2 };
    double radius = min(rect.right - rect.left, (rect.bottom - rect.top)) / 3;
    TCHAR text[] = L"ABCDEFGHIJLKMNOPQRSTUVWXYZ";
    REAL emSize = 24;
    Font* font = new Font(FontFamily::GenericSansSerif(), emSize, FontStyleBold);
    for (int i = 0; i < _tcslen(text); ++i)
    {
        RectF re, in;
        Status result = graphics.MeasureString(&text[i], 1, font, in, &re);;

        double charRadius = radius + re.Height;

        double angle = (((float)i / _tcslen(text)) - 0.25) * 2 * M_PI;

        double x = (int)(center.x + cos(angle) * charRadius);
        double y = (int)(center.y + sin(angle) * charRadius);


        result = graphics.TranslateTransform(x, y);

        result = graphics.RotateTransform((float)(90 + 360 * angle / (2 * M_PI)));
        PointF start(0, 0);
        SolidBrush Red(Color(255, 255, 0, 0));
        result = graphics.DrawString(&text[i], 1, font, start, &Red);

        result = graphics.ResetTransform();

        SolidBrush Green(Color(255, 0, 255, 0));
        Pen* pen = new Pen(&Green, 2.0f);
        result = graphics.DrawArc(pen, (REAL)(center.x - radius), (REAL)(center.y - radius), radius * 2, radius * 2, 0, 360);
    }
结果:

更新:

    Graphics graphics(hWnd);

    RECT rect = { 0 };
    GetWindowRect(hWnd, &rect);
    POINT center = { (rect.right - rect.left) / 2,(rect.bottom - rect.top) / 2 };
    double radius = min(rect.right - rect.left, (rect.bottom - rect.top)) / 3;
    TCHAR text[72][4] = { 0 };
    for (int i = 0; i < 72; i++)
    {
         _itot((i/2)*10, text[i],10);
         i++;
         _tcscpy(text[i],L"");
    }
    REAL emSize = 8;
    Font* font = new Font(FontFamily::GenericSansSerif(), emSize, FontStyleBold);
    for (int i = 0; i < 72; ++i)
    {
        RectF re, in,rel;
        Status result = graphics.MeasureString(text[i], _tcslen(text[i]), font, in, &re);
        result = graphics.MeasureString(L"|", 1, font, in, &rel);
        double charRadius = radius - re.Height;

        double angle = (((float)i / 72) - 0.25) * 2 * M_PI;

        double x = (center.x + cos(angle) * charRadius);
        double y = (center.y + sin(angle) * charRadius);


        result = graphics.TranslateTransform(x, y);

        result = graphics.RotateTransform((float)(90 + 360 * angle / (2 * M_PI)));
        PointF start(0- re.Width/2, 0);
        SolidBrush Red(Color(255, 255, 0, 0));
        result = graphics.DrawString(text[i], _tcslen(text[i]), font, start, &Red);
        result = graphics.ResetTransform();

        x = (int)(center.x + cos(angle) * radius);
        y = (int)(center.y + sin(angle) * radius);
        result = graphics.TranslateTransform(x, y);
        result = graphics.RotateTransform((float)(90 + 360 * angle / (2 * M_PI)));

        PointF start1(0 - rel.Width / 2, 0);
        result = graphics.DrawString(L"|", 1, font, start1, &Red);
        result = graphics.ResetTransform();
    }
    SolidBrush Green(Color(255, 0, 255, 0));
    Pen* pen = new Pen(&Green, 2.0f);
    Status result = graphics.DrawArc(pen, (REAL)(center.x - radius), (REAL)(center.y - radius), radius * 2, radius * 2, 0, 360);
图形(hWnd);
RECT RECT={0};
GetWindowRect(hWnd和&rect);
点中心={(rect.right-rect.left)/2,(rect.bottom-rect.top)/2};
双半径=最小值(右直-左直,(下直-上直))/3;
TCHAR text[72][4]={0};
对于(int i=0;i<72;i++)
{
_itot((i/2)*10,文本[i],10);
i++;
_tcscpy(文本[i],L“);
}
实际emSize=8;
Font*Font=新字体(FontFamily::GenericSansSerif(),emSize,FontStyleBold);
对于(int i=0;i<72;++i)
{
RectF-re,in,rel;
状态结果=graphics.MeasureString(文本[i],_tcslen(文本[i]),字体,输入,&re);
结果=图形.MeasureString(L“|”,1,font,in,&rel);
双半径=半径-再高度;
双角度=((浮动)i/72)-0.25)*2*M_-PI;
双x=(中心x+cos(角度)*半径);
双y=(中心y+sin(角度)*半径);
结果=图形。TranslateTransform(x,y);
结果=图形。旋转变换((浮动)(90+360*角度/(2*M_-PI));
点F开始(0-重新宽度/2,0);
SolidBrush红色(颜色(255,255,0,0));
结果=graphics.DrawString(文本[i]、_tcslen(文本[i])、字体、开始和红色);
结果=graphics.ResetTransform();
x=(int)(中心x+cos(角度)*半径);
y=(int)(中心y+sin(角度)*半径);
结果=图形。TranslateTransform(x,y);
结果=图形。旋转变换((浮动)(90+360*角度/(2*M_-PI));
点F起点1(0-相对宽度/2,0);
结果=graphics.DrawString(L“|”,1,font,start1,&红色);
结果=graphics.ResetTransform();
}
SolidBrush绿色(颜色(255,0,255,0));
钢笔*钢笔=新钢笔(&绿色,2.0f);
状态结果=graphics.DrawArc(笔,(实)(中心x-半径),(实)(中心y-半径),半径*2,半径*2,0,360);
结果:


。您可能必须切换到使用
TextOut()
函数,因为我感觉
DrawText()
不支持转换。@Jonathan,在我的场景中,如何为SetWorldTransform构造XForm以及如何为TextOut()计算x,y位置。这是一个数学问题,不是编程问题。。您可能必须切换到使用
TextOut()
函数,因为我感觉
DrawText()
不支持转换。@Jonathan,在我的场景中,如何为SetWorldTransform构造XForm以及如何为TextOut()计算x,y位置。这是一个数学问题,这不是一个编程问题。我无法理解这个角度/弧度计算双角度=((浮点)I/72)-0.25)*2*M_π;结果=图形。旋转变换((浮动)(90+360*角度/(2*M_-PI));请解释。它计算第i个字符的坐标,并以度为单位旋转轴。这实际上是一个三角形变换。以下公式给出了相同的坐标和角度:
double angle=((float)i/72))*2*M_PI;双x=(中心x+sin(角度)*半径);双y=(中心y-角x半径);结果=图形。旋转变换((浮动)(360*角度/(2*M_-PI))我无法理解此角度/弧度计算双角度=((浮点)I/72)-0.25)*2*M_PI;结果=图形。旋转变换((浮动)(90+360*角度/(2*M_-PI));请解释。它计算第i个字符的坐标,并以度为单位旋转轴。这是事实