win32-window 0.1.0.pre → 0.2.0.pre
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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.
|