3 * Copyright (C) 2005 Pat Thoyts <patthoyts@users.sourceforge.net>
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * A copy of the license is also included in the source distribution
12 * of Jim, as a TXT file name called LICENSE.
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
22 #include "jimautoconf.h"
24 /* Apparently windows.h and cygwin don't mix, but we seem to get
25 * away with it here. Use at your own risk under cygwin
27 #if defined(__CYGWIN__)
28 #define WIN32_LEAN_AND_MEAN
38 #pragma comment(lib, "shell32")
39 #pragma comment(lib, "user32")
40 #pragma comment(lib, "advapi32")
41 #pragma comment(lib, "psapi")
42 #endif /* _MSC_VER >= 1000 */
45 Win32ErrorObj(Jim_Interp
*interp
, const char * szPrefix
, DWORD dwError
)
47 Jim_Obj
*msgObj
= NULL
;
48 char * lpBuffer
= NULL
;
51 dwLen
= FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER
52 | FORMAT_MESSAGE_FROM_SYSTEM
, NULL
, dwError
, LANG_NEUTRAL
,
53 (char *)&lpBuffer
, 0, NULL
);
55 dwLen
= FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER
56 | FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_ARGUMENT_ARRAY
,
57 "code 0x%1!08X!%n", 0, LANG_NEUTRAL
,
58 (char *)&lpBuffer
, 0, (va_list *)&dwError
);
61 msgObj
= Jim_NewStringObj(interp
, szPrefix
, -1);
63 char *p
= lpBuffer
+ dwLen
- 1; /* remove cr-lf at end */
64 for ( ; p
&& *p
&& isspace(UCHAR(*p
)); p
--)
67 Jim_AppendString(interp
, msgObj
, ": ", 2);
68 Jim_AppendString(interp
, msgObj
, lpBuffer
, -1);
70 LocalFree((HLOCAL
)lpBuffer
);
74 /* win32.ShellExecute verb file args */
76 Win32_ShellExecute(Jim_Interp
*interp
, int objc
, Jim_Obj
* const *objv
)
79 const char *verb
, *file
, *parm
= NULL
;
80 char cwd
[MAX_PATH
+ 1];
82 if (objc
< 3 || objc
> 4) {
83 Jim_WrongNumArgs(interp
, 1, objv
, "verb path ?parameters?");
86 verb
= Jim_String(objv
[1]);
87 file
= Jim_String(objv
[2]);
88 GetCurrentDirectoryA(MAX_PATH
+ 1, cwd
);
90 parm
= Jim_String(objv
[3]);
91 r
= (int)ShellExecuteA(NULL
, verb
, file
, parm
, cwd
, SW_SHOWNORMAL
);
94 Win32ErrorObj(interp
, "ShellExecute", GetLastError()));
95 return (r
< 33) ? JIM_ERR
: JIM_OK
;
99 /* win32.FindWindow title ?class? */
101 Win32_FindWindow(Jim_Interp
*interp
, int objc
, Jim_Obj
* const *objv
)
103 const char *title
= NULL
, *class = NULL
;
107 if (objc
< 2 || objc
> 3) {
108 Jim_WrongNumArgs(interp
, 1, objv
, "title ?class?");
111 title
= Jim_String(objv
[1]);
113 class = Jim_String(objv
[2]);
114 hwnd
= FindWindowA(class, title
);
117 Jim_SetResult(interp
,
118 Win32ErrorObj(interp
, "FindWindow", GetLastError()));
121 Jim_SetResult(interp
, Jim_NewIntObj(interp
, (long)hwnd
));
126 /* win32.CloseWindow windowHandle */
128 Win32_CloseWindow(Jim_Interp
*interp
, int objc
, Jim_Obj
* const *objv
)
133 Jim_WrongNumArgs(interp
, 1, objv
, "?windowHandle?");
136 if (Jim_GetLong(interp
, objv
[1], &hwnd
) != JIM_OK
)
138 if (!CloseWindow((HWND
)hwnd
)) {
139 Jim_SetResult(interp
,
140 Win32ErrorObj(interp
, "CloseWindow", GetLastError()));
147 Win32_GetActiveWindow(Jim_Interp
*interp
, int objc
, Jim_Obj
* const *objv
)
149 Jim_SetResult(interp
, Jim_NewIntObj(interp
, (DWORD
)GetActiveWindow()));
154 Win32_SetActiveWindow(Jim_Interp
*interp
, int objc
, Jim_Obj
* const *objv
)
160 Jim_WrongNumArgs(interp
, 1, objv
, "windowHandle");
163 r
= Jim_GetLong(interp
, objv
[1], (long *)&hwnd
);
165 old
= SetActiveWindow(hwnd
);
167 Jim_SetResult(interp
,
168 Win32ErrorObj(interp
, "SetActiveWindow", GetLastError()));
171 Jim_SetResult(interp
, Jim_NewIntObj(interp
, (long)old
));
178 Win32_SetForegroundWindow(Jim_Interp
*interp
, int objc
, Jim_Obj
* const *objv
)
184 Jim_WrongNumArgs(interp
, 1, objv
, "windowHandle");
187 r
= Jim_GetLong(interp
, objv
[1], (long *)&hwnd
);
189 if (!SetForegroundWindow(hwnd
)) {
190 Jim_SetResult(interp
,
191 Win32ErrorObj(interp
, "SetForegroundWindow", GetLastError()));
199 Win32_Beep(Jim_Interp
*interp
, int objc
, Jim_Obj
* const *objv
)
205 Jim_WrongNumArgs(interp
, 1, objv
, "freq duration");
208 r
= Jim_GetLong(interp
, objv
[1], &freq
);
210 r
= Jim_GetLong(interp
, objv
[2], &duration
);
211 if (freq
< 0x25) freq
= 0x25;
212 if (freq
> 0x7fff) freq
= 0x7fff;
214 if (!Beep(freq
, duration
)) {
215 Jim_SetResult(interp
,
216 Win32ErrorObj(interp
, "Beep", GetLastError()));
224 Win32_GetComputerName(Jim_Interp
*interp
, int objc
, Jim_Obj
* const *objv
)
226 char name
[MAX_COMPUTERNAME_LENGTH
+ 1];
227 DWORD size
= MAX_COMPUTERNAME_LENGTH
;
231 Jim_WrongNumArgs(interp
, 1, objv
, "");
235 if (GetComputerNameA(name
, &size
)) {
236 Jim_Obj
*nameObj
= Jim_NewStringObj(interp
, name
, size
);
237 Jim_SetResult(interp
, nameObj
);
239 Jim_SetResult(interp
,
240 Win32ErrorObj(interp
, "GetComputerName", GetLastError()));
248 Win32_GetUserName(Jim_Interp
*interp
, int objc
, Jim_Obj
* const *objv
)
250 char name
[UNLEN
+ 1];
255 Jim_WrongNumArgs(interp
, 1, objv
, "");
259 if (GetUserNameA(name
, &size
)) {
260 Jim_Obj
*nameObj
= Jim_NewStringObj(interp
, name
, size
);
261 Jim_SetResult(interp
, nameObj
);
263 Jim_SetResult(interp
,
264 Win32ErrorObj(interp
, "GetUserName", GetLastError()));
272 Win32_GetModuleFileName(Jim_Interp
*interp
, int objc
, Jim_Obj
* const *objv
)
274 HMODULE hModule
= NULL
;
279 Jim_WrongNumArgs(interp
, 1, objv
, "?moduleid?");
284 if (Jim_GetLong(interp
, objv
[1], (long *)&hModule
) != JIM_OK
) {
289 len
= GetModuleFileNameA(hModule
, path
, MAX_PATH
);
291 Jim_Obj
*pathObj
= Jim_NewStringObj(interp
, path
, len
);
292 Jim_SetResult(interp
, pathObj
);
294 Jim_SetResult(interp
,
295 Win32ErrorObj(interp
, "GetModuleFileName", GetLastError()));
303 Win32_GetVersion(Jim_Interp
*interp
, int objc
, Jim_Obj
* const *objv
)
305 Jim_SetResult(interp
, Jim_NewIntObj(interp
, GetVersion()));
310 Win32_GetTickCount(Jim_Interp
*interp
, int objc
, Jim_Obj
* const *objv
)
312 Jim_SetResult(interp
, Jim_NewIntObj(interp
, GetTickCount()));
317 Win32_GetSystemTime(Jim_Interp
*interp
, int objc
, Jim_Obj
* const *objv
)
324 #define JIMADD(name) \
325 a[n++] = Jim_NewStringObj(interp, #name, -1); \
326 a[n++] = Jim_NewIntObj(interp, t.w ## name )
335 JIMADD(Milliseconds
);
338 Jim_SetResult(interp
, Jim_NewListObj(interp
, a
, n
));
342 /* function not available on mingw or cygwin */
343 #if !defined(__MINGW32__) && !defined(__CYGWIN__)
344 // FIX ME: win2k+ so should do version checks really.
346 Win32_GetPerformanceInfo(Jim_Interp
*interp
, int objc
, Jim_Obj
* const *objv
)
350 PERFORMANCE_INFORMATION pi
;
352 if (!GetPerformanceInfo(&pi
, sizeof(pi
))) {
353 Jim_SetResult(interp
,
354 Win32ErrorObj(interp
, "GetPerformanceInfo", GetLastError()));
358 #define JIMADD(name) \
359 a[n++] = Jim_NewStringObj(interp, #name, -1); \
360 a[n++] = Jim_NewIntObj(interp, pi. name )
365 JIMADD(PhysicalTotal
);
366 JIMADD(PhysicalAvailable
);
370 JIMADD(KernelNonpaged
);
373 JIMADD(ProcessCount
);
377 Jim_SetResult(interp
, Jim_NewListObj(interp
, a
, n
));
383 Win32_SetComputerName(Jim_Interp
*interp
, int objc
, Jim_Obj
* const *objv
)
388 Jim_WrongNumArgs(interp
, 1, objv
, "computername");
391 name
= Jim_String(objv
[1]);
392 if (!SetComputerNameA(name
)) {
393 Jim_SetResult(interp
,
394 Win32ErrorObj(interp
, "SetComputerName", GetLastError()));
401 Win32_GetModuleHandle(Jim_Interp
*interp
, int objc
, Jim_Obj
* const *objv
)
403 HMODULE hModule
= NULL
;
404 const char *name
= NULL
;
406 if (objc
< 1 || objc
> 2) {
407 Jim_WrongNumArgs(interp
, 1, objv
, "?name?");
411 name
= Jim_String(objv
[1]);
412 hModule
= GetModuleHandleA(name
);
413 if (hModule
== NULL
) {
414 Jim_SetResult(interp
,
415 Win32ErrorObj(interp
, "GetModuleHandle", GetLastError()));
418 Jim_SetResult(interp
, Jim_NewIntObj(interp
, (unsigned long)hModule
));
423 Win32_LoadLibrary(Jim_Interp
*interp
, int objc
, Jim_Obj
* const *objv
)
427 Jim_WrongNumArgs(interp
, 1, objv
, "path");
430 hLib
= LoadLibraryA(Jim_String(objv
[1]));
432 Jim_SetResult(interp
,
433 Win32ErrorObj(interp
, "LoadLibrary", GetLastError()));
436 Jim_SetResult(interp
, Jim_NewIntObj(interp
, (unsigned long)hLib
));
441 Win32_FreeLibrary(Jim_Interp
*interp
, int objc
, Jim_Obj
* const *objv
)
443 HMODULE hModule
= NULL
;
447 Jim_WrongNumArgs(interp
, 1, objv
, "hmodule");
451 r
= Jim_GetLong(interp
, objv
[1], (long *)&hModule
);
453 if (!FreeLibrary(hModule
)) {
454 Jim_SetResult(interp
,
455 Win32ErrorObj(interp
, "FreeLibrary", GetLastError()));
464 /* ---------------------------------------------------------------------- */
467 Jim_win32Init(Jim_Interp
*interp
)
469 if (Jim_PackageProvide(interp
, "win32", "1.0", JIM_ERRMSG
))
473 Jim_CreateCommand(interp, "win32." #name , Win32_ ## name , NULL, NULL)
478 CMD(GetActiveWindow
);
479 CMD(SetActiveWindow
);
480 CMD(SetForegroundWindow
);
482 CMD(GetComputerName
);
483 CMD(SetComputerName
);
485 CMD(GetModuleFileName
);
489 #if !defined(__MINGW32__) && !defined(__CYGWIN__)
490 CMD(GetPerformanceInfo
);
492 CMD(GetModuleHandle
);