66#include < string>
77#include < windows.h>
88
9- typedef int (__stdcall* lp_GetScaleFactorForMonitor) (HMONITOR, DEVICE_SCALE_FACTOR*);
9+ typedef int (__stdcall* lp_GetScaleFactorForMonitor) (HMONITOR, DEVICE_SCALE_FACTOR*);
1010
1111struct Process {
1212 int pid;
@@ -18,6 +18,10 @@ T getValueFromCallbackData (const Napi::CallbackInfo& info, unsigned handleIndex
1818 return reinterpret_cast <T> (info[handleIndex].As <Napi::Number> ().Int64Value ());
1919}
2020
21+ std::wstring get_wstring (const std::string str) {
22+ return std::wstring (str.begin (), str.end ());
23+ }
24+
2125std::string toUtf8 (const std::wstring& str) {
2226 std::string ret;
2327 int len = WideCharToMultiByte (CP_UTF8, 0 , str.c_str (), str.length (), NULL , 0 , NULL , NULL );
@@ -45,6 +49,60 @@ Process getWindowProcess (HWND handle) {
4549 return { static_cast <int > (pid), path };
4650}
4751
52+ HWND find_top_window (DWORD pid) {
53+ std::pair<HWND, DWORD> params = { 0 , pid };
54+
55+ BOOL bResult = EnumWindows (
56+ [] (HWND hwnd, LPARAM lParam) -> BOOL {
57+ auto pParams = (std::pair<HWND, DWORD>*)(lParam);
58+
59+ DWORD processId;
60+ if (GetWindowThreadProcessId (hwnd, &processId) && processId == pParams->second ) {
61+ SetLastError (-1 );
62+ pParams->first = hwnd;
63+ return FALSE ;
64+ }
65+
66+ return TRUE ;
67+ },
68+ (LPARAM)¶ms);
69+
70+ if (!bResult && GetLastError () == -1 && params.first ) {
71+ return params.first ;
72+ }
73+
74+ return 0 ;
75+ }
76+
77+ Napi::Number getProcessMainWindow (const Napi::CallbackInfo& info) {
78+ Napi::Env env{ info.Env () };
79+
80+ unsigned long process_id = info[0 ].ToNumber ().Uint32Value ();
81+
82+ auto handle = find_top_window (process_id);
83+
84+ return Napi::Number::New (env, reinterpret_cast <int64_t > (handle));
85+ }
86+
87+ Napi::Number createProcess (const Napi::CallbackInfo& info) {
88+ Napi::Env env{ info.Env () };
89+
90+ auto path = info[0 ].ToString ().Utf8Value ();
91+
92+ std::string cmd = " " ;
93+
94+ if (info[1 ].IsString ()) {
95+ cmd = info[1 ].ToString ().Utf8Value ();
96+ }
97+
98+ STARTUPINFOA sInfo = { sizeof (sInfo ) };
99+ PROCESS_INFORMATION processInfo;
100+ CreateProcessA (path.c_str (), &cmd[0 ], NULL , NULL , FALSE ,
101+ CREATE_NEW_PROCESS_GROUP | CREATE_NEW_CONSOLE, NULL , NULL , &sInfo , &processInfo);
102+
103+ return Napi::Number::New (env, processInfo.dwProcessId );
104+ }
105+
48106Napi::Number getActiveWindow (const Napi::CallbackInfo& info) {
49107 Napi::Env env{ info.Env () };
50108
@@ -261,16 +319,16 @@ Napi::Boolean bringWindowToTop (const Napi::CallbackInfo& info) {
261319 auto handle{ getValueFromCallbackData<HWND> (info, 0 ) };
262320 BOOL b{ SetForegroundWindow (handle) };
263321
264- HWND hCurWnd = ::GetForegroundWindow ();
265- DWORD dwMyID = ::GetCurrentThreadId ();
266- DWORD dwCurID = ::GetWindowThreadProcessId (hCurWnd, NULL );
267- ::AttachThreadInput (dwCurID, dwMyID, TRUE );
268- ::SetWindowPos (handle, HWND_TOPMOST, 0 , 0 , 0 , 0 , SWP_NOSIZE | SWP_NOMOVE);
269- ::SetWindowPos (handle, HWND_NOTOPMOST, 0 , 0 , 0 , 0 , SWP_NOSIZE | SWP_NOMOVE);
270- ::SetForegroundWindow (handle);
271- ::AttachThreadInput (dwCurID, dwMyID, FALSE );
272- ::SetFocus (handle);
273- ::SetActiveWindow (handle);
322+ HWND hCurWnd = ::GetForegroundWindow ();
323+ DWORD dwMyID = ::GetCurrentThreadId ();
324+ DWORD dwCurID = ::GetWindowThreadProcessId (hCurWnd, NULL );
325+ ::AttachThreadInput (dwCurID, dwMyID, TRUE );
326+ ::SetWindowPos (handle, HWND_TOPMOST, 0 , 0 , 0 , 0 , SWP_NOSIZE | SWP_NOMOVE);
327+ ::SetWindowPos (handle, HWND_NOTOPMOST, 0 , 0 , 0 , 0 , SWP_NOSIZE | SWP_NOMOVE);
328+ ::SetForegroundWindow (handle);
329+ ::AttachThreadInput (dwCurID, dwMyID, FALSE );
330+ ::SetFocus (handle);
331+ ::SetActiveWindow (handle);
274332
275333 return Napi::Boolean::New (env, b);
276334}
@@ -357,6 +415,8 @@ Napi::Object Init (Napi::Env env, Napi::Object exports) {
357415 exports.Set (Napi::String::New (env, " getMonitorInfo" ), Napi::Function::New (env, getMonitorInfo));
358416 exports.Set (Napi::String::New (env, " getWindows" ), Napi::Function::New (env, getWindows));
359417 exports.Set (Napi::String::New (env, " getMonitors" ), Napi::Function::New (env, getMonitors));
418+ exports.Set (Napi::String::New (env, " createProcess" ), Napi::Function::New (env, createProcess));
419+ exports.Set (Napi::String::New (env, " getProcessMainWindow" ), Napi::Function::New (env, getProcessMainWindow));
360420
361421 return exports;
362422}
0 commit comments