You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Visual C++ 6中标签旋转功能失效问题求助

VC++6 标签旋转功能失效的问题修正

问题根源梳理

你的代码存在三个核心问题导致旋转未生效:

  1. 旋转原点错误:当前的XFORM是绕屏幕坐标原点(0,0)旋转,而非目标标签的中点,所以视觉上看不到旋转效果
  2. 变换重置逻辑错误:使用SetWorldTransform(meta_dc, &xform)无法恢复原始绘图变换,应该提前保存初始变换,绘制完成后再恢复
  3. 缺少平移补偿:绕中点旋转需要先将文本的中点平移到原点,旋转完成后再平移回原位置,这一步完全缺失

修正后的代码

void do_labely(
    HDC meta_dc,
    SLATE_REC *slate_rec,
    const DEFAULT_STYLE *styl,
    double x,
    double y,
    unsigned char *the_str,
    short just,
    short style_idx,
    short size,
    short stylebits,
    short color,
    short v_just,
    BOOL clip,
    double theta)
{
    LOGFONT lf;
    HFONT font, old_font;
    UINT align;
    XFORM old_xform;
    SIZE text_size;
    double rad = theta * PI / 180;
    int x1 = (int)(x * slate_rec->xscale);
    int y1 = (int)(y * slate_rec->yscale);

    // 保存原始变换和字体
    GetWorldTransform(meta_dc, &old_xform);
    old_font = (HFONT)SelectObject(meta_dc, GetStockObject(SYSTEM_FONT));

    // 设置字体
    setup_logfont(meta_dc, &styl[style_idx], size, &lf, slate_rec, stylebits);
    font = CreateFontIndirect(&lf);
    SelectObject(meta_dc, font);

    // 设置文本颜色
    switch (color) {
        case WHITE: SetTextColor(meta_dc, RGB(0xFF,0xFF,0xFF)); break;
        case RED: SetTextColor(meta_dc, RGB(0xFF,0x00,0x00)); break;
        case GREEN: SetTextColor(meta_dc, RGB(0x00,0xFF,0x00)); break;
        case BLUE: SetTextColor(meta_dc, RGB(0x00,0x00,0xFF)); break;
        default: SetTextColor(meta_dc, RGB(0x00,0x00,0x00)); break;
    }

    // 设置文本对齐方式
    align = 0;
    switch (just) {
        case TX_JUST_LEFT: align = TA_LEFT; break;
        case TX_JUST_CENTER: align = TA_CENTER; break;
        case TX_JUST_RIGHT: align = TA_RIGHT; break;
        default: align = TA_LEFT; break;
    }
    switch (v_just) {
        case TX_JUST_TOP: align += TA_TOP; break;
        case TX_JUST_BASE: align += TA_BASELINE; break;
        case TX_JUST_BOTTOM: align += TA_BOTTOM; break;
        default: align += TA_TOP; break;
    }
    SetTextAlign(meta_dc, align);

    // 启用高级绘图模式
    SetGraphicsMode(meta_dc, GM_ADVANCED);

    // 获取文本尺寸(用于计算中点偏移)
    GetTextExtentPoint32(meta_dc, (char*)the_str, strlen((char*)the_str), &text_size);

    // 构建变换矩阵:平移到原点 → 旋转 → 平移回原位置
    XFORM xform_translate_to_origin, xform_rotate, xform_translate_back;

    // 计算平移到原点的偏移(基于文本对齐方式)
    int offset_x = 0, offset_y = 0;
    if (just == TX_JUST_CENTER) offset_x = -text_size.cx / 2;
    else if (just == TX_JUST_RIGHT) offset_x = -text_size.cx;

    if (v_just == TX_JUST_BASE) offset_y = -text_size.cy / 2; // 基线对齐时取垂直中点
    else if (v_just == TX_JUST_BOTTOM) offset_y = -text_size.cy;

    // 平移到原点的变换
    xform_translate_to_origin.eM11 = 1.0f;
    xform_translate_to_origin.eM12 = 0.0f;
    xform_translate_to_origin.eM21 = 0.0f;
    xform_translate_to_origin.eM22 = 1.0f;
    xform_translate_to_origin.eDx = x1 + offset_x;
    xform_translate_to_origin.eDy = y1 + offset_y;

    // 旋转变换
    xform_rotate.eM11 = cos(rad);
    xform_rotate.eM12 = -sin(rad);
    xform_rotate.eM21 = sin(rad);
    xform_rotate.eM22 = cos(rad);
    xform_rotate.eDx = 0.0f;
    xform_rotate.eDy = 0.0f;

    // 平移回原位置的变换(偏移取反)
    xform_translate_back.eM11 = 1.0f;
    xform_translate_back.eM12 = 0.0f;
    xform_translate_back.eM21 = 0.0f;
    xform_translate_back.eM22 = 1.0f;
    xform_translate_back.eDx = -(x1 + offset_x);
    xform_translate_back.eDy = -(y1 + offset_y);

    // 应用变换:先平移到原点,再旋转,最后平移回原位置
    ModifyWorldTransform(meta_dc, &xform_translate_to_origin, MWT_LEFTMULTIPLY);
    ModifyWorldTransform(meta_dc, &xform_rotate, MWT_LEFTMULTIPLY);
    ModifyWorldTransform(meta_dc, &xform_translate_back, MWT_LEFTMULTIPLY);

    // 绘制文本
    TextOut(meta_dc, x1, y1, (char*)the_str, strlen((char*)the_str));

    // 恢复原始变换和字体
    SetWorldTransform(meta_dc, &old_xform);
    SelectObject(meta_dc, old_font);
    DeleteObject(font);
}

关键修正点说明

  • 保存并恢复原始变换:用GetWorldTransform提前保存初始绘图变换,完成绘制后用SetWorldTransform恢复,避免影响后续绘图
  • 调整旋转原点:通过两次平移变换,先将文本中点移到坐标原点,旋转后再移回原位置,确保绕自身中点旋转
  • 计算文本尺寸:用GetTextExtentPoint32获取文本宽高,结合对齐方式计算正确的平移偏移量,保证旋转后文本位置符合预期

内容的提问来源于stack exchange,提问作者user3239379

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 14:05:13