rum 0.0.1-universal-darwin-10
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +3 -0
- data/README +30 -0
- data/Rakefile +134 -0
- data/bin/rum-client +124 -0
- data/doc/basic.rb +10 -0
- data/doc/doc.html +602 -0
- data/doc/example.rb +59 -0
- data/doc/reference.rb +415 -0
- data/doc/resources/bg.png +0 -0
- data/doc/resources/bottom.png +0 -0
- data/doc/resources/build.rb +235 -0
- data/doc/resources/doc.haml +167 -0
- data/doc/resources/emacs-auto-completion.png +0 -0
- data/doc/resources/flash.png +0 -0
- data/doc/resources/highlight.css +94 -0
- data/doc/resources/intro.rb +17 -0
- data/doc/resources/left.png +0 -0
- data/doc/resources/logo.png +0 -0
- data/doc/resources/screen.css +420 -0
- data/doc/resources/screenshot.png +0 -0
- data/doc/resources/top.png +0 -0
- data/ext/mac/keyboard_hook/English.lproj/InfoPlist.strings +0 -0
- data/ext/mac/keyboard_hook/Event.h +17 -0
- data/ext/mac/keyboard_hook/Event.m +18 -0
- data/ext/mac/keyboard_hook/EventTap.h +11 -0
- data/ext/mac/keyboard_hook/EventTap.m +77 -0
- data/ext/mac/keyboard_hook/Info.plist +26 -0
- data/ext/mac/keyboard_hook/KeyboardHook.xcodeproj/TemplateIcon.icns +0 -0
- data/ext/mac/keyboard_hook/KeyboardHook.xcodeproj/project.pbxproj +323 -0
- data/ext/mac/keyboard_hook/KeyboardHook_Prefix.pch +7 -0
- data/ext/mac/keyboard_hook/version.plist +16 -0
- data/ext/windows/keyboard_hook/extconf.rb +2 -0
- data/ext/windows/keyboard_hook/keyboard_hook.c +126 -0
- data/ext/windows/system/autohotkey_stuff.c +255 -0
- data/ext/windows/system/autohotkey_stuff.h +2 -0
- data/ext/windows/system/clipboard_watcher.c +58 -0
- data/ext/windows/system/clipboard_watcher.h +2 -0
- data/ext/windows/system/extconf.rb +3 -0
- data/ext/windows/system/input_box.c +239 -0
- data/ext/windows/system/input_box.h +4 -0
- data/ext/windows/system/system.c +273 -0
- data/lib/rum.rb +4 -0
- data/lib/rum/apps.rb +4 -0
- data/lib/rum/barrel.rb +157 -0
- data/lib/rum/barrel/emacs.rb +44 -0
- data/lib/rum/barrel/emacs_client.rb +74 -0
- data/lib/rum/core.rb +125 -0
- data/lib/rum/dsl.rb +109 -0
- data/lib/rum/gui.rb +93 -0
- data/lib/rum/help.rb +128 -0
- data/lib/rum/hotkey_core.rb +479 -0
- data/lib/rum/mac.rb +18 -0
- data/lib/rum/mac/app.rb +4 -0
- data/lib/rum/mac/apps.rb +19 -0
- data/lib/rum/mac/gui.rb +26 -0
- data/lib/rum/mac/gui/CocoaDialog.app/Contents/Info.plist +28 -0
- data/lib/rum/mac/gui/CocoaDialog.app/Contents/MacOS/CocoaDialog +0 -0
- data/lib/rum/mac/gui/CocoaDialog.app/Contents/Resources/Info.plist +28 -0
- data/lib/rum/mac/gui/CocoaDialog.app/Contents/Resources/InfoPlist.strings +0 -0
- data/lib/rum/mac/gui/CocoaDialog.app/Contents/Resources/Inputbox.nib/classes.nib +51 -0
- data/lib/rum/mac/gui/CocoaDialog.app/Contents/Resources/Inputbox.nib/info.nib +16 -0
- data/lib/rum/mac/gui/CocoaDialog.app/Contents/Resources/Inputbox.nib/keyedobjects.nib +0 -0
- data/lib/rum/mac/gui/CocoaDialog.app/Contents/Resources/MainMenu.nib/classes.nib +7 -0
- data/lib/rum/mac/gui/CocoaDialog.app/Contents/Resources/MainMenu.nib/info.nib +21 -0
- data/lib/rum/mac/gui/CocoaDialog.app/Contents/Resources/MainMenu.nib/info.nib.orig +21 -0
- data/lib/rum/mac/gui/CocoaDialog.app/Contents/Resources/MainMenu.nib/objects.nib +0 -0
- data/lib/rum/mac/gui/CocoaDialog.app/Contents/Resources/MainMenu.nib/objects.nib.orig +0 -0
- data/lib/rum/mac/gui/CocoaDialog.app/Contents/Resources/Msgbox.nib/classes.nib +27 -0
- data/lib/rum/mac/gui/CocoaDialog.app/Contents/Resources/Msgbox.nib/info.nib +16 -0
- data/lib/rum/mac/gui/CocoaDialog.app/Contents/Resources/Msgbox.nib/keyedobjects.nib +0 -0
- data/lib/rum/mac/gui/Growl.framework/Growl +0 -0
- data/lib/rum/mac/gui/Growl.framework/Versions/A/Growl +0 -0
- data/lib/rum/mac/gui/Growl.framework/Versions/A/Headers/Growl.h +6 -0
- data/lib/rum/mac/gui/Growl.framework/Versions/A/Headers/GrowlApplicationBridge-Carbon.h +780 -0
- data/lib/rum/mac/gui/Growl.framework/Versions/A/Headers/GrowlApplicationBridge.h +575 -0
- data/lib/rum/mac/gui/Growl.framework/Versions/A/Headers/GrowlDefines.h +348 -0
- data/lib/rum/mac/gui/Growl.framework/Versions/A/Resources/Info.plist +24 -0
- data/lib/rum/mac/gui/growl.rb +54 -0
- data/lib/rum/mac/irb/completion.rb +207 -0
- data/lib/rum/mac/keyboard_hook.rb +73 -0
- data/lib/rum/mac/keyboard_hook/KeyboardHook.framework/KeyboardHook +0 -0
- data/lib/rum/mac/keyboard_hook/KeyboardHook.framework/Versions/A/KeyboardHook +0 -0
- data/lib/rum/mac/keyboard_hook/KeyboardHook.framework/Versions/A/Resources/English.lproj/InfoPlist.strings +0 -0
- data/lib/rum/mac/keyboard_hook/KeyboardHook.framework/Versions/A/Resources/Info.plist +22 -0
- data/lib/rum/mac/layouts.rb +146 -0
- data/lib/rum/mac/system.rb +45 -0
- data/lib/rum/remote.rb +48 -0
- data/lib/rum/server.rb +92 -0
- data/lib/rum/windows.rb +23 -0
- data/lib/rum/windows/app.rb +72 -0
- data/lib/rum/windows/apps.rb +25 -0
- data/lib/rum/windows/gui.rb +116 -0
- data/lib/rum/windows/keyboard.rb +80 -0
- data/lib/rum/windows/keyboard_hook.rb +20 -0
- data/lib/rum/windows/layouts.rb +232 -0
- data/lib/rum/windows/system.rb +310 -0
- data/lib/rum/windows/system_foreign_functions.rb +129 -0
- data/rum.gemspec +14 -0
- metadata +166 -0
@@ -0,0 +1,239 @@
|
|
1
|
+
|
2
|
+
/* Inspired by https://sourceforge.net/projects/cinputbox */
|
3
|
+
|
4
|
+
#define UNICODE
|
5
|
+
#include <windows.h>
|
6
|
+
#include <stdio.h>
|
7
|
+
#include "input_box.h"
|
8
|
+
|
9
|
+
#define IB_CLASS_NAME L"RumInputBox"
|
10
|
+
#define IB_WIDTH 300
|
11
|
+
#define IB_HEIGHT 130
|
12
|
+
#define IB_SPAN 10
|
13
|
+
#define IB_LEFT_OFFSET 6
|
14
|
+
#define IB_TOP_OFFSET 4
|
15
|
+
#define IB_BTN_WIDTH 60
|
16
|
+
#define IB_BTN_HEIGHT 20
|
17
|
+
|
18
|
+
typedef struct {
|
19
|
+
HWND main_window, text, ok, cancel, edit_control;
|
20
|
+
LPTSTR result_text;
|
21
|
+
INT max_chars, result;
|
22
|
+
HINSTANCE instance;
|
23
|
+
} InputBox;
|
24
|
+
|
25
|
+
HMODULE global_instance;
|
26
|
+
|
27
|
+
static void input_box_populate_window(InputBox *box, HWND blank_window)
|
28
|
+
{
|
29
|
+
NONCLIENTMETRICS metrics;
|
30
|
+
HFONT font;
|
31
|
+
|
32
|
+
box->main_window = blank_window;
|
33
|
+
|
34
|
+
box->text = CreateWindow(L"Static", L"",
|
35
|
+
WS_CHILD | WS_VISIBLE,
|
36
|
+
IB_LEFT_OFFSET, IB_TOP_OFFSET,
|
37
|
+
IB_WIDTH-IB_LEFT_OFFSET*2, IB_BTN_HEIGHT*2,
|
38
|
+
box->main_window, NULL,
|
39
|
+
box->instance, NULL);
|
40
|
+
box->edit_control = CreateWindow(L"Edit", L"",
|
41
|
+
(WS_CHILD | WS_VISIBLE | WS_BORDER |
|
42
|
+
ES_AUTOHSCROLL | ES_LEFT),
|
43
|
+
IB_LEFT_OFFSET,
|
44
|
+
IB_TOP_OFFSET + IB_BTN_HEIGHT*2,
|
45
|
+
IB_WIDTH-IB_LEFT_OFFSET*3, IB_BTN_HEIGHT,
|
46
|
+
box->main_window, NULL,
|
47
|
+
box->instance, NULL);
|
48
|
+
box->ok = CreateWindow(L"Button", L"OK",
|
49
|
+
WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_PUSHBUTTON,
|
50
|
+
IB_WIDTH/2 - IB_SPAN*2 - IB_BTN_WIDTH,
|
51
|
+
IB_HEIGHT - IB_TOP_OFFSET*4 - IB_BTN_HEIGHT*2,
|
52
|
+
IB_BTN_WIDTH, IB_BTN_HEIGHT,
|
53
|
+
box->main_window, (HMENU)IDOK,
|
54
|
+
box->instance, NULL);
|
55
|
+
box->cancel = CreateWindow(L"Button", L"Cancel",
|
56
|
+
WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_PUSHBUTTON,
|
57
|
+
IB_WIDTH/2 + IB_SPAN,
|
58
|
+
IB_HEIGHT - IB_TOP_OFFSET*4 - IB_BTN_HEIGHT*2,
|
59
|
+
IB_BTN_WIDTH, IB_BTN_HEIGHT,
|
60
|
+
box->main_window, (HMENU)IDCANCEL,
|
61
|
+
box->instance, NULL);
|
62
|
+
|
63
|
+
font = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
|
64
|
+
|
65
|
+
SendMessage(box->text,WM_SETFONT,(WPARAM)font,FALSE);
|
66
|
+
SendMessage(box->edit_control,WM_SETFONT,(WPARAM)font,FALSE);
|
67
|
+
SendMessage(box->ok,WM_SETFONT,(WPARAM)font,FALSE);
|
68
|
+
SendMessage(box->cancel,WM_SETFONT,(WPARAM)font,FALSE);
|
69
|
+
}
|
70
|
+
|
71
|
+
static void input_box_close(InputBox *box)
|
72
|
+
{
|
73
|
+
PostMessage(box->main_window, WM_CLOSE, 0, 0);
|
74
|
+
}
|
75
|
+
|
76
|
+
static void input_box_submit(InputBox *box)
|
77
|
+
{
|
78
|
+
int input_length = (int)SendMessage(box->edit_control, EM_LINELENGTH, 0, 0);
|
79
|
+
if (input_length){
|
80
|
+
// Provide the max number of chars to be copied as a word in the buffer.
|
81
|
+
*((LPWORD)box->result_text) = box->max_chars;
|
82
|
+
// Although undocumented, the copied string is null-terminated.
|
83
|
+
input_length = (WORD)SendMessage(box->edit_control, EM_GETLINE, 0,
|
84
|
+
(LPARAM)box->result_text);
|
85
|
+
}
|
86
|
+
box->result = input_length;
|
87
|
+
}
|
88
|
+
|
89
|
+
LRESULT CALLBACK window_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
90
|
+
{
|
91
|
+
InputBox *box = (InputBox*)GetWindowLong(hwnd, GWL_USERDATA);
|
92
|
+
|
93
|
+
switch(msg)
|
94
|
+
{
|
95
|
+
case WM_CREATE:
|
96
|
+
box = (InputBox *) ((CREATESTRUCT *)lParam)->lpCreateParams;
|
97
|
+
SetWindowLong(hwnd, GWL_USERDATA, (long)box);
|
98
|
+
input_box_populate_window(box, hwnd);
|
99
|
+
break;
|
100
|
+
case WM_COMMAND:
|
101
|
+
switch(LOWORD(wParam)) {
|
102
|
+
case IDOK:
|
103
|
+
input_box_submit(box);
|
104
|
+
case IDCANCEL:
|
105
|
+
input_box_close(box);
|
106
|
+
break;
|
107
|
+
}
|
108
|
+
break;
|
109
|
+
case WM_SETFOCUS:
|
110
|
+
SetFocus(box->edit_control);
|
111
|
+
break;
|
112
|
+
case WM_CLOSE:
|
113
|
+
DestroyWindow(hwnd);
|
114
|
+
break;
|
115
|
+
case WM_DESTROY:
|
116
|
+
PostQuitMessage(0);
|
117
|
+
break;
|
118
|
+
}
|
119
|
+
return DefWindowProc(hwnd, msg, wParam, lParam);
|
120
|
+
}
|
121
|
+
|
122
|
+
void input_box_register_window_class(HINSTANCE instance)
|
123
|
+
{
|
124
|
+
WNDCLASSEX wndInputBox;
|
125
|
+
|
126
|
+
wndInputBox.cbSize = sizeof(wndInputBox);
|
127
|
+
wndInputBox.style = CS_HREDRAW | CS_VREDRAW;
|
128
|
+
wndInputBox.lpszClassName = IB_CLASS_NAME;
|
129
|
+
wndInputBox.lpfnWndProc = window_proc;
|
130
|
+
wndInputBox.lpszMenuName = NULL;
|
131
|
+
wndInputBox.cbClsExtra = 0;
|
132
|
+
wndInputBox.cbWndExtra = 0;
|
133
|
+
wndInputBox.hInstance = instance;
|
134
|
+
wndInputBox.hIcon = LoadIcon(NULL, IDI_QUESTION);
|
135
|
+
wndInputBox.hIconSm = NULL;
|
136
|
+
wndInputBox.hCursor = LoadCursor(NULL, IDC_ARROW);
|
137
|
+
wndInputBox.hbrBackground = (HBRUSH)(COLOR_WINDOW);
|
138
|
+
|
139
|
+
if(!RegisterClassEx(&wndInputBox))
|
140
|
+
{
|
141
|
+
MessageBox(NULL, L"Window Registration Failed!", L"Error!",
|
142
|
+
MB_ICONEXCLAMATION | MB_OK);
|
143
|
+
}
|
144
|
+
}
|
145
|
+
|
146
|
+
void input_box_unregister_window_class(InputBox *box)
|
147
|
+
{
|
148
|
+
UnregisterClass(IB_CLASS_NAME, box->instance);
|
149
|
+
}
|
150
|
+
|
151
|
+
static void input_box_show(InputBox *box, LPCTSTR title, LPCTSTR text,
|
152
|
+
LPTSTR result_text, int max_chars)
|
153
|
+
{
|
154
|
+
box->result_text = result_text;
|
155
|
+
box->max_chars = max_chars;
|
156
|
+
box->result = 0;
|
157
|
+
|
158
|
+
SetWindowText(box->main_window, title);
|
159
|
+
SetWindowText(box->edit_control, result_text);
|
160
|
+
SetWindowText(box->text, text);
|
161
|
+
SendMessage(box->edit_control, EM_LIMITTEXT,
|
162
|
+
max_chars-1, // Leave room for the terminating null char.
|
163
|
+
0);
|
164
|
+
SendMessage(box->edit_control, EM_SETSEL, 0, -1); // Select the whole text
|
165
|
+
ShowWindow(box->main_window, SW_SHOWNORMAL);
|
166
|
+
}
|
167
|
+
|
168
|
+
static void input_box_create(InputBox *box, HINSTANCE instance)
|
169
|
+
{
|
170
|
+
RECT rect;
|
171
|
+
|
172
|
+
GetWindowRect(GetDesktopWindow(), &rect);
|
173
|
+
|
174
|
+
box->instance = instance;
|
175
|
+
box->main_window = CreateWindowEx(WS_EX_TOPMOST,
|
176
|
+
IB_CLASS_NAME, L"",
|
177
|
+
(WS_BORDER | WS_CAPTION | WS_SYSMENU),
|
178
|
+
(rect.left + rect.right - IB_WIDTH)/2,
|
179
|
+
(rect.top + rect.bottom - IB_HEIGHT)/2,
|
180
|
+
IB_WIDTH, IB_HEIGHT,
|
181
|
+
GetForegroundWindow(), 0,
|
182
|
+
instance, box);
|
183
|
+
}
|
184
|
+
|
185
|
+
|
186
|
+
|
187
|
+
static void input_box_destroy(InputBox *box)
|
188
|
+
{
|
189
|
+
SendMessage(box->main_window, WM_DESTROY, 0, 0);
|
190
|
+
}
|
191
|
+
|
192
|
+
|
193
|
+
void input_box_initialize(HINSTANCE instance)
|
194
|
+
{
|
195
|
+
global_instance = instance;
|
196
|
+
input_box_register_window_class(instance);
|
197
|
+
}
|
198
|
+
|
199
|
+
int input_box(LPCTSTR text, LPCTSTR title,
|
200
|
+
LPTSTR result_text, int max_chars)
|
201
|
+
{
|
202
|
+
MSG msg;
|
203
|
+
InputBox box;
|
204
|
+
|
205
|
+
input_box_create(&box, global_instance);
|
206
|
+
|
207
|
+
input_box_show(&box, title, text, result_text, max_chars);
|
208
|
+
|
209
|
+
while(GetMessage(&msg, NULL, 0, 0) > 0)
|
210
|
+
{
|
211
|
+
if (msg.message == WM_KEYDOWN) {
|
212
|
+
switch (msg.wParam) {
|
213
|
+
case VK_RETURN:
|
214
|
+
input_box_submit(&box);
|
215
|
+
case VK_ESCAPE:
|
216
|
+
input_box_close(&box);
|
217
|
+
break;
|
218
|
+
default:
|
219
|
+
TranslateMessage(&msg);
|
220
|
+
}
|
221
|
+
} else {
|
222
|
+
TranslateMessage(&msg);
|
223
|
+
}
|
224
|
+
DispatchMessage(&msg);
|
225
|
+
}
|
226
|
+
|
227
|
+
input_box_destroy(&box);
|
228
|
+
|
229
|
+
return(box.result);
|
230
|
+
}
|
231
|
+
|
232
|
+
/* void input_box_demo() */
|
233
|
+
/* { */
|
234
|
+
/* input_box_initialize(GetModuleHandle(NULL)); */
|
235
|
+
/* #define chars 100 */
|
236
|
+
/* /\* UTF-16LE: 2 bytes per char. *\/ */
|
237
|
+
/* char buffer[chars*2] = {187, 3, 184, 3, 4, 4}; */
|
238
|
+
/* input_box(L"text", L"title", (LPTSTR)buffer, chars); */
|
239
|
+
/* } */
|
@@ -0,0 +1,273 @@
|
|
1
|
+
#include "ruby.h"
|
2
|
+
#include <windows.h>
|
3
|
+
#include <winuser.h>
|
4
|
+
#include <tlhelp32.h>
|
5
|
+
#include "autohotkey_stuff.h"
|
6
|
+
#include "input_box.h"
|
7
|
+
#include "clipboard_watcher.h"
|
8
|
+
|
9
|
+
VALUE mSystem;
|
10
|
+
VALUE mDesktop;
|
11
|
+
VALUE mScreen;
|
12
|
+
VALUE mClipboard;
|
13
|
+
VALUE cWindow;
|
14
|
+
|
15
|
+
struct KeybdEventParams {
|
16
|
+
int vkcode;
|
17
|
+
int scancode;
|
18
|
+
DWORD flags;
|
19
|
+
};
|
20
|
+
|
21
|
+
struct InputBoxParams {
|
22
|
+
LPCTSTR text;
|
23
|
+
LPCTSTR title;
|
24
|
+
LPTSTR result_text;
|
25
|
+
int length;
|
26
|
+
};
|
27
|
+
|
28
|
+
struct MessageBoxParams {
|
29
|
+
LPCWSTR text;
|
30
|
+
LPCWSTR title;
|
31
|
+
};
|
32
|
+
|
33
|
+
static BOOL CALLBACK enum_windows_proc(HWND hwnd, LPARAM lParam)
|
34
|
+
{
|
35
|
+
rb_yield(LONG2NUM((DWORD)hwnd));
|
36
|
+
return TRUE;
|
37
|
+
}
|
38
|
+
|
39
|
+
static VALUE enum_windows(VALUE self) {
|
40
|
+
EnumWindows(enum_windows_proc, 0);
|
41
|
+
return Qnil;
|
42
|
+
}
|
43
|
+
|
44
|
+
static void call_keybd_event(struct KeybdEventParams *event) {
|
45
|
+
#ifdef DEBUG
|
46
|
+
printf("Sending key: vkcode: %d, scancode: %d\n", event.vkcode, event.scancode);
|
47
|
+
#endif
|
48
|
+
keybd_event(event->vkcode, event->scancode, event->flags, 0);
|
49
|
+
}
|
50
|
+
|
51
|
+
static VALUE f_keybd_event(int argc, VALUE* argv, VALUE self)
|
52
|
+
{
|
53
|
+
VALUE vkcode, down, scancode, extended;
|
54
|
+
struct KeybdEventParams event;
|
55
|
+
rb_scan_args(argc, argv, "22", &vkcode, &down, &scancode, &extended);
|
56
|
+
|
57
|
+
event.flags = 0;
|
58
|
+
if (down != Qtrue)
|
59
|
+
event.flags |= KEYEVENTF_KEYUP;
|
60
|
+
if ( !(extended == Qnil || extended == Qfalse) )
|
61
|
+
event.flags |= KEYEVENTF_EXTENDEDKEY;
|
62
|
+
|
63
|
+
event.vkcode = NUM2INT(vkcode);
|
64
|
+
event.scancode = (NIL_P(scancode) ? 0 : NUM2INT(scancode));
|
65
|
+
rb_thread_blocking_region(call_keybd_event, &event, 0, 0);
|
66
|
+
return Qnil;
|
67
|
+
}
|
68
|
+
|
69
|
+
/* Returns 'true' if successful, 'false' if not. */
|
70
|
+
static VALUE ForceWindowToFront(VALUE self)
|
71
|
+
{
|
72
|
+
HWND TargetWindow = (HWND)NUM2ULONG(rb_iv_get(self, "@handle"));
|
73
|
+
if (SetForegroundWindowEx(TargetWindow))
|
74
|
+
return Qtrue;
|
75
|
+
else
|
76
|
+
return Qfalse;
|
77
|
+
}
|
78
|
+
|
79
|
+
static DWORD process_id(VALUE window)
|
80
|
+
{
|
81
|
+
VALUE handle = rb_iv_get(window, "@handle");
|
82
|
+
HWND window_handle = (HWND)NUM2ULONG(handle);
|
83
|
+
|
84
|
+
DWORD process_id = 0;
|
85
|
+
GetWindowThreadProcessId(window_handle, &process_id);
|
86
|
+
return process_id;
|
87
|
+
}
|
88
|
+
|
89
|
+
static void process_module(VALUE window, MODULEENTRY32 *module) {
|
90
|
+
DWORD processID = process_id(window);
|
91
|
+
|
92
|
+
// Take a snapshot of the modules of this process
|
93
|
+
HANDLE moduleSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, processID);
|
94
|
+
|
95
|
+
//Get the first module
|
96
|
+
module->dwSize = sizeof(MODULEENTRY32);
|
97
|
+
Module32First(moduleSnapshot, module);
|
98
|
+
}
|
99
|
+
|
100
|
+
static void get_exe_path(MODULEENTRY32 *module, char *buffer) {
|
101
|
+
strcpy(buffer, module->szExePath);
|
102
|
+
}
|
103
|
+
|
104
|
+
static void get_exe_name(MODULEENTRY32 *module, char *buffer) {
|
105
|
+
strcpy(buffer, module->szModule);
|
106
|
+
buffer[strlen(buffer) - 4] = '\0'; /* Remove .exe suffix */
|
107
|
+
}
|
108
|
+
|
109
|
+
static void access_window_process_data(VALUE window, void fn(MODULEENTRY32 *module, char *buffer), char *buffer) {
|
110
|
+
MODULEENTRY32 module = {0};
|
111
|
+
process_module(window, &module);
|
112
|
+
(*fn)(&module, buffer);
|
113
|
+
}
|
114
|
+
|
115
|
+
static VALUE exe_name(VALUE self)
|
116
|
+
{
|
117
|
+
char buffer[MAX_MODULE_NAME32 + 1];
|
118
|
+
access_window_process_data(self, &get_exe_name, buffer);
|
119
|
+
return rb_str_new2(buffer);
|
120
|
+
}
|
121
|
+
|
122
|
+
static VALUE exe_path(VALUE self)
|
123
|
+
{
|
124
|
+
char buffer[MAX_PATH];
|
125
|
+
access_window_process_data(self, &get_exe_path, buffer);
|
126
|
+
return rb_str_new2(buffer);
|
127
|
+
}
|
128
|
+
|
129
|
+
static LPRECT get_window_rect(VALUE window, LPRECT rect)
|
130
|
+
{
|
131
|
+
HWND window_handle = (HWND)NUM2ULONG(rb_iv_get(window, "@handle"));
|
132
|
+
GetWindowRect(window_handle, rect);
|
133
|
+
return rect;
|
134
|
+
}
|
135
|
+
|
136
|
+
static VALUE top(VALUE self)
|
137
|
+
{
|
138
|
+
RECT rect;
|
139
|
+
return LONG2NUM((get_window_rect(self, &rect)->top));
|
140
|
+
}
|
141
|
+
|
142
|
+
|
143
|
+
static VALUE right(VALUE self)
|
144
|
+
{
|
145
|
+
RECT rect;
|
146
|
+
return LONG2NUM((get_window_rect(self, &rect)->right));
|
147
|
+
}
|
148
|
+
|
149
|
+
static VALUE bottom(VALUE self)
|
150
|
+
{
|
151
|
+
RECT rect;
|
152
|
+
return LONG2NUM((get_window_rect(self, &rect)->bottom));
|
153
|
+
}
|
154
|
+
|
155
|
+
static VALUE left(VALUE self)
|
156
|
+
{
|
157
|
+
RECT rect;
|
158
|
+
return LONG2NUM((get_window_rect(self, &rect)->left));
|
159
|
+
}
|
160
|
+
|
161
|
+
static VALUE desktop_top(VALUE self)
|
162
|
+
{
|
163
|
+
RECT work_area;
|
164
|
+
SystemParametersInfo(SPI_GETWORKAREA, 0, &work_area, 0);
|
165
|
+
return LONG2NUM(work_area.top);
|
166
|
+
}
|
167
|
+
|
168
|
+
static VALUE desktop_right(VALUE self)
|
169
|
+
{
|
170
|
+
RECT work_area;
|
171
|
+
SystemParametersInfo(SPI_GETWORKAREA, 0, &work_area, 0);
|
172
|
+
return LONG2NUM(work_area.right);
|
173
|
+
}
|
174
|
+
|
175
|
+
static VALUE desktop_bottom(VALUE self)
|
176
|
+
{
|
177
|
+
RECT work_area;
|
178
|
+
SystemParametersInfo(SPI_GETWORKAREA, 0, &work_area, 0);
|
179
|
+
return LONG2NUM(work_area.bottom);
|
180
|
+
}
|
181
|
+
|
182
|
+
static VALUE desktop_left(VALUE self)
|
183
|
+
{
|
184
|
+
RECT work_area;
|
185
|
+
SystemParametersInfo(SPI_GETWORKAREA, 0, &work_area, 0);
|
186
|
+
return LONG2NUM(work_area.left);
|
187
|
+
}
|
188
|
+
|
189
|
+
static VALUE screen_width(VALUE self)
|
190
|
+
{
|
191
|
+
return INT2NUM(GetSystemMetrics(SM_CXSCREEN));
|
192
|
+
}
|
193
|
+
|
194
|
+
static VALUE screen_height(VALUE self)
|
195
|
+
{
|
196
|
+
return INT2NUM(GetSystemMetrics(SM_CYSCREEN));
|
197
|
+
}
|
198
|
+
|
199
|
+
static VALUE get_console_window(VALUE self)
|
200
|
+
{
|
201
|
+
/* Cast to ULONG_PTR to neutralize a compiler warning. */
|
202
|
+
return LONG2NUM((ULONG_PTR)GetConsoleWindow());
|
203
|
+
}
|
204
|
+
|
205
|
+
static VALUE call_message_box(struct MessageBoxParams *params)
|
206
|
+
{
|
207
|
+
int result = MessageBoxW(0, params->text, params->title,
|
208
|
+
MB_OKCANCEL | MB_TOPMOST | MB_SETFOREGROUND);
|
209
|
+
return result == IDOK ? Qtrue : Qfalse;
|
210
|
+
}
|
211
|
+
|
212
|
+
static VALUE message_box_internal(VALUE self, VALUE text, VALUE title)
|
213
|
+
{
|
214
|
+
struct MessageBoxParams params;
|
215
|
+
params.text = (LPCWSTR)RSTRING_PTR(text);
|
216
|
+
params.title = (LPCWSTR)RSTRING_PTR(title);
|
217
|
+
return rb_thread_blocking_region(call_message_box, ¶ms, 0, 0);
|
218
|
+
}
|
219
|
+
|
220
|
+
static VALUE call_input_box(struct InputBoxParams *params)
|
221
|
+
{
|
222
|
+
return INT2FIX(input_box(params->text, params->title,
|
223
|
+
params->result_text, params->length));
|
224
|
+
}
|
225
|
+
|
226
|
+
static VALUE input_box_internal(VALUE self, VALUE text, VALUE title,
|
227
|
+
VALUE result_text)
|
228
|
+
{
|
229
|
+
struct InputBoxParams params;
|
230
|
+
params.text = RSTRING_PTR(text);
|
231
|
+
params.title = RSTRING_PTR(title);
|
232
|
+
params.result_text = RSTRING_PTR(result_text);
|
233
|
+
params.length = RSTRING_LEN(result_text)/2;
|
234
|
+
|
235
|
+
return rb_thread_blocking_region(call_input_box, ¶ms, 0, 0);
|
236
|
+
}
|
237
|
+
|
238
|
+
|
239
|
+
void Init_system() {
|
240
|
+
input_box_initialize(GetModuleHandle(NULL));
|
241
|
+
autohotkey_stuff_initialize(GetCurrentThreadId());
|
242
|
+
|
243
|
+
mSystem = rb_define_module_under(rb_define_module("Rum"), "System");
|
244
|
+
mDesktop = rb_define_module_under(mSystem, "Desktop");
|
245
|
+
mScreen = rb_define_module_under(mSystem, "Screen");
|
246
|
+
mClipboard = rb_define_module_under(mSystem, "Clipboard");
|
247
|
+
cWindow = rb_define_class_under(mSystem, "Window", rb_cObject);
|
248
|
+
|
249
|
+
rb_define_method(mSystem, "enum_windows", enum_windows, 0);
|
250
|
+
rb_define_method(mSystem, "keybd_event", f_keybd_event, -1);
|
251
|
+
rb_define_method(mSystem, "get_console_window", get_console_window, 0);
|
252
|
+
rb_define_method(mSystem, "message_box_internal", message_box_internal, 2);
|
253
|
+
rb_define_method(mSystem, "input_box_internal", input_box_internal, 3);
|
254
|
+
|
255
|
+
rb_define_method(cWindow, "show", ForceWindowToFront, 0);
|
256
|
+
rb_define_method(cWindow, "exe_path", exe_path, 0);
|
257
|
+
rb_define_method(cWindow, "exe_name", exe_name, 0);
|
258
|
+
rb_define_method(cWindow, "left", left, 0);
|
259
|
+
rb_define_method(cWindow, "right", right, 0);
|
260
|
+
rb_define_method(cWindow, "top", top, 0);
|
261
|
+
rb_define_method(cWindow, "bottom", bottom, 0);
|
262
|
+
|
263
|
+
rb_define_module_function(mDesktop, "top", desktop_top, 0);
|
264
|
+
rb_define_module_function(mDesktop, "left", desktop_left, 0);
|
265
|
+
rb_define_module_function(mDesktop, "bottom", desktop_bottom, 0);
|
266
|
+
rb_define_module_function(mDesktop, "right", desktop_right, 0);
|
267
|
+
|
268
|
+
rb_define_module_function(mScreen, "width", screen_width, 0);
|
269
|
+
rb_define_module_function(mScreen, "height", screen_height, 0);
|
270
|
+
|
271
|
+
rb_define_method(mClipboard, "install_watcher", install_watcher, 0);
|
272
|
+
rb_define_method(mClipboard, "evaluate_watcher", evaluate_watcher, 2);
|
273
|
+
}
|