ffi-wingui-core 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|