ffi-wingui-core 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,164 @@
1
+ require 'ffi-wingui-core'
2
+
3
+ exit if defined?(Ocra)
4
+
5
+ include WinGUI
6
+
7
+ APPNAME = L(File.basename(__FILE__, '.rbw'))
8
+
9
+ CMD_ITEM1 = WM_APP + 1
10
+
11
+ WndExtra = Struct.new(
12
+ :hcm
13
+ ).send(:include, Util::Id2RefTracking)
14
+
15
+ def onCreate(hwnd,
16
+ cs
17
+ )
18
+ xtra = WndExtra::REFS[GetWindowLong(hwnd, GWL_USERDATA)]
19
+
20
+ xtra[:hcm] = CreatePopupMenu()
21
+ AppendMenu(xtra[:hcm], MF_STRING, CMD_ITEM1, L('Item&1'))
22
+
23
+ 0
24
+ end
25
+
26
+ def onDestroy(hwnd)
27
+ xtra = WndExtra::REFS[GetWindowLong(hwnd, GWL_USERDATA)]
28
+
29
+ DestroyMenu(xtra[:hcm])
30
+
31
+ PostQuitMessage(0); 0
32
+ end
33
+
34
+ def onContextMenu(hwnd,
35
+ x, y
36
+ )
37
+ xtra = WndExtra::REFS[GetWindowLong(hwnd, GWL_USERDATA)]
38
+
39
+ POINT.new { |point|
40
+ GetCursorPos(point)
41
+
42
+ x, y = point.values
43
+ } if x == -1
44
+
45
+ TrackPopupMenu(xtra[:hcm], TPM_RIGHTBUTTON, x, y, 0, hwnd, nil)
46
+
47
+ 0
48
+ end
49
+
50
+ def onItem1(verb,
51
+ hctl, hwnd
52
+ )
53
+ MessageBox(hwnd,
54
+ L(__method__.to_s),
55
+ APPNAME,
56
+ MB_ICONINFORMATION
57
+ )
58
+
59
+ 0
60
+ end
61
+
62
+ WindowProc = FFI::Function.new(:long,
63
+ [:pointer, :uint, :uint, :long],
64
+ convention: :stdcall
65
+ ) { |hwnd, uMsg, wParam, lParam|
66
+ begin
67
+ result = case uMsg
68
+ when WM_NCCREATE
69
+ DefWindowProc(hwnd, uMsg, wParam, lParam)
70
+
71
+ SetWindowLong(hwnd,
72
+ GWL_USERDATA,
73
+ CREATESTRUCT.new(FFI::Pointer.new(lParam))[:lpCreateParams].to_i
74
+ )
75
+
76
+ 1
77
+ when WM_CREATE
78
+ onCreate(hwnd, CREATESTRUCT.new(FFI::Pointer.new(lParam)))
79
+ when WM_DESTROY
80
+ onDestroy(hwnd)
81
+
82
+ when WM_CONTEXTMENU
83
+ onContextMenu(hwnd, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))
84
+ when WM_COMMAND
85
+ id, verb = LOWORD(wParam), HIWORD(wParam)
86
+ hctl = FFI::Pointer.new(lParam)
87
+
88
+ case id
89
+ when CMD_ITEM1
90
+ onItem1(verb, hctl, hwnd)
91
+ end
92
+ end
93
+
94
+ result || DefWindowProc(hwnd, uMsg, wParam, lParam)
95
+ rescue
96
+ case MessageBox(hwnd,
97
+ L(Util.FormatException($!)),
98
+ APPNAME,
99
+ MB_ABORTRETRYIGNORE | MB_ICONERROR
100
+ )
101
+ when IDABORT
102
+ PostQuitMessage(2)
103
+ when IDRETRY
104
+ retry
105
+ end
106
+ end
107
+ }
108
+
109
+ def main
110
+ xtra = WndExtra.new
111
+
112
+ WNDCLASSEX.new { |wc|
113
+ wc[:cbSize] = wc.size
114
+ wc[:lpfnWndProc] = WindowProc
115
+ wc[:cbWndExtra] = FFI::Type::Builtin::POINTER.size
116
+ wc[:hInstance] = GetModuleHandle(nil)
117
+ wc[:hIcon] = LoadIcon(nil, IDI_APPLICATION)
118
+ wc[:hCursor] = LoadCursor(nil, IDC_ARROW)
119
+ wc[:hbrBackground] = FFI::Pointer.new(
120
+ ((WINVER == WINXP) ? COLOR_MENUBAR : COLOR_MENU) + 1
121
+ )
122
+
123
+ PWSTR(APPNAME) { |className|
124
+ wc[:lpszClassName] = className
125
+
126
+ DetonateLastError(0, :RegisterClassEx,
127
+ wc
128
+ )
129
+ }
130
+ }
131
+
132
+ hwnd = CreateWindowEx(
133
+ 0, APPNAME, APPNAME, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
134
+ CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
135
+ nil, nil, GetModuleHandle(nil), FFI::Pointer.new(xtra.object_id)
136
+ )
137
+
138
+ raise "CreateWindowEx failed (last error: #{GetLastError()})" if
139
+ hwnd.null? && GetLastError() != 0
140
+
141
+ exit(0) if hwnd.null?
142
+
143
+ ShowWindow(hwnd, SW_SHOWNORMAL)
144
+ UpdateWindow(hwnd)
145
+
146
+ MSG.new { |msg|
147
+ until DetonateLastError(-1, :GetMessage,
148
+ msg, nil, 0, 0
149
+ ) == 0
150
+ TranslateMessage(msg)
151
+ DispatchMessage(msg)
152
+ end
153
+
154
+ exit(msg[:wParam])
155
+ }
156
+ rescue
157
+ MessageBox(hwnd,
158
+ L(Util.FormatException($!)),
159
+ APPNAME,
160
+ MB_ICONERROR
161
+ ); exit(1)
162
+ end
163
+
164
+ main
@@ -0,0 +1,326 @@
1
+ require 'ffi-wingui-core'
2
+
3
+ exit if defined?(Ocra)
4
+
5
+ include WinGUI
6
+
7
+ APPNAME = L(File.basename(__FILE__, '.rbw'))
8
+
9
+ unless WINVER >= WINVISTA
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
26
+
27
+ WndExtra = Struct.new(
28
+ :hbmp
29
+ ).send(:include, Util::Id2RefTracking)
30
+
31
+ def onCreate(hwnd,
32
+ cs
33
+ )
34
+ xtra = WndExtra::REFS[GetWindowLong(hwnd, GWL_USERDATA)]
35
+
36
+ xtra[:hbmp] = DetonateLastError(FFI::Pointer::NULL, :LoadImage,
37
+ nil,
38
+ L("#{File.dirname(File.expand_path(__FILE__))}/res/face-devilish.bmp"),
39
+ IMAGE_BITMAP, 0, 0,
40
+ LR_LOADFROMFILE | LR_CREATEDIBSECTION
41
+ )
42
+
43
+ info = MENUITEMINFO.new
44
+
45
+ info[:cbSize] = info.size
46
+ info[:fMask] = MIIM_BITMAP
47
+ info[:hbmpItem] = xtra[:hbmp]
48
+
49
+ hbar = CreateMenu()
50
+ hmenu1 = CreatePopupMenu()
51
+ AppendMenu(hmenu1, MF_STRING, CMD_ITEM1, L('Item&1'))
52
+ SetMenuDefaultItem(hmenu1, CMD_ITEM1, 0)
53
+ SetMenuItemInfo(hmenu1, CMD_ITEM1, 0, info)
54
+
55
+ AppendMenu(hmenu1, MF_STRING | MF_GRAYED, CMD_ITEM2, L('Item&2'))
56
+ SetMenuItemInfo(hmenu1, CMD_ITEM2, 0, info)
57
+
58
+ AppendMenu(hmenu1, MF_STRING | MF_CHECKED, CMD_ITEM3, L('Item&3'))
59
+ SetMenuItemInfo(hmenu1, CMD_ITEM3, 0, info)
60
+
61
+ AppendMenu(hmenu1, MF_SEPARATOR, 0, nil)
62
+
63
+ AppendMenu(hmenu1, MF_STRING | MF_CHECKED | MFT_RADIOCHECK,
64
+ CMD_ITEM4, L('Item&4'))
65
+ SetMenuItemInfo(hmenu1, CMD_ITEM4, 0, info)
66
+
67
+ AppendMenu(hmenu1, MF_STRING, CMD_ITEM5, L('Item&5'))
68
+ SetMenuItemInfo(hmenu1, CMD_ITEM5, 0, info)
69
+
70
+ AppendMenu(hmenu1, MF_SEPARATOR, 0, nil)
71
+
72
+ hmenu2 = CreatePopupMenu()
73
+ AppendMenu(hmenu2, MF_STRING | MF_CHECKED | MFT_RADIOCHECK,
74
+ CMD_ITEM6, L('Item&6'))
75
+ SetMenuItemInfo(hmenu2, CMD_ITEM6, 0, info)
76
+
77
+ AppendMenu(hmenu2, MF_STRING, CMD_ITEM7, L('Item&7'))
78
+ SetMenuItemInfo(hmenu2, CMD_ITEM7, 0, info)
79
+ AppendMenu(hmenu1, MF_POPUP, hmenu2.to_i, L('Menu&2'))
80
+ SetMenuItemInfo(hmenu1, 7, MF_BYPOSITION, info)
81
+ AppendMenu(hbar, MF_POPUP, hmenu1.to_i, L('Menu&1'))
82
+ SetMenuItemInfo(hbar, 0, MF_BYPOSITION, info)
83
+
84
+ AppendMenu(hbar, MF_STRING, CMD_ITEM8, L('Item&8'))
85
+ SetMenuItemInfo(hbar, CMD_ITEM8, 0, info)
86
+
87
+ hmenu3 = CreatePopupMenu()
88
+ AppendMenu(hmenu3, MF_BITMAP, CMD_ITEM9, xtra[:hbmp])
89
+ AppendMenu(hbar, MF_POPUP | MF_BITMAP | MF_RIGHTJUSTIFY, hmenu3.to_i, xtra[:hbmp])
90
+ SetMenu(hwnd, hbar)
91
+
92
+ 0
93
+ ensure
94
+ info.pointer.free if info
95
+ end
96
+
97
+ def onDestroy(hwnd)
98
+ xtra = WndExtra::REFS[GetWindowLong(hwnd, GWL_USERDATA)]
99
+
100
+ DeleteObject(xtra[:hbmp])
101
+
102
+ PostQuitMessage(0); 0
103
+ end
104
+
105
+ def onItem1(verb,
106
+ hctl, hwnd
107
+ )
108
+ hbar = GetMenu(hwnd)
109
+ i2grayed = (GetMenuState(hbar, CMD_ITEM2, 0) & MF_GRAYED) == MF_GRAYED
110
+
111
+ EnableMenuItem(hbar, CMD_ITEM2, (i2grayed) ? MF_ENABLED : MF_GRAYED)
112
+
113
+ 0
114
+ end
115
+
116
+ def onItem2(verb,
117
+ hctl, hwnd
118
+ )
119
+ MessageBox(hwnd,
120
+ L(__method__.to_s),
121
+ APPNAME,
122
+ MB_ICONINFORMATION
123
+ )
124
+
125
+ 0
126
+ end
127
+
128
+ def onItem3(verb,
129
+ hctl, hwnd
130
+ )
131
+ hbar = GetMenu(hwnd)
132
+ i3checked = (GetMenuState(hbar, CMD_ITEM3, 0) & MF_CHECKED) == MF_CHECKED
133
+
134
+ CheckMenuItem(hbar, CMD_ITEM3, (i3checked) ? MF_UNCHECKED : MF_CHECKED)
135
+
136
+ 0
137
+ end
138
+
139
+ def onItem4(verb,
140
+ hctl, hwnd
141
+ )
142
+ CheckMenuRadioItem(GetMenu(hwnd), CMD_ITEM4, CMD_ITEM5, CMD_ITEM4, 0)
143
+
144
+ 0
145
+ end
146
+
147
+ def onItem5(verb,
148
+ hctl, hwnd
149
+ )
150
+ CheckMenuRadioItem(GetMenu(hwnd), CMD_ITEM4, CMD_ITEM5, CMD_ITEM5, 0)
151
+
152
+ 0
153
+ end
154
+
155
+ def onItem6(verb,
156
+ hctl, hwnd
157
+ )
158
+ CheckMenuRadioItem(GetMenu(hwnd), CMD_ITEM6, CMD_ITEM7, CMD_ITEM6, 0)
159
+
160
+ 0
161
+ end
162
+
163
+ def onItem7(verb,
164
+ hctl, hwnd
165
+ )
166
+ CheckMenuRadioItem(GetMenu(hwnd), CMD_ITEM6, CMD_ITEM7, CMD_ITEM7, 0)
167
+
168
+ 0
169
+ end
170
+
171
+ def onItem8(verb,
172
+ hctl, hwnd
173
+ )
174
+ MessageBox(hwnd,
175
+ L(__method__.to_s),
176
+ APPNAME,
177
+ MB_ICONINFORMATION
178
+ )
179
+
180
+ 0
181
+ end
182
+
183
+ def onItem9(verb,
184
+ hctl, hwnd
185
+ )
186
+ hbar = GetMenu(hwnd)
187
+ i2grayed = (GetMenuState(hbar, CMD_ITEM2, 0) & MF_GRAYED) == MF_GRAYED
188
+ i3checked = (GetMenuState(hbar, CMD_ITEM3, 0) & MF_CHECKED) == MF_CHECKED
189
+ i4checked = (GetMenuState(hbar, CMD_ITEM4, 0) & MF_CHECKED) == MF_CHECKED
190
+ i5checked = (GetMenuState(hbar, CMD_ITEM5, 0) & MF_CHECKED) == MF_CHECKED
191
+ i6checked = (GetMenuState(hbar, CMD_ITEM6, 0) & MF_CHECKED) == MF_CHECKED
192
+ i7checked = (GetMenuState(hbar, CMD_ITEM7, 0) & MF_CHECKED) == MF_CHECKED
193
+
194
+ MessageBox(hwnd,
195
+ L("
196
+ Item2 - #{(i2grayed) ? 'grayed' : 'enabled'}
197
+ Item3 - #{(i3checked) ? 'checked' : 'unchecked'}
198
+ Item4 - #{(i4checked) ? 'checked' : 'unchecked'}
199
+ Item5 - #{(i5checked) ? 'checked' : 'unchecked'}
200
+ Item6 - #{(i6checked) ? 'checked' : 'unchecked'}
201
+ Item7 - #{(i7checked) ? 'checked' : 'unchecked'}
202
+ "),
203
+ APPNAME,
204
+ MB_ICONINFORMATION
205
+ )
206
+
207
+ 0
208
+ end
209
+
210
+ WindowProc = FFI::Function.new(:long,
211
+ [:pointer, :uint, :uint, :long],
212
+ convention: :stdcall
213
+ ) { |hwnd, uMsg, wParam, lParam|
214
+ begin
215
+ result = case uMsg
216
+ when WM_NCCREATE
217
+ DefWindowProc(hwnd, uMsg, wParam, lParam)
218
+
219
+ SetWindowLong(hwnd,
220
+ GWL_USERDATA,
221
+ CREATESTRUCT.new(FFI::Pointer.new(lParam))[:lpCreateParams].to_i
222
+ )
223
+
224
+ 1
225
+ when WM_CREATE
226
+ onCreate(hwnd, CREATESTRUCT.new(FFI::Pointer.new(lParam)))
227
+ when WM_DESTROY
228
+ onDestroy(hwnd)
229
+
230
+ when WM_COMMAND
231
+ id, verb = LOWORD(wParam), HIWORD(wParam)
232
+ hctl = FFI::Pointer.new(lParam)
233
+
234
+ case id
235
+ when CMD_ITEM1
236
+ onItem1(verb, hctl, hwnd)
237
+ when CMD_ITEM2
238
+ onItem2(verb, hctl, hwnd)
239
+ when CMD_ITEM3
240
+ onItem3(verb, hctl, hwnd)
241
+ when CMD_ITEM4
242
+ onItem4(verb, hctl, hwnd)
243
+ when CMD_ITEM5
244
+ onItem5(verb, hctl, hwnd)
245
+ when CMD_ITEM6
246
+ onItem6(verb, hctl, hwnd)
247
+ when CMD_ITEM7
248
+ onItem7(verb, hctl, hwnd)
249
+ when CMD_ITEM8
250
+ onItem8(verb, hctl, hwnd)
251
+ when CMD_ITEM9
252
+ onItem9(verb, hctl, hwnd)
253
+ end
254
+ end
255
+
256
+ result || DefWindowProc(hwnd, uMsg, wParam, lParam)
257
+ rescue
258
+ case MessageBox(hwnd,
259
+ L(Util.FormatException($!)),
260
+ APPNAME,
261
+ MB_ABORTRETRYIGNORE | MB_ICONERROR
262
+ )
263
+ when IDABORT
264
+ PostQuitMessage(2)
265
+ when IDRETRY
266
+ retry
267
+ end
268
+ end
269
+ }
270
+
271
+ def main
272
+ xtra = WndExtra.new
273
+
274
+ WNDCLASSEX.new { |wc|
275
+ wc[:cbSize] = wc.size
276
+ wc[:lpfnWndProc] = WindowProc
277
+ wc[:cbWndExtra] = FFI::Type::Builtin::POINTER.size
278
+ wc[:hInstance] = GetModuleHandle(nil)
279
+ wc[:hIcon] = LoadIcon(nil, IDI_APPLICATION)
280
+ wc[:hCursor] = LoadCursor(nil, IDC_ARROW)
281
+ wc[:hbrBackground] = FFI::Pointer.new(
282
+ ((WINVER == WINXP) ? COLOR_MENUBAR : COLOR_MENU) + 1
283
+ )
284
+
285
+ PWSTR(APPNAME) { |className|
286
+ wc[:lpszClassName] = className
287
+
288
+ DetonateLastError(0, :RegisterClassEx,
289
+ wc
290
+ )
291
+ }
292
+ }
293
+
294
+ hwnd = CreateWindowEx(
295
+ 0, APPNAME, APPNAME, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
296
+ CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
297
+ nil, nil, GetModuleHandle(nil), FFI::Pointer.new(xtra.object_id)
298
+ )
299
+
300
+ raise "CreateWindowEx failed (last error: #{GetLastError()})" if
301
+ hwnd.null? && GetLastError() != 0
302
+
303
+ exit(0) if hwnd.null?
304
+
305
+ ShowWindow(hwnd, SW_SHOWNORMAL)
306
+ UpdateWindow(hwnd)
307
+
308
+ MSG.new { |msg|
309
+ until DetonateLastError(-1, :GetMessage,
310
+ msg, nil, 0, 0
311
+ ) == 0
312
+ TranslateMessage(msg)
313
+ DispatchMessage(msg)
314
+ end
315
+
316
+ exit(msg[:wParam])
317
+ }
318
+ rescue
319
+ MessageBox(hwnd,
320
+ L(Util.FormatException($!)),
321
+ APPNAME,
322
+ MB_ICONERROR
323
+ ); exit(1)
324
+ end
325
+
326
+ main