windows_gui 2.0.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.
@@ -0,0 +1,308 @@
1
+ require 'windows_gui'
2
+
3
+ include WindowsGUI
4
+
5
+ TARGETVER(WINVISTA,
6
+ L("This example requires Windows Vista or later\n\nRun anyway?")
7
+ )
8
+
9
+ WndExtra = Struct.new(
10
+ :hbmp
11
+ )
12
+
13
+ def OnCreate(hwnd,
14
+ cs
15
+ )
16
+ xtra = Util::Id2Ref[GetWindowLong(hwnd, GWL_USERDATA)]
17
+
18
+ xtra[:hbmp] = DetonateLastError(FFI::Pointer::NULL, :LoadImage,
19
+ nil,
20
+ L("#{File.dirname(File.expand_path(__FILE__))}/res/face-devilish.bmp"),
21
+ IMAGE_BITMAP, 0, 0,
22
+ LR_LOADFROMFILE | LR_CREATEDIBSECTION
23
+ )
24
+
25
+ info = MENUITEMINFO.new
26
+
27
+ info[:cbSize] = info.size
28
+ info[:fMask] = MIIM_BITMAP
29
+ info[:hbmpItem] = xtra[:hbmp]
30
+
31
+ hbar = CreateMenu()
32
+ hmenu1 = CreatePopupMenu()
33
+ AppendMenu(hmenu1, MF_STRING, CMD[:ITEM1], L('Item&1'))
34
+ SetMenuDefaultItem(hmenu1, CMD[:ITEM1], 0)
35
+ SetMenuItemInfo(hmenu1, CMD[:ITEM1], 0, info)
36
+
37
+ AppendMenu(hmenu1, MF_STRING | MF_GRAYED, CMD[:ITEM2], L('Item&2'))
38
+ SetMenuItemInfo(hmenu1, CMD[:ITEM2], 0, info)
39
+
40
+ AppendMenu(hmenu1, MF_STRING | MF_CHECKED, CMD[:ITEM3], L('Item&3'))
41
+ SetMenuItemInfo(hmenu1, CMD[:ITEM3], 0, info)
42
+
43
+ AppendMenu(hmenu1, MF_SEPARATOR, 0, nil)
44
+
45
+ AppendMenu(hmenu1, MF_STRING | MF_CHECKED | MFT_RADIOCHECK,
46
+ CMD[:ITEM4], L('Item&4'))
47
+ SetMenuItemInfo(hmenu1, CMD[:ITEM4], 0, info)
48
+
49
+ AppendMenu(hmenu1, MF_STRING, CMD[:ITEM5], L('Item&5'))
50
+ SetMenuItemInfo(hmenu1, CMD[:ITEM5], 0, info)
51
+
52
+ AppendMenu(hmenu1, MF_SEPARATOR, 0, nil)
53
+
54
+ hmenu2 = CreatePopupMenu()
55
+ AppendMenu(hmenu2, MF_STRING | MF_CHECKED | MFT_RADIOCHECK,
56
+ CMD[:ITEM6], L('Item&6'))
57
+ SetMenuItemInfo(hmenu2, CMD[:ITEM6], 0, info)
58
+
59
+ AppendMenu(hmenu2, MF_STRING, CMD[:ITEM7], L('Item&7'))
60
+ SetMenuItemInfo(hmenu2, CMD[:ITEM7], 0, info)
61
+ AppendMenu(hmenu1, MF_POPUP, hmenu2.to_i, L('Menu&2'))
62
+ SetMenuItemInfo(hmenu1, 7, MF_BYPOSITION, info)
63
+ AppendMenu(hbar, MF_POPUP, hmenu1.to_i, L('Menu&1'))
64
+ SetMenuItemInfo(hbar, 0, MF_BYPOSITION, info)
65
+
66
+ AppendMenu(hbar, MF_STRING, CMD[:ITEM8], L('Item&8!'))
67
+ SetMenuItemInfo(hbar, CMD[:ITEM8], 0, info)
68
+
69
+ hmenu3 = CreatePopupMenu()
70
+ AppendMenu(hmenu3, MF_BITMAP, CMD[:ITEM9], xtra[:hbmp])
71
+ AppendMenu(hbar, MF_POPUP | MF_BITMAP | MF_RIGHTJUSTIFY, hmenu3.to_i, xtra[:hbmp])
72
+ SetMenu(hwnd, hbar)
73
+
74
+ 0
75
+ ensure
76
+ info.pointer.free if info
77
+ end
78
+
79
+ def OnDestroy(hwnd)
80
+ xtra = Util::Id2Ref[GetWindowLong(hwnd, GWL_USERDATA)]
81
+
82
+ DeleteObject(xtra[:hbmp])
83
+
84
+ PostQuitMessage(0); 0
85
+ end
86
+
87
+ def OnItem1(verb,
88
+ hctl, hwnd
89
+ )
90
+ hbar = GetMenu(hwnd)
91
+ i2grayed = (GetMenuState(hbar, CMD[:ITEM2], 0) & MF_GRAYED) == MF_GRAYED
92
+
93
+ EnableMenuItem(hbar, CMD[:ITEM2], (i2grayed) ? MF_ENABLED : MF_GRAYED)
94
+
95
+ 0
96
+ end
97
+
98
+ def OnItem2(verb,
99
+ hctl, hwnd
100
+ )
101
+ MessageBox(hwnd,
102
+ L(__method__.to_s),
103
+ APPNAME,
104
+ MB_ICONINFORMATION
105
+ )
106
+
107
+ 0
108
+ end
109
+
110
+ def OnItem3(verb,
111
+ hctl, hwnd
112
+ )
113
+ hbar = GetMenu(hwnd)
114
+ i3checked = (GetMenuState(hbar, CMD[:ITEM3], 0) & MF_CHECKED) == MF_CHECKED
115
+
116
+ CheckMenuItem(hbar, CMD[:ITEM3], (i3checked) ? MF_UNCHECKED : MF_CHECKED)
117
+
118
+ 0
119
+ end
120
+
121
+ def OnItem4(verb,
122
+ hctl, hwnd
123
+ )
124
+ CheckMenuRadioItem(GetMenu(hwnd), CMD[:ITEM4], CMD[:ITEM5], CMD[:ITEM4], 0)
125
+
126
+ 0
127
+ end
128
+
129
+ def OnItem5(verb,
130
+ hctl, hwnd
131
+ )
132
+ CheckMenuRadioItem(GetMenu(hwnd), CMD[:ITEM4], CMD[:ITEM5], CMD[:ITEM5], 0)
133
+
134
+ 0
135
+ end
136
+
137
+ def OnItem6(verb,
138
+ hctl, hwnd
139
+ )
140
+ CheckMenuRadioItem(GetMenu(hwnd), CMD[:ITEM6], CMD[:ITEM7], CMD[:ITEM6], 0)
141
+
142
+ 0
143
+ end
144
+
145
+ def OnItem7(verb,
146
+ hctl, hwnd
147
+ )
148
+ CheckMenuRadioItem(GetMenu(hwnd), CMD[:ITEM6], CMD[:ITEM7], CMD[:ITEM7], 0)
149
+
150
+ 0
151
+ end
152
+
153
+ def OnItem8(verb,
154
+ hctl, hwnd
155
+ )
156
+ MessageBox(hwnd,
157
+ L(__method__.to_s),
158
+ APPNAME,
159
+ MB_ICONINFORMATION
160
+ )
161
+
162
+ 0
163
+ end
164
+
165
+ def OnItem9(verb,
166
+ hctl, hwnd
167
+ )
168
+ hbar = GetMenu(hwnd)
169
+ i2grayed = (GetMenuState(hbar, CMD[:ITEM2], 0) & MF_GRAYED) == MF_GRAYED
170
+ i3checked = (GetMenuState(hbar, CMD[:ITEM3], 0) & MF_CHECKED) == MF_CHECKED
171
+ i4checked = (GetMenuState(hbar, CMD[:ITEM4], 0) & MF_CHECKED) == MF_CHECKED
172
+ i5checked = (GetMenuState(hbar, CMD[:ITEM5], 0) & MF_CHECKED) == MF_CHECKED
173
+ i6checked = (GetMenuState(hbar, CMD[:ITEM6], 0) & MF_CHECKED) == MF_CHECKED
174
+ i7checked = (GetMenuState(hbar, CMD[:ITEM7], 0) & MF_CHECKED) == MF_CHECKED
175
+
176
+ MessageBox(hwnd,
177
+ L("
178
+ Item2 - #{(i2grayed) ? 'grayed' : 'enabled'}
179
+ Item3 - #{(i3checked) ? 'checked' : 'unchecked'}
180
+ Item4 - #{(i4checked) ? 'checked' : 'unchecked'}
181
+ Item5 - #{(i5checked) ? 'checked' : 'unchecked'}
182
+ Item6 - #{(i6checked) ? 'checked' : 'unchecked'}
183
+ Item7 - #{(i7checked) ? 'checked' : 'unchecked'}
184
+ "),
185
+ APPNAME,
186
+ MB_ICONINFORMATION
187
+ )
188
+
189
+ 0
190
+ end
191
+
192
+ WindowProc = FFI::Function.new(:long,
193
+ [:pointer, :uint, :uint, :long],
194
+ convention: :stdcall
195
+ ) { |hwnd, uMsg, wParam, lParam|
196
+ begin
197
+ result = case uMsg
198
+ when WM_NCCREATE
199
+ DefWindowProc(hwnd, uMsg, wParam, lParam)
200
+
201
+ SetWindowLong(hwnd,
202
+ GWL_USERDATA,
203
+ CREATESTRUCT.new(FFI::Pointer.new(lParam))[:lpCreateParams].to_i
204
+ )
205
+
206
+ 1
207
+ when WM_CREATE
208
+ OnCreate(hwnd, CREATESTRUCT.new(FFI::Pointer.new(lParam)))
209
+ when WM_DESTROY
210
+ OnDestroy(hwnd)
211
+
212
+ when WM_COMMAND
213
+ id, verb = LOWORD(wParam), HIWORD(wParam)
214
+ hctl = FFI::Pointer.new(lParam)
215
+
216
+ case id
217
+ when CMD[:ITEM1]
218
+ OnItem1(verb, hctl, hwnd)
219
+ when CMD[:ITEM2]
220
+ OnItem2(verb, hctl, hwnd)
221
+ when CMD[:ITEM3]
222
+ OnItem3(verb, hctl, hwnd)
223
+ when CMD[:ITEM4]
224
+ OnItem4(verb, hctl, hwnd)
225
+ when CMD[:ITEM5]
226
+ OnItem5(verb, hctl, hwnd)
227
+ when CMD[:ITEM6]
228
+ OnItem6(verb, hctl, hwnd)
229
+ when CMD[:ITEM7]
230
+ OnItem7(verb, hctl, hwnd)
231
+ when CMD[:ITEM8]
232
+ OnItem8(verb, hctl, hwnd)
233
+ when CMD[:ITEM9]
234
+ OnItem9(verb, hctl, hwnd)
235
+ end
236
+ end
237
+
238
+ result || DefWindowProc(hwnd, uMsg, wParam, lParam)
239
+ rescue SystemExit => ex
240
+ PostQuitMessage(ex.status)
241
+ rescue
242
+ case MessageBox(hwnd,
243
+ L(Util.FormatException($!)),
244
+ APPNAME,
245
+ MB_ABORTRETRYIGNORE | MB_ICONERROR
246
+ )
247
+ when IDABORT
248
+ PostQuitMessage(2)
249
+ when IDRETRY
250
+ retry
251
+ end
252
+ end
253
+ }
254
+
255
+ def WinMain
256
+ Util.Id2RefTrack(xtra = WndExtra.new)
257
+
258
+ WNDCLASSEX.new { |wc|
259
+ wc[:cbSize] = wc.size
260
+ wc[:lpfnWndProc] = WindowProc
261
+ wc[:cbWndExtra] = FFI::Type::Builtin::POINTER.size
262
+ wc[:hInstance] = GetModuleHandle(nil)
263
+ wc[:hIcon] = LoadIcon(nil, IDI_APPLICATION)
264
+ wc[:hCursor] = LoadCursor(nil, IDC_ARROW)
265
+ wc[:hbrBackground] = FFI::Pointer.new(COLOR_WINDOW + 1)
266
+
267
+ PWSTR(APPNAME) { |className|
268
+ wc[:lpszClassName] = className
269
+
270
+ DetonateLastError(0, :RegisterClassEx,
271
+ wc
272
+ )
273
+ }
274
+ }
275
+
276
+ hwnd = CreateWindowEx(
277
+ 0, APPNAME, APPNAME, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
278
+ CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
279
+ nil, nil, GetModuleHandle(nil), FFI::Pointer.new(xtra.object_id)
280
+ )
281
+
282
+ raise "CreateWindowEx failed (last error: #{GetLastError()})" if
283
+ hwnd.null? && GetLastError() != 0
284
+
285
+ exit(0) if hwnd.null?
286
+
287
+ ShowWindow(hwnd, SW_SHOWNORMAL)
288
+ UpdateWindow(hwnd)
289
+
290
+ MSG.new { |msg|
291
+ until DetonateLastError(-1, :GetMessage,
292
+ msg, nil, 0, 0
293
+ ) == 0
294
+ TranslateMessage(msg)
295
+ DispatchMessage(msg)
296
+ end
297
+
298
+ exit(msg[:wParam])
299
+ }
300
+ rescue
301
+ MessageBox(hwnd,
302
+ L(Util.FormatException($!)),
303
+ APPNAME,
304
+ MB_ICONERROR
305
+ ); exit(1)
306
+ end
307
+
308
+ WinMain()
@@ -0,0 +1,98 @@
1
+ require 'windows_gui'
2
+
3
+ include WindowsGUI
4
+
5
+ def OnDestroy(hwnd)
6
+ PostQuitMessage(0); 0
7
+ end
8
+
9
+ def OnMinMax(hwnd,
10
+ minmax
11
+ )
12
+ minmax[:ptMinTrackSize][:x], minmax[:ptMinTrackSize][:y] = DPIAwareXY(400, 300)
13
+ minmax[:ptMaxTrackSize][:x], minmax[:ptMaxTrackSize][:y] = DPIAwareXY(800, 600)
14
+
15
+ 0
16
+ end
17
+
18
+ WindowProc = FFI::Function.new(:long,
19
+ [:pointer, :uint, :uint, :long],
20
+ convention: :stdcall
21
+ ) { |hwnd, uMsg, wParam, lParam|
22
+ begin
23
+ result = case uMsg
24
+ when WM_DESTROY
25
+ OnDestroy(hwnd)
26
+
27
+ when WM_GETMINMAXINFO
28
+ OnMinMax(hwnd, MINMAXINFO.new(FFI::Pointer.new(lParam)))
29
+ end
30
+
31
+ result || DefWindowProc(hwnd, uMsg, wParam, lParam)
32
+ rescue SystemExit => ex
33
+ PostQuitMessage(ex.status)
34
+ rescue
35
+ case MessageBox(hwnd,
36
+ L(Util.FormatException($!)),
37
+ APPNAME,
38
+ MB_ABORTRETRYIGNORE | MB_ICONERROR
39
+ )
40
+ when IDABORT
41
+ PostQuitMessage(2)
42
+ when IDRETRY
43
+ retry
44
+ end
45
+ end
46
+ }
47
+
48
+ def WinMain
49
+ WNDCLASSEX.new { |wc|
50
+ wc[:cbSize] = wc.size
51
+ wc[:lpfnWndProc] = WindowProc
52
+ wc[:hInstance] = GetModuleHandle(nil)
53
+ wc[:hIcon] = LoadIcon(nil, IDI_APPLICATION)
54
+ wc[:hCursor] = LoadCursor(nil, IDC_ARROW)
55
+ wc[:hbrBackground] = FFI::Pointer.new(COLOR_WINDOW + 1)
56
+
57
+ PWSTR(APPNAME) { |className|
58
+ wc[:lpszClassName] = className
59
+
60
+ DetonateLastError(0, :RegisterClassEx,
61
+ wc
62
+ )
63
+ }
64
+ }
65
+
66
+ hwnd = CreateWindowEx(
67
+ 0, APPNAME, APPNAME, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
68
+ CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
69
+ nil, nil, GetModuleHandle(nil), nil
70
+ )
71
+
72
+ raise "CreateWindowEx failed (last error: #{GetLastError()})" if
73
+ hwnd.null? && GetLastError() != 0
74
+
75
+ exit(0) if hwnd.null?
76
+
77
+ ShowWindow(hwnd, SW_SHOWNORMAL)
78
+ UpdateWindow(hwnd)
79
+
80
+ MSG.new { |msg|
81
+ until DetonateLastError(-1, :GetMessage,
82
+ msg, nil, 0, 0
83
+ ) == 0
84
+ TranslateMessage(msg)
85
+ DispatchMessage(msg)
86
+ end
87
+
88
+ exit(msg[:wParam])
89
+ }
90
+ rescue
91
+ MessageBox(hwnd,
92
+ L(Util.FormatException($!)),
93
+ APPNAME,
94
+ MB_ICONERROR
95
+ ); exit(1)
96
+ end
97
+
98
+ WinMain()
@@ -0,0 +1,86 @@
1
+ require 'windows_gui'
2
+
3
+ include WindowsGUI
4
+
5
+ def OnDestroy(hwnd)
6
+ PostQuitMessage(0); 0
7
+ end
8
+
9
+ WindowProc = FFI::Function.new(:long,
10
+ [:pointer, :uint, :uint, :long],
11
+ convention: :stdcall
12
+ ) { |hwnd, uMsg, wParam, lParam|
13
+ begin
14
+ result = case uMsg
15
+ when WM_DESTROY
16
+ OnDestroy(hwnd)
17
+ end
18
+
19
+ result || DefWindowProc(hwnd, uMsg, wParam, lParam)
20
+ rescue SystemExit => ex
21
+ PostQuitMessage(ex.status)
22
+ rescue
23
+ case MessageBox(hwnd,
24
+ L(Util.FormatException($!)),
25
+ APPNAME,
26
+ MB_ABORTRETRYIGNORE | MB_ICONERROR
27
+ )
28
+ when IDABORT
29
+ PostQuitMessage(2)
30
+ when IDRETRY
31
+ retry
32
+ end
33
+ end
34
+ }
35
+
36
+ def WinMain
37
+ WNDCLASSEX.new { |wc|
38
+ wc[:cbSize] = wc.size
39
+ wc[:lpfnWndProc] = WindowProc
40
+ wc[:hInstance] = GetModuleHandle(nil)
41
+ wc[:hIcon] = LoadIcon(nil, IDI_APPLICATION)
42
+ wc[:hCursor] = LoadCursor(nil, IDC_ARROW)
43
+ wc[:hbrBackground] = FFI::Pointer.new(COLOR_WINDOW + 1)
44
+
45
+ PWSTR(APPNAME) { |className|
46
+ wc[:lpszClassName] = className
47
+
48
+ DetonateLastError(0, :RegisterClassEx,
49
+ wc
50
+ )
51
+ }
52
+ }
53
+
54
+ hwnd = CreateWindowEx(
55
+ 0, APPNAME, APPNAME, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
56
+ CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
57
+ nil, nil, GetModuleHandle(nil), nil
58
+ )
59
+
60
+ raise "CreateWindowEx failed (last error: #{GetLastError()})" if
61
+ hwnd.null? && GetLastError() != 0
62
+
63
+ exit(0) if hwnd.null?
64
+
65
+ ShowWindow(hwnd, SW_SHOWNORMAL)
66
+ UpdateWindow(hwnd)
67
+
68
+ MSG.new { |msg|
69
+ until DetonateLastError(-1, :GetMessage,
70
+ msg, nil, 0, 0
71
+ ) == 0
72
+ TranslateMessage(msg)
73
+ DispatchMessage(msg)
74
+ end
75
+
76
+ exit(msg[:wParam])
77
+ }
78
+ rescue
79
+ MessageBox(hwnd,
80
+ L(Util.FormatException($!)),
81
+ APPNAME,
82
+ MB_ICONERROR
83
+ ); exit(1)
84
+ end
85
+
86
+ WinMain()
@@ -0,0 +1,151 @@
1
+ require 'windows_gui'
2
+
3
+ include WindowsGUI
4
+
5
+ WndExtra = Struct.new(
6
+ :hfont
7
+ )
8
+
9
+ def OnCreate(hwnd,
10
+ cs
11
+ )
12
+ xtra = Util::Id2Ref[GetWindowLong(hwnd, GWL_USERDATA)]
13
+
14
+ LOGFONT.new { |lf|
15
+ lf[:lfHeight] = DPIAwareFontHeight(16)
16
+ lf[:lfItalic] = 1
17
+ lf[:lfFaceName].to_ptr.put_bytes(0, L('Verdana'))
18
+
19
+ xtra[:hfont] = CreateFontIndirect(lf)
20
+ }
21
+
22
+ 0
23
+ end
24
+
25
+ def OnDestroy(hwnd)
26
+ xtra = Util::Id2Ref[GetWindowLong(hwnd, GWL_USERDATA)]
27
+
28
+ DeleteObject(xtra[:hfont])
29
+
30
+ PostQuitMessage(0); 0
31
+ end
32
+
33
+ def OnPaint(hwnd,
34
+ ps
35
+ )
36
+ xtra = Util::Id2Ref[GetWindowLong(hwnd, GWL_USERDATA)]
37
+
38
+ SetBkColor(ps[:hdc], RGB(255, 0, 0))
39
+ SetTextColor(ps[:hdc], RGB(255, 255, 255))
40
+
41
+ UseObjects(ps[:hdc], xtra[:hfont]) {
42
+ RECT.new { |rect|
43
+ GetClientRect(hwnd, rect)
44
+
45
+ DrawText(ps[:hdc],
46
+ L('The quick brown fox jumps over the lazy dog. 1234567890'), -1,
47
+ rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER
48
+ )
49
+ }
50
+ }
51
+
52
+ 0
53
+ end
54
+
55
+ WindowProc = FFI::Function.new(:long,
56
+ [:pointer, :uint, :uint, :long],
57
+ convention: :stdcall
58
+ ) { |hwnd, uMsg, wParam, lParam|
59
+ begin
60
+ result = case uMsg
61
+ when WM_NCCREATE
62
+ DefWindowProc(hwnd, uMsg, wParam, lParam)
63
+
64
+ SetWindowLong(hwnd,
65
+ GWL_USERDATA,
66
+ CREATESTRUCT.new(FFI::Pointer.new(lParam))[:lpCreateParams].to_i
67
+ )
68
+
69
+ 1
70
+ when WM_CREATE
71
+ OnCreate(hwnd, CREATESTRUCT.new(FFI::Pointer.new(lParam)))
72
+ when WM_DESTROY
73
+ OnDestroy(hwnd)
74
+
75
+ when WM_PAINT
76
+ DoPaint(hwnd) { |ps| result = OnPaint(hwnd, ps) }
77
+ when WM_PRINTCLIENT
78
+ DoPrintClient(hwnd, wParam) { |ps| result = OnPaint(hwnd, ps) }
79
+ end
80
+
81
+ result || DefWindowProc(hwnd, uMsg, wParam, lParam)
82
+ rescue SystemExit => ex
83
+ PostQuitMessage(ex.status)
84
+ rescue
85
+ case MessageBox(hwnd,
86
+ L(Util.FormatException($!)),
87
+ APPNAME,
88
+ MB_ABORTRETRYIGNORE | MB_ICONERROR
89
+ )
90
+ when IDABORT
91
+ PostQuitMessage(2)
92
+ when IDRETRY
93
+ retry
94
+ end
95
+ end
96
+ }
97
+
98
+ def WinMain
99
+ Util.Id2RefTrack(xtra = WndExtra.new)
100
+
101
+ WNDCLASSEX.new { |wc|
102
+ wc[:cbSize] = wc.size
103
+ wc[:style] = CS_HREDRAW | CS_VREDRAW
104
+ wc[:lpfnWndProc] = WindowProc
105
+ wc[:cbWndExtra] = FFI::Type::Builtin::POINTER.size
106
+ wc[:hInstance] = GetModuleHandle(nil)
107
+ wc[:hIcon] = LoadIcon(nil, IDI_APPLICATION)
108
+ wc[:hCursor] = LoadCursor(nil, IDC_ARROW)
109
+ wc[:hbrBackground] = FFI::Pointer.new(COLOR_WINDOW + 1)
110
+
111
+ PWSTR(APPNAME) { |className|
112
+ wc[:lpszClassName] = className
113
+
114
+ DetonateLastError(0, :RegisterClassEx,
115
+ wc
116
+ )
117
+ }
118
+ }
119
+
120
+ hwnd = CreateWindowEx(
121
+ WS_EX_CLIENTEDGE, APPNAME, APPNAME, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
122
+ CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
123
+ nil, nil, GetModuleHandle(nil), FFI::Pointer.new(xtra.object_id)
124
+ )
125
+
126
+ raise "CreateWindowEx failed (last error: #{GetLastError()})" if
127
+ hwnd.null? && GetLastError() != 0
128
+
129
+ exit(0) if hwnd.null?
130
+
131
+ AnimateWindow(hwnd, 1000, AW_ACTIVATE | AW_BLEND)
132
+
133
+ MSG.new { |msg|
134
+ until DetonateLastError(-1, :GetMessage,
135
+ msg, nil, 0, 0
136
+ ) == 0
137
+ TranslateMessage(msg)
138
+ DispatchMessage(msg)
139
+ end
140
+
141
+ exit(msg[:wParam])
142
+ }
143
+ rescue
144
+ MessageBox(hwnd,
145
+ L(Util.FormatException($!)),
146
+ APPNAME,
147
+ MB_ICONERROR
148
+ ); exit(1)
149
+ end
150
+
151
+ WinMain()