fzeet 0.6.1 → 0.6.2
Sign up to get free protection for your applications and to get access to all the features.
- data/examples/UIRibbon/ApplicationModes.dll +0 -0
- data/examples/UIRibbon/ApplicationModes.rb +40 -0
- data/examples/UIRibbon/ApplicationModes.rbw +14 -0
- data/examples/UIRibbon/ApplicationModes.xml +83 -0
- data/examples/UIRibbon/Color.rbw +1 -1
- data/examples/UIRibbon/Control/Button.dll +0 -0
- data/examples/UIRibbon/Control/Button.rb +9 -5
- data/examples/UIRibbon/Control/Button.rbw +3 -1
- data/examples/UIRibbon/Control/Button.xml +6 -0
- data/examples/UIRibbon/Control/ColorPicker.dll +0 -0
- data/examples/UIRibbon/Control/ColorPicker.rb +55 -0
- data/examples/UIRibbon/Control/ColorPicker.rbw +91 -0
- data/examples/UIRibbon/Control/ColorPicker.xml +131 -0
- data/examples/UIRibbon/Control/ComboBox.dll +0 -0
- data/examples/UIRibbon/Control/ComboBox.rb +23 -0
- data/examples/UIRibbon/Control/ComboBox.rbw +56 -0
- data/examples/UIRibbon/Control/ComboBox.xml +75 -0
- data/examples/UIRibbon/Control/FontControl.dll +0 -0
- data/examples/UIRibbon/Control/FontControl.rb +34 -0
- data/examples/UIRibbon/Control/FontControl.rbw +83 -0
- data/examples/UIRibbon/Control/FontControl.xml +96 -0
- data/examples/UIRibbon/Control/Gallery.dll +0 -0
- data/examples/UIRibbon/Control/Gallery.rb +55 -0
- data/examples/UIRibbon/Control/Gallery.rbw +124 -0
- data/examples/UIRibbon/Control/Gallery.xml +132 -0
- data/examples/UIRibbon/Control/Spinner.dll +0 -0
- data/examples/UIRibbon/Control/Spinner.rb +14 -0
- data/examples/UIRibbon/Control/Spinner.rbw +27 -0
- data/examples/UIRibbon/Control/Spinner.xml +37 -0
- data/examples/UIRibbon/Size.rbw +1 -1
- data/examples/UIRibbon/TabGroup.dll +0 -0
- data/examples/UIRibbon/TabGroup.rb +12 -0
- data/examples/UIRibbon/TabGroup.rbw +23 -0
- data/examples/UIRibbon/TabGroup.xml +42 -0
- data/examples/UIRibbon/Viewer.rbw +1 -1
- data/examples/res/applications-graphics-big.bmp +0 -0
- data/examples/res/applications-graphics-small.bmp +0 -0
- data/examples/res/applications-graphics.bmp +0 -0
- data/examples/res/document-print-big.bmp +0 -0
- data/examples/res/document-print-preview-big.bmp +0 -0
- data/examples/res/document-print-preview-small.bmp +0 -0
- data/examples/res/document-print-preview.bmp +0 -0
- data/examples/res/document-print-small.bmp +0 -0
- data/examples/res/document-print.bmp +0 -0
- data/examples/res/go-bottom-big.bmp +0 -0
- data/examples/res/go-bottom-small.bmp +0 -0
- data/examples/res/go-bottom.bmp +0 -0
- data/examples/res/preferences-desktop-font-big.bmp +0 -0
- data/examples/res/preferences-desktop-font-small.bmp +0 -0
- data/examples/res/preferences-desktop-font.bmp +0 -0
- data/examples/res/process-stop-big.bmp +0 -0
- data/examples/res/process-stop-small.bmp +0 -0
- data/examples/res/process-stop.bmp +0 -0
- data/lib/fzeet/Application.rb +6 -1
- data/lib/fzeet/Common.rb +17 -0
- data/lib/fzeet/Dialog/ShellFileDialog.rb +8 -48
- data/lib/fzeet/UIRibbon.rb +174 -7
- data/lib/fzeet/windows/com.rb +2 -0
- data/lib/fzeet/windows/common.rb +47 -6
- data/lib/fzeet/windows/gdi.rb +8 -0
- data/lib/fzeet/windows/kernel.rb +2 -0
- data/lib/fzeet/windows/ole.rb +34 -0
- data/lib/fzeet/windows/propsys.rb +7 -1
- data/lib/fzeet/windows/shell/Common.rb +44 -0
- data/lib/fzeet/windows/shlwapi.rb +10 -0
- data/lib/fzeet/windows/uiribbon.rb +15 -0
- data/lib/fzeet/windows.rb +1 -0
- metadata +51 -8
@@ -0,0 +1,42 @@
|
|
1
|
+
<?xml version='1.0' encoding='utf-8' ?>
|
2
|
+
<Application xmlns='http://schemas.microsoft.com/windows/2009/Ribbon'>
|
3
|
+
<Application.Commands>
|
4
|
+
<Command Name='cmdAppMenu' />
|
5
|
+
|
6
|
+
<Command Name='cmdQAT' />
|
7
|
+
|
8
|
+
<Command Name='cmdTab1' LabelTitle='Tab1' />
|
9
|
+
|
10
|
+
<Command Name='cmdTabGroup1' LabelTitle='TabGroup1' />
|
11
|
+
|
12
|
+
<Command Name='cmdTabGroup1Tab1' LabelTitle='Tab1' />
|
13
|
+
<Command Name='cmdTabGroup1Tab2' LabelTitle='Tab2' />
|
14
|
+
</Application.Commands>
|
15
|
+
|
16
|
+
<Application.Views>
|
17
|
+
<Ribbon>
|
18
|
+
<Ribbon.ApplicationMenu>
|
19
|
+
<ApplicationMenu CommandName='cmdAppMenu'>
|
20
|
+
|
21
|
+
</ApplicationMenu>
|
22
|
+
</Ribbon.ApplicationMenu>
|
23
|
+
|
24
|
+
<Ribbon.QuickAccessToolbar>
|
25
|
+
<QuickAccessToolbar CommandName='cmdQAT'>
|
26
|
+
|
27
|
+
</QuickAccessToolbar>
|
28
|
+
</Ribbon.QuickAccessToolbar>
|
29
|
+
|
30
|
+
<Ribbon.Tabs>
|
31
|
+
<Tab CommandName='cmdTab1' />
|
32
|
+
</Ribbon.Tabs>
|
33
|
+
|
34
|
+
<Ribbon.ContextualTabs>
|
35
|
+
<TabGroup CommandName='cmdTabGroup1'>
|
36
|
+
<Tab CommandName='cmdTabGroup1Tab1' />
|
37
|
+
<Tab CommandName='cmdTabGroup1Tab2' />
|
38
|
+
</TabGroup>
|
39
|
+
</Ribbon.ContextualTabs>
|
40
|
+
</Ribbon>
|
41
|
+
</Application.Views>
|
42
|
+
</Application>
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
data/lib/fzeet/Application.rb
CHANGED
@@ -12,10 +12,15 @@ module Fzeet
|
|
12
12
|
@accelerators = []
|
13
13
|
@dialogs = []
|
14
14
|
@images = {}
|
15
|
+
Fzeet.using(ScreenDC.new) { |dc|
|
16
|
+
@devcaps = {
|
17
|
+
logpixelsy: Windows.GetDeviceCaps(dc.handle, Windows::LOGPIXELSY)
|
18
|
+
}
|
19
|
+
}
|
15
20
|
|
16
21
|
class << self
|
17
22
|
attr_accessor :name, :version, :authors, :quitWhenMainWindowCloses
|
18
|
-
attr_reader :window, :accelerators, :dialogs, :images
|
23
|
+
attr_reader :window, :accelerators, :dialogs, :images, :devcaps
|
19
24
|
end
|
20
25
|
|
21
26
|
def self.window=(window)
|
data/lib/fzeet/Common.rb
CHANGED
@@ -153,6 +153,10 @@ module Fzeet
|
|
153
153
|
def rb; Point.new(self[:right], self[:bottom]) end
|
154
154
|
end
|
155
155
|
|
156
|
+
class LOGFONT
|
157
|
+
include Toggle
|
158
|
+
end
|
159
|
+
|
156
160
|
class Message < Windows::MSG
|
157
161
|
def get!(window = nil, msgFilterMin = 0, msgFilterMax = 0)
|
158
162
|
Windows.DetonateLastError(-1, :GetMessage, self, window && window.handle, msgFilterMin, msgFilterMax) != 0
|
@@ -299,6 +303,9 @@ module Fzeet
|
|
299
303
|
def color; Windows.GetTextColor(@handle) end
|
300
304
|
def color=(color) Windows.SetTextColor(@handle, color) end
|
301
305
|
|
306
|
+
def background; Windows.GetBkColor(@handle) end
|
307
|
+
def background=(background) Windows.SetBkColor(@handle, background) end
|
308
|
+
|
302
309
|
def fillRect(rect, brush) Windows.DetonateLastError(0, :FillRect, @handle, rect, brush.handle); self end
|
303
310
|
|
304
311
|
def text(text, rect, flags = 0) Windows.DetonateLastError(0, :DrawText, @handle, text, -1, rect, Fzeet.flags(flags, :dt_)); self end
|
@@ -328,4 +335,14 @@ module Fzeet
|
|
328
335
|
|
329
336
|
def dispose; Windows.ReleaseDC(@window.handle, @handle); detach end
|
330
337
|
end
|
338
|
+
|
339
|
+
class ScreenDC < Handle
|
340
|
+
include DCMethods
|
341
|
+
|
342
|
+
def initialize
|
343
|
+
@handle = Windows.DetonateLastError(FFI::Pointer::NULL, :GetDC, nil); attach
|
344
|
+
end
|
345
|
+
|
346
|
+
def dispose; Windows.ReleaseDC(nil, @handle); detach end
|
347
|
+
end
|
331
348
|
end
|
@@ -10,78 +10,38 @@ module Fzeet
|
|
10
10
|
result
|
11
11
|
end
|
12
12
|
|
13
|
-
def
|
14
|
-
result = nil
|
15
|
-
|
13
|
+
def item
|
16
14
|
FFI::MemoryPointer.new(:pointer) { |psi|
|
17
15
|
next unless GetResult(psi) == Windows::S_OK
|
18
16
|
|
19
17
|
si = Windows::ShellItem.new(psi.read_pointer)
|
20
18
|
|
21
19
|
begin
|
22
|
-
|
23
|
-
next unless si.GetDisplayName(Windows::SIGDN_FILESYSPATH, pwcs) == Windows::S_OK
|
24
|
-
|
25
|
-
wcs = pwcs.read_pointer
|
26
|
-
|
27
|
-
begin
|
28
|
-
result = Windows.WCSTOMBS(wcs)
|
29
|
-
ensure
|
30
|
-
Windows.CoTaskMemFree(wcs)
|
31
|
-
end
|
32
|
-
}
|
20
|
+
yield si
|
33
21
|
ensure
|
34
22
|
si.Release
|
35
23
|
end
|
36
24
|
}
|
37
|
-
|
38
|
-
result
|
39
25
|
end
|
40
26
|
|
41
|
-
def
|
42
|
-
result = []
|
43
|
-
|
27
|
+
def items
|
44
28
|
FFI::MemoryPointer.new(:pointer) { |psia|
|
45
29
|
next unless GetResults(psia) == Windows::S_OK
|
46
30
|
|
47
31
|
sia = Windows::ShellItemArray.new(psia.read_pointer)
|
48
32
|
|
49
33
|
begin
|
50
|
-
|
51
|
-
next unless sia.GetCount(pc) == Windows::S_OK
|
52
|
-
|
53
|
-
pc.read_long.times { |i|
|
54
|
-
FFI::MemoryPointer.new(:pointer) { |psi|
|
55
|
-
next unless sia.GetItemAt(i, psi) == Windows::S_OK
|
56
|
-
|
57
|
-
si = Windows::ShellItem.new(psi.read_pointer)
|
58
|
-
|
59
|
-
begin
|
60
|
-
FFI::MemoryPointer.new(:pointer) { |pwcs|
|
61
|
-
next unless si.GetDisplayName(Windows::SIGDN_FILESYSPATH, pwcs) == Windows::S_OK
|
62
|
-
|
63
|
-
wcs = pwcs.read_pointer
|
64
|
-
|
65
|
-
begin
|
66
|
-
result << Windows.WCSTOMBS(wcs)
|
67
|
-
ensure
|
68
|
-
Windows.CoTaskMemFree(wcs)
|
69
|
-
end
|
70
|
-
}
|
71
|
-
ensure
|
72
|
-
si.Release
|
73
|
-
end
|
74
|
-
}
|
75
|
-
}
|
76
|
-
}
|
34
|
+
yield sia
|
77
35
|
ensure
|
78
36
|
sia.Release
|
79
37
|
end
|
80
38
|
}
|
81
|
-
|
82
|
-
result
|
83
39
|
end
|
84
40
|
|
41
|
+
def path; item { |si| return si.path } end
|
42
|
+
|
43
|
+
def paths; items { |sia| return sia.map(&:path) } end
|
44
|
+
|
85
45
|
def show(window = Application.window)
|
86
46
|
DialogResult.new((Show(window.handle) == Windows::S_OK) ? Windows::IDOK : Windows::IDCANCEL)
|
87
47
|
end
|
data/lib/fzeet/UIRibbon.rb
CHANGED
@@ -7,6 +7,38 @@ module Fzeet
|
|
7
7
|
|
8
8
|
prop(*args)
|
9
9
|
end
|
10
|
+
|
11
|
+
def update(from)
|
12
|
+
case from
|
13
|
+
when Windows::LOGFONT
|
14
|
+
uiprop(:FontProperties_Family, Windows::PROPVARIANT[:wstring, from.face])
|
15
|
+
uiprop(:FontProperties_Size, Windows::PROPVARIANT[:decimal, from.size.round])
|
16
|
+
uiprop(:FontProperties_Bold, Windows::PROPVARIANT[:uint, (from.bold?) ? 2 : 1])
|
17
|
+
uiprop(:FontProperties_Italic, Windows::PROPVARIANT[:uint, (from.italic?) ? 2 : 1])
|
18
|
+
uiprop(:FontProperties_Underline, Windows::PROPVARIANT[:uint, (from.underline?) ? 2 : 1])
|
19
|
+
uiprop(:FontProperties_Strikethrough, Windows::PROPVARIANT[:uint, (from.strikeout?) ? 2 : 1])
|
20
|
+
else raise ArgumentError
|
21
|
+
end
|
22
|
+
|
23
|
+
self
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class Windows::UISimplePropertySet
|
28
|
+
def get(k) Windows::PROPVARIANT.new.tap { |v| GetValue(k, v) } end
|
29
|
+
|
30
|
+
def prop(*args)
|
31
|
+
case args.length
|
32
|
+
when 1; get(*args)
|
33
|
+
else raise ArgumentError
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def uiprop(*args)
|
38
|
+
args[0] = Windows.const_get("UI_PKEY_#{args[0]}")
|
39
|
+
|
40
|
+
prop(*args)
|
41
|
+
end
|
10
42
|
end
|
11
43
|
|
12
44
|
class UIRibbon
|
@@ -102,11 +134,63 @@ module Fzeet
|
|
102
134
|
}
|
103
135
|
end
|
104
136
|
|
105
|
-
|
137
|
+
class GalleryItem < Windows::UISimplePropertySetCallback
|
138
|
+
def initialize(label, categoryId = 0, image = nil)
|
139
|
+
@label, @categoryId, @image = label, categoryId, image
|
140
|
+
|
141
|
+
super()
|
142
|
+
end
|
143
|
+
|
144
|
+
attr_reader :label, :categoryId, :image
|
145
|
+
|
146
|
+
def GetValue(pkey, pvalue)
|
147
|
+
key, value = Windows::PROPERTYKEY.new(pkey), Windows::PROPVARIANT.new(pvalue)
|
148
|
+
|
149
|
+
case key
|
150
|
+
when Windows::UI_PKEY_CategoryId
|
151
|
+
value.uint = @categoryId; Windows::S_OK
|
152
|
+
when Windows::UI_PKEY_Label
|
153
|
+
value.wstring = @label; Windows::S_OK
|
154
|
+
when Windows::UI_PKEY_ItemImage
|
155
|
+
FFI::MemoryPointer.new(:pointer) { |punk|
|
156
|
+
Windows::UIImageFromBitmap.new.CreateImage(PARGB32.new(@image).handle, Windows::UI_OWNERSHIP_TRANSFER, punk)
|
157
|
+
|
158
|
+
unk = Windows::Unknown.new(punk.read_pointer)
|
159
|
+
value.unknown = unk
|
160
|
+
unk.Release
|
161
|
+
}
|
162
|
+
|
163
|
+
Windows::S_OK
|
164
|
+
else
|
165
|
+
Windows::E_NOTIMPL
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
def initialize(_window, opts = {})
|
171
|
+
handlers = {}
|
172
|
+
|
173
|
+
opts.delete_if { |k, v|
|
174
|
+
next false unless v.kind_of?(Proc)
|
175
|
+
|
176
|
+
handlers[k] = v; true
|
177
|
+
}
|
178
|
+
|
179
|
+
_opts = {
|
180
|
+
name: Application.name,
|
181
|
+
resname: 'APPLICATION_RIBBON'
|
182
|
+
}
|
183
|
+
badopts = opts.keys - _opts.keys; raise "Bad option(s): #{badopts.join(', ')}." unless badopts.empty?
|
184
|
+
_opts.merge!(opts)
|
185
|
+
|
106
186
|
@creates = []
|
107
187
|
@destroys = []
|
108
188
|
@sizes = []
|
109
189
|
@executesAllVerbs = {}
|
190
|
+
@executesExecute = {}
|
191
|
+
@executesPreview = {}
|
192
|
+
@executesCancelPreview = {}
|
193
|
+
@updatesAllKeys = {}
|
110
194
|
|
111
195
|
@window = _window
|
112
196
|
|
@@ -124,6 +208,7 @@ module Fzeet
|
|
124
208
|
attr_reader :ribbon
|
125
209
|
|
126
210
|
def Execute(*args) ribbon.execute(*args); Windows::S_OK end
|
211
|
+
def UpdateProperty(*args) ribbon.update(*args); Windows::S_OK end
|
127
212
|
end
|
128
213
|
|
129
214
|
@uia = Windows::UIApplication.new
|
@@ -183,10 +268,18 @@ module Fzeet
|
|
183
268
|
def OnCreateUICommand(*args) uich.QueryInterface(uich.class::IID, args[-1]); Windows::S_OK end
|
184
269
|
end
|
185
270
|
|
271
|
+
@hdll = Windows.LoadRibbonDll(_opts[:name])
|
272
|
+
|
273
|
+
handlers.each { |k, v|
|
274
|
+
k[1] = Object.const_get(k[1]) if k.length > 1
|
275
|
+
|
276
|
+
on(*k, &v)
|
277
|
+
}
|
278
|
+
|
186
279
|
@uif = Windows::UIFramework.new
|
187
280
|
|
188
281
|
uif.Initialize(window.handle, uia)
|
189
|
-
uif.LoadUI(@hdll
|
282
|
+
uif.LoadUI(@hdll, "#{_opts[:resname]}\0".encode('utf-16le'))
|
190
283
|
|
191
284
|
window.on(:destroy) {
|
192
285
|
uich.Release
|
@@ -203,15 +296,28 @@ module Fzeet
|
|
203
296
|
args = {
|
204
297
|
commandId: commandId,
|
205
298
|
verb: verb,
|
206
|
-
key: key,
|
207
|
-
value: value,
|
208
|
-
props: props,
|
299
|
+
key: (key.null?) ? nil : Windows::PROPERTYKEY.new(key),
|
300
|
+
value: (value.null?) ? nil : Windows::PROPVARIANT.new(value),
|
301
|
+
props: (props.null?) ? nil : Windows::UISimplePropertySet.new(props),
|
209
302
|
ribbon: self,
|
210
303
|
sender: Command.new(self, commandId)
|
211
304
|
}
|
212
305
|
|
213
|
-
|
214
|
-
|
306
|
+
(handlers = @executesAllVerbs[commandId]) and handlers.each { |handler|
|
307
|
+
(handler.arity == 0) ? handler.call : handler.call(args)
|
308
|
+
}
|
309
|
+
|
310
|
+
case verb
|
311
|
+
when Windows::UI_EXECUTIONVERB_EXECUTE
|
312
|
+
(handlers = @executesExecute[commandId]) and handlers.each { |handler|
|
313
|
+
(handler.arity == 0) ? handler.call : handler.call(args)
|
314
|
+
}
|
315
|
+
when Windows::UI_EXECUTIONVERB_PREVIEW
|
316
|
+
(handlers = @executesPreview[commandId]) and handlers.each { |handler|
|
317
|
+
(handler.arity == 0) ? handler.call : handler.call(args)
|
318
|
+
}
|
319
|
+
when Windows::UI_EXECUTIONVERB_CANCELPREVIEW
|
320
|
+
(handlers = @executesCancelPreview[commandId]) and handlers.each { |handler|
|
215
321
|
(handler.arity == 0) ? handler.call : handler.call(args)
|
216
322
|
}
|
217
323
|
end
|
@@ -223,6 +329,33 @@ module Fzeet
|
|
223
329
|
self
|
224
330
|
end
|
225
331
|
|
332
|
+
def update(commandId, key, value, newValue)
|
333
|
+
args = {
|
334
|
+
commandId: commandId,
|
335
|
+
key: (key.null?) ? nil : Windows::PROPERTYKEY.new(key),
|
336
|
+
value: (value.null?) ? nil : Windows::PROPVARIANT.new(value),
|
337
|
+
newValue: (newValue.null?) ? nil : Windows::PROPVARIANT.new(newValue),
|
338
|
+
ribbon: self,
|
339
|
+
sender: Command.new(self, commandId)
|
340
|
+
}
|
341
|
+
|
342
|
+
(handlers = @updatesAllKeys[commandId]) and handlers.each { |handler|
|
343
|
+
(handler.arity == 0) ? handler.call : handler.call(args)
|
344
|
+
}
|
345
|
+
|
346
|
+
self
|
347
|
+
rescue
|
348
|
+
Fzeet.message %Q{#{$!}\n\n#{$!.backtrace.join("\n")}}, icon: :error
|
349
|
+
|
350
|
+
self
|
351
|
+
end
|
352
|
+
|
353
|
+
def invalidate(commandId, flags = Windows::UI_INVALIDATIONS_ALLPROPERTIES, key = nil)
|
354
|
+
@uif.InvalidateUICommand(commandId, flags, key)
|
355
|
+
|
356
|
+
self
|
357
|
+
end
|
358
|
+
|
226
359
|
def on(*args, &block)
|
227
360
|
case args.size
|
228
361
|
when 1
|
@@ -233,12 +366,46 @@ module Fzeet
|
|
233
366
|
when Integer; (@executesAllVerbs[args[0]] ||= []) << block
|
234
367
|
else raise ArgumentError
|
235
368
|
end
|
369
|
+
when 2
|
370
|
+
case args[0]
|
371
|
+
when /^execute$/i; (@executesExecute[args[1]] ||= []) << block
|
372
|
+
when /^preview$/i; (@executesPreview[args[1]] ||= []) << block
|
373
|
+
when /^cancelpreview$/i; (@executesCancelPreview[args[1]] ||= []) << block
|
374
|
+
when /^update$/i; (@updatesAllKeys[args[1]] ||= []) << block
|
375
|
+
else raise ArgumentError
|
376
|
+
end
|
236
377
|
else raise ArgumentError
|
237
378
|
end
|
238
379
|
|
239
380
|
self
|
240
381
|
end
|
241
382
|
|
383
|
+
def fontPropsUpdate(args)
|
384
|
+
return self unless args[:key] == Windows::UI_PKEY_FontProperties
|
385
|
+
|
386
|
+
args[:value].unknown { |current|
|
387
|
+
current.QueryInstance(Windows::PropertyStore) { |ps|
|
388
|
+
yield ps
|
389
|
+
|
390
|
+
args[:newValue].unknown = current
|
391
|
+
}
|
392
|
+
}
|
393
|
+
|
394
|
+
self
|
395
|
+
end
|
396
|
+
|
397
|
+
def fontPropsChanged(args)
|
398
|
+
return self unless args[:key] == Windows::UI_PKEY_FontProperties
|
399
|
+
|
400
|
+
args[:props].uiprop(:FontProperties_ChangedProperties).unknown { |changed|
|
401
|
+
changed.QueryInstance(Windows::PropertyStore) { |ps|
|
402
|
+
yield ps
|
403
|
+
}
|
404
|
+
}
|
405
|
+
|
406
|
+
self
|
407
|
+
end
|
408
|
+
|
242
409
|
def contextualUI(id, x, y)
|
243
410
|
uif.UseInstance(Windows::UIContextualUI, :GetView, id) { |view|
|
244
411
|
view.ShowAtLocation(x, y)
|
data/lib/fzeet/windows/com.rb
CHANGED
data/lib/fzeet/windows/common.rb
CHANGED
@@ -87,13 +87,17 @@ module Fzeet
|
|
87
87
|
def GET_Y_LPARAM(l) ((w = HIWORD(l)) > 0x7fff) ? w - 0x1_0000 : w end
|
88
88
|
|
89
89
|
def LPWSTR(s)
|
90
|
-
FFI::MemoryPointer.new(:uchar, (s.length + 2) * 2)
|
91
|
-
"#{s}\0".encode('utf-16le').each_byte.with_index { |b, i|
|
92
|
-
p.put_char(i, b)
|
90
|
+
p = FFI::MemoryPointer.new(:uchar, (s.length + 2) * 2)
|
93
91
|
|
94
|
-
|
95
|
-
|
96
|
-
|
92
|
+
"#{s}\0".encode('utf-16le').each_byte.with_index { |b, i| p.put_char(i, b) }
|
93
|
+
|
94
|
+
begin
|
95
|
+
yield p; return nil
|
96
|
+
ensure
|
97
|
+
p.free
|
98
|
+
end if block_given?
|
99
|
+
|
100
|
+
p
|
97
101
|
end
|
98
102
|
|
99
103
|
def WCSTOMBS(p)
|
@@ -172,6 +176,43 @@ module Fzeet
|
|
172
176
|
:lfQuality, :uchar,
|
173
177
|
:lfPitchAndFamily, :uchar,
|
174
178
|
:lfFaceName, [:char, 32]
|
179
|
+
|
180
|
+
def face; self[:lfFaceName].to_s end
|
181
|
+
def face=(face) self[:lfFaceName] = face end
|
182
|
+
|
183
|
+
def size; -Rational(self[:lfHeight] * 72, Application.devcaps[:logpixelsy]) end
|
184
|
+
def size=(size) self[:lfHeight] = -Windows.MulDiv((size * 10).to_i, Application.devcaps[:logpixelsy], 720) end
|
185
|
+
|
186
|
+
def bold?; self[:lfWeight] >= 700 end
|
187
|
+
def bold=(bold) self[:lfWeight] = (bold) ? 700 : 0 end
|
188
|
+
|
189
|
+
def italic?; self[:lfItalic] == 1 end
|
190
|
+
def italic=(italic) self[:lfItalic] = (italic) ? 1 : 0 end
|
191
|
+
|
192
|
+
def underline?; self[:lfUnderline] == 1 end
|
193
|
+
def underline=(underline) self[:lfUnderline] = (underline) ? 1 : 0 end
|
194
|
+
|
195
|
+
def strikeout?; self[:lfStrikeOut] == 1 end
|
196
|
+
def strikeout=(strikeout) self[:lfStrikeOut] = (strikeout) ? 1 : 0 end
|
197
|
+
|
198
|
+
def update(from)
|
199
|
+
case from
|
200
|
+
when PropertyStore
|
201
|
+
from.each { |k, v|
|
202
|
+
case k
|
203
|
+
when UI_PKEY_FontProperties_Family; self.face = v.wstring
|
204
|
+
when UI_PKEY_FontProperties_Size; self.size = v.decimal.to_f
|
205
|
+
when UI_PKEY_FontProperties_Bold; self.bold = v.uint == 2
|
206
|
+
when UI_PKEY_FontProperties_Italic; self.italic = v.uint == 2
|
207
|
+
when UI_PKEY_FontProperties_Underline; self.underline = v.uint == 2
|
208
|
+
when UI_PKEY_FontProperties_Strikethrough; self.strikeout = v.uint == 2
|
209
|
+
end
|
210
|
+
}
|
211
|
+
else raise ArgumentError
|
212
|
+
end
|
213
|
+
|
214
|
+
self
|
215
|
+
end
|
175
216
|
end
|
176
217
|
|
177
218
|
class SYSTEMTIME < FFI::Struct
|
data/lib/fzeet/windows/gdi.rb
CHANGED
@@ -13,6 +13,11 @@ module Fzeet
|
|
13
13
|
module_function \
|
14
14
|
:GetRValue, :GetGValue, :GetBValue, :RGB
|
15
15
|
|
16
|
+
LOGPIXELSX = 88
|
17
|
+
LOGPIXELSY = 90
|
18
|
+
|
19
|
+
attach_function :GetDeviceCaps, [:pointer, :int], :int
|
20
|
+
|
16
21
|
DEFAULT_GUI_FONT = 17
|
17
22
|
|
18
23
|
attach_function :GetStockObject, [:int], :pointer
|
@@ -46,6 +51,9 @@ module Fzeet
|
|
46
51
|
attach_function :GetTextColor, [:pointer], :ulong
|
47
52
|
attach_function :SetTextColor, [:pointer, :ulong], :ulong
|
48
53
|
|
54
|
+
attach_function :GetBkColor, [:pointer], :ulong
|
55
|
+
attach_function :SetBkColor, [:pointer, :ulong], :ulong
|
56
|
+
|
49
57
|
attach_function :MoveToEx, [:pointer, :int, :int, :pointer], :int
|
50
58
|
attach_function :LineTo, [:pointer, :int, :int], :int
|
51
59
|
end
|
data/lib/fzeet/windows/kernel.rb
CHANGED
data/lib/fzeet/windows/ole.rb
CHANGED
@@ -85,6 +85,8 @@ module Fzeet
|
|
85
85
|
key[:pid] = type
|
86
86
|
}
|
87
87
|
end
|
88
|
+
|
89
|
+
def ==(other) Windows.memcmp(other, self, size) == 0 end
|
88
90
|
end
|
89
91
|
|
90
92
|
class LARGE_INTEGER < FFI::Union
|
@@ -246,6 +248,38 @@ module Fzeet
|
|
246
248
|
|
247
249
|
def uint; raise 'Wrong type tag.' unless self[:vt] == VT_UI4; self[:uintVal] end
|
248
250
|
def uint=(uint) self[:vt] = VT_UI4; self[:uintVal] = uint end
|
251
|
+
|
252
|
+
def unknown
|
253
|
+
raise 'Wrong type tag.' unless self[:vt] == VT_UNKNOWN
|
254
|
+
|
255
|
+
yield Unknown.new(self[:punkVal])
|
256
|
+
ensure
|
257
|
+
Windows.PropVariantClear(self)
|
258
|
+
end
|
259
|
+
|
260
|
+
def unknown=(unknown) self[:vt] = VT_UNKNOWN; self[:punkVal] = unknown.pointer; unknown.AddRef end
|
261
|
+
|
262
|
+
def wstring; raise 'Wrong type tag.' unless self[:vt] == VT_LPWSTR; Windows.WCSTOMBS(self[:pwszVal]) end
|
263
|
+
|
264
|
+
def wstring=(string)
|
265
|
+
self[:vt] = VT_LPWSTR
|
266
|
+
|
267
|
+
FFI::MemoryPointer.new(:pointer) { |p|
|
268
|
+
Windows.DetonateHresult(:SHStrDup, string, p)
|
269
|
+
|
270
|
+
self[:pwszVal] = p.read_pointer
|
271
|
+
}
|
272
|
+
end
|
273
|
+
|
274
|
+
def decimal
|
275
|
+
raise 'Wrong type tag.' unless self[:vt] == VT_DECIMAL
|
276
|
+
|
277
|
+
Rational(self[:decVal][:Lo64], 10 ** self[:decVal][:scale]) + self[:decVal][:Hi32]
|
278
|
+
end
|
279
|
+
|
280
|
+
def decimal=(decimal) self[:vt] = VT_DECIMAL; self[:decVal][:Lo64] = decimal end
|
249
281
|
end
|
282
|
+
|
283
|
+
attach_function :PropVariantClear, [:pointer], :long
|
250
284
|
end
|
251
285
|
end
|
@@ -18,10 +18,14 @@ module Fzeet
|
|
18
18
|
PropertyStore = COM::Instance[IPropertyStore]
|
19
19
|
|
20
20
|
class PropertyStore
|
21
|
-
|
21
|
+
include Enumerable
|
22
|
+
|
23
|
+
def count; FFI::MemoryPointer.new(:ulong) { |pc| GetCount(pc); return pc.get_ulong(0) } end
|
22
24
|
alias :size :count
|
23
25
|
alias :length :count
|
24
26
|
|
27
|
+
def key(i) PROPERTYKEY.new.tap { |k| GetAt(i, k) } end
|
28
|
+
|
25
29
|
# superclass.superclass is FFI::Struct, so do NOT touch [] and []=
|
26
30
|
def get(k) PROPVARIANT.new.tap { |v| GetValue(k, v) } end
|
27
31
|
def set(k, v) SetValue(k, v); self end
|
@@ -35,6 +39,8 @@ module Fzeet
|
|
35
39
|
end
|
36
40
|
|
37
41
|
def commit; Commit(); self end
|
42
|
+
|
43
|
+
def each; length.times { |i| v = get(k = key(i)); yield k, v }; self end
|
38
44
|
end
|
39
45
|
end
|
40
46
|
end
|