如何在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)
关键说明
HWND转字符串:
- 利用
std::stringstream格式化十六进制输出,设置std::setw(16)和std::setfill('0')保证输出16位补零格式,和你之前cout输出的结果一致。 - 用
uintptr_t适配32/64位系统,避免指针转换问题。
- 利用
窗口标题处理:
- 使用Windows API的宽字符版本
GetWindowTextW,避免中文等非ASCII字符乱码。 - 通过
WideCharToMultiByte将宽字符串转成UTF-8,适配Node.js的字符串编码。
- 使用Windows API的宽字符版本
回调数据传递:
- 定义
EnumData结构体存储目标标题、结果字符串和找到标志,通过LPARAM传递给回调函数,解决静态回调无法直接访问外部变量的问题。
- 定义
Node.js扩展适配:
- 使用
node-addon-api编写扩展,暴露findWindowByTitle函数给JS调用,调用时传入目标窗口标题即可返回HWND的十六进制字符串。
- 使用
原代码问题修正
- 原代码中
int::main()语法错误,应为int main()。 - 原代码用
new char[]未释放内存,会导致泄漏,改用std::wstring自动管理内存。 - 原代码用
char处理窗口标题可能引发乱码,改用宽字符API解决。
内容的提问来源于stack exchange,提问作者lakers5824
相关产品推荐
相关产品推荐

