ffi-wingui-core 0.6.0 → 1.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,153 @@
1
+ require 'ffi'
2
+
3
+ WINGUI_VISUAL_STYLES = true unless defined?(WINGUI_VISUAL_STYLES)
4
+ WINGUI_DPI_AWARE = true unless defined?(WINGUI_DPI_AWARE)
5
+
6
+ module WinGUI
7
+ extend FFI::Library
8
+
9
+ module Util
10
+ def FormatException(ex)
11
+ str, trace = ex.to_s, ex.backtrace
12
+
13
+ str << "\n\n-- backtrace --\n\n" << trace.join("\n") if trace
14
+
15
+ str
16
+ end
17
+
18
+ module_function :FormatException
19
+
20
+ Id2Ref = {}
21
+
22
+ def Id2RefTrack(object)
23
+ Id2Ref[object.object_id] = object
24
+
25
+ ObjectSpace.define_finalizer(object, -> id {
26
+ Id2Ref.delete(id)
27
+ })
28
+ end
29
+
30
+ module_function :Id2RefTrack
31
+
32
+ unless FFI::Struct.respond_to?(:by_ref)
33
+ class << FFI::Struct
34
+ def by_ref(*args)
35
+ FFI::Type::Builtin::POINTER
36
+ end
37
+ end
38
+ end
39
+
40
+ module ScopedStruct
41
+ def new(*args)
42
+ raise ArgumentError, 'Cannot accept both arguments and a block' if
43
+ args.length > 0 && block_given?
44
+
45
+ struct = super
46
+
47
+ return struct unless block_given?
48
+
49
+ begin
50
+ yield struct
51
+ ensure
52
+ struct.pointer.free
53
+
54
+ p "Native memory for #{struct} freed" if $DEBUG
55
+ end
56
+
57
+ nil
58
+ end
59
+ end
60
+ end
61
+
62
+ INVALID_HANDLE_VALUE = FFI::Pointer.new(-1)
63
+
64
+ def MAKEWORD(lobyte, hibyte)
65
+ (lobyte & 0xff) | ((hibyte & 0xff) << 8)
66
+ end
67
+
68
+ def LOBYTE(word)
69
+ word & 0xff
70
+ end
71
+
72
+ def HIBYTE(word)
73
+ (word >> 8) & 0xff
74
+ end
75
+
76
+ module_function :MAKEWORD, :LOBYTE, :HIBYTE
77
+
78
+ def MAKELONG(loword, hiword)
79
+ (loword & 0xffff) | ((hiword & 0xffff) << 16)
80
+ end
81
+
82
+ def LOWORD(long)
83
+ long & 0xffff
84
+ end
85
+
86
+ def HIWORD(long)
87
+ (long >> 16) & 0xffff
88
+ end
89
+
90
+ def LOSHORT(long)
91
+ ((loshort = LOWORD(long)) > 0x7fff) ? loshort - 0x1_0000 : loshort
92
+ end
93
+
94
+ def HISHORT(long)
95
+ ((hishort = HIWORD(long)) > 0x7fff) ? hishort - 0x1_0000 : hishort
96
+ end
97
+
98
+ module_function :MAKELONG, :LOWORD, :HIWORD, :LOSHORT, :HISHORT
99
+
100
+ def L(str)
101
+ (str << "\0").encode!('utf-16le')
102
+ end
103
+
104
+ def PWSTR(wstr)
105
+ raise 'Invalid Unicode string' unless
106
+ wstr.encoding == Encoding::UTF_16LE && wstr[-1] == L('')
107
+
108
+ ptr = FFI::MemoryPointer.new(:ushort, wstr.length).
109
+ put_bytes(0, wstr)
110
+
111
+ return ptr unless block_given?
112
+
113
+ begin
114
+ yield ptr
115
+ ensure
116
+ ptr.free
117
+
118
+ p "Native copy of '#{wstr[0...-1].encode($0.encoding)}' freed" if $DEBUG
119
+ end
120
+
121
+ nil
122
+ end
123
+
124
+ module_function :L, :PWSTR
125
+
126
+ APPNAME = L(File.basename($0, '.rbw'))
127
+
128
+ class POINT < FFI::Struct
129
+ extend Util::ScopedStruct
130
+
131
+ layout \
132
+ :x, :long,
133
+ :y, :long
134
+ end
135
+
136
+ class SIZE < FFI::Struct
137
+ extend Util::ScopedStruct
138
+
139
+ layout \
140
+ :cx, :long,
141
+ :cy, :long
142
+ end
143
+
144
+ class RECT < FFI::Struct
145
+ extend Util::ScopedStruct
146
+
147
+ layout \
148
+ :left, :long,
149
+ :top, :long,
150
+ :right, :long,
151
+ :bottom, :long
152
+ end
153
+ end
@@ -0,0 +1,575 @@
1
+ if __FILE__ == $0
2
+ require_relative 'kernel32'
3
+ end
4
+ require_relative 'common'
5
+
6
+ module WinGUI
7
+ ffi_lib 'gdi32'
8
+ ffi_convention :stdcall
9
+
10
+ HGDI_ERROR = FFI::Pointer.new(-1)
11
+
12
+ def RGB(r, g, b)
13
+ r | (g << 8) | (b << 16)
14
+ end
15
+
16
+ def GetRValue(rgb)
17
+ LOBYTE(rgb)
18
+ end
19
+
20
+ def GetGValue(rgb)
21
+ LOBYTE(rgb >> 8)
22
+ end
23
+
24
+ def GetBValue(rgb)
25
+ LOBYTE(rgb >> 16)
26
+ end
27
+
28
+ module_function :RGB, :GetRValue, :GetGValue, :GetBValue
29
+
30
+ attach_function :CreateCompatibleDC, [
31
+ :pointer
32
+ ], :pointer
33
+
34
+ attach_function :DeleteDC, [
35
+ :pointer
36
+ ], :int
37
+
38
+ LOGPIXELSX = 88
39
+ LOGPIXELSY = 90
40
+
41
+ attach_function :GetDeviceCaps, [
42
+ :pointer,
43
+ :int
44
+ ], :int
45
+
46
+ attach_function :CreateCompatibleBitmap, [
47
+ :pointer,
48
+ :int,
49
+ :int
50
+ ], :pointer
51
+
52
+ def DPIAwareFontHeight(pointSize)
53
+ -MulDiv(pointSize, DPIY, 72)
54
+ end
55
+
56
+ module_function :DPIAwareFontHeight
57
+
58
+ FW_DONTCARE = 0
59
+ FW_THIN = 100
60
+ FW_EXTRALIGHT = 200
61
+ FW_LIGHT = 300
62
+ FW_NORMAL = 400
63
+ FW_MEDIUM = 500
64
+ FW_SEMIBOLD = 600
65
+ FW_BOLD = 700
66
+ FW_EXTRABOLD = 800
67
+ FW_HEAVY = 900
68
+
69
+ DEFAULT_CHARSET = 1
70
+ ANSI_CHARSET = 0
71
+
72
+ OUT_DEFAULT_PRECIS = 0
73
+ OUT_DEVICE_PRECIS = 5
74
+ OUT_RASTER_PRECIS = 6
75
+ OUT_OUTLINE_PRECIS = 8
76
+ OUT_SCREEN_OUTLINE_PRECIS = 9
77
+ OUT_PS_ONLY_PRECIS = 10
78
+ OUT_TT_PRECIS = 4
79
+ OUT_TT_ONLY_PRECIS = 7
80
+
81
+ CLIP_DEFAULT_PRECIS = 0
82
+
83
+ DEFAULT_QUALITY = 0
84
+ DRAFT_QUALITY = 1
85
+ PROOF_QUALITY = 2
86
+ NONANTIALIASED_QUALITY = 3
87
+ ANTIALIASED_QUALITY = 4
88
+ if WINVER >= WINXP
89
+ CLEARTYPE_QUALITY = 5
90
+ CLEARTYPE_NATURAL_QUALITY = 6
91
+ end
92
+
93
+ DEFAULT_PITCH = 0
94
+ FIXED_PITCH = 1
95
+ VARIABLE_PITCH = 2
96
+
97
+ FF_DONTCARE = 0 << 4
98
+ FF_MODERN = 3 << 4
99
+ FF_SWISS = 2 << 4
100
+ FF_ROMAN = 1 << 4
101
+ FF_SCRIPT = 4 << 4
102
+ FF_DECORATIVE = 5 << 4
103
+
104
+ class LOGFONT < FFI::Struct
105
+ extend Util::ScopedStruct
106
+
107
+ layout \
108
+ :lfHeight, :long,
109
+ :lfWidth, :long,
110
+ :lfEscapement, :long,
111
+ :lfOrientation, :long,
112
+ :lfWeight, :long,
113
+ :lfItalic, :uchar,
114
+ :lfUnderline, :uchar,
115
+ :lfStrikeOut, :uchar,
116
+ :lfCharSet, :uchar,
117
+ :lfOutPrecision, :uchar,
118
+ :lfClipPrecision, :uchar,
119
+ :lfQuality, :uchar,
120
+ :lfPitchAndFamily, :uchar,
121
+ :lfFaceName, [:ushort, 32]
122
+ end
123
+
124
+ attach_function :CreateFontIndirect, :CreateFontIndirectW, [
125
+ LOGFONT.by_ref(:in)
126
+ ], :pointer
127
+
128
+ BS_NULL = 1
129
+ BS_SOLID = 0
130
+ BS_HATCHED = 2
131
+ BS_PATTERN = 3
132
+ BS_DIBPATTERN = 5
133
+ BS_DIBPATTERNPT = 6
134
+
135
+ DIB_RGB_COLORS = 0
136
+ DIB_PAL_COLORS = 1
137
+
138
+ HS_HORIZONTAL = 0
139
+ HS_VERTICAL = 1
140
+ HS_FDIAGONAL = 2
141
+ HS_BDIAGONAL = 3
142
+ HS_CROSS = 4
143
+ HS_DIAGCROSS = 5
144
+
145
+ class LOGBRUSH < FFI::Struct
146
+ extend Util::ScopedStruct
147
+
148
+ layout \
149
+ :lbStyle, :uint,
150
+ :lbColor, :ulong,
151
+ :lbHatch, :ulong
152
+ end
153
+
154
+ attach_function :CreateBrushIndirect, [
155
+ LOGBRUSH.by_ref(:in)
156
+ ], :pointer
157
+
158
+ PS_COSMETIC = 0x0000_0000
159
+ PS_GEOMETRIC = 0x0001_0000
160
+
161
+ PS_NULL = 5
162
+ PS_SOLID = 0
163
+ PS_DASH = 1
164
+ PS_DOT = 2
165
+ PS_DASHDOT = 3
166
+ PS_DASHDOTDOT = 4
167
+ PS_ALTERNATE = 8
168
+ PS_USERSTYLE = 7
169
+ PS_INSIDEFRAME = 6
170
+
171
+ PS_ENDCAP_FLAT = 0x0000_0200
172
+ PS_ENDCAP_SQUARE = 0x0000_0100
173
+ PS_ENDCAP_ROUND = 0x0000_0000
174
+
175
+ PS_JOIN_BEVEL = 0x0000_1000
176
+ PS_JOIN_MITER = 0x0000_2000
177
+ PS_JOIN_ROUND = 0x0000_0000
178
+
179
+ class LOGPEN < FFI::Struct
180
+ extend Util::ScopedStruct
181
+
182
+ layout \
183
+ :lopnStyle, :uint,
184
+ :lopnWidth, POINT,
185
+ :lopnColor, :ulong
186
+ end
187
+
188
+ attach_function :CreatePenIndirect, [
189
+ LOGPEN.by_ref(:in)
190
+ ], :pointer
191
+
192
+ attach_function :ExtCreatePen, [
193
+ :ulong,
194
+ :ulong,
195
+ LOGBRUSH.by_ref(:in),
196
+ :ulong,
197
+ :pointer
198
+ ], :pointer
199
+
200
+ attach_function :CreateRectRgn, [
201
+ :int,
202
+ :int,
203
+ :int,
204
+ :int
205
+ ], :pointer
206
+
207
+ attach_function :CreateRoundRectRgn, [
208
+ :int,
209
+ :int,
210
+ :int,
211
+ :int,
212
+ :int,
213
+ :int
214
+ ], :pointer
215
+
216
+ attach_function :CreateEllipticRgn, [
217
+ :int,
218
+ :int,
219
+ :int,
220
+ :int
221
+ ], :pointer
222
+
223
+ ALTERNATE = 1
224
+ WINDING = 2
225
+
226
+ attach_function :SetPolyFillMode, [
227
+ :pointer,
228
+ :int
229
+ ], :int
230
+
231
+ attach_function :GetPolyFillMode, [
232
+ :pointer
233
+ ], :int
234
+
235
+ attach_function :CreatePolygonRgn, [
236
+ :pointer,
237
+ :int,
238
+ :int
239
+ ], :pointer
240
+
241
+ attach_function :CreatePolyPolygonRgn, [
242
+ :pointer,
243
+ :pointer,
244
+ :int,
245
+ :int
246
+ ], :pointer
247
+
248
+ attach_function :OffsetRgn, [
249
+ :pointer,
250
+ :int,
251
+ :int
252
+ ], :int
253
+
254
+ RGN_COPY = 5
255
+ RGN_DIFF = 4
256
+ RGN_AND = 1
257
+ RGN_OR = 2
258
+ RGN_XOR = 3
259
+
260
+ ERROR = 0
261
+ NULLREGION = 1
262
+ SIMPLEREGION = 2
263
+ COMPLEXREGION = 3
264
+
265
+ attach_function :CombineRgn, [
266
+ :pointer,
267
+ :pointer,
268
+ :pointer,
269
+ :int
270
+ ], :int
271
+
272
+ attach_function :GetRgnBox, [
273
+ :pointer,
274
+ RECT.by_ref(:out)
275
+ ], :int
276
+
277
+ attach_function :PtInRegion, [
278
+ :pointer,
279
+ :int,
280
+ :int
281
+ ], :int
282
+
283
+ attach_function :RectInRegion, [
284
+ :pointer,
285
+ RECT.by_ref(:in)
286
+ ], :int
287
+
288
+ attach_function :EqualRgn, [
289
+ :pointer,
290
+ :pointer
291
+ ], :int
292
+
293
+ attach_function :FrameRgn, [
294
+ :pointer,
295
+ :pointer,
296
+ :pointer,
297
+ :int,
298
+ :int
299
+ ], :int
300
+
301
+ attach_function :FillRgn, [
302
+ :pointer,
303
+ :pointer,
304
+ :pointer
305
+ ], :int
306
+
307
+ attach_function :DeleteObject, [
308
+ :pointer
309
+ ], :int
310
+
311
+ attach_function :GetObject, :GetObjectW, [
312
+ :pointer,
313
+ :int,
314
+ :pointer
315
+ ], :int
316
+
317
+ R2_BLACK = 1
318
+ R2_WHITE = 16
319
+
320
+ R2_NOP = 11
321
+ R2_NOT = 6
322
+ R2_COPYPEN = 13
323
+ R2_NOTCOPYPEN = 4
324
+
325
+ R2_MERGEPEN = 15
326
+ R2_MERGENOTPEN = 12
327
+ R2_MERGEPENNOT = 14
328
+ R2_NOTMERGEPEN = 2
329
+
330
+ R2_MASKPEN = 9
331
+ R2_MASKNOTPEN = 3
332
+ R2_MASKPENNOT = 5
333
+ R2_NOTMASKPEN = 8
334
+
335
+ R2_XORPEN = 7
336
+ R2_NOTXORPEN = 10
337
+
338
+ attach_function :SetROP2, [
339
+ :pointer,
340
+ :int
341
+ ], :int
342
+
343
+ attach_function :GetROP2, [
344
+ :pointer
345
+ ], :int
346
+
347
+ attach_function :SetBkColor, [
348
+ :pointer,
349
+ :ulong
350
+ ], :ulong
351
+
352
+ attach_function :GetBkColor, [
353
+ :pointer
354
+ ], :ulong
355
+
356
+ attach_function :SetTextColor, [
357
+ :pointer,
358
+ :ulong
359
+ ], :ulong
360
+
361
+ attach_function :GetTextColor, [
362
+ :pointer
363
+ ], :ulong
364
+
365
+ attach_function :SelectObject, [
366
+ :pointer,
367
+ :pointer
368
+ ], :pointer
369
+
370
+ def UseObjects(hdc, *hgdiobjs)
371
+ holds = []
372
+
373
+ hgdiobjs.each { |hgdiobj|
374
+ holds << DetonateLastError([FFI::Pointer::NULL, HGDI_ERROR], :SelectObject,
375
+ hdc, hgdiobj
376
+ )
377
+ }
378
+
379
+ yield
380
+ ensure
381
+ holds.each { |hgdiobj|
382
+ SelectObject(hdc, hgdiobj)
383
+ }
384
+ end
385
+
386
+ module_function :UseObjects
387
+
388
+ AD_COUNTERCLOCKWISE = 1
389
+ AD_CLOCKWISE = 2
390
+
391
+ attach_function :SetArcDirection, [
392
+ :pointer,
393
+ :int
394
+ ], :int
395
+
396
+ attach_function :GetArcDirection, [
397
+ :int
398
+ ], :int
399
+
400
+ attach_function :SaveDC, [
401
+ :pointer
402
+ ], :int
403
+
404
+ attach_function :RestoreDC, [
405
+ :pointer,
406
+ :int
407
+ ], :int
408
+
409
+ attach_function :GetTextExtentPoint32, :GetTextExtentPoint32W, [
410
+ :pointer,
411
+ :buffer_in,
412
+ :int,
413
+ SIZE.by_ref(:out)
414
+ ], :int
415
+
416
+ attach_function :TextOut, :TextOutW, [
417
+ :pointer,
418
+ :int,
419
+ :int,
420
+ :buffer_in,
421
+ :int
422
+ ], :int
423
+
424
+ attach_function :MoveToEx, [
425
+ :pointer,
426
+ :int,
427
+ :int,
428
+ POINT.by_ref(:out)
429
+ ], :int
430
+
431
+ attach_function :LineTo, [
432
+ :pointer,
433
+ :int,
434
+ :int
435
+ ], :int
436
+
437
+ attach_function :Polyline, [
438
+ :pointer,
439
+ :pointer,
440
+ :int
441
+ ], :int
442
+
443
+ attach_function :PolylineTo, [
444
+ :pointer,
445
+ :pointer,
446
+ :ulong
447
+ ], :int
448
+
449
+ attach_function :PolyPolyline, [
450
+ :pointer,
451
+ :pointer,
452
+ :pointer,
453
+ :ulong
454
+ ], :int
455
+
456
+ attach_function :Arc, [
457
+ :pointer,
458
+ :int,
459
+ :int,
460
+ :int,
461
+ :int,
462
+ :int,
463
+ :int,
464
+ :int,
465
+ :int,
466
+ ], :int
467
+
468
+ attach_function :ArcTo, [
469
+ :pointer,
470
+ :int,
471
+ :int,
472
+ :int,
473
+ :int,
474
+ :int,
475
+ :int,
476
+ :int,
477
+ :int,
478
+ ], :int
479
+
480
+ attach_function :AngleArc, [
481
+ :pointer,
482
+ :int,
483
+ :int,
484
+ :ulong,
485
+ :float,
486
+ :float
487
+ ], :int
488
+
489
+ attach_function :PolyBezier, [
490
+ :pointer,
491
+ :pointer,
492
+ :ulong
493
+ ], :int
494
+
495
+ attach_function :PolyBezierTo, [
496
+ :pointer,
497
+ :pointer,
498
+ :ulong
499
+ ], :int
500
+
501
+ PT_MOVETO = 0x06
502
+ PT_LINETO = 0x02
503
+ PT_BEZIERTO = 0x04
504
+ PT_CLOSEFIGURE = 0x01
505
+
506
+ attach_function :PolyDraw, [
507
+ :pointer,
508
+ :pointer,
509
+ :pointer,
510
+ :int
511
+ ], :int
512
+
513
+ attach_function :Rectangle, [
514
+ :pointer,
515
+ :int,
516
+ :int,
517
+ :int,
518
+ :int
519
+ ], :int
520
+
521
+ attach_function :RoundRect, [
522
+ :pointer,
523
+ :int,
524
+ :int,
525
+ :int,
526
+ :int,
527
+ :int,
528
+ :int
529
+ ], :int
530
+
531
+ attach_function :Ellipse, [
532
+ :pointer,
533
+ :int,
534
+ :int,
535
+ :int,
536
+ :int
537
+ ], :int
538
+
539
+ attach_function :Pie, [
540
+ :pointer,
541
+ :int,
542
+ :int,
543
+ :int,
544
+ :int,
545
+ :int,
546
+ :int,
547
+ :int,
548
+ :int
549
+ ], :int
550
+
551
+ attach_function :Chord, [
552
+ :pointer,
553
+ :int,
554
+ :int,
555
+ :int,
556
+ :int,
557
+ :int,
558
+ :int,
559
+ :int,
560
+ :int
561
+ ], :int
562
+
563
+ attach_function :Polygon, [
564
+ :pointer,
565
+ :pointer,
566
+ :int
567
+ ], :int
568
+
569
+ attach_function :PolyPolygon, [
570
+ :pointer,
571
+ :pointer,
572
+ :pointer,
573
+ :int
574
+ ], :int
575
+ end