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

如何在C++中将HWND转换为字符串?Node.js扩展场景需求

解决HWND转字符串并适配Node.js扩展的方案

核心问题拆解

你需要实现两个关键步骤:将HWND转换为十六进制字符串,以及在Windows窗口枚举回调中传递结果,最终暴露给Node.js调用。以下是完整的修正和实现代码:

完整代码实现(Node.js C++扩展)

#include <napi.h>
#include <windows.h>
#include <string>
#include <sstream>
#include <iomanip>

// 用于在枚举回调中传递数据的结构体
struct EnumData {
    std::string targetTitle;
    std::string resultHwnd;
    bool found;
};

// 将HWND转换为16位十六进制字符串(与cout输出格式一致)
std::string hwndToString(HWND hWnd) {
    std::stringstream ss;
    // 使用uintptr_t适配32/64位系统
    ss << std::hex << std::setw(16) << std::setfill('0') << reinterpret_cast<uintptr_t>(hWnd);
    return ss.str();
}

// 窗口枚举回调函数
static BOOL CALLBACK enumWindowCallback(HWND hWnd, LPARAM lparam) {
    EnumData* data = reinterpret_cast<EnumData*>(lparam);
    if (data->found) return FALSE; // 已找到目标,停止枚举

    // 获取窗口标题(用宽字符避免中文乱码)
    int titleLength = GetWindowTextLengthW(hWnd);
    if (titleLength == 0) return TRUE;

    std::wstring windowTitle(titleLength, L'\0');
    GetWindowTextW(hWnd, &windowTitle[0], titleLength + 1);

    // 转成UTF-8字符串适配Node.js
    std::string utf8Title;
    int utf8Size = WideCharToMultiByte(CP_UTF8, 0, windowTitle.c_str(), -1, nullptr, 0, nullptr, nullptr);
    if (utf8Size > 0) {
        utf8Title.resize(utf8Size - 1);
        WideCharToMultiByte(CP_UTF8, 0, windowTitle.c_str(), -1, &utf8Title[0], utf8Size, nullptr, nullptr);
    }

    // 匹配目标窗口标题
    if (IsWindowVisible(hWnd) && utf8Title == data->targetTitle) {
        data->resultHwnd = hwndToString(hWnd);
        data->found = true;
        return FALSE;
    }

    return TRUE;
}

// 暴露给Node.js的函数
Napi::String FindWindowByTitle(const Napi::CallbackInfo& info) {
    Napi::Env env = info.Env();

    // 参数校验
    if (info.Length() < 1 || !info[0].IsString()) {
        Napi::TypeError::New(env, "必须传入字符串类型的窗口标题").ThrowAsJavaScriptException();
        return Napi::String::New(env, "");
    }

    std::string targetTitle = info[0].As<Napi::String>();
    EnumData data{targetTitle, "", false};

    // 启动窗口枚举
    EnumWindows(enumWindowCallback, reinterpret_cast<LPARAM>(&data));

    return Napi::String::New(env, data.found ? data.resultHwnd : "");
}

// 扩展初始化
Napi::Object Init(Napi::Env env, Napi::Object exports) {
    exports.Set(Napi::String::New(env, "findWindowByTitle"),
                Napi::Function::New(env, FindWindowByTitle));
    return exports;
}

NODE_API_MODULE(window_finder, Init)

关键说明

  1. HWND转字符串:

    • 利用std::stringstream格式化十六进制输出,设置std::setw(16)和std::setfill('0')保证输出16位补零格式,和你之前cout输出的结果一致。
    • 用uintptr_t适配32/64位系统,避免指针转换问题。
  2. 窗口标题处理:

    • 使用Windows API的宽字符版本GetWindowTextW,避免中文等非ASCII字符乱码。
    • 通过WideCharToMultiByte将宽字符串转成UTF-8,适配Node.js的字符串编码。
  3. 回调数据传递:

    • 定义EnumData结构体存储目标标题、结果字符串和找到标志,通过LPARAM传递给回调函数,解决静态回调无法直接访问外部变量的问题。
  4. Node.js扩展适配:

    • 使用node-addon-api编写扩展,暴露findWindowByTitle函数给JS调用,调用时传入目标窗口标题即可返回HWND的十六进制字符串。

原代码问题修正

  • 原代码中int::main()语法错误,应为int main()。
  • 原代码用new char[]未释放内存,会导致泄漏,改用std::wstring自动管理内存。
  • 原代码用char处理窗口标题可能引发乱码,改用宽字符API解决。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 19:01:01