win32-window 0.1.0.pre → 0.2.0.pre
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/win32/window/version.rb +1 -1
- data/lib/win32/window/window.rb +236 -31
- metadata +53 -5
data/lib/win32/window/version.rb
CHANGED
@@ -1 +1 @@
|
|
1
|
-
$version = '0.
|
1
|
+
$version = '0.2.0.pre'
|
data/lib/win32/window/window.rb
CHANGED
@@ -11,31 +11,109 @@ module Win32
|
|
11
11
|
class Size < Struct.new(:width, :height)
|
12
12
|
end
|
13
13
|
|
14
|
+
module Geometry
|
15
|
+
def location
|
16
|
+
g = geometry()
|
17
|
+
Point.new(g.left, g.top)
|
18
|
+
end
|
19
|
+
|
20
|
+
def x
|
21
|
+
location.x
|
22
|
+
end
|
23
|
+
|
24
|
+
def y
|
25
|
+
location.y
|
26
|
+
end
|
27
|
+
|
28
|
+
def left
|
29
|
+
geometry.left
|
30
|
+
end
|
31
|
+
|
32
|
+
def right
|
33
|
+
geometry.right
|
34
|
+
end
|
35
|
+
|
36
|
+
def top
|
37
|
+
geometry.top
|
38
|
+
end
|
39
|
+
|
40
|
+
def bottom
|
41
|
+
geometry.bottom
|
42
|
+
end
|
43
|
+
|
44
|
+
def size
|
45
|
+
g = geometry()
|
46
|
+
Size.new(g.right - g.left + 1, g.bottom - g.top + 1)
|
47
|
+
end
|
48
|
+
|
49
|
+
def width
|
50
|
+
size.width
|
51
|
+
end
|
52
|
+
|
53
|
+
def height
|
54
|
+
size.height
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
14
58
|
class Window
|
15
59
|
def initialize(handle)
|
60
|
+
# TODO: Validate handle parameter?
|
61
|
+
|
16
62
|
@handle = handle
|
63
|
+
@client = Client.new(@handle)
|
17
64
|
end
|
18
65
|
|
19
66
|
def self.find(opts = {})
|
20
|
-
matches = []
|
67
|
+
Thread.current[:matches] = []
|
68
|
+
Thread.current[:opts] = opts
|
69
|
+
|
70
|
+
@@callback ||= API::Callback.new('LP', 'I') { |handle|
|
71
|
+
opts = Thread.current[:opts]
|
21
72
|
|
22
|
-
callback = API::Callback.new('LP', 'I') { |handle|
|
23
73
|
match = true
|
24
74
|
match &&= opts[:title].nil? || (get_title(handle) =~ opts[:title])
|
25
75
|
match &&= opts[:pid].nil? || (get_pid(handle) == opts[:pid])
|
26
76
|
|
27
77
|
if match
|
28
|
-
matches << Window.new(handle)
|
78
|
+
Thread.current[:matches] << Window.new(handle)
|
29
79
|
end
|
30
80
|
|
31
81
|
1
|
32
82
|
}
|
33
83
|
|
34
|
-
EnumWindows.call(callback, nil)
|
84
|
+
EnumWindows.call(@@callback, nil)
|
85
|
+
|
86
|
+
return Thread.current[:matches]
|
87
|
+
end
|
88
|
+
|
89
|
+
def self.from_point(*args)
|
90
|
+
if (args.length == 1) && (args[0].is_a? Point)
|
91
|
+
x = args[0].x
|
92
|
+
y = args[0].y
|
93
|
+
elsif args.length == 2
|
94
|
+
x, y = args
|
95
|
+
else
|
96
|
+
raise ArgumentError
|
97
|
+
end
|
98
|
+
|
99
|
+
handle = WindowFromPoint.call(x,y)
|
100
|
+
if handle == 0
|
101
|
+
nil
|
102
|
+
else
|
103
|
+
Window.new(handle)
|
104
|
+
end
|
105
|
+
end
|
35
106
|
|
36
|
-
|
107
|
+
def self.from_handle(handle)
|
108
|
+
if IsWindow.call(handle) != 0
|
109
|
+
Window.new(handle)
|
110
|
+
else
|
111
|
+
nil
|
112
|
+
end
|
37
113
|
end
|
38
114
|
|
115
|
+
# See also GetShellWindow
|
116
|
+
# http://msdn.microsoft.com/en-us/library/windows/desktop/ms633512(v=vs.85).aspx
|
39
117
|
def self.desktop
|
40
118
|
Window.new(GetDesktopWindow.call())
|
41
119
|
end
|
@@ -48,22 +126,90 @@ module Win32
|
|
48
126
|
Window.get_title(@handle)
|
49
127
|
end
|
50
128
|
|
129
|
+
def handle
|
130
|
+
@handle
|
131
|
+
end
|
132
|
+
|
133
|
+
def eql?(other)
|
134
|
+
self == other
|
135
|
+
end
|
136
|
+
|
137
|
+
def ==(other)
|
138
|
+
handle == other.handle
|
139
|
+
end
|
140
|
+
|
141
|
+
def topmost?
|
142
|
+
end
|
143
|
+
|
51
144
|
def topmost=(topmost)
|
52
145
|
SetWindowPos.call(@handle, topmost ? HWND_TOPMOST : HWND_NOTTOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE)
|
53
146
|
end
|
54
147
|
|
148
|
+
# Use also SetForegroundWindow?
|
149
|
+
# http://msdn.microsoft.com/en-us/library/windows/desktop/ms633539(v=vs.85).aspx
|
150
|
+
# def bring_to_top
|
151
|
+
# BringWindowToTop.call(@handle)
|
152
|
+
# end
|
153
|
+
|
154
|
+
def focus
|
155
|
+
# ...?
|
156
|
+
end
|
157
|
+
|
158
|
+
def focused?
|
159
|
+
end
|
160
|
+
|
161
|
+
# window.children.from_point(...)
|
162
|
+
# http://msdn.microsoft.com/en-us/library/windows/desktop/ms632677(v=vs.85).aspx
|
163
|
+
# ChildWindowFromPointEx
|
164
|
+
|
165
|
+
# window.children.each/window.each_child
|
166
|
+
# http://msdn.microsoft.com/en-us/library/windows/desktop/ms633494(v=vs.85).aspx
|
167
|
+
# EnumChildWindows
|
168
|
+
|
169
|
+
# window.children.topmost
|
170
|
+
# http://msdn.microsoft.com/en-us/library/windows/desktop/ms633514(v=vs.85).aspx
|
171
|
+
# GetTopWindow
|
172
|
+
|
173
|
+
# window.child_of?
|
174
|
+
# http://msdn.microsoft.com/en-us/library/windows/desktop/ms633524(v=vs.85).aspx
|
175
|
+
# IsChild
|
176
|
+
|
55
177
|
def minimize
|
56
|
-
|
178
|
+
ShowWindow.call(@handle, SW_MINIMIZE)
|
57
179
|
end
|
58
180
|
|
59
181
|
def minimized?
|
60
182
|
IsIconic.call(@handle) != 0
|
61
183
|
end
|
62
184
|
|
185
|
+
def maximize
|
186
|
+
ShowWindow.call(@handle, SW_MAXIMIZE)
|
187
|
+
end
|
188
|
+
|
189
|
+
# TODO: max -> min -> restore does not show the window restored,
|
190
|
+
# you have to do max -> min -> restore -> restore.
|
191
|
+
def restore
|
192
|
+
ShowWindow.call(@handle, SW_RESTORE)
|
193
|
+
end
|
194
|
+
|
195
|
+
def maximized?
|
196
|
+
IsZoomed.call(@handle) != 0
|
197
|
+
end
|
198
|
+
|
63
199
|
def visible?
|
64
200
|
IsWindowVisible.call(@handle) != 0
|
65
201
|
end
|
66
202
|
|
203
|
+
# TODO: hide -> maximize/minimize/restore forces the window
|
204
|
+
# to be shown again, use SetWindowPlacement?
|
205
|
+
def hide
|
206
|
+
ShowWindow.call(@handle, SW_HIDE)
|
207
|
+
end
|
208
|
+
|
209
|
+
def show
|
210
|
+
ShowWindow.call(@handle, SW_SHOW)
|
211
|
+
end
|
212
|
+
|
67
213
|
def parent
|
68
214
|
parent = GetParent.call(@handle)
|
69
215
|
if parent == 0
|
@@ -73,6 +219,17 @@ module Win32
|
|
73
219
|
end
|
74
220
|
end
|
75
221
|
|
222
|
+
# See GetAncestor
|
223
|
+
# http://msdn.microsoft.com/en-us/library/windows/desktop/ms633502(v=vs.85).aspx
|
224
|
+
def root
|
225
|
+
end
|
226
|
+
|
227
|
+
# See GetAncestor
|
228
|
+
# http://msdn.microsoft.com/en-us/library/windows/desktop/ms633502(v=vs.85).aspx
|
229
|
+
def owner
|
230
|
+
# ...
|
231
|
+
end
|
232
|
+
|
76
233
|
def pid
|
77
234
|
Window.get_pid(@handle)
|
78
235
|
end
|
@@ -85,16 +242,10 @@ module Win32
|
|
85
242
|
SetWindowPos.call(@handle, 0, 0, 0, width, height, SWP_NOMOVE | SWP_NOZORDER)
|
86
243
|
end
|
87
244
|
|
88
|
-
|
89
|
-
g = geometry()
|
90
|
-
Point.new(g.left, g.top)
|
91
|
-
end
|
92
|
-
|
93
|
-
def size
|
94
|
-
g = geometry()
|
95
|
-
Size.new(g.right - g.left, g.bottom - g.top)
|
96
|
-
end
|
245
|
+
include Geometry
|
97
246
|
|
247
|
+
# TODO: geometry should return special values when
|
248
|
+
# the window is minimized.
|
98
249
|
def geometry
|
99
250
|
rect = Window.buffer(4 * 4)
|
100
251
|
GetWindowRect.call(@handle, rect)
|
@@ -102,22 +253,50 @@ module Win32
|
|
102
253
|
return Rect.new(left, top, right, bottom)
|
103
254
|
end
|
104
255
|
|
105
|
-
def
|
106
|
-
|
107
|
-
|
108
|
-
|
256
|
+
def client
|
257
|
+
@client
|
258
|
+
end
|
259
|
+
|
260
|
+
# See GetWindowModuleFileName
|
261
|
+
# http://msdn.microsoft.com/en-us/library/windows/desktop/ms633517(v=vs.85).aspx
|
262
|
+
def module_name
|
263
|
+
end
|
109
264
|
|
110
|
-
|
111
|
-
|
265
|
+
private
|
266
|
+
class Client
|
267
|
+
def initialize(handle)
|
268
|
+
@handle = handle
|
269
|
+
end
|
270
|
+
|
271
|
+
include Geometry
|
272
|
+
|
273
|
+
def geometry
|
274
|
+
rect = Window.buffer(4 * 4)
|
275
|
+
GetClientRect.call(@handle, rect)
|
276
|
+
left, top, right, bottom = rect.unpack('LLLL')
|
277
|
+
|
278
|
+
# From GetClientRect documentation: "In conformance with conventions for
|
279
|
+
# the RECT structure, the bottom-right coordinates of the returned rectangle
|
280
|
+
# are exclusive. In other words, the pixel at (right, bottom) lies immediately
|
281
|
+
# outside the rectangle."
|
282
|
+
# Because of this, we decrement to determine the inclusive coordinate.
|
283
|
+
right -= 1
|
284
|
+
bottom -= 1
|
285
|
+
|
286
|
+
width = right - left + 1
|
287
|
+
height = bottom - top + 1
|
112
288
|
|
113
|
-
|
114
|
-
|
115
|
-
|
289
|
+
top_left = Window.point(left, top)
|
290
|
+
ClientToScreen.call(@handle, top_left)
|
291
|
+
screen_left, screen_top = top_left.unpack('LL')
|
116
292
|
|
117
|
-
|
293
|
+
screen_right = screen_left + width - 1
|
294
|
+
screen_bottom = screen_top + height - 1
|
295
|
+
|
296
|
+
return Rect.new(screen_left, screen_top, screen_right, screen_bottom)
|
297
|
+
end
|
118
298
|
end
|
119
299
|
|
120
|
-
private
|
121
300
|
def self.get_title(handle)
|
122
301
|
if GetWindowTextW.call(handle, buffer = "\0" * 1024, buffer.length) == 0
|
123
302
|
nil
|
@@ -133,10 +312,10 @@ module Win32
|
|
133
312
|
end
|
134
313
|
|
135
314
|
def self.buffer(bytes)
|
136
|
-
|
315
|
+
"\0" * bytes
|
137
316
|
end
|
138
317
|
|
139
|
-
def point(x, y)
|
318
|
+
def self.point(x, y)
|
140
319
|
[x, y].pack('LL')
|
141
320
|
end
|
142
321
|
end
|
@@ -159,9 +338,6 @@ module Win32
|
|
159
338
|
# http://msdn.microsoft.com/en-us/library/windows/desktop/ms633522(v=vs.85).aspx
|
160
339
|
GetWindowThreadProcessId = API.new('GetWindowThreadProcessId', 'IP', 'L', 'user32')
|
161
340
|
|
162
|
-
# http://msdn.microsoft.com/en-us/library/windows/desktop/ms632678(v=vs.85).aspx
|
163
|
-
CloseWindow = API.new('CloseWindow', 'I', 'L', 'user32')
|
164
|
-
|
165
341
|
# http://msdn.microsoft.com/en-us/library/windows/desktop/ms633504(v=vs.85).aspx
|
166
342
|
GetDesktopWindow = API.new('GetDesktopWindow', '', 'I', 'user32')
|
167
343
|
|
@@ -174,9 +350,38 @@ module Win32
|
|
174
350
|
# http://msdn.microsoft.com/en-us/library/windows/desktop/ms633527(v=vs.85).aspx
|
175
351
|
IsIconic = API.new('IsIconic', 'I', 'I', 'user32')
|
176
352
|
|
353
|
+
# http://msdn.microsoft.com/en-us/library/windows/desktop/ms633531(v=vs.85).aspx
|
354
|
+
IsZoomed = API.new('IsZoomed', 'I', 'I', 'user32')
|
355
|
+
|
177
356
|
# http://msdn.microsoft.com/en-us/library/windows/desktop/ms633530(v=vs.85).aspx
|
178
357
|
IsWindowVisible = API.new('IsWindowVisible', 'I', 'I', 'user32')
|
179
358
|
|
359
|
+
# http://msdn.microsoft.com/en-us/library/windows/desktop/ms633548(v=vs.85).aspx
|
360
|
+
ShowWindow = API.new('ShowWindow', 'II', 'I', 'user32')
|
361
|
+
|
362
|
+
# http://msdn.microsoft.com/en-us/library/windows/desktop/ms633558(v=vs.85).aspx
|
363
|
+
WindowFromPoint = API.new('WindowFromPoint', 'LL', 'I', 'user32')
|
364
|
+
|
365
|
+
# http://msdn.microsoft.com/en-us/library/windows/desktop/ms632673(v=vs.85).aspx
|
366
|
+
BringWindowToTop = API.new('BringWindowToTop', 'I', 'I', 'user32')
|
367
|
+
|
368
|
+
# http://msdn.microsoft.com/en-us/library/windows/desktop/ms633528(v=vs.85).aspx
|
369
|
+
IsWindow = API.new('IsWindow', 'I', 'I', 'user32')
|
370
|
+
|
371
|
+
SW_FORCEMINIMIZE = 11
|
372
|
+
SW_HIDE = 0
|
373
|
+
SW_MAXIMIZE = 3
|
374
|
+
SW_MINIMIZE = 6
|
375
|
+
SW_RESTORE = 9
|
376
|
+
SW_SHOW = 5
|
377
|
+
SW_SHOWDEFAULT = 10
|
378
|
+
SW_SHOWMAXIMIZED = 3
|
379
|
+
SW_SHOWMINIMIZED = 2
|
380
|
+
SW_SHOWMINNOACTIVE = 7
|
381
|
+
SW_SHOWNA = 8
|
382
|
+
SW_SHOWNOACTIVATE = 4
|
383
|
+
SW_SHOWNORMAL = 1
|
384
|
+
|
180
385
|
HWND_BOTTOM = 1
|
181
386
|
HWND_NOTTOPMOST = -2
|
182
387
|
HWND_TOP = 0
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: win32-window
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0.pre
|
5
5
|
prerelease: 6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,8 +9,24 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-07-
|
12
|
+
date: 2012-07-19 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: win32-api
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 1.4.8
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 1.4.8
|
14
30
|
- !ruby/object:Gem::Dependency
|
15
31
|
name: rake
|
16
32
|
requirement: !ruby/object:Gem::Requirement
|
@@ -18,7 +34,39 @@ dependencies:
|
|
18
34
|
requirements:
|
19
35
|
- - ! '>='
|
20
36
|
- !ruby/object:Gem::Version
|
21
|
-
version: 0.9
|
37
|
+
version: '0.9'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0.9'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: qtbindings
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '4.6'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '4.6'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: win32-semaphore
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0.4'
|
22
70
|
type: :development
|
23
71
|
prerelease: false
|
24
72
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -26,7 +74,7 @@ dependencies:
|
|
26
74
|
requirements:
|
27
75
|
- - ! '>='
|
28
76
|
- !ruby/object:Gem::Version
|
29
|
-
version: 0.
|
77
|
+
version: '0.4'
|
30
78
|
description: ! " A Ruby library to work with Microsoft Windows' Win32 window management
|
31
79
|
APIs,\n including search, enumeration, and window manipulation.\n"
|
32
80
|
email: schmch@gmail.com
|
@@ -58,7 +106,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
58
106
|
version: 1.3.1
|
59
107
|
requirements: []
|
60
108
|
rubyforge_project:
|
61
|
-
rubygems_version: 1.8.
|
109
|
+
rubygems_version: 1.8.24
|
62
110
|
signing_key:
|
63
111
|
specification_version: 3
|
64
112
|
summary: Ruby interface to the Win32 window management APIs.
|