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

如何获取Win32接口DrawText()将为其添加下划线的对应字符

你观察到的DrawText()给字符加下划线的逻辑,是对字符串中&前缀的助记符处理结果:单个&后的第一个字符会被标记为助记符并加下划线,连续&&会被渲染为单个&且不生成助记符。

你不需要自己实现解析逻辑,直接用Win32原生API就可以拿到结果,天然支持日文等多语言字符,实现方案如下:

解决方案

使用DrawTextW(宽字符版本,支持所有Unicode字符包括日文)配合专属标志位即可直接获取结果,完全和实际渲染逻辑一致,不会出现自行解析的偏差:

核心原理

调用DrawTextW时传入DT_CALCRECT + DT_PREFIXONLY标志组合:

  • DT_CALCRECT 让API只计算参数不实际绘制内容,不会产生UI副作用
  • DT_PREFIXONLY 让API仅处理助记符逻辑,返回值直接是助记符在原字符串中的下标

代码示例

#include <windows.h>
#include <string>

/**
 * 获取DrawText会加下划线的助记符
 * @param str 传入的原始字符串,宽字符版本支持日文等Unicode内容
 * @param drawTextFlags 你实际调用DrawText时用的其他标志位,保证和渲染逻辑一致
 * @return 会被加下划线的助记符,无有效助记符时返回0
 */
WCHAR GetUnderlineCharForDrawText(const std::wstring& str, UINT drawTextFlags = 0) {
    // 叠加核心标志位
    UINT calculateFlags = DT_CALCRECT | DT_PREFIXONLY | DT_SINGLELINE | drawTextFlags;
    RECT dummyRect = {0};
    HDC hdc = GetDC(NULL);

    int mnemonicIndex = DrawTextW(hdc, str.c_str(), static_cast<int>(str.size()), &dummyRect, calculateFlags);
    ReleaseDC(NULL, hdc);

    // 校验下标合法性
    if (mnemonicIndex < 0 || mnemonicIndex >= static_cast<int>(str.size())) {
        return 0;
    }
    return str[mnemonicIndex];
}

测试验证

传入你示例的字符串 L"my rando&m string" 调用该函数,返回结果就是 L'm',和你观察到的DrawText()渲染结果完全一致。

注意事项

如果你实际绘制时传入了DT_NOPREFIX标志,DrawText()会跳过助记符处理,不会有下划线字符,此时调用上述函数也会返回0,和实际表现对齐。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.09 17:21:01