ffi-wingui-core 0.2.0 → 0.3.0
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/examples/Command.rbw +52 -53
- data/examples/Hello1.rbw +21 -0
- data/examples/LifeCycle.rbw +38 -28
- data/examples/LifeCycle1.rbw +38 -28
- data/examples/Minimal.rbw +38 -28
- data/examples/Scribble.rbw +246 -0
- data/examples/WndExtra.rbw +39 -45
- data/lib/ffi-wingui-core.rb +339 -161
- metadata +6 -4
@@ -0,0 +1,246 @@
|
|
1
|
+
require 'ffi-wingui-core'
|
2
|
+
|
3
|
+
include WinGUI
|
4
|
+
|
5
|
+
EnableVisualStyles()
|
6
|
+
|
7
|
+
APPNAME = L(File.basename(__FILE__, '.rbw'))
|
8
|
+
|
9
|
+
WndExtra = Struct.new(
|
10
|
+
:scribbles,
|
11
|
+
:hpen
|
12
|
+
)
|
13
|
+
|
14
|
+
class WndExtra
|
15
|
+
REFS = {}
|
16
|
+
|
17
|
+
def initialize(*args)
|
18
|
+
super
|
19
|
+
|
20
|
+
REFS[object_id] = self
|
21
|
+
|
22
|
+
ObjectSpace.define_finalizer(self, -> id {
|
23
|
+
REFS.delete(id)
|
24
|
+
})
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def onCreate(hwnd,
|
29
|
+
cs
|
30
|
+
)
|
31
|
+
xtra = WndExtra::REFS[GetWindowLong(hwnd, GWL_USERDATA)]
|
32
|
+
|
33
|
+
xtra[:scribbles] = []
|
34
|
+
|
35
|
+
LOGPEN.new { |lp|
|
36
|
+
lp[:lopnWidth][:x] = DPIAwareX(4)
|
37
|
+
lp[:lopnColor] = RGB(255, 0, 0)
|
38
|
+
|
39
|
+
xtra[:hpen] = CreatePenIndirect(lp)
|
40
|
+
}
|
41
|
+
|
42
|
+
0
|
43
|
+
end
|
44
|
+
|
45
|
+
def onDestroy(hwnd)
|
46
|
+
xtra = WndExtra::REFS[GetWindowLong(hwnd, GWL_USERDATA)]
|
47
|
+
|
48
|
+
DeleteObject(xtra[:hpen])
|
49
|
+
|
50
|
+
PostQuitMessage(0); 0
|
51
|
+
end
|
52
|
+
|
53
|
+
def onPaint(hwnd,
|
54
|
+
ps
|
55
|
+
)
|
56
|
+
xtra = WndExtra::REFS[GetWindowLong(hwnd, GWL_USERDATA)]
|
57
|
+
|
58
|
+
hdefpen = SelectObject(ps[:hdc], xtra[:hpen])
|
59
|
+
|
60
|
+
xtra[:scribbles].each { |scribble|
|
61
|
+
MoveToEx(ps[:hdc], *scribble[0], nil)
|
62
|
+
|
63
|
+
scribble.each { |x, y|
|
64
|
+
LineTo(ps[:hdc], x, y)
|
65
|
+
}
|
66
|
+
}
|
67
|
+
|
68
|
+
0
|
69
|
+
ensure
|
70
|
+
SelectObject(ps[:hdc], hdefpen)
|
71
|
+
end
|
72
|
+
|
73
|
+
def onLButtonDown(hwnd,
|
74
|
+
x, y
|
75
|
+
)
|
76
|
+
xtra = WndExtra::REFS[GetWindowLong(hwnd, GWL_USERDATA)]
|
77
|
+
|
78
|
+
SetCapture(hwnd)
|
79
|
+
|
80
|
+
(xtra[:scribbles] << []).last << [x, y]
|
81
|
+
|
82
|
+
RECT.new { |rect|
|
83
|
+
rect[:left] = x - DPIAwareX(2)
|
84
|
+
rect[:top] = y - DPIAwareY(2)
|
85
|
+
rect[:right] = x + DPIAwareX(2)
|
86
|
+
rect[:bottom] = y + DPIAwareY(2)
|
87
|
+
|
88
|
+
InvalidateRect(hwnd, rect, 1)
|
89
|
+
}
|
90
|
+
|
91
|
+
0
|
92
|
+
end
|
93
|
+
|
94
|
+
def onLButtonUp(hwnd,
|
95
|
+
x, y
|
96
|
+
)
|
97
|
+
xtra = WndExtra::REFS[GetWindowLong(hwnd, GWL_USERDATA)]
|
98
|
+
|
99
|
+
ReleaseCapture()
|
100
|
+
|
101
|
+
0
|
102
|
+
end
|
103
|
+
|
104
|
+
def onMouseMove(hwnd,
|
105
|
+
x, y
|
106
|
+
)
|
107
|
+
return 0 if GetCapture() != hwnd
|
108
|
+
|
109
|
+
xtra = WndExtra::REFS[GetWindowLong(hwnd, GWL_USERDATA)]
|
110
|
+
|
111
|
+
xtra[:scribbles].last << [x, y]
|
112
|
+
|
113
|
+
InvalidateRect(hwnd, nil, 0)
|
114
|
+
|
115
|
+
0
|
116
|
+
end
|
117
|
+
|
118
|
+
def onRButtonDown(hwnd,
|
119
|
+
x, y
|
120
|
+
)
|
121
|
+
return 0 if GetCapture() == hwnd
|
122
|
+
|
123
|
+
xtra = WndExtra::REFS[GetWindowLong(hwnd, GWL_USERDATA)]
|
124
|
+
|
125
|
+
xtra[:scribbles].clear
|
126
|
+
|
127
|
+
InvalidateRect(hwnd, nil, 1)
|
128
|
+
|
129
|
+
0
|
130
|
+
end
|
131
|
+
|
132
|
+
WindowProc = FFI::Function.new(:long,
|
133
|
+
[:pointer, :uint, :uint, :long],
|
134
|
+
convention: :stdcall
|
135
|
+
) { |hwnd, uMsg, wParam, lParam|
|
136
|
+
begin
|
137
|
+
result = case uMsg
|
138
|
+
when WM_NCCREATE
|
139
|
+
DefWindowProc(hwnd, uMsg, wParam, lParam)
|
140
|
+
|
141
|
+
SetWindowLong(hwnd,
|
142
|
+
GWL_USERDATA,
|
143
|
+
CREATESTRUCT.new(FFI::Pointer.new(lParam))[:lpCreateParams].to_i
|
144
|
+
)
|
145
|
+
|
146
|
+
1
|
147
|
+
when WM_CREATE
|
148
|
+
onCreate(hwnd, CREATESTRUCT.new(FFI::Pointer.new(lParam)))
|
149
|
+
when WM_DESTROY
|
150
|
+
onDestroy(hwnd)
|
151
|
+
|
152
|
+
when WM_PAINT
|
153
|
+
r = nil
|
154
|
+
|
155
|
+
if GetUpdateRect(hwnd, nil, 0) != 0
|
156
|
+
PAINTSTRUCT.new { |ps|
|
157
|
+
BeginPaint(hwnd, ps)
|
158
|
+
|
159
|
+
begin
|
160
|
+
r = onPaint(hwnd, ps)
|
161
|
+
ensure
|
162
|
+
EndPaint(hwnd, ps)
|
163
|
+
end
|
164
|
+
}
|
165
|
+
end
|
166
|
+
|
167
|
+
when WM_LBUTTONDOWN
|
168
|
+
onLButtonDown(hwnd, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))
|
169
|
+
when WM_LBUTTONUP
|
170
|
+
onLButtonUp(hwnd, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))
|
171
|
+
when WM_MOUSEMOVE
|
172
|
+
onMouseMove(hwnd, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))
|
173
|
+
|
174
|
+
when WM_RBUTTONDOWN
|
175
|
+
onRButtonDown(hwnd, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))
|
176
|
+
end
|
177
|
+
|
178
|
+
result || DefWindowProc(hwnd, uMsg, wParam, lParam)
|
179
|
+
rescue
|
180
|
+
case MessageBox(hwnd,
|
181
|
+
L(Util.FormatException($!)),
|
182
|
+
APPNAME,
|
183
|
+
MB_ABORTRETRYIGNORE | MB_ICONERROR
|
184
|
+
)
|
185
|
+
when IDABORT
|
186
|
+
PostQuitMessage(2)
|
187
|
+
when IDRETRY
|
188
|
+
retry
|
189
|
+
end
|
190
|
+
end
|
191
|
+
}
|
192
|
+
|
193
|
+
def main
|
194
|
+
xtra = WndExtra.new
|
195
|
+
|
196
|
+
WNDCLASSEX.new { |wc|
|
197
|
+
wc[:cbSize] = wc.size
|
198
|
+
wc[:lpfnWndProc] = WindowProc
|
199
|
+
wc[:cbWndExtra] = FFI::Type::Builtin::POINTER.size
|
200
|
+
wc[:hInstance] = GetModuleHandle(nil)
|
201
|
+
wc[:hIcon] = LoadIcon(nil, IDI_APPLICATION)
|
202
|
+
wc[:hCursor] = LoadCursor(nil, IDC_CROSS)
|
203
|
+
wc[:hbrBackground] = FFI::Pointer.new(COLOR_WINDOW + 1)
|
204
|
+
|
205
|
+
PWSTR(APPNAME) { |className|
|
206
|
+
wc[:lpszClassName] = className
|
207
|
+
|
208
|
+
DetonateLastError(0, :RegisterClassEx,
|
209
|
+
wc
|
210
|
+
)
|
211
|
+
}
|
212
|
+
}
|
213
|
+
|
214
|
+
hwnd = CreateWindowEx(
|
215
|
+
0, APPNAME, APPNAME, WS_OVERLAPPEDWINDOW,
|
216
|
+
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
|
217
|
+
nil, nil, GetModuleHandle(nil), FFI::Pointer.new(xtra.object_id)
|
218
|
+
)
|
219
|
+
|
220
|
+
raise "CreateWindowEx failed (last error: #{GetLastError()})" if
|
221
|
+
hwnd.null? && GetLastError() != 0
|
222
|
+
|
223
|
+
exit(0) if hwnd.null?
|
224
|
+
|
225
|
+
ShowWindow(hwnd, SW_SHOWNORMAL)
|
226
|
+
UpdateWindow(hwnd)
|
227
|
+
|
228
|
+
MSG.new { |msg|
|
229
|
+
until DetonateLastError(-1, :GetMessage,
|
230
|
+
msg, nil, 0, 0
|
231
|
+
) == 0
|
232
|
+
TranslateMessage(msg)
|
233
|
+
DispatchMessage(msg)
|
234
|
+
end
|
235
|
+
|
236
|
+
exit(msg[:wParam])
|
237
|
+
}
|
238
|
+
rescue
|
239
|
+
MessageBox(hwnd,
|
240
|
+
L(Util.FormatException($!)),
|
241
|
+
APPNAME,
|
242
|
+
MB_ICONERROR
|
243
|
+
); exit(1)
|
244
|
+
end
|
245
|
+
|
246
|
+
main
|
data/examples/WndExtra.rbw
CHANGED
@@ -8,26 +8,11 @@ APPNAME = L(File.basename(__FILE__, '.rbw'))
|
|
8
8
|
|
9
9
|
WndExtra = Struct.new(
|
10
10
|
:foo
|
11
|
-
)
|
12
|
-
|
13
|
-
class WndExtra
|
14
|
-
REFS = {}
|
15
|
-
|
16
|
-
def initialize(*args)
|
17
|
-
super
|
18
|
-
|
19
|
-
REFS[object_id] = self
|
20
|
-
|
21
|
-
ObjectSpace.define_finalizer(self, -> id {
|
22
|
-
REFS.delete(id)
|
23
|
-
})
|
24
|
-
end
|
25
|
-
end
|
11
|
+
).send(:include, Util::Id2RefTracking)
|
26
12
|
|
27
13
|
def onCreate(hwnd,
|
28
14
|
cs
|
29
15
|
)
|
30
|
-
#xtra = ObjectSpace._id2ref(GetWindowLong(hwnd, GWL_USERDATA))
|
31
16
|
xtra = WndExtra::REFS[GetWindowLong(hwnd, GWL_USERDATA)]
|
32
17
|
|
33
18
|
xtra[:foo] = L('Foo')
|
@@ -36,7 +21,6 @@ def onCreate(hwnd,
|
|
36
21
|
end
|
37
22
|
|
38
23
|
def onDestroy(hwnd)
|
39
|
-
#xtra = ObjectSpace._id2ref(GetWindowLong(hwnd, GWL_USERDATA))
|
40
24
|
xtra = WndExtra::REFS[GetWindowLong(hwnd, GWL_USERDATA)]
|
41
25
|
|
42
26
|
MessageBox(nil,
|
@@ -71,31 +55,39 @@ begin
|
|
71
55
|
|
72
56
|
result || DefWindowProc(hwnd, uMsg, wParam, lParam)
|
73
57
|
rescue
|
74
|
-
MessageBox(
|
75
|
-
L(
|
58
|
+
case MessageBox(hwnd,
|
59
|
+
L(Util.FormatException($!)),
|
76
60
|
APPNAME,
|
77
|
-
MB_ICONERROR
|
78
|
-
)
|
61
|
+
MB_ABORTRETRYIGNORE | MB_ICONERROR
|
62
|
+
)
|
63
|
+
when IDABORT
|
64
|
+
PostQuitMessage(2)
|
65
|
+
when IDRETRY
|
66
|
+
retry
|
67
|
+
end
|
79
68
|
end
|
80
69
|
}
|
81
70
|
|
82
71
|
def main
|
83
|
-
wc = WNDCLASSEX.new
|
84
72
|
xtra = WndExtra.new
|
85
73
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
74
|
+
WNDCLASSEX.new { |wc|
|
75
|
+
wc[:cbSize] = wc.size
|
76
|
+
wc[:lpfnWndProc] = WindowProc
|
77
|
+
wc[:cbWndExtra] = FFI::Type::Builtin::POINTER.size
|
78
|
+
wc[:hInstance] = GetModuleHandle(nil)
|
79
|
+
wc[:hIcon] = LoadIcon(nil, IDI_APPLICATION)
|
80
|
+
wc[:hCursor] = LoadCursor(nil, IDC_ARROW)
|
81
|
+
wc[:hbrBackground] = FFI::Pointer.new(COLOR_WINDOW + 1)
|
82
|
+
|
83
|
+
PWSTR(APPNAME) { |className|
|
84
|
+
wc[:lpszClassName] = className
|
95
85
|
|
96
|
-
|
97
|
-
|
98
|
-
|
86
|
+
DetonateLastError(0, :RegisterClassEx,
|
87
|
+
wc
|
88
|
+
)
|
89
|
+
}
|
90
|
+
}
|
99
91
|
|
100
92
|
hwnd = CreateWindowEx(
|
101
93
|
0, APPNAME, APPNAME, WS_OVERLAPPEDWINDOW,
|
@@ -106,22 +98,24 @@ def main
|
|
106
98
|
raise "CreateWindowEx failed (last error: #{GetLastError()})" if
|
107
99
|
hwnd.null? && GetLastError() != 0
|
108
100
|
|
101
|
+
exit(0) if hwnd.null?
|
102
|
+
|
109
103
|
ShowWindow(hwnd, SW_SHOWNORMAL)
|
110
104
|
UpdateWindow(hwnd)
|
111
105
|
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
end
|
106
|
+
MSG.new { |msg|
|
107
|
+
until DetonateLastError(-1, :GetMessage,
|
108
|
+
msg, nil, 0, 0
|
109
|
+
) == 0
|
110
|
+
TranslateMessage(msg)
|
111
|
+
DispatchMessage(msg)
|
112
|
+
end
|
120
113
|
|
121
|
-
|
114
|
+
exit(msg[:wParam])
|
115
|
+
}
|
122
116
|
rescue
|
123
|
-
MessageBox(
|
124
|
-
L(
|
117
|
+
MessageBox(hwnd,
|
118
|
+
L(Util.FormatException($!)),
|
125
119
|
APPNAME,
|
126
120
|
MB_ICONERROR
|
127
121
|
); exit(1)
|
data/lib/ffi-wingui-core.rb
CHANGED
@@ -3,51 +3,104 @@ require 'ffi'
|
|
3
3
|
module WinGUI
|
4
4
|
extend FFI::Library
|
5
5
|
|
6
|
+
#{ common
|
7
|
+
module Util
|
8
|
+
def FormatException(ex)
|
9
|
+
str, trace = ex.to_s, ex.backtrace
|
10
|
+
|
11
|
+
str << "\n\n-- backtrace --\n\n" << trace.join("\n") if trace
|
12
|
+
|
13
|
+
str
|
14
|
+
end
|
15
|
+
|
16
|
+
module_function :FormatException
|
17
|
+
|
18
|
+
module Id2RefTracking
|
19
|
+
REFS = {}
|
20
|
+
|
21
|
+
def initialize(*args)
|
22
|
+
super
|
23
|
+
|
24
|
+
REFS[object_id] = self
|
25
|
+
|
26
|
+
ObjectSpace.define_finalizer(self, -> id {
|
27
|
+
REFS.delete(id)
|
28
|
+
})
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
module ScopedStruct
|
33
|
+
def new(*args)
|
34
|
+
raise ArgumentError, 'Cannot accept both arguments and a block' if
|
35
|
+
args.length > 0 && block_given?
|
36
|
+
|
37
|
+
struct = super
|
38
|
+
|
39
|
+
return struct unless block_given?
|
40
|
+
|
41
|
+
begin
|
42
|
+
yield struct
|
43
|
+
ensure
|
44
|
+
struct.pointer.free
|
45
|
+
|
46
|
+
p "Native memory for #{struct} freed" if $DEBUG
|
47
|
+
end
|
48
|
+
|
49
|
+
nil
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
6
54
|
INVALID_HANDLE_VALUE = FFI::Pointer.new(-1)
|
7
55
|
|
8
|
-
def MAKEWORD(
|
9
|
-
(
|
56
|
+
def MAKEWORD(lobyte, hibyte)
|
57
|
+
(lobyte & 0xff) | ((hibyte & 0xff) << 8)
|
10
58
|
end
|
11
59
|
|
12
|
-
def LOBYTE(
|
13
|
-
|
60
|
+
def LOBYTE(word)
|
61
|
+
word & 0xff
|
14
62
|
end
|
15
63
|
|
16
|
-
def HIBYTE(
|
17
|
-
(
|
64
|
+
def HIBYTE(word)
|
65
|
+
(word >> 8) & 0xff
|
18
66
|
end
|
19
67
|
|
20
|
-
def MAKELONG(
|
21
|
-
(
|
68
|
+
def MAKELONG(loword, hiword)
|
69
|
+
(loword & 0xffff) | ((hiword & 0xffff) << 16)
|
22
70
|
end
|
23
71
|
|
24
|
-
def LOWORD(
|
25
|
-
|
72
|
+
def LOWORD(long)
|
73
|
+
long & 0xffff
|
26
74
|
end
|
27
75
|
|
28
|
-
def HIWORD(
|
29
|
-
(
|
76
|
+
def HIWORD(long)
|
77
|
+
(long >> 16) & 0xffff
|
30
78
|
end
|
31
79
|
|
32
80
|
module_function \
|
33
81
|
:MAKEWORD, :LOBYTE, :HIBYTE,
|
34
82
|
:MAKELONG, :LOWORD, :HIWORD
|
35
83
|
|
36
|
-
def L(
|
37
|
-
(
|
84
|
+
def L(str)
|
85
|
+
(str << "\0").encode!('utf-16le')
|
38
86
|
end
|
39
87
|
|
40
|
-
def PWSTR(
|
88
|
+
def PWSTR(wstr)
|
41
89
|
raise 'Invalid Unicode string' unless
|
42
|
-
|
43
|
-
|
90
|
+
wstr.encoding == Encoding::UTF_16LE && wstr[-1] == L('')
|
91
|
+
|
92
|
+
ptr = FFI::MemoryPointer.new(:ushort, wstr.length).
|
93
|
+
put_bytes(0, wstr)
|
44
94
|
|
45
|
-
|
46
|
-
put_bytes(0, ws)
|
95
|
+
return ptr unless block_given?
|
47
96
|
|
48
|
-
|
97
|
+
begin
|
98
|
+
yield ptr
|
99
|
+
ensure
|
100
|
+
ptr.free
|
49
101
|
|
50
|
-
|
102
|
+
p "Native copy of '#{wstr[0...-1].encode($0.encoding)}' freed" if $DEBUG
|
103
|
+
end
|
51
104
|
|
52
105
|
nil
|
53
106
|
end
|
@@ -55,55 +108,33 @@ module WinGUI
|
|
55
108
|
module_function :L, :PWSTR
|
56
109
|
|
57
110
|
class POINT < FFI::Struct
|
111
|
+
extend Util::ScopedStruct
|
112
|
+
|
58
113
|
layout \
|
59
114
|
:x, :long,
|
60
115
|
:y, :long
|
61
|
-
|
62
|
-
def self.[](x, y)
|
63
|
-
new.tap { |point|
|
64
|
-
point[:x], point[:y] = x, y
|
65
|
-
}
|
66
|
-
end
|
67
|
-
|
68
|
-
def to_a
|
69
|
-
[self[:x], self[:y]]
|
70
|
-
end
|
71
116
|
end
|
72
117
|
|
73
118
|
class SIZE < FFI::Struct
|
119
|
+
extend Util::ScopedStruct
|
120
|
+
|
74
121
|
layout \
|
75
122
|
:cx, :long,
|
76
123
|
:cy, :long
|
77
|
-
|
78
|
-
def self.[](cx, cy)
|
79
|
-
new.tap { |size|
|
80
|
-
size[:cx], size[:cy] = cx, cy
|
81
|
-
}
|
82
|
-
end
|
83
|
-
|
84
|
-
def to_a
|
85
|
-
[self[:cx], self[:cy]]
|
86
|
-
end
|
87
124
|
end
|
88
125
|
|
89
126
|
class RECT < FFI::Struct
|
127
|
+
extend Util::ScopedStruct
|
128
|
+
|
90
129
|
layout \
|
91
130
|
:left, :long,
|
92
131
|
:top, :long,
|
93
132
|
:right, :long,
|
94
133
|
:bottom, :long
|
95
|
-
|
96
|
-
def self.[](l, t, r, b)
|
97
|
-
new.tap { |rect|
|
98
|
-
rect[:left], rect[:top], rect[:right], rect[:bottom] = l, t, r, b
|
99
|
-
}
|
100
|
-
end
|
101
|
-
|
102
|
-
def to_a
|
103
|
-
[self[:left], self[:top], self[:right], self[:bottom]]
|
104
|
-
end
|
105
134
|
end
|
135
|
+
#}
|
106
136
|
|
137
|
+
#{ kernel32
|
107
138
|
ffi_lib 'kernel32'
|
108
139
|
ffi_convention :stdcall
|
109
140
|
|
@@ -136,6 +167,8 @@ module WinGUI
|
|
136
167
|
module_function :Detonate, :DetonateLastError
|
137
168
|
|
138
169
|
class OSVERSIONINFOEX < FFI::Struct
|
170
|
+
extend Util::ScopedStruct
|
171
|
+
|
139
172
|
layout \
|
140
173
|
:dwOSVersionInfoSize, :ulong,
|
141
174
|
:dwMajorVersion, :ulong,
|
@@ -151,10 +184,12 @@ module WinGUI
|
|
151
184
|
end
|
152
185
|
|
153
186
|
attach_function :GetVersionEx, :GetVersionExW, [
|
154
|
-
:pointer
|
187
|
+
:pointer # OSVERSIONINFOEX.by_ref
|
155
188
|
], :int
|
156
189
|
|
157
|
-
|
190
|
+
OSVERSION = OSVERSIONINFOEX.new.tap { |ovi|
|
191
|
+
at_exit { OSVERSION.pointer.free }
|
192
|
+
|
158
193
|
ovi[:dwOSVersionInfoSize] = ovi.size
|
159
194
|
|
160
195
|
DetonateLastError(0, :GetVersionEx,
|
@@ -201,8 +236,8 @@ module WinGUI
|
|
201
236
|
#}
|
202
237
|
|
203
238
|
NTDDI_VERSION = MAKELONG(
|
204
|
-
MAKEWORD(
|
205
|
-
MAKEWORD(
|
239
|
+
MAKEWORD(OSVERSION[:wServicePackMinor], OSVERSION[:wServicePackMajor]),
|
240
|
+
MAKEWORD(OSVERSION[:dwMinorVersion], OSVERSION[:dwMajorVersion])
|
206
241
|
)
|
207
242
|
|
208
243
|
#{ WINxxx
|
@@ -214,6 +249,14 @@ module WinGUI
|
|
214
249
|
|
215
250
|
WINVER = HIWORD(NTDDI_VERSION)
|
216
251
|
|
252
|
+
if WINVER == WIN2K
|
253
|
+
class << FFI::Struct
|
254
|
+
def by_ref(*args)
|
255
|
+
FFI::Type::Builtin::POINTER
|
256
|
+
end
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
217
260
|
attach_function :GetModuleHandle, :GetModuleHandleW, [
|
218
261
|
:buffer_in
|
219
262
|
], :pointer
|
@@ -228,6 +271,8 @@ module WinGUI
|
|
228
271
|
|
229
272
|
if WINVER >= WINXP
|
230
273
|
class ACTCTX < FFI::Struct
|
274
|
+
extend Util::ScopedStruct
|
275
|
+
|
231
276
|
layout \
|
232
277
|
:cbSize, :ulong,
|
233
278
|
:dwFlags, :ulong,
|
@@ -241,7 +286,7 @@ module WinGUI
|
|
241
286
|
end
|
242
287
|
|
243
288
|
attach_function :CreateActCtx, :CreateActCtxW, [
|
244
|
-
|
289
|
+
ACTCTX.by_ref
|
245
290
|
], :pointer
|
246
291
|
|
247
292
|
attach_function :ReleaseActCtx, [
|
@@ -281,7 +326,7 @@ module WinGUI
|
|
281
326
|
raise 'Visual styles already enabled' if
|
282
327
|
COMMON_CONTROLS_ACTCTX[:activated]
|
283
328
|
|
284
|
-
manifest = "#{ENV['TEMP']}/
|
329
|
+
manifest = "#{ENV['TEMP']}/WinGUI.Common-Controls.manifest"
|
285
330
|
|
286
331
|
File.open(manifest, 'w:utf-8') { |file|
|
287
332
|
file << <<-XML
|
@@ -303,15 +348,18 @@ module WinGUI
|
|
303
348
|
XML
|
304
349
|
}
|
305
350
|
|
306
|
-
|
351
|
+
ACTCTX.new { |ac|
|
352
|
+
ac[:cbSize] = ac.size
|
307
353
|
|
308
|
-
|
309
|
-
|
354
|
+
PWSTR(L(manifest)) { |source|
|
355
|
+
ac[:lpSource] = source
|
310
356
|
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
357
|
+
COMMON_CONTROLS_ACTCTX[:handle] =
|
358
|
+
DetonateLastError(INVALID_HANDLE_VALUE, :CreateActCtx,
|
359
|
+
ac
|
360
|
+
)
|
361
|
+
}
|
362
|
+
}
|
315
363
|
|
316
364
|
DetonateLastError(0, :ActivateActCtx,
|
317
365
|
COMMON_CONTROLS_ACTCTX[:handle], COMMON_CONTROLS_ACTCTX[:cookie]
|
@@ -332,7 +380,9 @@ module WinGUI
|
|
332
380
|
:int,
|
333
381
|
:int
|
334
382
|
], :int
|
383
|
+
#}
|
335
384
|
|
385
|
+
#{ gdi32
|
336
386
|
ffi_lib 'gdi32'
|
337
387
|
ffi_convention :stdcall
|
338
388
|
|
@@ -352,18 +402,27 @@ module WinGUI
|
|
352
402
|
LOBYTE(rgb >> 16)
|
353
403
|
end
|
354
404
|
|
355
|
-
module_function
|
356
|
-
:RGB, :GetRValue, :GetGValue, :GetBValue
|
405
|
+
module_function :RGB, :GetRValue, :GetGValue, :GetBValue
|
357
406
|
|
407
|
+
#{ GetDeviceCaps indices
|
358
408
|
LOGPIXELSX = 88
|
359
409
|
LOGPIXELSY = 90
|
410
|
+
#}
|
360
411
|
|
361
412
|
attach_function :GetDeviceCaps, [
|
362
413
|
:pointer,
|
363
414
|
:int
|
364
415
|
], :int
|
365
416
|
|
417
|
+
def DPIAwareFontHeight(pointSize)
|
418
|
+
-MulDiv(pointSize, DPIY, 72)
|
419
|
+
end
|
420
|
+
|
421
|
+
module_function :DPIAwareFontHeight
|
422
|
+
|
366
423
|
class LOGFONT < FFI::Struct
|
424
|
+
extend Util::ScopedStruct
|
425
|
+
|
367
426
|
layout \
|
368
427
|
:lfHeight, :long,
|
369
428
|
:lfWidth, :long,
|
@@ -382,17 +441,44 @@ module WinGUI
|
|
382
441
|
end
|
383
442
|
|
384
443
|
attach_function :CreateFontIndirect, :CreateFontIndirectW, [
|
385
|
-
:
|
444
|
+
LOGFONT.by_ref(:in)
|
445
|
+
], :pointer
|
446
|
+
|
447
|
+
class LOGBRUSH < FFI::Struct
|
448
|
+
extend Util::ScopedStruct
|
449
|
+
|
450
|
+
layout \
|
451
|
+
:lbStyle, :uint,
|
452
|
+
:lbColor, :ulong,
|
453
|
+
:lbHatch, :ulong
|
454
|
+
end
|
455
|
+
|
456
|
+
attach_function :CreateBrushIndirect, [
|
457
|
+
LOGBRUSH.by_ref(:in)
|
458
|
+
], :pointer
|
459
|
+
|
460
|
+
class LOGPEN < FFI::Struct
|
461
|
+
extend Util::ScopedStruct
|
462
|
+
|
463
|
+
layout \
|
464
|
+
:lopnStyle, :uint,
|
465
|
+
:lopnWidth, POINT,
|
466
|
+
:lopnColor, :ulong
|
467
|
+
end
|
468
|
+
|
469
|
+
attach_function :CreatePenIndirect, [
|
470
|
+
LOGPEN.by_ref(:in)
|
386
471
|
], :pointer
|
387
472
|
|
388
473
|
attach_function :DeleteObject, [
|
389
474
|
:pointer
|
390
475
|
], :int
|
391
476
|
|
392
|
-
attach_function :
|
477
|
+
attach_function :GetObject, :GetObjectW, [
|
393
478
|
:pointer,
|
479
|
+
:int,
|
394
480
|
:pointer
|
395
|
-
], :
|
481
|
+
], :int
|
396
482
|
|
397
483
|
attach_function :SetBkColor, [
|
398
484
|
:pointer,
|
@@ -412,11 +498,24 @@ module WinGUI
|
|
412
498
|
:pointer
|
413
499
|
], :ulong
|
414
500
|
|
501
|
+
attach_function :SelectObject, [
|
502
|
+
:pointer,
|
503
|
+
:pointer
|
504
|
+
], :pointer
|
505
|
+
|
506
|
+
attach_function :TextOut, :TextOutW, [
|
507
|
+
:pointer,
|
508
|
+
:int,
|
509
|
+
:int,
|
510
|
+
:buffer_in,
|
511
|
+
:int
|
512
|
+
], :int
|
513
|
+
|
415
514
|
attach_function :MoveToEx, [
|
416
515
|
:pointer,
|
417
516
|
:int,
|
418
517
|
:int,
|
419
|
-
:
|
518
|
+
POINT.by_ref(:out)
|
420
519
|
], :int
|
421
520
|
|
422
521
|
attach_function :LineTo, [
|
@@ -424,7 +523,9 @@ module WinGUI
|
|
424
523
|
:int,
|
425
524
|
:int
|
426
525
|
], :int
|
526
|
+
#}
|
427
527
|
|
528
|
+
#{ user32
|
428
529
|
ffi_lib 'user32'
|
429
530
|
ffi_convention :stdcall
|
430
531
|
|
@@ -434,10 +535,95 @@ module WinGUI
|
|
434
535
|
], :int
|
435
536
|
|
436
537
|
Detonate(0, :SetProcessDPIAware) unless
|
437
|
-
Object.const_defined?(:DPI_AWARE) &&
|
438
|
-
|
538
|
+
Object.const_defined?(:DPI_AWARE) && !DPI_AWARE
|
539
|
+
end
|
540
|
+
|
541
|
+
attach_function :GetDC, [
|
542
|
+
:pointer
|
543
|
+
], :pointer
|
544
|
+
|
545
|
+
attach_function :ReleaseDC, [
|
546
|
+
:pointer,
|
547
|
+
:pointer
|
548
|
+
], :int
|
549
|
+
|
550
|
+
#{ DPIxxx
|
551
|
+
Detonate(FFI::Pointer::NULL, :GetDC,
|
552
|
+
nil
|
553
|
+
).tap { |hdc|
|
554
|
+
DPIX = GetDeviceCaps(hdc, LOGPIXELSX)
|
555
|
+
DPIY = GetDeviceCaps(hdc, LOGPIXELSY)
|
556
|
+
|
557
|
+
ReleaseDC(nil, hdc)
|
558
|
+
}
|
559
|
+
#}
|
560
|
+
|
561
|
+
def DPIAwareX(x)
|
562
|
+
MulDiv(x, DPIX, 96)
|
563
|
+
end
|
564
|
+
|
565
|
+
def DPIAwareY(y)
|
566
|
+
MulDiv(y, DPIY, 96)
|
567
|
+
end
|
568
|
+
|
569
|
+
def DPIAwareXY(*args)
|
570
|
+
raise ArgumentError, 'Expected two or more, even count arguments' if
|
571
|
+
args.length < 2 || args.length.odd?
|
572
|
+
|
573
|
+
args.each_with_index { |arg, i|
|
574
|
+
args[i] = (i.even?) ? DPIAwareX(arg) : DPIAwareY(arg)
|
575
|
+
}
|
576
|
+
end
|
577
|
+
|
578
|
+
module_function :DPIAwareX, :DPIAwareY, :DPIAwareXY
|
579
|
+
|
580
|
+
#{ SM_xxx
|
581
|
+
SM_CXSCREEN = 0
|
582
|
+
SM_CYSCREEN = 1
|
583
|
+
#}
|
584
|
+
|
585
|
+
attach_function :GetSystemMetrics, [
|
586
|
+
:int
|
587
|
+
], :int
|
588
|
+
|
589
|
+
#{ SPI_xxx
|
590
|
+
class NONCLIENTMETRICS < FFI::Struct
|
591
|
+
extend Util::ScopedStruct
|
592
|
+
|
593
|
+
layout *[
|
594
|
+
:cbSize, :uint,
|
595
|
+
:iBorderWidth, :int,
|
596
|
+
:iScrollWidth, :int,
|
597
|
+
:iScrollHeight, :int,
|
598
|
+
:iCaptionWidth, :int,
|
599
|
+
:iCaptionHeight, :int,
|
600
|
+
:lfCaptionFont, LOGFONT,
|
601
|
+
:iSmCaptionWidth, :int,
|
602
|
+
:iSmCaptionHeight, :int,
|
603
|
+
:lfSmCaptionFont, LOGFONT,
|
604
|
+
:iMenuWidth, :int,
|
605
|
+
:iMenuHeight, :int,
|
606
|
+
:lfMenuFont, LOGFONT,
|
607
|
+
:lfStatusFont, LOGFONT,
|
608
|
+
:lfMessageFont, LOGFONT,
|
609
|
+
(WINVER >= WINVISTA) ? [:iPaddedBorderWidth, :int] : nil
|
610
|
+
].tap { |layout|
|
611
|
+
layout.flatten!
|
612
|
+
layout.compact!
|
613
|
+
}
|
439
614
|
end
|
440
615
|
|
616
|
+
SPI_SETNONCLIENTMETRICS = 0x002A
|
617
|
+
SPI_GETNONCLIENTMETRICS = 0x0029
|
618
|
+
#}
|
619
|
+
|
620
|
+
attach_function :SystemParametersInfo, :SystemParametersInfoW, [
|
621
|
+
:uint,
|
622
|
+
:uint,
|
623
|
+
:pointer,
|
624
|
+
:uint
|
625
|
+
], :int
|
626
|
+
|
441
627
|
#{ MB_xxx
|
442
628
|
MB_OK = 0x00000000
|
443
629
|
MB_OKCANCEL = 0x00000001
|
@@ -473,6 +659,9 @@ module WinGUI
|
|
473
659
|
IDIGNORE = 5
|
474
660
|
IDTRYAGAIN = 10
|
475
661
|
IDCONTINUE = 11
|
662
|
+
if WINVER >= WINXP
|
663
|
+
IDTIMEOUT = 32000
|
664
|
+
end
|
476
665
|
#}
|
477
666
|
|
478
667
|
attach_function :MessageBox, :MessageBoxW, [
|
@@ -482,6 +671,20 @@ module WinGUI
|
|
482
671
|
:uint
|
483
672
|
], :int
|
484
673
|
|
674
|
+
if WINVER >= WINXP
|
675
|
+
begin
|
676
|
+
attach_function :MessageBoxTimeout, :MessageBoxTimeoutW, [
|
677
|
+
:pointer,
|
678
|
+
:buffer_in,
|
679
|
+
:buffer_in,
|
680
|
+
:uint,
|
681
|
+
:ushort,
|
682
|
+
:ulong
|
683
|
+
], :int
|
684
|
+
rescue FFI::NotFoundError # MessageBoxTimeout is undocumented
|
685
|
+
end
|
686
|
+
end
|
687
|
+
|
485
688
|
#{ CS_xxx
|
486
689
|
CS_DBLCLKS = 0x0008
|
487
690
|
CS_HREDRAW = 0x0002
|
@@ -511,12 +714,21 @@ module WinGUI
|
|
511
714
|
], :long
|
512
715
|
|
513
716
|
#{ IDI_xxx
|
717
|
+
IDI_WINLOGO = FFI::Pointer.new(32517)
|
514
718
|
IDI_APPLICATION = FFI::Pointer.new(32512)
|
719
|
+
if WINVER >= WINVISTA
|
720
|
+
IDI_SHIELD = FFI::Pointer.new(32518)
|
721
|
+
end
|
722
|
+
|
723
|
+
IDI_INFORMATION = FFI::Pointer.new(32516)
|
724
|
+
IDI_WARNING = FFI::Pointer.new(32515)
|
725
|
+
IDI_ERROR = FFI::Pointer.new(32513)
|
726
|
+
IDI_QUESTION = FFI::Pointer.new(32514)
|
515
727
|
#}
|
516
728
|
|
517
729
|
attach_function :LoadIcon, :LoadIconW, [
|
518
730
|
:pointer,
|
519
|
-
:
|
731
|
+
:buffer_in
|
520
732
|
], :pointer
|
521
733
|
|
522
734
|
#{ IDC_xxx
|
@@ -524,6 +736,7 @@ module WinGUI
|
|
524
736
|
IDC_WAIT = FFI::Pointer.new(32514)
|
525
737
|
IDC_APPSTARTING = FFI::Pointer.new(32650)
|
526
738
|
IDC_HAND = FFI::Pointer.new(32649)
|
739
|
+
IDC_CROSS = FFI::Pointer.new(32515)
|
527
740
|
IDC_SIZEALL = FFI::Pointer.new(32646)
|
528
741
|
IDC_SIZENS = FFI::Pointer.new(32645)
|
529
742
|
IDC_SIZEWE = FFI::Pointer.new(32644)
|
@@ -533,7 +746,7 @@ module WinGUI
|
|
533
746
|
|
534
747
|
attach_function :LoadCursor, :LoadCursorW, [
|
535
748
|
:pointer,
|
536
|
-
:
|
749
|
+
:buffer_in
|
537
750
|
], :pointer
|
538
751
|
|
539
752
|
#{ COLOR/CTLCOLOR_xxx
|
@@ -544,6 +757,8 @@ module WinGUI
|
|
544
757
|
#}
|
545
758
|
|
546
759
|
class WNDCLASSEX < FFI::Struct
|
760
|
+
extend Util::ScopedStruct
|
761
|
+
|
547
762
|
layout \
|
548
763
|
:cbSize, :uint,
|
549
764
|
:style, :uint,
|
@@ -560,18 +775,18 @@ module WinGUI
|
|
560
775
|
end
|
561
776
|
|
562
777
|
attach_function :RegisterClassEx, :RegisterClassExW, [
|
563
|
-
:
|
778
|
+
WNDCLASSEX.by_ref(:in)
|
564
779
|
], :ushort
|
565
780
|
|
566
781
|
attach_function :UnregisterClass, :UnregisterClassW, [
|
567
|
-
:
|
782
|
+
:buffer_in,
|
568
783
|
:pointer
|
569
784
|
], :int
|
570
785
|
|
571
786
|
attach_function :GetClassInfoEx, :GetClassInfoExW, [
|
572
787
|
:pointer,
|
573
|
-
:
|
574
|
-
:
|
788
|
+
:buffer_in,
|
789
|
+
WNDCLASSEX.by_ref(:out)
|
575
790
|
], :int
|
576
791
|
|
577
792
|
#{ WS_xxx
|
@@ -661,7 +876,7 @@ module WinGUI
|
|
661
876
|
|
662
877
|
attach_function :GetClassName, :GetClassNameW, [
|
663
878
|
:pointer,
|
664
|
-
:
|
879
|
+
:buffer_out,
|
665
880
|
:int
|
666
881
|
], :int
|
667
882
|
|
@@ -772,31 +987,31 @@ module WinGUI
|
|
772
987
|
|
773
988
|
attach_function :GetWindowRect, [
|
774
989
|
:pointer,
|
775
|
-
:
|
990
|
+
RECT.by_ref(:out)
|
776
991
|
], :int
|
777
992
|
|
778
993
|
attach_function :GetClientRect, [
|
779
994
|
:pointer,
|
780
|
-
:
|
995
|
+
RECT.by_ref(:out)
|
781
996
|
], :int
|
782
997
|
|
783
998
|
attach_function :GetCursorPos, [
|
784
|
-
:
|
999
|
+
POINT.by_ref(:out)
|
785
1000
|
], :int
|
786
1001
|
|
787
1002
|
attach_function :ScreenToClient, [
|
788
1003
|
:pointer,
|
789
|
-
|
1004
|
+
POINT.by_ref
|
790
1005
|
], :int
|
791
1006
|
|
792
1007
|
attach_function :ClientToScreen, [
|
793
1008
|
:pointer,
|
794
|
-
|
1009
|
+
POINT.by_ref
|
795
1010
|
], :int
|
796
1011
|
|
797
1012
|
attach_function :InvalidateRect, [
|
798
1013
|
:pointer,
|
799
|
-
:
|
1014
|
+
RECT.by_ref(:in),
|
800
1015
|
:int
|
801
1016
|
], :int
|
802
1017
|
|
@@ -804,49 +1019,27 @@ module WinGUI
|
|
804
1019
|
:pointer
|
805
1020
|
], :int
|
806
1021
|
|
807
|
-
attach_function :
|
1022
|
+
attach_function :SetCapture, [
|
808
1023
|
:pointer
|
809
1024
|
], :pointer
|
810
1025
|
|
811
|
-
attach_function :
|
812
|
-
:pointer,
|
813
|
-
:pointer
|
814
|
-
], :int
|
815
|
-
|
816
|
-
Detonate(FFI::Pointer::NULL, :GetDC,
|
817
|
-
nil
|
818
|
-
).tap { |hdc|
|
819
|
-
DPIX = GetDeviceCaps(hdc, LOGPIXELSX)
|
820
|
-
DPIY = GetDeviceCaps(hdc, LOGPIXELSY)
|
1026
|
+
attach_function :ReleaseCapture, [
|
821
1027
|
|
822
|
-
|
823
|
-
}
|
824
|
-
|
825
|
-
def DPIScaleX(x)
|
826
|
-
MulDiv(x, DPIX, 96)
|
827
|
-
end
|
1028
|
+
], :int
|
828
1029
|
|
829
|
-
|
830
|
-
MulDiv(y, DPIY, 96)
|
831
|
-
end
|
1030
|
+
attach_function :GetCapture, [
|
832
1031
|
|
833
|
-
|
834
|
-
case args.length
|
835
|
-
when 2 # POINT, SIZE
|
836
|
-
[DPIScaleX(args[0]), DPIScaleY(args[1])]
|
837
|
-
when 4 # RECT
|
838
|
-
[
|
839
|
-
DPIScaleX(args[0]), DPIScaleY(args[1]),
|
840
|
-
DPIScaleX(args[2]), DPIScaleY(args[3])
|
841
|
-
]
|
842
|
-
else
|
843
|
-
raise ArgumentError
|
844
|
-
end
|
845
|
-
end
|
1032
|
+
], :pointer
|
846
1033
|
|
847
|
-
|
1034
|
+
attach_function :GetUpdateRect, [
|
1035
|
+
:pointer,
|
1036
|
+
RECT.by_ref(:out),
|
1037
|
+
:int
|
1038
|
+
], :int
|
848
1039
|
|
849
1040
|
class PAINTSTRUCT < FFI::Struct
|
1041
|
+
extend Util::ScopedStruct
|
1042
|
+
|
850
1043
|
layout \
|
851
1044
|
:hdc, :pointer,
|
852
1045
|
:fErase, :int,
|
@@ -858,12 +1051,12 @@ module WinGUI
|
|
858
1051
|
|
859
1052
|
attach_function :BeginPaint, [
|
860
1053
|
:pointer,
|
861
|
-
:
|
1054
|
+
PAINTSTRUCT.by_ref(:out)
|
862
1055
|
], :pointer
|
863
1056
|
|
864
1057
|
attach_function :EndPaint, [
|
865
1058
|
:pointer,
|
866
|
-
:
|
1059
|
+
PAINTSTRUCT.by_ref(:in)
|
867
1060
|
], :int
|
868
1061
|
|
869
1062
|
attach_function :SetMenu, [
|
@@ -890,6 +1083,8 @@ module WinGUI
|
|
890
1083
|
|
891
1084
|
#{ WM_xxx
|
892
1085
|
class CREATESTRUCT < FFI::Struct
|
1086
|
+
extend Util::ScopedStruct
|
1087
|
+
|
893
1088
|
layout \
|
894
1089
|
:lpCreateParams, :pointer,
|
895
1090
|
:hInstance, :pointer,
|
@@ -918,6 +1113,18 @@ module WinGUI
|
|
918
1113
|
|
919
1114
|
WM_PAINT = 0x000F
|
920
1115
|
|
1116
|
+
def GET_X_LPARAM(lParam)
|
1117
|
+
((x = LOWORD(lParam)) > 0x7fff) ?
|
1118
|
+
x - 0x1_0000 :
|
1119
|
+
x
|
1120
|
+
end
|
1121
|
+
|
1122
|
+
def GET_Y_LPARAM(lParam)
|
1123
|
+
((y = HIWORD(lParam)) > 0x7fff) ?
|
1124
|
+
y - 0x1_0000 :
|
1125
|
+
y
|
1126
|
+
end
|
1127
|
+
|
921
1128
|
WM_LBUTTONDOWN = 0x0201
|
922
1129
|
WM_LBUTTONUP = 0x0202
|
923
1130
|
WM_LBUTTONDBLCLK = 0x0203
|
@@ -932,6 +1139,8 @@ module WinGUI
|
|
932
1139
|
WM_COMMAND = 0x0111
|
933
1140
|
|
934
1141
|
class NMHDR < FFI::Struct
|
1142
|
+
extend Util::ScopedStruct
|
1143
|
+
|
935
1144
|
layout \
|
936
1145
|
:hwndFrom, :pointer,
|
937
1146
|
:idFrom, :uint,
|
@@ -958,6 +1167,8 @@ module WinGUI
|
|
958
1167
|
], :int
|
959
1168
|
|
960
1169
|
class MSG < FFI::Struct
|
1170
|
+
extend Util::ScopedStruct
|
1171
|
+
|
961
1172
|
layout \
|
962
1173
|
:hwnd, :pointer,
|
963
1174
|
:message, :uint,
|
@@ -968,7 +1179,7 @@ module WinGUI
|
|
968
1179
|
end
|
969
1180
|
|
970
1181
|
attach_function :GetMessage, :GetMessageW, [
|
971
|
-
:
|
1182
|
+
MSG.by_ref(:out),
|
972
1183
|
:pointer,
|
973
1184
|
:uint,
|
974
1185
|
:uint
|
@@ -976,21 +1187,21 @@ module WinGUI
|
|
976
1187
|
|
977
1188
|
attach_function :IsDialogMessage, [
|
978
1189
|
:pointer,
|
979
|
-
:
|
1190
|
+
MSG.by_ref(:in)
|
980
1191
|
], :int
|
981
1192
|
|
982
1193
|
attach_function :TranslateAccelerator, :TranslateAcceleratorW, [
|
983
1194
|
:pointer,
|
984
1195
|
:pointer,
|
985
|
-
:
|
1196
|
+
MSG.by_ref(:in)
|
986
1197
|
], :int
|
987
1198
|
|
988
1199
|
attach_function :TranslateMessage, [
|
989
|
-
:
|
1200
|
+
MSG.by_ref(:in)
|
990
1201
|
], :int
|
991
1202
|
|
992
1203
|
attach_function :DispatchMessage, :DispatchMessageW, [
|
993
|
-
:
|
1204
|
+
MSG.by_ref(:in)
|
994
1205
|
], :long
|
995
1206
|
|
996
1207
|
attach_function :PostQuitMessage, [
|
@@ -1081,6 +1292,8 @@ module WinGUI
|
|
1081
1292
|
#}
|
1082
1293
|
|
1083
1294
|
class ACCEL < FFI::Struct
|
1295
|
+
extend Util::ScopedStruct
|
1296
|
+
|
1084
1297
|
layout \
|
1085
1298
|
:fVirt, :uchar,
|
1086
1299
|
:key, :ushort,
|
@@ -1095,40 +1308,5 @@ module WinGUI
|
|
1095
1308
|
attach_function :DestroyAcceleratorTable, [
|
1096
1309
|
:pointer
|
1097
1310
|
], :int
|
1098
|
-
|
1099
|
-
#{ SPI_xxx
|
1100
|
-
class NONCLIENTMETRICS < FFI::Struct
|
1101
|
-
layout *[
|
1102
|
-
:cbSize, :uint,
|
1103
|
-
:iBorderWidth, :int,
|
1104
|
-
:iScrollWidth, :int,
|
1105
|
-
:iScrollHeight, :int,
|
1106
|
-
:iCaptionWidth, :int,
|
1107
|
-
:iCaptionHeight, :int,
|
1108
|
-
:lfCaptionFont, LOGFONT,
|
1109
|
-
:iSmCaptionWidth, :int,
|
1110
|
-
:iSmCaptionHeight, :int,
|
1111
|
-
:lfSmCaptionFont, LOGFONT,
|
1112
|
-
:iMenuWidth, :int,
|
1113
|
-
:iMenuHeight, :int,
|
1114
|
-
:lfMenuFont, LOGFONT,
|
1115
|
-
:lfStatusFont, LOGFONT,
|
1116
|
-
:lfMessageFont, LOGFONT,
|
1117
|
-
(WINVER >= WINVISTA) ? [:iPaddedBorderWidth, :int] : nil
|
1118
|
-
].tap { |layout|
|
1119
|
-
layout.flatten!
|
1120
|
-
layout.compact!
|
1121
|
-
}
|
1122
|
-
end
|
1123
|
-
|
1124
|
-
SPI_SETNONCLIENTMETRICS = 0x002A
|
1125
|
-
SPI_GETNONCLIENTMETRICS = 0x0029
|
1126
1311
|
#}
|
1127
|
-
|
1128
|
-
attach_function :SystemParametersInfo, :SystemParametersInfoW, [
|
1129
|
-
:uint,
|
1130
|
-
:uint,
|
1131
|
-
:pointer,
|
1132
|
-
:uint
|
1133
|
-
], :int
|
1134
1312
|
end
|