ffi-wingui-core 0.4.0 → 0.5.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 +42 -23
- data/examples/Hello.rbw +1 -2
- data/examples/HelloOptout.rbw +1 -2
- data/examples/HelloTimeout.rbw +11 -12
- data/examples/Layered.rbw +99 -0
- data/examples/LifeCycle.rbw +3 -4
- data/examples/LifeCycleNC.rbw +3 -4
- data/examples/Menu.rbw +47 -58
- data/examples/MenuContext.rbw +11 -14
- data/examples/MenuPARGB32.rbw +58 -73
- data/examples/MinMax.rbw +101 -0
- data/examples/Minimal.rbw +3 -4
- data/examples/Region.rbw +100 -0
- data/examples/Scribble.rbw +15 -18
- data/examples/WndExtra.rbw +7 -8
- data/lib/ffi-wingui-core.rb +496 -50
- data/lib/ffi-wingui-core/ocra.rb +1 -0
- metadata +17 -13
data/examples/MenuContext.rbw
CHANGED
@@ -1,30 +1,25 @@
|
|
1
1
|
require 'ffi-wingui-core'
|
2
|
-
|
3
|
-
exit if defined?(Ocra)
|
2
|
+
require 'ffi-wingui-core/ocra'
|
4
3
|
|
5
4
|
include WinGUI
|
6
5
|
|
7
|
-
APPNAME = L(File.basename(__FILE__, '.rbw'))
|
8
|
-
|
9
|
-
CMD_ITEM1 = WM_APP + 1
|
10
|
-
|
11
6
|
WndExtra = Struct.new(
|
12
7
|
:hcm
|
13
|
-
)
|
8
|
+
)
|
14
9
|
|
15
10
|
def onCreate(hwnd,
|
16
11
|
cs
|
17
12
|
)
|
18
|
-
xtra =
|
13
|
+
xtra = Util::Id2Ref[GetWindowLong(hwnd, GWL_USERDATA)]
|
19
14
|
|
20
15
|
xtra[:hcm] = CreatePopupMenu()
|
21
|
-
|
16
|
+
InsertMenu(xtra[:hcm], -1, MF_STRING, ID[:ITEM1], L('Item&1'))
|
22
17
|
|
23
18
|
0
|
24
19
|
end
|
25
20
|
|
26
21
|
def onDestroy(hwnd)
|
27
|
-
xtra =
|
22
|
+
xtra = Util::Id2Ref[GetWindowLong(hwnd, GWL_USERDATA)]
|
28
23
|
|
29
24
|
DestroyMenu(xtra[:hcm])
|
30
25
|
|
@@ -34,7 +29,7 @@ end
|
|
34
29
|
def onContextMenu(hwnd,
|
35
30
|
x, y
|
36
31
|
)
|
37
|
-
xtra =
|
32
|
+
xtra = Util::Id2Ref[GetWindowLong(hwnd, GWL_USERDATA)]
|
38
33
|
|
39
34
|
POINT.new { |point|
|
40
35
|
GetCursorPos(point)
|
@@ -80,18 +75,20 @@ begin
|
|
80
75
|
onDestroy(hwnd)
|
81
76
|
|
82
77
|
when WM_CONTEXTMENU
|
83
|
-
onContextMenu(hwnd,
|
78
|
+
onContextMenu(hwnd, LOSHORT(lParam), HISHORT(lParam))
|
84
79
|
when WM_COMMAND
|
85
80
|
id, verb = LOWORD(wParam), HIWORD(wParam)
|
86
81
|
hctl = FFI::Pointer.new(lParam)
|
87
82
|
|
88
83
|
case id
|
89
|
-
when
|
84
|
+
when ID[:ITEM1]
|
90
85
|
onItem1(verb, hctl, hwnd)
|
91
86
|
end
|
92
87
|
end
|
93
88
|
|
94
89
|
result || DefWindowProc(hwnd, uMsg, wParam, lParam)
|
90
|
+
rescue SystemExit => ex
|
91
|
+
PostQuitMessage(ex.status)
|
95
92
|
rescue
|
96
93
|
case MessageBox(hwnd,
|
97
94
|
L(Util.FormatException($!)),
|
@@ -107,7 +104,7 @@ end
|
|
107
104
|
}
|
108
105
|
|
109
106
|
def main
|
110
|
-
xtra = WndExtra.new
|
107
|
+
Util.Id2RefTrack(xtra = WndExtra.new)
|
111
108
|
|
112
109
|
WNDCLASSEX.new { |wc|
|
113
110
|
wc[:cbSize] = wc.size
|
data/examples/MenuPARGB32.rbw
CHANGED
@@ -1,37 +1,20 @@
|
|
1
1
|
require 'ffi-wingui-core'
|
2
|
-
|
3
|
-
exit if defined?(Ocra)
|
2
|
+
require 'ffi-wingui-core/ocra'
|
4
3
|
|
5
4
|
include WinGUI
|
6
5
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
MessageBox(nil,
|
11
|
-
L('This example requires Windows Vista or later'),
|
12
|
-
APPNAME,
|
13
|
-
MB_ICONERROR
|
14
|
-
); exit(0)
|
15
|
-
end
|
16
|
-
|
17
|
-
CMD_ITEM1 = WM_APP + 1
|
18
|
-
CMD_ITEM2 = CMD_ITEM1 + 1
|
19
|
-
CMD_ITEM3 = CMD_ITEM2 + 1
|
20
|
-
CMD_ITEM4 = CMD_ITEM3 + 1
|
21
|
-
CMD_ITEM5 = CMD_ITEM4 + 1
|
22
|
-
CMD_ITEM6 = CMD_ITEM5 + 1
|
23
|
-
CMD_ITEM7 = CMD_ITEM6 + 1
|
24
|
-
CMD_ITEM8 = CMD_ITEM7 + 1
|
25
|
-
CMD_ITEM9 = CMD_ITEM8 + 1
|
6
|
+
TARGETVER(WINVISTA,
|
7
|
+
L("This example requires Windows Vista or later\n\nRun anyway?")
|
8
|
+
)
|
26
9
|
|
27
10
|
WndExtra = Struct.new(
|
28
11
|
:hbmp
|
29
|
-
)
|
12
|
+
)
|
30
13
|
|
31
14
|
def onCreate(hwnd,
|
32
15
|
cs
|
33
16
|
)
|
34
|
-
xtra =
|
17
|
+
xtra = Util::Id2Ref[GetWindowLong(hwnd, GWL_USERDATA)]
|
35
18
|
|
36
19
|
xtra[:hbmp] = DetonateLastError(FFI::Pointer::NULL, :LoadImage,
|
37
20
|
nil,
|
@@ -48,45 +31,45 @@ def onCreate(hwnd,
|
|
48
31
|
|
49
32
|
hbar = CreateMenu()
|
50
33
|
hmenu1 = CreatePopupMenu()
|
51
|
-
|
52
|
-
SetMenuDefaultItem(hmenu1,
|
53
|
-
SetMenuItemInfo(hmenu1,
|
34
|
+
InsertMenu(hmenu1, -1, MF_STRING, ID[:ITEM1], L('Item&1'))
|
35
|
+
SetMenuDefaultItem(hmenu1, ID[:ITEM1], 0)
|
36
|
+
SetMenuItemInfo(hmenu1, ID[:ITEM1], 0, info)
|
54
37
|
|
55
|
-
|
56
|
-
SetMenuItemInfo(hmenu1,
|
38
|
+
InsertMenu(hmenu1, -1, MF_STRING | MF_GRAYED, ID[:ITEM2], L('Item&2'))
|
39
|
+
SetMenuItemInfo(hmenu1, ID[:ITEM2], 0, info)
|
57
40
|
|
58
|
-
|
59
|
-
SetMenuItemInfo(hmenu1,
|
41
|
+
InsertMenu(hmenu1, -1, MF_STRING | MF_CHECKED, ID[:ITEM3], L('Item&3'))
|
42
|
+
SetMenuItemInfo(hmenu1, ID[:ITEM3], 0, info)
|
60
43
|
|
61
|
-
|
44
|
+
InsertMenu(hmenu1, -1, MF_SEPARATOR, 0, nil)
|
62
45
|
|
63
|
-
|
64
|
-
|
65
|
-
SetMenuItemInfo(hmenu1,
|
46
|
+
InsertMenu(hmenu1, -1, MF_STRING | MF_CHECKED | MFT_RADIOCHECK,
|
47
|
+
ID[:ITEM4], L('Item&4'))
|
48
|
+
SetMenuItemInfo(hmenu1, ID[:ITEM4], 0, info)
|
66
49
|
|
67
|
-
|
68
|
-
SetMenuItemInfo(hmenu1,
|
50
|
+
InsertMenu(hmenu1, -1, MF_STRING, ID[:ITEM5], L('Item&5'))
|
51
|
+
SetMenuItemInfo(hmenu1, ID[:ITEM5], 0, info)
|
69
52
|
|
70
|
-
|
53
|
+
InsertMenu(hmenu1, -1, MF_SEPARATOR, 0, nil)
|
71
54
|
|
72
55
|
hmenu2 = CreatePopupMenu()
|
73
|
-
|
74
|
-
|
75
|
-
SetMenuItemInfo(hmenu2,
|
56
|
+
InsertMenu(hmenu2, -1, MF_STRING | MF_CHECKED | MFT_RADIOCHECK,
|
57
|
+
ID[:ITEM6], L('Item&6'))
|
58
|
+
SetMenuItemInfo(hmenu2, ID[:ITEM6], 0, info)
|
76
59
|
|
77
|
-
|
78
|
-
SetMenuItemInfo(hmenu2,
|
79
|
-
|
60
|
+
InsertMenu(hmenu2, -1, MF_STRING, ID[:ITEM7], L('Item&7'))
|
61
|
+
SetMenuItemInfo(hmenu2, ID[:ITEM7], 0, info)
|
62
|
+
InsertMenu(hmenu1, -1, MF_POPUP, hmenu2.to_i, L('Menu&2'))
|
80
63
|
SetMenuItemInfo(hmenu1, 7, MF_BYPOSITION, info)
|
81
|
-
|
64
|
+
InsertMenu(hbar, -1, MF_POPUP, hmenu1.to_i, L('Menu&1'))
|
82
65
|
SetMenuItemInfo(hbar, 0, MF_BYPOSITION, info)
|
83
66
|
|
84
|
-
|
85
|
-
SetMenuItemInfo(hbar,
|
67
|
+
InsertMenu(hbar, -1, MF_STRING, ID[:ITEM8], L('Item&8'))
|
68
|
+
SetMenuItemInfo(hbar, ID[:ITEM8], 0, info)
|
86
69
|
|
87
70
|
hmenu3 = CreatePopupMenu()
|
88
|
-
|
89
|
-
|
71
|
+
InsertMenu(hmenu3, -1, MF_BITMAP, ID[:ITEM9], xtra[:hbmp])
|
72
|
+
InsertMenu(hbar, -1, MF_POPUP | MF_BITMAP | MF_RIGHTJUSTIFY, hmenu3.to_i, xtra[:hbmp])
|
90
73
|
SetMenu(hwnd, hbar)
|
91
74
|
|
92
75
|
0
|
@@ -95,7 +78,7 @@ ensure
|
|
95
78
|
end
|
96
79
|
|
97
80
|
def onDestroy(hwnd)
|
98
|
-
xtra =
|
81
|
+
xtra = Util::Id2Ref[GetWindowLong(hwnd, GWL_USERDATA)]
|
99
82
|
|
100
83
|
DeleteObject(xtra[:hbmp])
|
101
84
|
|
@@ -106,9 +89,9 @@ def onItem1(verb,
|
|
106
89
|
hctl, hwnd
|
107
90
|
)
|
108
91
|
hbar = GetMenu(hwnd)
|
109
|
-
i2grayed = (GetMenuState(hbar,
|
92
|
+
i2grayed = (GetMenuState(hbar, ID[:ITEM2], 0) & MF_GRAYED) == MF_GRAYED
|
110
93
|
|
111
|
-
EnableMenuItem(hbar,
|
94
|
+
EnableMenuItem(hbar, ID[:ITEM2], (i2grayed) ? MF_ENABLED : MF_GRAYED)
|
112
95
|
|
113
96
|
0
|
114
97
|
end
|
@@ -129,9 +112,9 @@ def onItem3(verb,
|
|
129
112
|
hctl, hwnd
|
130
113
|
)
|
131
114
|
hbar = GetMenu(hwnd)
|
132
|
-
i3checked = (GetMenuState(hbar,
|
115
|
+
i3checked = (GetMenuState(hbar, ID[:ITEM3], 0) & MF_CHECKED) == MF_CHECKED
|
133
116
|
|
134
|
-
CheckMenuItem(hbar,
|
117
|
+
CheckMenuItem(hbar, ID[:ITEM3], (i3checked) ? MF_UNCHECKED : MF_CHECKED)
|
135
118
|
|
136
119
|
0
|
137
120
|
end
|
@@ -139,7 +122,7 @@ end
|
|
139
122
|
def onItem4(verb,
|
140
123
|
hctl, hwnd
|
141
124
|
)
|
142
|
-
CheckMenuRadioItem(GetMenu(hwnd),
|
125
|
+
CheckMenuRadioItem(GetMenu(hwnd), ID[:ITEM4], ID[:ITEM5], ID[:ITEM4], 0)
|
143
126
|
|
144
127
|
0
|
145
128
|
end
|
@@ -147,7 +130,7 @@ end
|
|
147
130
|
def onItem5(verb,
|
148
131
|
hctl, hwnd
|
149
132
|
)
|
150
|
-
CheckMenuRadioItem(GetMenu(hwnd),
|
133
|
+
CheckMenuRadioItem(GetMenu(hwnd), ID[:ITEM4], ID[:ITEM5], ID[:ITEM5], 0)
|
151
134
|
|
152
135
|
0
|
153
136
|
end
|
@@ -155,7 +138,7 @@ end
|
|
155
138
|
def onItem6(verb,
|
156
139
|
hctl, hwnd
|
157
140
|
)
|
158
|
-
CheckMenuRadioItem(GetMenu(hwnd),
|
141
|
+
CheckMenuRadioItem(GetMenu(hwnd), ID[:ITEM6], ID[:ITEM7], ID[:ITEM6], 0)
|
159
142
|
|
160
143
|
0
|
161
144
|
end
|
@@ -163,7 +146,7 @@ end
|
|
163
146
|
def onItem7(verb,
|
164
147
|
hctl, hwnd
|
165
148
|
)
|
166
|
-
CheckMenuRadioItem(GetMenu(hwnd),
|
149
|
+
CheckMenuRadioItem(GetMenu(hwnd), ID[:ITEM6], ID[:ITEM7], ID[:ITEM7], 0)
|
167
150
|
|
168
151
|
0
|
169
152
|
end
|
@@ -184,12 +167,12 @@ def onItem9(verb,
|
|
184
167
|
hctl, hwnd
|
185
168
|
)
|
186
169
|
hbar = GetMenu(hwnd)
|
187
|
-
i2grayed = (GetMenuState(hbar,
|
188
|
-
i3checked = (GetMenuState(hbar,
|
189
|
-
i4checked = (GetMenuState(hbar,
|
190
|
-
i5checked = (GetMenuState(hbar,
|
191
|
-
i6checked = (GetMenuState(hbar,
|
192
|
-
i7checked = (GetMenuState(hbar,
|
170
|
+
i2grayed = (GetMenuState(hbar, ID[:ITEM2], 0) & MF_GRAYED) == MF_GRAYED
|
171
|
+
i3checked = (GetMenuState(hbar, ID[:ITEM3], 0) & MF_CHECKED) == MF_CHECKED
|
172
|
+
i4checked = (GetMenuState(hbar, ID[:ITEM4], 0) & MF_CHECKED) == MF_CHECKED
|
173
|
+
i5checked = (GetMenuState(hbar, ID[:ITEM5], 0) & MF_CHECKED) == MF_CHECKED
|
174
|
+
i6checked = (GetMenuState(hbar, ID[:ITEM6], 0) & MF_CHECKED) == MF_CHECKED
|
175
|
+
i7checked = (GetMenuState(hbar, ID[:ITEM7], 0) & MF_CHECKED) == MF_CHECKED
|
193
176
|
|
194
177
|
MessageBox(hwnd,
|
195
178
|
L("
|
@@ -232,28 +215,30 @@ begin
|
|
232
215
|
hctl = FFI::Pointer.new(lParam)
|
233
216
|
|
234
217
|
case id
|
235
|
-
when
|
218
|
+
when ID[:ITEM1]
|
236
219
|
onItem1(verb, hctl, hwnd)
|
237
|
-
when
|
220
|
+
when ID[:ITEM2]
|
238
221
|
onItem2(verb, hctl, hwnd)
|
239
|
-
when
|
222
|
+
when ID[:ITEM3]
|
240
223
|
onItem3(verb, hctl, hwnd)
|
241
|
-
when
|
224
|
+
when ID[:ITEM4]
|
242
225
|
onItem4(verb, hctl, hwnd)
|
243
|
-
when
|
226
|
+
when ID[:ITEM5]
|
244
227
|
onItem5(verb, hctl, hwnd)
|
245
|
-
when
|
228
|
+
when ID[:ITEM6]
|
246
229
|
onItem6(verb, hctl, hwnd)
|
247
|
-
when
|
230
|
+
when ID[:ITEM7]
|
248
231
|
onItem7(verb, hctl, hwnd)
|
249
|
-
when
|
232
|
+
when ID[:ITEM8]
|
250
233
|
onItem8(verb, hctl, hwnd)
|
251
|
-
when
|
234
|
+
when ID[:ITEM9]
|
252
235
|
onItem9(verb, hctl, hwnd)
|
253
236
|
end
|
254
237
|
end
|
255
238
|
|
256
239
|
result || DefWindowProc(hwnd, uMsg, wParam, lParam)
|
240
|
+
rescue SystemExit => ex
|
241
|
+
PostQuitMessage(ex.status)
|
257
242
|
rescue
|
258
243
|
case MessageBox(hwnd,
|
259
244
|
L(Util.FormatException($!)),
|
@@ -269,7 +254,7 @@ end
|
|
269
254
|
}
|
270
255
|
|
271
256
|
def main
|
272
|
-
xtra = WndExtra.new
|
257
|
+
Util.Id2RefTrack(xtra = WndExtra.new)
|
273
258
|
|
274
259
|
WNDCLASSEX.new { |wc|
|
275
260
|
wc[:cbSize] = wc.size
|
data/examples/MinMax.rbw
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
require 'ffi-wingui-core'
|
2
|
+
require 'ffi-wingui-core/ocra'
|
3
|
+
|
4
|
+
include WinGUI
|
5
|
+
|
6
|
+
def onDestroy(hwnd)
|
7
|
+
PostQuitMessage(0); 0
|
8
|
+
end
|
9
|
+
|
10
|
+
def onMinMax(hwnd,
|
11
|
+
minmax
|
12
|
+
)
|
13
|
+
minmax[:ptMinTrackSize][:x], minmax[:ptMinTrackSize][:y] = DPIAwareXY(400, 300)
|
14
|
+
minmax[:ptMaxTrackSize][:x], minmax[:ptMaxTrackSize][:y] = DPIAwareXY(800, 600)
|
15
|
+
|
16
|
+
0
|
17
|
+
end
|
18
|
+
|
19
|
+
WindowProc = FFI::Function.new(:long,
|
20
|
+
[:pointer, :uint, :uint, :long],
|
21
|
+
convention: :stdcall
|
22
|
+
) { |hwnd, uMsg, wParam, lParam|
|
23
|
+
begin
|
24
|
+
result = case uMsg
|
25
|
+
when WM_DESTROY
|
26
|
+
onDestroy(hwnd)
|
27
|
+
|
28
|
+
when WM_GETMINMAXINFO
|
29
|
+
onMinMax(hwnd, MINMAXINFO.new(FFI::Pointer.new(lParam)))
|
30
|
+
end
|
31
|
+
|
32
|
+
result || DefWindowProc(hwnd, uMsg, wParam, lParam)
|
33
|
+
rescue SystemExit => ex
|
34
|
+
PostQuitMessage(ex.status)
|
35
|
+
rescue
|
36
|
+
case MessageBox(hwnd,
|
37
|
+
L(Util.FormatException($!)),
|
38
|
+
APPNAME,
|
39
|
+
MB_ABORTRETRYIGNORE | MB_ICONERROR
|
40
|
+
)
|
41
|
+
when IDABORT
|
42
|
+
PostQuitMessage(2)
|
43
|
+
when IDRETRY
|
44
|
+
retry
|
45
|
+
end
|
46
|
+
end
|
47
|
+
}
|
48
|
+
|
49
|
+
def main
|
50
|
+
WNDCLASSEX.new { |wc|
|
51
|
+
wc[:cbSize] = wc.size
|
52
|
+
wc[:lpfnWndProc] = WindowProc
|
53
|
+
wc[:hInstance] = GetModuleHandle(nil)
|
54
|
+
wc[:hIcon] = LoadIcon(nil, IDI_APPLICATION)
|
55
|
+
wc[:hCursor] = LoadCursor(nil, IDC_ARROW)
|
56
|
+
wc[:hbrBackground] = FFI::Pointer.new(
|
57
|
+
((WINVER == WINXP) ? COLOR_MENUBAR : COLOR_MENU) + 1
|
58
|
+
)
|
59
|
+
|
60
|
+
PWSTR(APPNAME) { |className|
|
61
|
+
wc[:lpszClassName] = className
|
62
|
+
|
63
|
+
DetonateLastError(0, :RegisterClassEx,
|
64
|
+
wc
|
65
|
+
)
|
66
|
+
}
|
67
|
+
}
|
68
|
+
|
69
|
+
hwnd = CreateWindowEx(
|
70
|
+
0, APPNAME, APPNAME, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
|
71
|
+
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
|
72
|
+
nil, nil, GetModuleHandle(nil), nil
|
73
|
+
)
|
74
|
+
|
75
|
+
raise "CreateWindowEx failed (last error: #{GetLastError()})" if
|
76
|
+
hwnd.null? && GetLastError() != 0
|
77
|
+
|
78
|
+
exit(0) if hwnd.null?
|
79
|
+
|
80
|
+
ShowWindow(hwnd, SW_SHOWNORMAL)
|
81
|
+
UpdateWindow(hwnd)
|
82
|
+
|
83
|
+
MSG.new { |msg|
|
84
|
+
until DetonateLastError(-1, :GetMessage,
|
85
|
+
msg, nil, 0, 0
|
86
|
+
) == 0
|
87
|
+
TranslateMessage(msg)
|
88
|
+
DispatchMessage(msg)
|
89
|
+
end
|
90
|
+
|
91
|
+
exit(msg[:wParam])
|
92
|
+
}
|
93
|
+
rescue
|
94
|
+
MessageBox(hwnd,
|
95
|
+
L(Util.FormatException($!)),
|
96
|
+
APPNAME,
|
97
|
+
MB_ICONERROR
|
98
|
+
); exit(1)
|
99
|
+
end
|
100
|
+
|
101
|
+
main
|
data/examples/Minimal.rbw
CHANGED
@@ -1,11 +1,8 @@
|
|
1
1
|
require 'ffi-wingui-core'
|
2
|
-
|
3
|
-
exit if defined?(Ocra)
|
2
|
+
require 'ffi-wingui-core/ocra'
|
4
3
|
|
5
4
|
include WinGUI
|
6
5
|
|
7
|
-
APPNAME = L(File.basename(__FILE__, '.rbw'))
|
8
|
-
|
9
6
|
def onDestroy(hwnd)
|
10
7
|
PostQuitMessage(0); 0
|
11
8
|
end
|
@@ -21,6 +18,8 @@ begin
|
|
21
18
|
end
|
22
19
|
|
23
20
|
result || DefWindowProc(hwnd, uMsg, wParam, lParam)
|
21
|
+
rescue SystemExit => ex
|
22
|
+
PostQuitMessage(ex.status)
|
24
23
|
rescue
|
25
24
|
case MessageBox(hwnd,
|
26
25
|
L(Util.FormatException($!)),
|
data/examples/Region.rbw
ADDED
@@ -0,0 +1,100 @@
|
|
1
|
+
require 'ffi-wingui-core'
|
2
|
+
require 'ffi-wingui-core/ocra'
|
3
|
+
|
4
|
+
include WinGUI
|
5
|
+
|
6
|
+
def onCreate(hwnd,
|
7
|
+
cs
|
8
|
+
)
|
9
|
+
SetWindowRgn(hwnd,
|
10
|
+
CreateEllipticRgn(*DPIAwareXY(42, 42, 420, 210)),
|
11
|
+
0
|
12
|
+
)
|
13
|
+
|
14
|
+
0
|
15
|
+
end
|
16
|
+
|
17
|
+
def onDestroy(hwnd)
|
18
|
+
PostQuitMessage(0); 0
|
19
|
+
end
|
20
|
+
|
21
|
+
WindowProc = FFI::Function.new(:long,
|
22
|
+
[:pointer, :uint, :uint, :long],
|
23
|
+
convention: :stdcall
|
24
|
+
) { |hwnd, uMsg, wParam, lParam|
|
25
|
+
begin
|
26
|
+
result = case uMsg
|
27
|
+
when WM_CREATE
|
28
|
+
onCreate(hwnd, CREATESTRUCT.new(FFI::Pointer.new(lParam)))
|
29
|
+
when WM_DESTROY
|
30
|
+
onDestroy(hwnd)
|
31
|
+
end
|
32
|
+
|
33
|
+
result || DefWindowProc(hwnd, uMsg, wParam, lParam)
|
34
|
+
rescue SystemExit => ex
|
35
|
+
PostQuitMessage(ex.status)
|
36
|
+
rescue
|
37
|
+
case MessageBox(hwnd,
|
38
|
+
L(Util.FormatException($!)),
|
39
|
+
APPNAME,
|
40
|
+
MB_ABORTRETRYIGNORE | MB_ICONERROR
|
41
|
+
)
|
42
|
+
when IDABORT
|
43
|
+
PostQuitMessage(2)
|
44
|
+
when IDRETRY
|
45
|
+
retry
|
46
|
+
end
|
47
|
+
end
|
48
|
+
}
|
49
|
+
|
50
|
+
def main
|
51
|
+
WNDCLASSEX.new { |wc|
|
52
|
+
wc[:cbSize] = wc.size
|
53
|
+
wc[:lpfnWndProc] = WindowProc
|
54
|
+
wc[:hInstance] = GetModuleHandle(nil)
|
55
|
+
wc[:hIcon] = LoadIcon(nil, IDI_APPLICATION)
|
56
|
+
wc[:hCursor] = LoadCursor(nil, IDC_ARROW)
|
57
|
+
wc[:hbrBackground] = FFI::Pointer.new(COLOR_DESKTOP + 1)
|
58
|
+
|
59
|
+
PWSTR(APPNAME) { |className|
|
60
|
+
wc[:lpszClassName] = className
|
61
|
+
|
62
|
+
DetonateLastError(0, :RegisterClassEx,
|
63
|
+
wc
|
64
|
+
)
|
65
|
+
}
|
66
|
+
}
|
67
|
+
|
68
|
+
hwnd = CreateWindowEx(
|
69
|
+
0, APPNAME, APPNAME, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
|
70
|
+
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
|
71
|
+
nil, nil, GetModuleHandle(nil), nil
|
72
|
+
)
|
73
|
+
|
74
|
+
raise "CreateWindowEx failed (last error: #{GetLastError()})" if
|
75
|
+
hwnd.null? && GetLastError() != 0
|
76
|
+
|
77
|
+
exit(0) if hwnd.null?
|
78
|
+
|
79
|
+
ShowWindow(hwnd, SW_SHOWNORMAL)
|
80
|
+
UpdateWindow(hwnd)
|
81
|
+
|
82
|
+
MSG.new { |msg|
|
83
|
+
until DetonateLastError(-1, :GetMessage,
|
84
|
+
msg, nil, 0, 0
|
85
|
+
) == 0
|
86
|
+
TranslateMessage(msg)
|
87
|
+
DispatchMessage(msg)
|
88
|
+
end
|
89
|
+
|
90
|
+
exit(msg[:wParam])
|
91
|
+
}
|
92
|
+
rescue
|
93
|
+
MessageBox(hwnd,
|
94
|
+
L(Util.FormatException($!)),
|
95
|
+
APPNAME,
|
96
|
+
MB_ICONERROR
|
97
|
+
); exit(1)
|
98
|
+
end
|
99
|
+
|
100
|
+
main
|