From 35bc1d560ee36deb1bd03b18570f6dfb0e6b6094 Mon Sep 17 00:00:00 2001 From: bubuzi Date: Tue, 9 May 2023 15:51:30 +0800 Subject: [PATCH] Change Nan to Napi --- binding.gyp | 17 +++--- lib/index.js | 5 +- package.json | 11 ++-- src/clip_win.cc | 140 ++++++++++++++++++++++++++++++------------------ src/clip_win.h | 16 ++---- src/main.cc | 53 +++++++----------- test/index.js | 5 +- 7 files changed, 124 insertions(+), 123 deletions(-) diff --git a/binding.gyp b/binding.gyp index b0171e0..626ea45 100644 --- a/binding.gyp +++ b/binding.gyp @@ -1,10 +1,14 @@ { "targets": [{ "target_name": "binding", + "cflags!": [ "-fno-exceptions" ], # 忽略编译时异常 + "cflags_cc!": [ "-fno-exceptions" ], # 忽略编译时异常 "sources": [ "src/main.cc" ], - "include_dirs": [" get_file_names(Isolate *isolate) +Napi::Value get_file_names(const Napi::CallbackInfo &info) { - Local fileNames = Array::New(isolate, 0); - Local context = isolate->GetCurrentContext(); - if (OpenClipboard(NULL)) // open clipboard - { - HDROP hDrop = HDROP(::GetClipboardData(CF_HDROP)); // get the file path hwnd of clipboard - if (hDrop != NULL) - { - char szFilePathName[MAX_PATH + 1] = { 0 }; - UINT nNumOfFiles = DragQueryFile(hDrop, 0xFFFFFFFF, NULL, 0); // get the count of files - fileNames = Array::New(isolate, nNumOfFiles); - for (UINT nIndex = 0; nIndex < nNumOfFiles; ++nIndex) - { - memset(szFilePathName, 0, MAX_PATH + 1); - DragQueryFile(hDrop, nIndex, szFilePathName, MAX_PATH); // get file name - fileNames->Set(context, nIndex, String::NewFromUtf8(isolate, GBK2Utf8(szFilePathName), NewStringType::kNormal).ToLocalChecked()); - } - } - CloseClipboard(); // close clipboard - } - return fileNames; + + Napi::Env env = info.Env(); + // uint32_t index = 0; + + Napi::Array fileNames; + if (OpenClipboard(NULL)) // open clipboard + { + HDROP hDrop = HDROP(::GetClipboardData(CF_HDROP)); // get the file path hwnd of clipboard + if (hDrop != NULL) + { + char szFilePathName[MAX_PATH + 1] = {0}; + + UINT nNumOfFiles = DragQueryFile(hDrop, 0xFFFFFFFF, NULL, 0); // get the count of files + fileNames = Napi::Array::New(env, nNumOfFiles); + for (UINT nIndex = 0; nIndex < nNumOfFiles; ++nIndex) + { + memset(szFilePathName, 0, MAX_PATH + 1); + + DragQueryFile(hDrop, nIndex, (LPSTR)szFilePathName, MAX_PATH); // get file name + fileNames.Set(nIndex, Napi::String::New(env, GBK2Utf8(szFilePathName))); + } + } + CloseClipboard(); // close clipboard + } + return fileNames; } -std::wstring stringToWstring(const std::string& str) +std::wstring stringToWstring(const std::string &str) { int nLen = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, NULL, 0); - if (nLen == 0) + if (nLen == 0) return std::wstring(L""); - wchar_t* wide = new wchar_t[nLen]; - if (!wide) + wchar_t *wide = new wchar_t[nLen]; + if (!wide) return std::wstring(L""); MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, wide, nLen); @@ -55,17 +60,43 @@ std::wstring stringToWstring(const std::string& str) return wstr; } -void write_file_names(Isolate *isolate, Local fileNames) +Napi::Value write_file_names(const Napi::CallbackInfo &info) { - Local context = isolate->GetCurrentContext(); - + Napi::Env env = info.Env(); + if (info.Length() != 1) + { + Napi::Error::New(env, "Expected exactly one argument") + .ThrowAsJavaScriptException(); + return env.Undefined(); + } + if (!(info[0].IsArray() || info[0].IsString())) + { + Napi::Error::New(env, "Expect a string or array of strings") + .ThrowAsJavaScriptException(); + return env.Undefined(); + } std::vector files; - for (size_t i = 0; i < fileNames->Length(); i++) { - MaybeLocal maybeIndex = fileNames->Get(context, i); - Local index = maybeIndex.ToLocalChecked(); - String::Utf8Value path(isolate, index); - std::string pathStr(*path); - files.push_back(stringToWstring(pathStr)); + if (info[0].IsArray()) + { + Napi::Array fileNames = info[0].As(); + + for (size_t i = 0; i < fileNames.Length(); i++) + { + Napi::Value item = fileNames.Get(i); + if (!item.IsString()) + { + Napi::Error::New(env, "Expect a string or array of strings") + .ThrowAsJavaScriptException(); + return info.Env().Undefined(); + } + std::string filename = item.ToString(); + files.push_back(stringToWstring(filename)); + } + } + else + { + std::string filename = info[0].As(); + files.push_back(stringToWstring(filename)); } size_t bytes = sizeof(DROPFILES); @@ -74,23 +105,26 @@ void write_file_names(Isolate *isolate, Local fileNames) bytes += sizeof(wchar_t); HANDLE hdata = ::GlobalAlloc(GMEM_MOVEABLE, bytes); if (!hdata) - return; - DROPFILES* drop_files = static_cast(::GlobalLock(hdata)); + return env.Undefined(); + DROPFILES *drop_files = static_cast(::GlobalLock(hdata)); drop_files->pFiles = sizeof(DROPFILES); drop_files->fWide = TRUE; - BYTE* data = reinterpret_cast(drop_files) + sizeof(DROPFILES); + BYTE *data = reinterpret_cast(drop_files) + sizeof(DROPFILES); // Copy the strings stored in 'files' with proper NULL separation. - wchar_t* data_pos = reinterpret_cast(data); - for (size_t i = 0; i < files.size(); ++i) { + wchar_t *data_pos = reinterpret_cast(data); + for (size_t i = 0; i < files.size(); ++i) + { size_t offset = files[i].length() + 1; memcpy(data_pos, files[i].c_str(), offset * sizeof(wchar_t)); data_pos += offset; - } - data_pos[0] = L'\0'; // Double NULL termination after the last string. + } + data_pos[0] = L'\0'; // Double NULL termination after the last string. ::GlobalUnlock(hdata); - if (OpenClipboard(NULL)) { + if (OpenClipboard(NULL)) + { EmptyClipboard(); SetClipboardData(CF_HDROP, hdata); CloseClipboard(); - } + } + return env.Undefined(); } diff --git a/src/clip_win.h b/src/clip_win.h index 2ffb65b..489d12e 100644 --- a/src/clip_win.h +++ b/src/clip_win.h @@ -1,22 +1,12 @@ #include -#include +#include #include #include #include #include using namespace std; -using v8::Context; -using v8::Array; -using v8::FunctionCallbackInfo; -using v8::Isolate; -using v8::Local; -using v8::MaybeLocal; -using v8::Object; -using v8::String; -using v8::NewStringType; -using v8::Value; -Local get_file_names(Isolate *isolate); +Napi::Value get_file_names(const Napi::CallbackInfo &info); -void write_file_names(Isolate *isolate, Local fileNames); \ No newline at end of file +Napi::Value write_file_names(const Napi::CallbackInfo &info); \ No newline at end of file diff --git a/src/main.cc b/src/main.cc index 64acea7..811e243 100644 --- a/src/main.cc +++ b/src/main.cc @@ -1,44 +1,27 @@ -#include +#include #ifdef __WIN32__ #include "clip_win.h" #elif __APPLE__ #include "clip_osx.h" #endif -namespace clipboard -{ - using v8::Context; - using v8::Array; - using v8::FunctionCallbackInfo; - using v8::Isolate; - using v8::Local; - using v8::MaybeLocal; - using v8::Object; - using v8::String; - using v8::NewStringType; - using v8::Value; - - void readFiles(const FunctionCallbackInfo &args) - { - Isolate *isolate = args.GetIsolate(); - Local fileNames = get_file_names(isolate); - args.GetReturnValue().Set(fileNames); - } +Napi::Value get_file_names(const Napi::CallbackInfo &info); - void writeFiles(const FunctionCallbackInfo &args) - { - if (args[0]->IsArray()) { - Isolate *isolate = args.GetIsolate(); - Local array = Local::Cast(args[0]); - write_file_names(isolate, array); - } - } +Napi::Value write_file_names(const Napi::CallbackInfo &info); - void Init(Local exports) - { - NODE_SET_METHOD(exports, "readFiles", readFiles); - NODE_SET_METHOD(exports, "writeFiles", writeFiles); - } +static Napi::Value readFiles(const Napi::CallbackInfo &info) +{ + return get_file_names(info); +} +static Napi::Value writeFiles(const Napi::CallbackInfo &info) +{ + return write_file_names(info); +} +static Napi::Object Init(Napi::Env env, Napi::Object exports) +{ + exports["readFiles"] = Napi::Function::New(env, readFiles); + exports["writeFiles"] = Napi::Function::New(env, writeFiles); + return exports; +} - NODE_MODULE(NODE_GYP_MODULE_NAME, Init) -} \ No newline at end of file +NODE_API_MODULE(NODE_GYP_MODULE_NAME, Init) \ No newline at end of file diff --git a/test/index.js b/test/index.js index 99a0cfe..149473a 100644 --- a/test/index.js +++ b/test/index.js @@ -1,7 +1,8 @@ -const clipboard = require("../lib"); +const { join } = require('path') +const clipboard = require(`../lib`) if (process.platform === 'darwin') { clipboard.writeFiles(['/Users/Alex/Download/helloWorld.js']); // rewrite an existing path } else if (process.platform === 'win32') { - clipboard.writeFiles(['C:\\Users\\Alex\\Documents\\helloWorld.js']); // rewrite an existing path + clipboard.writeFiles(join(__dirname, "helloWorld.js")); // rewrite an existing path } console.log("files:", clipboard.readFiles()); \ No newline at end of file