ffi-wingui-core 0.6.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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