#include "api.h" #include #include #include HWND g_console = 0; int main(int argc, char* argv[]) { char fname[512]; if (argc > 1) { strcpy(fname, argv[1]); } else { // execute scrit in the file with the same name as the executable. strcpy(fname, argv[0]); int len = strlen(fname); if (len > 4 && fname[len-4] == '.') { char s[4]; s[0] = toupper(fname[len-3]); s[1] = toupper(fname[len-2]); s[2] = toupper(fname[len-1]); s[3] = 0; if (strcmp(s, "EXE") == 0) fname[len-4] = 0; } } g_console = FindWindowEx(NULL, NULL, "ConsoleWindowClass", NULL); char err[256]; void *module = api_parse_file(fname, err); if (!module) { printf("%s\n", err); return 0; } void *ctx = api_get_context(module); for (int i = 0; i < argc; i++) { sprintf(err, "%d", i); api_set_object(ctx, err, api_create_string(ctx, argv[i])); std::string s(argv[i]); size_t loc = s.find("=", 0); if (loc != std::string::npos) { if (loc == s.size() - 1) { printf("bad argument: %s\n", argv[i]); api_delete_module(module); module = 0; return 0; } api_set_object(ctx, s.substr(0,loc).c_str(), api_create_string(ctx, s.substr(loc+1).c_str())); } } if (api_exec_module(module, err) <= 0) printf("%s\n", err); api_delete_module(module); module = 0; if (g_console) ShowWindow(g_console, SW_SHOW); return 0; } ///////////////////////////////////////////////////////////////////// #define PROG_NAME "ZeGraph" static HWND g_hWnd = 0; static void *g_callback = 0; static void *g_ctx = 0; void process_message(const char* message, HWND hWnd, WPARAM wParam, LPARAM lParam) { if (!g_callback) return; void *p[8]; p[0] = api_create_user(g_ctx, hWnd, 0, 0, 0); p[1] = api_create_string(g_ctx, message); p[2] = api_create_integer(g_ctx, wParam); p[3] = api_create_integer(g_ctx, LOWORD(wParam)); p[4] = api_create_integer(g_ctx, HIWORD(wParam)); p[5] = api_create_integer(g_ctx, lParam); p[6] = api_create_integer(g_ctx, LOWORD(lParam)); p[7] = api_create_integer(g_ctx, HIWORD(lParam)); api_call_func(g_ctx, g_callback, 8, p); } LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { PAINTSTRUCT ps; HDC hdc; switch(message) { case WM_CREATE: if (g_hWnd == 0) g_hWnd = hWnd; process_message("CREATE", hWnd, wParam, lParam); return 0; case WM_COMMAND: process_message("COMMAND", hWnd, wParam, lParam); return 0; case WM_SIZE: process_message("SIZE", hWnd, wParam, lParam); return 0; case WM_PAINT: hdc = BeginPaint(hWnd, &ps); process_message("PAINT", hWnd, wParam, lParam); EndPaint(hWnd, &ps); return 0; case WM_KEYUP: process_message("KEYUP", hWnd, wParam, lParam); return 0; case WM_KEYDOWN: process_message("KEYDOW", hWnd, wParam, lParam); return 0; case WM_LBUTTONUP: process_message("LBUTTONUP", hWnd, wParam, lParam); return 0; case WM_LBUTTONDOWN: process_message("LBUTTONDOWN", hWnd, wParam, lParam); return 0; case WM_LBUTTONDBLCLK: process_message("LBUTTONDBLCLK", hWnd, wParam, lParam); return 0; case WM_MOUSEMOVE: process_message("MOUSEMOVE", hWnd, wParam, lParam); return 0; case WM_RBUTTONUP: process_message("RBUTTONUP", hWnd, wParam, lParam); return 0; case WM_RBUTTONDOWN: process_message("RBUTTONDOWN", hWnd, wParam, lParam); return 0; case WM_RBUTTONDBLCLK: process_message("RBUTTONDBLCLK", hWnd, wParam, lParam); return 0; case WM_TIMER: process_message("TIMER", hWnd, wParam, lParam); return 0; case WM_DESTROY: PostQuitMessage(0); g_hWnd = 0; return 0; default: return DefWindowProc(hWnd, message, wParam, lParam); } } struct lParamPtr { void *in; void*out; }; BOOL CALLBACK EnumWinProc(HWND hwnd, LPARAM lParam) { if (IsWindowVisible(hwnd)) { char str[512]; GetClassName(hwnd, str, 256); if (lParam == 0) printf("class -> %s\n", str); GetWindowText(hwnd, str, 256); if (lParam == 0) printf("title -> %s\n", str); if (lParam != 0) { lParamPtr *p = (lParamPtr*)lParam; std::string s(str); if (s.find((char*)p->in, 0) != std::string::npos) { p->out = hwnd; return TRUE; } } } return TRUE; } void* main_window(void* ctx, int nargs, void **args) { if (nargs == 0) { // Show windows info EnumWindows(EnumWinProc, 0); return 0; } if (nargs == 1) { // Activate a windows const char *s = api_get_string(ctx, args[0]); HWND hwnd = FindWindow(s, 0); if (hwnd) return api_create_user(ctx, hwnd, 0, 0, 0); lParamPtr p = { (void*)s, 0 }; EnumWindows(EnumWinProc, (LPARAM)&p); if (p.out != 0) return api_create_user(ctx, p.out, 0, 0, 0); return 0; } if (nargs < 3) api_input_error(ctx); int w = api_get_integer(ctx, args[0]); if (w < 32) w = 32; int h = api_get_integer(ctx, args[1]); if (h < 32) h = 32; g_callback = api_get_func(ctx, api_get_string(ctx, args[2])); g_ctx = ctx; WNDCLASS wndClass; wndClass.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS; wndClass.lpfnWndProc = WndProc; wndClass.cbClsExtra = 0; wndClass.cbWndExtra = 0; wndClass.hInstance = 0; wndClass.hIcon = LoadIcon(NULL, IDI_WINLOGO); wndClass.hCursor = LoadCursor(NULL, IDC_ARROW); wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW); wndClass.lpszMenuName = 0; if (nargs > 3) { wndClass.lpszClassName = TEXT(api_get_string(ctx, args[3])); } else { wndClass.lpszClassName = TEXT(PROG_NAME); } RegisterClass(&wndClass); RECT rect = {0, 0, w, h}; AdjustWindowRect(&rect, WS_SYSMENU | WS_THICKFRAME, 1); HWND hWnd = CreateWindow( TEXT(PROG_NAME), TEXT(PROG_NAME), WS_SYSMENU | WS_MINIMIZEBOX, CW_USEDEFAULT, CW_USEDEFAULT, rect.right-rect.left, rect.bottom-rect.top, 0, 0, 0, 0); g_hWnd = hWnd; ShowWindow(hWnd, SW_SHOW); UpdateWindow(hWnd); MSG msg; while(GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } g_hWnd = 0; g_callback = 0; g_ctx = 0; return 0; } void* main_hide(void* ctx, int nargs, void **args) { if (g_console) ShowWindow(g_console, SW_HIDE); if (g_hWnd) SetForegroundWindow(g_hWnd); return 0; } void* main_timer(void* ctx, int nargs, void **args) { if (nargs < 1) api_input_error(ctx); if (g_hWnd > 0) { KillTimer(g_hWnd, (int)g_hWnd); int ms = api_get_integer(ctx, args[0]); if (ms > 0) SetTimer(g_hWnd, (int)g_hWnd, ms, NULL); } return 0; } void* main_fullscreen(void* ctx, int nargs, void **args) { if (g_hWnd > 0) { HWND hwnd = GetDesktopWindow(); RECT rect; GetWindowRect(hwnd, &rect); int w = rect.right-rect.left; int h = rect.bottom-rect.top; SetWindowPos(g_hWnd, HWND_TOPMOST, 0, 0, w, h, SWP_SHOWWINDOW); } return 0; } void* main_resize(void* ctx, int nargs, void **args) { if (nargs < 2) api_input_error(ctx); if (g_hWnd > 0) { SetWindowPos(g_hWnd, HWND_TOPMOST, 10, 10, api_get_integer(ctx, args[0]), api_get_integer(ctx, args[1]), SWP_SHOWWINDOW); } return 0; } void* main_message(void* ctx, int nargs, void **args) { if (nargs < 1) api_input_error(ctx); MessageBox(0, api_get_string(ctx, args[0]), "ZeGraph", MB_OK); return 0; } void* main_title(void* ctx, int nargs, void **args) { if (nargs < 1) api_input_error(ctx); if (g_hWnd > 0) { SetWindowText(g_hWnd, api_get_string(ctx, args[0])); } return 0; } ///////////////////////////////////////////////////////////////////// void* main_shellexec(void* ctx, int nargs, void **args) { if (nargs < 2) api_input_error(ctx); SHELLEXECUTEINFO shellInfo; ZeroMemory(&shellInfo, sizeof(shellInfo)); shellInfo.cbSize = sizeof(shellInfo); shellInfo.fMask = SEE_MASK_FLAG_NO_UI | SEE_MASK_NOCLOSEPROCESS; shellInfo.nShow = api_get_integer(ctx, args[0]); shellInfo.lpFile = api_get_string(ctx, args[1]); if (nargs > 2) shellInfo.lpParameters = api_get_string(ctx, args[2]); if (ShellExecuteEx(&shellInfo) != TRUE) return 0; return api_create_user(ctx, shellInfo.hProcess, 0, 0, 0); } void* main_terminate(void* ctx, int nargs, void **args) { if (nargs < 1) api_input_error(ctx); TerminateProcess((HANDLE)api_get_ptr(ctx, args[0]), 0); return 0; } void* main_sendkey(void* ctx, int nargs, void **args) { if (nargs < 1) api_input_error(ctx); const char *key = api_get_string(ctx, args[0]); BYTE code = 0, scan = 0x45; DWORD flag = KEYEVENTF_EXTENDEDKEY; int ms = 100, len = strlen(key); if (nargs > 1 && api_is_user(args[1])) { HWND hwnd = (HWND)api_get_ptr(ctx, args[1]); SetForegroundWindow(hwnd); Sleep(ms); } if (len == 1) { code = toupper(key[0]); scan = 0; flag = 0; } else if (strcmp(key,"Shift") == 0) { code = VK_SHIFT; } else if (strcmp(key,"Ctrl") == 0) { code = VK_CONTROL; } else if (strcmp(key,"Alt") == 0) { code = VK_MENU; } else if (strcmp(key,"Esc") == 0) { code = VK_ESCAPE; } else if (strcmp(key,"Back") == 0) { code = VK_BACK; } else if (strcmp(key,"Tab") == 0) { code = VK_TAB; } else if (strcmp(key,"Enter") == 0) { code = VK_RETURN; } else if (strcmp(key,"Space") == 0) { code = VK_SPACE; } else if (strcmp(key,"PgUp") == 0) { code = VK_PRIOR; } else if (strcmp(key,"PgDn") == 0) { code = VK_NEXT; } else if (strcmp(key,"End") == 0) { code = VK_END; } else if (strcmp(key,"Home") == 0) { code = VK_HOME; } else if (strcmp(key,"Insert") == 0) { code = VK_INSERT; } else if (strcmp(key,"delete") == 0) { code = VK_DELETE; } else if (strcmp(key,"Left") == 0) { code = VK_LEFT; } else if (strcmp(key,"Up") == 0) { code = VK_UP; } else if (strcmp(key,"Right") == 0) { code = VK_RIGHT; } else if (strcmp(key,"Down") == 0) { code = VK_DOWN; } else if (strcmp(key,"PrScr") == 0) { code = VK_SNAPSHOT; } else if (strcmp(key,"Scroll") == 0) { code = VK_SCROLL; } else if (strcmp(key,"Pause") == 0) { code = VK_PAUSE; } else if (strcmp(key,"F1") == 0) { code = VK_F1; } else if (strcmp(key,"F2") == 0) { code = VK_F2; } else if (strcmp(key,"F3") == 0) { code = VK_F3; } else if (strcmp(key,"F4") == 0) { code = VK_F4; } else if (strcmp(key,"F5") == 0) { code = VK_F5; } else if (strcmp(key,"F6") == 0) { code = VK_F6; } else if (strcmp(key,"F7") == 0) { code = VK_F7; } else if (strcmp(key,"F8") == 0) { code = VK_F8; } else if (strcmp(key,"F9") == 0) { code = VK_F9; } else if (strcmp(key,"F10") == 0) { code = VK_F10; } else if (strcmp(key,"F11") == 0) { code = VK_F11; } else if (strcmp(key,"F12") == 0) { code = VK_F12; } else if (strcmp(key,"Num") == 0) { code = VK_NUMLOCK; } else if (strcmp(key,"Caps") == 0) { code = VK_CAPITAL; } else { for (int j = 0; j < len; j++) { keybd_event(key[j], 0, 0, 0); Sleep(ms); keybd_event(key[j], 0, KEYEVENTF_KEYUP, 0); } return 0; } keybd_event(code, scan, flag, 0); Sleep(ms); keybd_event(code, scan, flag | KEYEVENTF_KEYUP, 0); Sleep(ms); return api_create_integer(ctx, code); } typedef struct _SERVICE_STATUS_PROCESS { DWORD dwServiceType; DWORD dwCurrentState; DWORD dwControlsAccepted; DWORD dwWin32ExitCode; DWORD dwServiceSpecificExitCode; DWORD dwCheckPoint; DWORD dwWaitHint; DWORD dwProcessId; DWORD dwServiceFlags; } SERVICE_STATUS_PROCESS, *LPSERVICE_STATUS_PROCESS; void* main_qservice(void* ctx, int nargs, void **args) { if (nargs < 1) api_input_error(ctx); const char *sname = api_get_string(ctx, args[0]); SC_HANDLE h1 = OpenSCManager(0, 0, SC_MANAGER_ALL_ACCESS); if (NULL == h1) return api_create_string(ctx, "OpenSCManager error."); SC_HANDLE h2 = OpenService(h1, sname, SERVICE_QUERY_STATUS); if (NULL == h2) { /* switch (GetLastError()) { case ERROR_ACCESS_DENIED: printf("ERROR_ACCESS_DENIED\n"); break; case ERROR_INVALID_HANDLE: printf("ERROR_INVALID_HANDLE\n"); break; case ERROR_INVALID_NAME: printf("ERROR_INVALID_NAME\n"); break; case ERROR_SERVICE_DOES_NOT_EXIST: printf("ERROR_SERVICE_DOES_NOT_EXIST\n"); break; default: printf("ERROR_???"); } */ CloseServiceHandle(h1); return api_create_string(ctx, "OpenService error."); } void *ret; SERVICE_STATUS st; if (QueryServiceStatus(h2, &st)) { switch (st.dwCurrentState) { case SERVICE_CONTINUE_PENDING: ret = api_create_string(ctx, "CONTINUE_PENDING"); break; case SERVICE_PAUSE_PENDING: ret = api_create_string(ctx, "PAUSE_PENDING"); break; case SERVICE_PAUSED: ret = api_create_string(ctx, "PAUSED"); break; case SERVICE_RUNNING: ret = api_create_string(ctx, "RUNNING"); break; case SERVICE_START_PENDING: ret = api_create_string(ctx, "START_PENDING"); break; case SERVICE_STOP_PENDING: ret = api_create_string(ctx, "STOP_PENDING"); break; case SERVICE_STOPPED: ret = api_create_string(ctx, "STOPPED"); break; default: ret = api_create_string(ctx, "UNKNOWN_STATUS"); break; } } else { ret = api_create_string(ctx, "QueryServiceStatusEx error."); } CloseServiceHandle(h2); return ret; } /* void* main_download(void* ctx, int nargs, void **args) { if (nargs < 2) api_input_error(ctx); HRESULT ret = URLDownloadToFile(0, api_get_string(ctx, args[0]), api_get_string(ctx, args[1]), 0, 0); return api_create_integer(ctx, ret == S_OK); } */ ///////////////////////////////////////////////////////////////////// class zsRegPrimitive { public: zsRegPrimitive() { api_add_primitive("window", 0, main_window); api_add_primitive("hide", 0, main_hide); api_add_primitive("timer", 0, main_timer); api_add_primitive("fullscreen", 0, main_fullscreen); api_add_primitive("resize", 0, main_resize); api_add_primitive("message", 0, main_message); api_add_primitive("title", 0, main_title); api_add_primitive("shellexec", 0, main_shellexec); api_add_primitive("terminate", 0, main_terminate); api_add_primitive("sendkey", 0, main_sendkey); // api_add_primitive("download", 0, main_download); api_add_primitive("qservice", 0, main_qservice); } ~zsRegPrimitive() { } }; zsRegPrimitive main_register;