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
data/examples/Command.rbw
CHANGED
@@ -12,26 +12,11 @@ CTL_BUTTON1 = CMD_ITEM1 + 1
|
|
12
12
|
WndExtra = Struct.new(
|
13
13
|
:haccel,
|
14
14
|
:hmf
|
15
|
-
)
|
16
|
-
|
17
|
-
class WndExtra
|
18
|
-
REFS = {}
|
19
|
-
|
20
|
-
def initialize(*args)
|
21
|
-
super
|
22
|
-
|
23
|
-
REFS[object_id] = self
|
24
|
-
|
25
|
-
ObjectSpace.define_finalizer(self, -> id {
|
26
|
-
REFS.delete(id)
|
27
|
-
})
|
28
|
-
end
|
29
|
-
end
|
15
|
+
).send(:include, Util::Id2RefTracking)
|
30
16
|
|
31
17
|
def onCreate(hwnd,
|
32
18
|
cs
|
33
19
|
)
|
34
|
-
#xtra = ObjectSpace._id2ref(GetWindowLong(hwnd, GWL_USERDATA))
|
35
20
|
xtra = WndExtra::REFS[GetWindowLong(hwnd, GWL_USERDATA)]
|
36
21
|
|
37
22
|
hbar = CreateMenu()
|
@@ -44,32 +29,35 @@ def onCreate(hwnd,
|
|
44
29
|
[FVIRTKEY | FALT, 'I'.ord, CMD_ITEM1]
|
45
30
|
]
|
46
31
|
|
47
|
-
FFI::MemoryPointer.new(ACCEL, accels.
|
32
|
+
FFI::MemoryPointer.new(ACCEL, accels.count) { |paccels|
|
48
33
|
accels.each.with_index { |data, i|
|
49
34
|
accel = ACCEL.new(paccels + i * ACCEL.size)
|
50
35
|
|
51
36
|
accel[:fVirt], accel[:key], accel[:cmd] = data
|
52
37
|
}
|
53
38
|
|
54
|
-
xtra[:haccel] = CreateAcceleratorTable(paccels, accels.
|
39
|
+
xtra[:haccel] = CreateAcceleratorTable(paccels, accels.count)
|
55
40
|
}
|
56
41
|
|
57
|
-
|
58
|
-
|
59
|
-
|
42
|
+
NONCLIENTMETRICS.new { |ncm|
|
43
|
+
ncm[:cbSize] = ncm.size
|
44
|
+
|
45
|
+
SystemParametersInfo(SPI_GETNONCLIENTMETRICS, ncm.size, ncm, 0);
|
46
|
+
xtra[:hmf] = CreateFontIndirect(ncm[:lfMenuFont])
|
47
|
+
}
|
60
48
|
|
61
49
|
hbtn1 = CreateWindowEx(
|
62
50
|
0, L('Button'), L('&Button1'), WS_CHILD | WS_VISIBLE,
|
63
|
-
*
|
51
|
+
*DPIAwareXY(10, 10, 100, 25),
|
64
52
|
hwnd, FFI::Pointer.new(CTL_BUTTON1), GetModuleHandle(nil), nil
|
65
53
|
)
|
54
|
+
|
66
55
|
SendMessage(hbtn1, WM_SETFONT, xtra[:hmf].to_i, 1)
|
67
56
|
|
68
57
|
0
|
69
58
|
end
|
70
59
|
|
71
60
|
def onDestroy(hwnd)
|
72
|
-
#xtra = ObjectSpace._id2ref(GetWindowLong(hwnd, GWL_USERDATA))
|
73
61
|
xtra = WndExtra::REFS[GetWindowLong(hwnd, GWL_USERDATA)]
|
74
62
|
|
75
63
|
DestroyAcceleratorTable(xtra[:haccel])
|
@@ -144,6 +132,7 @@ begin
|
|
144
132
|
onCreate(hwnd, CREATESTRUCT.new(FFI::Pointer.new(lParam)))
|
145
133
|
when WM_DESTROY
|
146
134
|
onDestroy(hwnd)
|
135
|
+
|
147
136
|
when WM_COMMAND
|
148
137
|
id, verb = LOWORD(wParam), HIWORD(wParam)
|
149
138
|
hctl = FFI::Pointer.new(lParam)
|
@@ -158,31 +147,39 @@ begin
|
|
158
147
|
|
159
148
|
result || DefWindowProc(hwnd, uMsg, wParam, lParam)
|
160
149
|
rescue
|
161
|
-
MessageBox(
|
162
|
-
L(
|
150
|
+
case MessageBox(hwnd,
|
151
|
+
L(Util.FormatException($!)),
|
163
152
|
APPNAME,
|
164
|
-
MB_ICONERROR
|
165
|
-
)
|
153
|
+
MB_ABORTRETRYIGNORE | MB_ICONERROR
|
154
|
+
)
|
155
|
+
when IDABORT
|
156
|
+
PostQuitMessage(2)
|
157
|
+
when IDRETRY
|
158
|
+
retry
|
159
|
+
end
|
166
160
|
end
|
167
161
|
}
|
168
162
|
|
169
163
|
def main
|
170
|
-
wc = WNDCLASSEX.new
|
171
164
|
xtra = WndExtra.new
|
172
165
|
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
166
|
+
WNDCLASSEX.new { |wc|
|
167
|
+
wc[:cbSize] = wc.size
|
168
|
+
wc[:lpfnWndProc] = WindowProc
|
169
|
+
wc[:cbWndExtra] = FFI::Type::Builtin::POINTER.size
|
170
|
+
wc[:hInstance] = GetModuleHandle(nil)
|
171
|
+
wc[:hIcon] = LoadIcon(nil, IDI_APPLICATION)
|
172
|
+
wc[:hCursor] = LoadCursor(nil, IDC_ARROW)
|
173
|
+
wc[:hbrBackground] = FFI::Pointer.new(CTLCOLOR_DLG + 1)
|
174
|
+
|
175
|
+
PWSTR(APPNAME) { |className|
|
176
|
+
wc[:lpszClassName] = className
|
177
|
+
|
178
|
+
DetonateLastError(0, :RegisterClassEx,
|
179
|
+
wc
|
180
|
+
)
|
181
|
+
}
|
182
|
+
}
|
186
183
|
|
187
184
|
hwnd = CreateWindowEx(
|
188
185
|
0, APPNAME, APPNAME, WS_OVERLAPPEDWINDOW,
|
@@ -193,24 +190,26 @@ def main
|
|
193
190
|
raise "CreateWindowEx failed (last error: #{GetLastError()})" if
|
194
191
|
hwnd.null? && GetLastError() != 0
|
195
192
|
|
193
|
+
exit(0) if hwnd.null?
|
194
|
+
|
196
195
|
ShowWindow(hwnd, SW_SHOWNORMAL)
|
197
196
|
UpdateWindow(hwnd)
|
198
197
|
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
198
|
+
MSG.new { |msg|
|
199
|
+
until DetonateLastError(-1, :GetMessage,
|
200
|
+
msg, nil, 0, 0
|
201
|
+
) == 0
|
202
|
+
if TranslateAccelerator(hwnd, xtra[:haccel], msg) == 0
|
203
|
+
TranslateMessage(msg)
|
204
|
+
DispatchMessage(msg)
|
205
|
+
end
|
207
206
|
end
|
208
|
-
end
|
209
207
|
|
210
|
-
|
208
|
+
exit(msg[:wParam])
|
209
|
+
}
|
211
210
|
rescue
|
212
|
-
MessageBox(
|
213
|
-
L(
|
211
|
+
MessageBox(hwnd,
|
212
|
+
L(Util.FormatException($!)),
|
214
213
|
APPNAME,
|
215
214
|
MB_ICONERROR
|
216
215
|
); exit(1)
|
data/examples/Hello1.rbw
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'ffi-wingui-core'
|
2
|
+
|
3
|
+
include WinGUI
|
4
|
+
|
5
|
+
EnableVisualStyles()
|
6
|
+
|
7
|
+
if respond_to?(:MessageBoxTimeout)
|
8
|
+
MessageBoxTimeout(nil,
|
9
|
+
L("Hello, world!\n\n(Disappearing in 3 seconds...)"),
|
10
|
+
L('Hello'),
|
11
|
+
MB_ICONINFORMATION,
|
12
|
+
0,
|
13
|
+
3000
|
14
|
+
)
|
15
|
+
else
|
16
|
+
MessageBox(nil,
|
17
|
+
L('MessageBoxTimeout is not supported'),
|
18
|
+
nil,
|
19
|
+
MB_ICONERROR
|
20
|
+
)
|
21
|
+
end
|
data/examples/LifeCycle.rbw
CHANGED
@@ -59,28 +59,36 @@ begin
|
|
59
59
|
|
60
60
|
result || DefWindowProc(hwnd, uMsg, wParam, lParam)
|
61
61
|
rescue
|
62
|
-
MessageBox(
|
63
|
-
L(
|
62
|
+
case MessageBox(hwnd,
|
63
|
+
L(Util.FormatException($!)),
|
64
64
|
APPNAME,
|
65
|
-
MB_ICONERROR
|
66
|
-
)
|
65
|
+
MB_ABORTRETRYIGNORE | MB_ICONERROR
|
66
|
+
)
|
67
|
+
when IDABORT
|
68
|
+
PostQuitMessage(2)
|
69
|
+
when IDRETRY
|
70
|
+
retry
|
71
|
+
end
|
67
72
|
end
|
68
73
|
}
|
69
74
|
|
70
75
|
def main
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
76
|
+
WNDCLASSEX.new { |wc|
|
77
|
+
wc[:cbSize] = wc.size
|
78
|
+
wc[:lpfnWndProc] = WindowProc
|
79
|
+
wc[:hInstance] = GetModuleHandle(nil)
|
80
|
+
wc[:hIcon] = LoadIcon(nil, IDI_APPLICATION)
|
81
|
+
wc[:hCursor] = LoadCursor(nil, IDC_ARROW)
|
82
|
+
wc[:hbrBackground] = FFI::Pointer.new(COLOR_WINDOW + 1)
|
83
|
+
|
84
|
+
PWSTR(APPNAME) { |className|
|
85
|
+
wc[:lpszClassName] = className
|
86
|
+
|
87
|
+
DetonateLastError(0, :RegisterClassEx,
|
88
|
+
wc
|
89
|
+
)
|
90
|
+
}
|
91
|
+
}
|
84
92
|
|
85
93
|
hwnd = CreateWindowEx(
|
86
94
|
0, APPNAME, APPNAME, WS_OVERLAPPEDWINDOW,
|
@@ -91,22 +99,24 @@ def main
|
|
91
99
|
raise "CreateWindowEx failed (last error: #{GetLastError()})" if
|
92
100
|
hwnd.null? && GetLastError() != 0
|
93
101
|
|
102
|
+
exit(0) if hwnd.null?
|
103
|
+
|
94
104
|
ShowWindow(hwnd, SW_SHOWNORMAL)
|
95
105
|
UpdateWindow(hwnd)
|
96
106
|
|
97
|
-
|
107
|
+
MSG.new { |msg|
|
108
|
+
until DetonateLastError(-1, :GetMessage,
|
109
|
+
msg, nil, 0, 0
|
110
|
+
) == 0
|
111
|
+
TranslateMessage(msg)
|
112
|
+
DispatchMessage(msg)
|
113
|
+
end
|
98
114
|
|
99
|
-
|
100
|
-
|
101
|
-
) == 0
|
102
|
-
TranslateMessage(msg)
|
103
|
-
DispatchMessage(msg)
|
104
|
-
end
|
105
|
-
|
106
|
-
exit(msg[:wParam])
|
115
|
+
exit(msg[:wParam])
|
116
|
+
}
|
107
117
|
rescue
|
108
|
-
MessageBox(
|
109
|
-
L(
|
118
|
+
MessageBox(hwnd,
|
119
|
+
L(Util.FormatException($!)),
|
110
120
|
APPNAME,
|
111
121
|
MB_ICONERROR
|
112
122
|
); exit(1)
|
data/examples/LifeCycle1.rbw
CHANGED
@@ -89,28 +89,36 @@ begin
|
|
89
89
|
|
90
90
|
result || DefWindowProc(hwnd, uMsg, wParam, lParam)
|
91
91
|
rescue
|
92
|
-
MessageBox(
|
93
|
-
L(
|
92
|
+
case MessageBox(hwnd,
|
93
|
+
L(Util.FormatException($!)),
|
94
94
|
APPNAME,
|
95
|
-
MB_ICONERROR
|
96
|
-
)
|
95
|
+
MB_ABORTRETRYIGNORE | MB_ICONERROR
|
96
|
+
)
|
97
|
+
when IDABORT
|
98
|
+
PostQuitMessage(2)
|
99
|
+
when IDRETRY
|
100
|
+
retry
|
101
|
+
end
|
97
102
|
end
|
98
103
|
}
|
99
104
|
|
100
105
|
def main
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
106
|
+
WNDCLASSEX.new { |wc|
|
107
|
+
wc[:cbSize] = wc.size
|
108
|
+
wc[:lpfnWndProc] = WindowProc
|
109
|
+
wc[:hInstance] = GetModuleHandle(nil)
|
110
|
+
wc[:hIcon] = LoadIcon(nil, IDI_APPLICATION)
|
111
|
+
wc[:hCursor] = LoadCursor(nil, IDC_ARROW)
|
112
|
+
wc[:hbrBackground] = FFI::Pointer.new(COLOR_WINDOW + 1)
|
113
|
+
|
114
|
+
PWSTR(APPNAME) { |className|
|
115
|
+
wc[:lpszClassName] = className
|
116
|
+
|
117
|
+
DetonateLastError(0, :RegisterClassEx,
|
118
|
+
wc
|
119
|
+
)
|
120
|
+
}
|
121
|
+
}
|
114
122
|
|
115
123
|
hwnd = CreateWindowEx(
|
116
124
|
0, APPNAME, APPNAME, WS_OVERLAPPEDWINDOW,
|
@@ -121,22 +129,24 @@ def main
|
|
121
129
|
raise "CreateWindowEx failed (last error: #{GetLastError()})" if
|
122
130
|
hwnd.null? && GetLastError() != 0
|
123
131
|
|
132
|
+
exit(0) if hwnd.null?
|
133
|
+
|
124
134
|
ShowWindow(hwnd, SW_SHOWNORMAL)
|
125
135
|
UpdateWindow(hwnd)
|
126
136
|
|
127
|
-
|
137
|
+
MSG.new { |msg|
|
138
|
+
until DetonateLastError(-1, :GetMessage,
|
139
|
+
msg, nil, 0, 0
|
140
|
+
) == 0
|
141
|
+
TranslateMessage(msg)
|
142
|
+
DispatchMessage(msg)
|
143
|
+
end
|
128
144
|
|
129
|
-
|
130
|
-
|
131
|
-
) == 0
|
132
|
-
TranslateMessage(msg)
|
133
|
-
DispatchMessage(msg)
|
134
|
-
end
|
135
|
-
|
136
|
-
exit(msg[:wParam])
|
145
|
+
exit(msg[:wParam])
|
146
|
+
}
|
137
147
|
rescue
|
138
|
-
MessageBox(
|
139
|
-
L(
|
148
|
+
MessageBox(hwnd,
|
149
|
+
L(Util.FormatException($!)),
|
140
150
|
APPNAME,
|
141
151
|
MB_ICONERROR
|
142
152
|
); exit(1)
|
data/examples/Minimal.rbw
CHANGED
@@ -22,28 +22,36 @@ begin
|
|
22
22
|
|
23
23
|
result || DefWindowProc(hwnd, uMsg, wParam, lParam)
|
24
24
|
rescue
|
25
|
-
MessageBox(
|
26
|
-
L(
|
25
|
+
case MessageBox(hwnd,
|
26
|
+
L(Util.FormatException($!)),
|
27
27
|
APPNAME,
|
28
|
-
MB_ICONERROR
|
29
|
-
)
|
28
|
+
MB_ABORTRETRYIGNORE | MB_ICONERROR
|
29
|
+
)
|
30
|
+
when IDABORT
|
31
|
+
PostQuitMessage(2)
|
32
|
+
when IDRETRY
|
33
|
+
retry
|
34
|
+
end
|
30
35
|
end
|
31
36
|
}
|
32
37
|
|
33
38
|
def main
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
39
|
+
WNDCLASSEX.new { |wc|
|
40
|
+
wc[:cbSize] = wc.size
|
41
|
+
wc[:lpfnWndProc] = WindowProc
|
42
|
+
wc[:hInstance] = GetModuleHandle(nil)
|
43
|
+
wc[:hIcon] = LoadIcon(nil, IDI_APPLICATION)
|
44
|
+
wc[:hCursor] = LoadCursor(nil, IDC_ARROW)
|
45
|
+
wc[:hbrBackground] = FFI::Pointer.new(COLOR_WINDOW + 1)
|
46
|
+
|
47
|
+
PWSTR(APPNAME) { |className|
|
48
|
+
wc[:lpszClassName] = className
|
49
|
+
|
50
|
+
DetonateLastError(0, :RegisterClassEx,
|
51
|
+
wc
|
52
|
+
)
|
53
|
+
}
|
54
|
+
}
|
47
55
|
|
48
56
|
hwnd = CreateWindowEx(
|
49
57
|
0, APPNAME, APPNAME, WS_OVERLAPPEDWINDOW,
|
@@ -54,22 +62,24 @@ def main
|
|
54
62
|
raise "CreateWindowEx failed (last error: #{GetLastError()})" if
|
55
63
|
hwnd.null? && GetLastError() != 0
|
56
64
|
|
65
|
+
exit(0) if hwnd.null?
|
66
|
+
|
57
67
|
ShowWindow(hwnd, SW_SHOWNORMAL)
|
58
68
|
UpdateWindow(hwnd)
|
59
69
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
end
|
70
|
+
MSG.new { |msg|
|
71
|
+
until DetonateLastError(-1, :GetMessage,
|
72
|
+
msg, nil, 0, 0
|
73
|
+
) == 0
|
74
|
+
TranslateMessage(msg)
|
75
|
+
DispatchMessage(msg)
|
76
|
+
end
|
68
77
|
|
69
|
-
|
78
|
+
exit(msg[:wParam])
|
79
|
+
}
|
70
80
|
rescue
|
71
|
-
MessageBox(
|
72
|
-
L(
|
81
|
+
MessageBox(hwnd,
|
82
|
+
L(Util.FormatException($!)),
|
73
83
|
APPNAME,
|
74
84
|
MB_ICONERROR
|
75
85
|
); exit(1)
|