4 * Copyright (C) 2005 Pat Thoyts <patthoyts@users.sourceforge.net>
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following
14 * disclaimer in the documentation and/or other materials
15 * provided with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY THE JIM TCL PROJECT ``AS IS'' AND ANY
18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
19 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
21 * JIM TCL PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
22 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
28 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 * The views and conclusions contained in the software and documentation
31 * are those of the authors and should not be interpreted as representing
32 * official policies, either expressed or implied, of the Jim Tcl Project.
37 /* Apparently windows.h and cygwin don't mix, but we seem to get
38 * away with it here. Use at your own risk under cygwin
40 #if defined(__CYGWIN__) || defined(__MINGW32__)
41 #define WIN32_LEAN_AND_MEAN
51 #pragma comment(lib, "shell32")
52 #pragma comment(lib, "user32")
53 #pragma comment(lib, "advapi32")
54 #pragma comment(lib, "psapi")
55 #endif /* _MSC_VER >= 1000 */
57 #if _WIN32_WINNT < 0x600
58 #define GetTickCount64 GetTickCount
62 Win32ErrorObj(Jim_Interp
*interp
, const char * szPrefix
, DWORD dwError
)
64 Jim_Obj
*msgObj
= NULL
;
65 char * lpBuffer
= NULL
;
68 dwLen
= FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER
69 | FORMAT_MESSAGE_FROM_SYSTEM
, NULL
, dwError
, LANG_NEUTRAL
,
70 (char *)&lpBuffer
, 0, NULL
);
72 dwLen
= FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER
73 | FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_ARGUMENT_ARRAY
,
74 "code 0x%1!08X!%n", 0, LANG_NEUTRAL
,
75 (char *)&lpBuffer
, 0, (va_list *)&dwError
);
78 msgObj
= Jim_NewStringObj(interp
, szPrefix
, -1);
80 char *p
= lpBuffer
+ dwLen
- 1; /* remove cr-lf at end */
81 for ( ; p
&& *p
&& isspace(UCHAR(*p
)); p
--)
84 Jim_AppendString(interp
, msgObj
, ": ", 2);
85 Jim_AppendString(interp
, msgObj
, lpBuffer
, -1);
87 LocalFree((HLOCAL
)lpBuffer
);
91 /* win32.ShellExecute verb file args */
93 Win32_ShellExecute(Jim_Interp
*interp
, int objc
, Jim_Obj
* const *objv
)
96 const char *verb
, *file
, *parm
= NULL
;
97 char cwd
[MAX_PATH
+ 1];
99 if (objc
< 3 || objc
> 4) {
100 Jim_WrongNumArgs(interp
, 1, objv
, "verb path ?parameters?");
103 verb
= Jim_String(objv
[1]);
104 file
= Jim_String(objv
[2]);
105 GetCurrentDirectoryA(MAX_PATH
+ 1, cwd
);
107 parm
= Jim_String(objv
[3]);
108 r
= (ptrdiff_t)ShellExecuteA(NULL
, verb
, file
, parm
, cwd
, SW_SHOWNORMAL
);
110 Jim_SetResult(interp
,
111 Win32ErrorObj(interp
, "ShellExecute", GetLastError()));
112 return (r
< 33) ? JIM_ERR
: JIM_OK
;
116 /* win32.FindWindow title ?class? */
118 Win32_FindWindow(Jim_Interp
*interp
, int objc
, Jim_Obj
* const *objv
)
120 const char *title
= NULL
, *class = NULL
;
124 if (objc
< 2 || objc
> 3) {
125 Jim_WrongNumArgs(interp
, 1, objv
, "title ?class?");
128 title
= Jim_String(objv
[1]);
130 class = Jim_String(objv
[2]);
131 hwnd
= FindWindowA(class, title
);
134 Jim_SetResult(interp
,
135 Win32ErrorObj(interp
, "FindWindow", GetLastError()));
138 Jim_SetResult(interp
, Jim_NewIntObj(interp
, (long)hwnd
));
143 /* win32.CloseWindow windowHandle */
145 Win32_CloseWindow(Jim_Interp
*interp
, int objc
, Jim_Obj
* const *objv
)
150 Jim_WrongNumArgs(interp
, 1, objv
, "?windowHandle?");
153 if (Jim_GetLong(interp
, objv
[1], &hwnd
) != JIM_OK
)
155 if (!CloseWindow((HWND
)hwnd
)) {
156 Jim_SetResult(interp
,
157 Win32ErrorObj(interp
, "CloseWindow", GetLastError()));
164 Win32_GetActiveWindow(Jim_Interp
*interp
, int objc
, Jim_Obj
* const *objv
)
166 Jim_SetResult(interp
, Jim_NewIntObj(interp
, (ptrdiff_t)GetActiveWindow()));
171 Win32_SetActiveWindow(Jim_Interp
*interp
, int objc
, Jim_Obj
* const *objv
)
177 Jim_WrongNumArgs(interp
, 1, objv
, "windowHandle");
180 r
= Jim_GetLong(interp
, objv
[1], (long *)&hwnd
);
182 old
= SetActiveWindow(hwnd
);
184 Jim_SetResult(interp
,
185 Win32ErrorObj(interp
, "SetActiveWindow", GetLastError()));
188 Jim_SetResult(interp
, Jim_NewIntObj(interp
, (long)old
));
195 Win32_SetForegroundWindow(Jim_Interp
*interp
, int objc
, Jim_Obj
* const *objv
)
201 Jim_WrongNumArgs(interp
, 1, objv
, "windowHandle");
204 r
= Jim_GetLong(interp
, objv
[1], (long *)&hwnd
);
206 if (!SetForegroundWindow(hwnd
)) {
207 Jim_SetResult(interp
,
208 Win32ErrorObj(interp
, "SetForegroundWindow", GetLastError()));
216 Win32_Beep(Jim_Interp
*interp
, int objc
, Jim_Obj
* const *objv
)
222 Jim_WrongNumArgs(interp
, 1, objv
, "freq duration");
225 r
= Jim_GetLong(interp
, objv
[1], &freq
);
227 r
= Jim_GetLong(interp
, objv
[2], &duration
);
228 if (freq
< 0x25) freq
= 0x25;
229 if (freq
> 0x7fff) freq
= 0x7fff;
231 if (!Beep(freq
, duration
)) {
232 Jim_SetResult(interp
,
233 Win32ErrorObj(interp
, "Beep", GetLastError()));
241 Win32_GetComputerName(Jim_Interp
*interp
, int objc
, Jim_Obj
* const *objv
)
243 char name
[MAX_COMPUTERNAME_LENGTH
+ 1];
244 DWORD size
= MAX_COMPUTERNAME_LENGTH
;
248 Jim_WrongNumArgs(interp
, 1, objv
, "");
252 if (GetComputerNameA(name
, &size
)) {
253 Jim_Obj
*nameObj
= Jim_NewStringObj(interp
, name
, size
);
254 Jim_SetResult(interp
, nameObj
);
256 Jim_SetResult(interp
,
257 Win32ErrorObj(interp
, "GetComputerName", GetLastError()));
265 Win32_GetUserName(Jim_Interp
*interp
, int objc
, Jim_Obj
* const *objv
)
267 char name
[UNLEN
+ 1];
272 Jim_WrongNumArgs(interp
, 1, objv
, "");
276 if (GetUserNameA(name
, &size
)) {
277 Jim_Obj
*nameObj
= Jim_NewStringObj(interp
, name
, size
);
278 Jim_SetResult(interp
, nameObj
);
280 Jim_SetResult(interp
,
281 Win32ErrorObj(interp
, "GetUserName", GetLastError()));
289 Win32_GetModuleFileName(Jim_Interp
*interp
, int objc
, Jim_Obj
* const *objv
)
291 HMODULE hModule
= NULL
;
296 Jim_WrongNumArgs(interp
, 1, objv
, "?moduleid?");
301 if (Jim_GetLong(interp
, objv
[1], (long *)&hModule
) != JIM_OK
) {
306 len
= GetModuleFileNameA(hModule
, path
, MAX_PATH
);
308 Jim_Obj
*pathObj
= Jim_NewStringObj(interp
, path
, len
);
309 Jim_SetResult(interp
, pathObj
);
311 Jim_SetResult(interp
,
312 Win32ErrorObj(interp
, "GetModuleFileName", GetLastError()));
320 Win32_GetVersion(Jim_Interp
*interp
, int objc
, Jim_Obj
* const *objv
)
322 Jim_SetResult(interp
, Jim_NewIntObj(interp
, GetVersion()));
327 Win32_GetTickCount(Jim_Interp
*interp
, int objc
, Jim_Obj
* const *objv
)
329 Jim_SetResult(interp
, Jim_NewIntObj(interp
, GetTickCount64()));
334 Win32_GetSystemTime(Jim_Interp
*interp
, int objc
, Jim_Obj
* const *objv
)
341 #define JIMADD(name) \
342 a[n++] = Jim_NewStringObj(interp, #name, -1); \
343 a[n++] = Jim_NewIntObj(interp, t.w ## name )
352 JIMADD(Milliseconds
);
355 Jim_SetResult(interp
, Jim_NewListObj(interp
, a
, n
));
359 /* function not available on mingw or cygwin */
360 #if !defined(__MINGW32__) && !defined(__CYGWIN__)
361 // FIX ME: win2k+ so should do version checks really.
363 Win32_GetPerformanceInfo(Jim_Interp
*interp
, int objc
, Jim_Obj
* const *objv
)
367 PERFORMANCE_INFORMATION pi
;
369 if (!GetPerformanceInfo(&pi
, sizeof(pi
))) {
370 Jim_SetResult(interp
,
371 Win32ErrorObj(interp
, "GetPerformanceInfo", GetLastError()));
375 #define JIMADD(name) \
376 a[n++] = Jim_NewStringObj(interp, #name, -1); \
377 a[n++] = Jim_NewIntObj(interp, pi. name )
382 JIMADD(PhysicalTotal
);
383 JIMADD(PhysicalAvailable
);
387 JIMADD(KernelNonpaged
);
390 JIMADD(ProcessCount
);
394 Jim_SetResult(interp
, Jim_NewListObj(interp
, a
, n
));
400 Win32_SetComputerName(Jim_Interp
*interp
, int objc
, Jim_Obj
* const *objv
)
405 Jim_WrongNumArgs(interp
, 1, objv
, "computername");
408 name
= Jim_String(objv
[1]);
409 if (!SetComputerNameA(name
)) {
410 Jim_SetResult(interp
,
411 Win32ErrorObj(interp
, "SetComputerName", GetLastError()));
418 Win32_GetModuleHandle(Jim_Interp
*interp
, int objc
, Jim_Obj
* const *objv
)
420 HMODULE hModule
= NULL
;
421 const char *name
= NULL
;
423 if (objc
< 1 || objc
> 2) {
424 Jim_WrongNumArgs(interp
, 1, objv
, "?name?");
428 name
= Jim_String(objv
[1]);
429 hModule
= GetModuleHandleA(name
);
430 if (hModule
== NULL
) {
431 Jim_SetResult(interp
,
432 Win32ErrorObj(interp
, "GetModuleHandle", GetLastError()));
435 Jim_SetResult(interp
, Jim_NewIntObj(interp
, (unsigned long)hModule
));
440 Win32_LoadLibrary(Jim_Interp
*interp
, int objc
, Jim_Obj
* const *objv
)
444 Jim_WrongNumArgs(interp
, 1, objv
, "path");
447 hLib
= LoadLibraryA(Jim_String(objv
[1]));
449 Jim_SetResult(interp
,
450 Win32ErrorObj(interp
, "LoadLibrary", GetLastError()));
453 Jim_SetResult(interp
, Jim_NewIntObj(interp
, (unsigned long)hLib
));
458 Win32_FreeLibrary(Jim_Interp
*interp
, int objc
, Jim_Obj
* const *objv
)
460 HMODULE hModule
= NULL
;
464 Jim_WrongNumArgs(interp
, 1, objv
, "hmodule");
468 r
= Jim_GetLong(interp
, objv
[1], (long *)&hModule
);
470 if (!FreeLibrary(hModule
)) {
471 Jim_SetResult(interp
,
472 Win32ErrorObj(interp
, "FreeLibrary", GetLastError()));
480 /* win32.MessageBox message title ?type? */
482 Win32_MessageBox(Jim_Interp
*interp
, int objc
, Jim_Obj
* const *objv
)
485 const char *message
, *title
;
488 if (objc
< 3 || objc
> 4) {
489 Jim_WrongNumArgs(interp
, 1, objv
, "message title ?type?");
492 message
= Jim_String(objv
[1]);
493 title
= Jim_String(objv
[2]);
495 if (Jim_GetLong(interp
, objv
[3], &type
) != JIM_OK
)
498 r
= (int) MessageBoxA(NULL
, message
, title
, (int)type
);
499 Jim_SetResultInt(interp
, r
);
504 /* ---------------------------------------------------------------------- */
507 Jim_win32Init(Jim_Interp
*interp
)
509 if (Jim_PackageProvide(interp
, "win32", "1.0", JIM_ERRMSG
))
513 Jim_CreateCommand(interp, "win32." #name , Win32_ ## name , NULL, NULL)
518 CMD(GetActiveWindow
);
519 CMD(SetActiveWindow
);
520 CMD(SetForegroundWindow
);
522 CMD(GetComputerName
);
523 CMD(SetComputerName
);
525 CMD(GetModuleFileName
);
529 #if !defined(__MINGW32__) && !defined(__CYGWIN__)
530 CMD(GetPerformanceInfo
);
532 CMD(GetModuleHandle
);