win 0.3.5 → 0.3.6
Sign up to get free protection for your applications and to get access to all the features.
- data/HISTORY +4 -0
- data/VERSION +1 -1
- data/lib/win/gui/dialog.rb +11 -12
- data/lib/win/gui/input.rb +1 -26
- data/lib/win/gui/message.rb +58 -58
- data/lib/win/gui/window.rb +2 -2
- data/lib/win/library.rb +2 -1
- data/spec/win/gui/dialog_spec.rb +0 -23
- data/spec/win/gui/input_spec.rb +25 -42
- data/spec/win/gui/window_spec.rb +1 -1
- metadata +3 -3
data/HISTORY
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.3.
|
1
|
+
0.3.6
|
data/lib/win/gui/dialog.rb
CHANGED
@@ -6,6 +6,17 @@ module Win
|
|
6
6
|
# Contains constants and Win32API functions related to dialog manipulation
|
7
7
|
#
|
8
8
|
module Dialog
|
9
|
+
|
10
|
+
# IDs of standard dialog controls and items
|
11
|
+
IDOK = 1
|
12
|
+
IDCANCEL = 2
|
13
|
+
IDABORT = 3
|
14
|
+
IDRETRY = 4
|
15
|
+
IDIGNORE = 5
|
16
|
+
IDYES = 6
|
17
|
+
IDNO = 7
|
18
|
+
ErrorIcon = 0x0014
|
19
|
+
|
9
20
|
include Win::Library
|
10
21
|
include Win::Gui::Window
|
11
22
|
|
@@ -31,18 +42,6 @@ module Win
|
|
31
42
|
#
|
32
43
|
function :GetDlgItem, [:ulong, :int], :ulong
|
33
44
|
|
34
|
-
# Convenience methods:
|
35
|
-
|
36
|
-
# finds top-level dialog window by title and yields found dialog window to block if given
|
37
|
-
# def dialog(title, seconds=3)
|
38
|
-
# d = begin
|
39
|
-
# win = Window::Window.top_level(title, seconds)
|
40
|
-
# yield(win) ? win : nil
|
41
|
-
# rescue TimeoutError
|
42
|
-
# end
|
43
|
-
# d.wait_for_close if d
|
44
|
-
# return d
|
45
|
-
# end
|
46
45
|
end
|
47
46
|
end
|
48
47
|
end
|
data/lib/win/gui/input.rb
CHANGED
@@ -7,12 +7,7 @@ module Win
|
|
7
7
|
module Input
|
8
8
|
include Win::Library
|
9
9
|
|
10
|
-
#
|
11
|
-
|
12
|
-
# Key event delay
|
13
|
-
KEY_DELAY = 0.00001
|
14
|
-
|
15
|
-
# Windows keyboard-related Constants:
|
10
|
+
# Windows defined constants:
|
16
11
|
|
17
12
|
# Key down keyboard event (the key is being depressed)
|
18
13
|
KEYEVENTF_KEYDOWN = 0
|
@@ -295,26 +290,6 @@ module Win
|
|
295
290
|
|
296
291
|
|
297
292
|
# Convenience methods
|
298
|
-
|
299
|
-
##
|
300
|
-
# Emulates combinations of (any amount of) keys pressed one after another (Ctrl+Alt+P) and then released
|
301
|
-
# *keys should be a sequence of a virtual-key codes. The codes must be a value in the range 1 to 254.
|
302
|
-
# For a complete list, see msdn:Virtual Key Codes.
|
303
|
-
def keystroke(*keys)
|
304
|
-
return if keys.empty?
|
305
|
-
keybd_event keys.first, 0, KEYEVENTF_KEYDOWN, 0
|
306
|
-
sleep KEY_DELAY
|
307
|
-
keystroke *keys[1..-1]
|
308
|
-
sleep KEY_DELAY
|
309
|
-
keybd_event keys.first, 0, KEYEVENTF_KEYUP, 0
|
310
|
-
end
|
311
|
-
|
312
|
-
# types text message into window holding the focus
|
313
|
-
def type_in(message)
|
314
|
-
message.scan(/./m) do |char|
|
315
|
-
keystroke(*char.to_vkeys)
|
316
|
-
end
|
317
|
-
end
|
318
293
|
end
|
319
294
|
end
|
320
295
|
end
|
data/lib/win/gui/message.rb
CHANGED
@@ -7,36 +7,37 @@ module Win
|
|
7
7
|
# Below is a table of system-defined message prefixes:
|
8
8
|
#
|
9
9
|
# *Prefix*:: *Message* *category*
|
10
|
-
# ABM::
|
11
|
-
# BM::
|
12
|
-
# CB::
|
13
|
-
# CBEM::
|
14
|
-
# CDM::
|
15
|
-
# DBT::
|
16
|
-
# DL::
|
17
|
-
# DM::
|
18
|
-
# DTM::
|
19
|
-
# EM::
|
20
|
-
# HDM::
|
21
|
-
# HKM::
|
22
|
-
# IPM::
|
23
|
-
# LB::
|
24
|
-
# LVM::
|
25
|
-
# MCM::
|
26
|
-
# PBM::
|
27
|
-
# PGM::
|
28
|
-
# PSM::
|
29
|
-
# RB::
|
30
|
-
# SB::
|
31
|
-
# SBM::
|
32
|
-
# STM::
|
33
|
-
# TB::
|
34
|
-
# TBM::
|
35
|
-
# TCM::
|
36
|
-
# TTM::
|
37
|
-
# TVM::
|
38
|
-
# UDM::
|
39
|
-
# WM::
|
10
|
+
# ABM:: Application desktop toolbar
|
11
|
+
# BM:: Button control
|
12
|
+
# CB:: Combo box control
|
13
|
+
# CBEM:: Extended combo box control
|
14
|
+
# CDM:: Common dialog box
|
15
|
+
# DBT:: Device
|
16
|
+
# DL:: Drag list box
|
17
|
+
# DM:: Default push button control
|
18
|
+
# DTM:: Date and time picker control
|
19
|
+
# EM:: Edit control
|
20
|
+
# HDM:: Header control
|
21
|
+
# HKM:: Hot key control
|
22
|
+
# IPM:: IP address control
|
23
|
+
# LB:: List box control
|
24
|
+
# LVM:: List view control
|
25
|
+
# MCM:: Month calendar control
|
26
|
+
# PBM:: Progress bar
|
27
|
+
# PGM:: Pager control
|
28
|
+
# PSM:: Property sheet
|
29
|
+
# RB:: Rebar control
|
30
|
+
# SB:: Status bar window
|
31
|
+
# SBM:: Scroll bar control
|
32
|
+
# STM:: Static control
|
33
|
+
# TB:: Toolbar
|
34
|
+
# TBM:: Trackbar
|
35
|
+
# TCM:: Tab control
|
36
|
+
# TTM:: Tooltip control
|
37
|
+
# TVM:: Tree-view control
|
38
|
+
# UDM:: Up-down control
|
39
|
+
# WM:: General window
|
40
|
+
|
40
41
|
module Message
|
41
42
|
include Win::Library
|
42
43
|
|
@@ -334,6 +335,33 @@ module Win
|
|
334
335
|
# PM_QS_SENDMESSAGE - Windows 98/Me, Windows 2000/XP: Process all sent messages.
|
335
336
|
PM_QS_SENDMESSAGE= (QS_SENDMESSAGE << 16)
|
336
337
|
|
338
|
+
# The MSG structure contains message information from a thread's message queue.
|
339
|
+
#
|
340
|
+
# typedef struct {
|
341
|
+
# HWND hwnd;
|
342
|
+
# UINT message;
|
343
|
+
# WPARAM wParam;
|
344
|
+
# LPARAM lParam;
|
345
|
+
# DWORD time;
|
346
|
+
# POINT pt;
|
347
|
+
# } MSG, *PMSG;
|
348
|
+
#
|
349
|
+
# hwnd:: Handle to the window whose window procedure receives the message. NULL when the message is a thread message.
|
350
|
+
# message:: Message identifier. Applications can only use the low word; the high word is reserved by the system.
|
351
|
+
# wParam:: Additional info about the message. Exact meaning depends on the value of the message member.
|
352
|
+
# lParam:: Additional info about the message. Exact meaning depends on the value of the message member.
|
353
|
+
# time:: Specifies the time at which the message was posted.
|
354
|
+
# pt:: POINT structure - the cursor position, in screen coordinates, when the message was posted.
|
355
|
+
# (in my definition, it is changed to two longs: x, y - has the same effect, just avoid nested structs)
|
356
|
+
class Msg < FFI::Struct
|
357
|
+
layout :hwnd, :ulong,
|
358
|
+
:message, :uint,
|
359
|
+
:w_param, :long,
|
360
|
+
:l_param, :pointer,
|
361
|
+
:time, :uint32,
|
362
|
+
:x, :long,
|
363
|
+
:y, :long
|
364
|
+
end
|
337
365
|
|
338
366
|
##
|
339
367
|
# The SendAsyncProc function is an application-defined callback function used with the SendMessageCallback
|
@@ -477,34 +505,6 @@ module Win
|
|
477
505
|
#
|
478
506
|
function :SendMessage, [:ulong, :uint, :uint, :pointer], :int # LPARAM different from PostMessage!
|
479
507
|
|
480
|
-
# The MSG structure contains message information from a thread's message queue.
|
481
|
-
#
|
482
|
-
# typedef struct {
|
483
|
-
# HWND hwnd;
|
484
|
-
# UINT message;
|
485
|
-
# WPARAM wParam;
|
486
|
-
# LPARAM lParam;
|
487
|
-
# DWORD time;
|
488
|
-
# POINT pt;
|
489
|
-
# } MSG, *PMSG;
|
490
|
-
#
|
491
|
-
# hwnd:: Handle to the window whose window procedure receives the message. NULL when the message is a thread message.
|
492
|
-
# message:: Message identifier. Applications can only use the low word; the high word is reserved by the system.
|
493
|
-
# wParam:: Additional info about the message. Exact meaning depends on the value of the message member.
|
494
|
-
# lParam:: Additional info about the message. Exact meaning depends on the value of the message member.
|
495
|
-
# time:: Specifies the time at which the message was posted.
|
496
|
-
# pt:: POINT structure - the cursor position, in screen coordinates, when the message was posted.
|
497
|
-
# (in my definition, it is changed to two longs: x, y - has the same effect, just avoid nested structs)
|
498
|
-
class Msg < FFI::Struct
|
499
|
-
layout :hwnd, :ulong,
|
500
|
-
:message, :uint,
|
501
|
-
:w_param, :long,
|
502
|
-
:l_param, :pointer,
|
503
|
-
:time, :uint32,
|
504
|
-
:x, :long,
|
505
|
-
:y, :long
|
506
|
-
end
|
507
|
-
|
508
508
|
##
|
509
509
|
# The GetMessage function retrieves a message from the calling thread's message queue. The function
|
510
510
|
# dispatches incoming sent messages until a posted message is available for retrieval.
|
data/lib/win/gui/window.rb
CHANGED
@@ -788,8 +788,8 @@ module Win
|
|
788
788
|
# ---
|
789
789
|
# *Remarks*: It is *different* from GetWindowText that returns only window title
|
790
790
|
#
|
791
|
-
def text( win_handle )
|
792
|
-
buffer = FFI::MemoryPointer.new :char,
|
791
|
+
def text( win_handle, buffer_size=1024 )
|
792
|
+
buffer = FFI::MemoryPointer.new :char, buffer_size
|
793
793
|
num_chars = send_message win_handle, Win::Gui::Message::WM_GETTEXT, buffer.size, buffer
|
794
794
|
num_chars == 0 ? nil : buffer.get_bytes(0, num_chars)
|
795
795
|
end
|
data/lib/win/library.rb
CHANGED
@@ -343,7 +343,8 @@ module Win
|
|
343
343
|
# Create API object that holds information about function names, params, etc
|
344
344
|
api = API.new(namespace, name, effective_name, params, returns, libs)
|
345
345
|
|
346
|
-
# Only define enhanced API if snake_name is different from original name (e.g. keybd_event)
|
346
|
+
# Only define enhanced API if snake_name is different from original name (e.g. keybd_event),
|
347
|
+
# If names are the same, this function is already "attached", not possible to enhance its API
|
347
348
|
unless snake_name.to_s == name.to_s
|
348
349
|
method_body = if def_block
|
349
350
|
if zeronil
|
data/spec/win/gui/dialog_spec.rb
CHANGED
@@ -15,29 +15,6 @@ module WinWindowTest
|
|
15
15
|
it 'returns handle to correctly specified control'
|
16
16
|
|
17
17
|
end
|
18
|
-
|
19
|
-
describe Win::Gui::Dialog, ' defines convenience/service methods on top of Windows API' do
|
20
|
-
# describe 'dialog' do
|
21
|
-
# spec{ use{ dialog( title ='Dialog Title', timeout_sec = 0.001, &any_block) }}
|
22
|
-
#
|
23
|
-
# it 'finds top-level dialog window by title' do
|
24
|
-
# pending 'Some problems (?with timeouts?) leave window open ~half of the runs'
|
25
|
-
# test_app do |app|
|
26
|
-
# keystroke(VK_ALT, 'F'.ord, 'A'.ord)
|
27
|
-
# @found = false
|
28
|
-
# dialog('Save As', 0.5) do |dialog_window|
|
29
|
-
# @found = true
|
30
|
-
# keystroke(VK_ESCAPE)
|
31
|
-
# dialog_window
|
32
|
-
# end
|
33
|
-
# @found.should == true
|
34
|
-
# end
|
35
|
-
# end
|
36
|
-
#
|
37
|
-
# it 'yields found dialog window to a given block'
|
38
|
-
#
|
39
|
-
# end
|
40
|
-
end
|
41
18
|
end
|
42
19
|
end
|
43
20
|
|
data/spec/win/gui/input_spec.rb
CHANGED
@@ -11,24 +11,35 @@ module WinWindowTest
|
|
11
11
|
|
12
12
|
describe '#keydb_event' do
|
13
13
|
spec{ use{ keybd_event(vkey = 0, bscan = 0, flags = 0, extra_info = 0) }}
|
14
|
+
before(:each){ (@app=launch_test_app)}
|
15
|
+
after(:each) do
|
16
|
+
3.times do # rolling back changes to allow window closing without dialog!
|
17
|
+
keybd_event(VK_CONTROL, 0, KEYEVENTF_KEYDOWN, 0)
|
18
|
+
sleep KEY_DELAY
|
19
|
+
keybd_event('Z'.ord, 0, KEYEVENTF_KEYDOWN, 0)
|
20
|
+
sleep KEY_DELAY
|
21
|
+
keybd_event('Z'.ord, 0, KEYEVENTF_KEYUP, 0)
|
22
|
+
sleep KEY_DELAY
|
23
|
+
keybd_event(VK_CONTROL, 0, KEYEVENTF_KEYUP, 0)
|
24
|
+
sleep KEY_DELAY
|
25
|
+
end
|
26
|
+
close_test_app
|
27
|
+
end
|
14
28
|
|
15
29
|
it 'synthesizes a numeric keystrokes, emulating keyboard driver' do
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
sleep KEY_DELAY
|
23
|
-
end
|
24
|
-
text(app.textarea).should =~ Regexp.new(text)
|
25
|
-
5.times {keystroke(VK_CONTROL, 'Z'.ord)} # rolling back changes to allow window closing without dialog!
|
30
|
+
text = '123'
|
31
|
+
text.upcase.each_byte do |b| # upcase needed since user32 keybd_event expects upper case chars
|
32
|
+
keybd_event(b.ord, 0, KEYEVENTF_KEYDOWN, 0)
|
33
|
+
sleep KEY_DELAY
|
34
|
+
keybd_event(b.ord, 0, KEYEVENTF_KEYUP, 0)
|
35
|
+
sleep KEY_DELAY
|
26
36
|
end
|
37
|
+
text(@app.textarea).should =~ Regexp.new(text)
|
27
38
|
end
|
28
39
|
end # describe '#keydb_event'
|
29
|
-
|
40
|
+
|
30
41
|
describe '#mouse_event' do
|
31
|
-
spec { use {mouse_event( flags = MOUSEEVENTF_ABSOLUTE
|
42
|
+
spec { use {mouse_event( flags = MOUSEEVENTF_ABSOLUTE, dx = 0, dy = 0, data=0, extra_info=0 )}}
|
32
43
|
it 'Emulates Mouse clicks'
|
33
44
|
end # describe '#mouse_event'
|
34
45
|
|
@@ -61,41 +72,13 @@ module WinWindowTest
|
|
61
72
|
|
62
73
|
it 'sets cursor`s position, in screen coordinates' do
|
63
74
|
SetCursorPos(x=600, y=600).should be_true
|
64
|
-
get_cursor_pos().should == [600,600]
|
75
|
+
get_cursor_pos().should == [600, 600]
|
65
76
|
set_cursor_pos(x=0, y=0).should be_true
|
66
|
-
get_cursor_pos().should == [0,0]
|
77
|
+
get_cursor_pos().should == [0, 0]
|
67
78
|
end
|
68
79
|
end # describe '#set_cursor_pos'
|
69
80
|
|
70
81
|
end # Win::Gui::Input, ' defines a set of API functions related to user input'
|
71
82
|
|
72
|
-
describe Win::Gui::Input, ' defines convenience/service methods on top of Windows API' do
|
73
|
-
describe '#keystroke' do
|
74
|
-
spec{ use{ keystroke( vkey = 30, vkey = 30) }}
|
75
|
-
|
76
|
-
it 'emulates combinations of keys pressed (Ctrl+Alt+P+M, etc)' do
|
77
|
-
test_app do |app|
|
78
|
-
keystroke(VK_CONTROL, 'A'.ord)
|
79
|
-
keystroke(VK_SPACE)
|
80
|
-
text(app.textarea).should.should == ' '
|
81
|
-
2.times {keystroke(VK_CONTROL, 'Z'.ord)} # rolling back changes to allow window closing without dialog!
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end # describe '#keystroke'
|
85
|
-
|
86
|
-
describe '#type_in' do
|
87
|
-
spec{ use{ type_in(message = '') }}
|
88
|
-
|
89
|
-
it 'types text message into the window holding the focus' do
|
90
|
-
test_app do |app|
|
91
|
-
text = '12 34'
|
92
|
-
type_in(text)
|
93
|
-
text(app.textarea).should =~ Regexp.new(text)
|
94
|
-
5.times {keystroke(VK_CONTROL, 'Z'.ord)} # rolling back changes to allow window closing without dialog!
|
95
|
-
end
|
96
|
-
end
|
97
|
-
end # describe '#type_in'
|
98
|
-
|
99
|
-
end # Win::Gui::Input, ' defines convenience/service methods on top of Windows API'
|
100
83
|
end
|
101
84
|
|
data/spec/win/gui/window_spec.rb
CHANGED
@@ -651,7 +651,7 @@ module WinWindowTest
|
|
651
651
|
end
|
652
652
|
|
653
653
|
describe '#text' do
|
654
|
-
spec{ use{ text = text(any_handle) }}
|
654
|
+
spec{ use{ text = text(any_handle, buffer_size=1024) }}
|
655
655
|
|
656
656
|
it 'returns text associated with window by sending WM_GETTEXT message to it' do
|
657
657
|
test_app do |app|
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 3
|
8
|
-
-
|
9
|
-
version: 0.3.
|
8
|
+
- 6
|
9
|
+
version: 0.3.6
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- arvicco
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-05-
|
17
|
+
date: 2010-05-31 00:00:00 +04:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|