fzeet 0.6.5 → 0.6.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (140) hide show
  1. data/LICENSE_CEF +29 -0
  2. data/checks/Bstr.rb +14 -0
  3. data/checks/Decimal.rb +27 -0
  4. data/checks/OSVERSIONINFOEX.rb +14 -0
  5. data/checks/Point.rb +65 -0
  6. data/checks/Rect.rb +104 -0
  7. data/checks/RunAll.rb +2 -0
  8. data/checks/SafeArray.rb +27 -0
  9. data/checks/Size.rb +45 -0
  10. data/checks/SystemTime.rb +43 -0
  11. data/checks/Variant.rb +160 -0
  12. data/examples/Control/DateTimePicker.rbw +1 -1
  13. data/examples/Control/MonthCalendar.rbw +1 -1
  14. data/examples/Control/{WebBrowser.rbw → WebBrowser/WebBrowser.rbw} +2 -2
  15. data/examples/Control/{WebBrowser1.rbw → WebBrowser/WebBrowser1.rbw} +0 -0
  16. data/examples/Control/WebBrowser/WebBrowser2.rbw +24 -0
  17. data/examples/Control/{WebBrowser3.rbw → WebBrowser/WebBrowser3.rbw} +0 -0
  18. data/examples/Control/{WebBrowser4.rbw → WebBrowser/WebBrowser4.rbw} +8 -3
  19. data/examples/Control/{WebBrowser4Sinatra.rb → WebBrowser/WebBrowser4Sinatra.rb} +0 -0
  20. data/examples/Control/{WebBrowser5.rbw → WebBrowser/WebBrowser5.rbw} +4 -2
  21. data/examples/Control/WebBrowser/jQueryUI.html +53 -0
  22. data/examples/Control/WebBrowser/jQueryUI.rbw +26 -0
  23. data/examples/MDI.rbw +2 -2
  24. data/examples/Raw/UIRibbon/Command.rbw +3 -3
  25. data/examples/Raw/UIRibbon/Minimal.rbw +3 -3
  26. data/examples/Version.rbw +1 -1
  27. data/lib/fzeet.rb +22 -7
  28. data/lib/fzeet/windows.rb +82 -5
  29. data/lib/fzeet/windows/com.rb +1 -318
  30. data/lib/fzeet/windows/com/Common.rb +318 -0
  31. data/lib/fzeet/windows/comctl.rb +1 -1
  32. data/lib/fzeet/windows/comctl/ComboBoxEx.rb +32 -0
  33. data/lib/fzeet/windows/comctl/DateTimePicker.rb +35 -0
  34. data/lib/fzeet/windows/comctl/Header.rb +61 -1
  35. data/lib/fzeet/windows/comctl/ListView.rb +133 -3
  36. data/lib/fzeet/windows/comctl/MonthCalendar.rb +35 -0
  37. data/lib/fzeet/windows/comctl/ProgressBar.rb +37 -0
  38. data/lib/fzeet/windows/comctl/PropertySheet.rb +50 -2
  39. data/lib/fzeet/windows/comctl/SysLink.rb +37 -0
  40. data/lib/fzeet/windows/comctl/Tab.rb +56 -0
  41. data/lib/fzeet/windows/comctl/TreeView.rb +81 -2
  42. data/lib/fzeet/windows/comctl/UpDown.rb +33 -0
  43. data/lib/fzeet/windows/comdlg.rb +1 -0
  44. data/lib/fzeet/windows/comdlg/ColorDialog.rb +41 -0
  45. data/lib/fzeet/windows/comdlg/Common.rb +87 -0
  46. data/lib/fzeet/windows/comdlg/FileDialog.rb +133 -0
  47. data/lib/fzeet/windows/comdlg/FindReplaceDialog.rb +102 -0
  48. data/lib/fzeet/windows/comdlg/FontDialog.rb +36 -0
  49. data/lib/fzeet/windows/comdlg/PrintDialog.rb +72 -0
  50. data/lib/fzeet/{Dialog → windows/comdlg}/ShellFileDialog.rb +0 -0
  51. data/lib/fzeet/windows/core.rb +5 -0
  52. data/lib/fzeet/windows/core/Common.rb +324 -0
  53. data/lib/fzeet/windows/core/Point.rb +42 -0
  54. data/lib/fzeet/windows/core/Rect.rb +114 -0
  55. data/lib/fzeet/windows/core/Size.rb +34 -0
  56. data/lib/fzeet/windows/core/SystemTime.rb +46 -0
  57. data/lib/fzeet/windows/core/Version.rb +57 -0
  58. data/lib/fzeet/windows/gdi.rb +1 -62
  59. data/lib/fzeet/windows/gdi/Common.rb +40 -0
  60. data/lib/fzeet/windows/gdi/Font.rb +64 -0
  61. data/lib/fzeet/windows/kernel.rb +1 -92
  62. data/lib/fzeet/windows/kernel/Common.rb +92 -0
  63. data/lib/fzeet/windows/libc.rb +1 -1
  64. data/lib/fzeet/windows/libcef.rb +1 -0
  65. data/lib/fzeet/windows/mshtml.rb +1 -1135
  66. data/lib/fzeet/windows/mshtml/Common.rb +1135 -0
  67. data/lib/fzeet/windows/ole.rb +1 -561
  68. data/lib/fzeet/windows/ole/Common.rb +112 -0
  69. data/lib/fzeet/windows/ole/PropVariant.rb +141 -0
  70. data/lib/fzeet/windows/oleaut.rb +3 -0
  71. data/lib/fzeet/windows/oleaut/Bstr.rb +39 -0
  72. data/lib/fzeet/windows/oleaut/Common.rb +187 -0
  73. data/lib/fzeet/windows/oleaut/SafeArray.rb +104 -0
  74. data/lib/fzeet/windows/oleaut/Variant.rb +269 -0
  75. data/lib/fzeet/windows/scintilla.rb +115 -1
  76. data/lib/fzeet/windows/{SciLexer.dll → scintilla/SciLexer.dll} +0 -0
  77. data/lib/fzeet/windows/shdocvw.rb +150 -0
  78. data/lib/fzeet/windows/shell.rb +1 -1
  79. data/lib/fzeet/windows/shell/Common.rb +94 -2
  80. data/lib/fzeet/windows/shlwapi.rb +1 -1
  81. data/lib/fzeet/windows/uiribbon.rb +416 -0
  82. data/lib/fzeet/windows/urlmon.rb +2 -2
  83. data/lib/fzeet/windows/user.rb +20 -0
  84. data/lib/fzeet/windows/user/Accelerator.rb +45 -0
  85. data/lib/fzeet/windows/user/Common.rb +3 -2
  86. data/lib/fzeet/windows/user/Control/Button.rb +54 -0
  87. data/lib/fzeet/windows/user/Control/ComboBox.rb +44 -1
  88. data/lib/fzeet/windows/user/Control/Common.rb +88 -1
  89. data/lib/fzeet/windows/user/Control/Edit.rb +50 -0
  90. data/lib/fzeet/windows/user/Control/ListBox.rb +69 -0
  91. data/lib/fzeet/windows/user/Control/Static.rb +31 -0
  92. data/lib/fzeet/windows/user/Menu.rb +130 -0
  93. data/lib/fzeet/windows/user/Message.rb +9 -0
  94. data/lib/fzeet/windows/user/MessageBox.rb +47 -0
  95. data/lib/fzeet/windows/user/SystemParametersInfo.rb +1 -1
  96. data/lib/fzeet/windows/user/Window.rb +5 -463
  97. data/lib/fzeet/{Window → windows/user/Window}/Common.rb +460 -0
  98. data/lib/fzeet/{Window → windows/user/Window}/Container.rb +0 -0
  99. data/lib/fzeet/{Window → windows/user/Window}/Dialog.rb +0 -0
  100. data/lib/fzeet/{Window → windows/user/Window}/MDI.rb +0 -0
  101. data/lib/fzeet/{Window → windows/user/Window}/View.rb +0 -0
  102. data/lib/fzeet/{Window → windows/user/Window}/Window.rb +0 -0
  103. data/lib/fzeet/{Window → windows/user/Window}/WindowMethods.rb +1 -1
  104. metadata +55 -61
  105. data/examples/Control/WebBrowser2.rbw +0 -39
  106. data/lib/fzeet/Accelerator.rb +0 -48
  107. data/lib/fzeet/Application.rb +0 -71
  108. data/lib/fzeet/Common.rb +0 -350
  109. data/lib/fzeet/Control.rb +0 -19
  110. data/lib/fzeet/Control/Button.rb +0 -57
  111. data/lib/fzeet/Control/ComboBox.rb +0 -46
  112. data/lib/fzeet/Control/ComboBoxEx.rb +0 -35
  113. data/lib/fzeet/Control/Common.rb +0 -89
  114. data/lib/fzeet/Control/DateTimePicker.rb +0 -38
  115. data/lib/fzeet/Control/Edit.rb +0 -53
  116. data/lib/fzeet/Control/ExplorerBrowser.rb +0 -66
  117. data/lib/fzeet/Control/Header.rb +0 -63
  118. data/lib/fzeet/Control/ListBox.rb +0 -72
  119. data/lib/fzeet/Control/ListView.rb +0 -133
  120. data/lib/fzeet/Control/MonthCalendar.rb +0 -38
  121. data/lib/fzeet/Control/ProgressBar.rb +0 -40
  122. data/lib/fzeet/Control/PropertySheet.rb +0 -51
  123. data/lib/fzeet/Control/Scintilla.rb +0 -117
  124. data/lib/fzeet/Control/Static.rb +0 -34
  125. data/lib/fzeet/Control/SysLink.rb +0 -40
  126. data/lib/fzeet/Control/Tab.rb +0 -59
  127. data/lib/fzeet/Control/TreeView.rb +0 -82
  128. data/lib/fzeet/Control/UpDown.rb +0 -36
  129. data/lib/fzeet/Control/WebBrowser.rb +0 -153
  130. data/lib/fzeet/Dialog.rb +0 -6
  131. data/lib/fzeet/Dialog/ColorDialog.rb +0 -44
  132. data/lib/fzeet/Dialog/Common.rb +0 -89
  133. data/lib/fzeet/Dialog/FileDialog.rb +0 -136
  134. data/lib/fzeet/Dialog/FindReplaceDialog.rb +0 -105
  135. data/lib/fzeet/Dialog/FontDialog.rb +0 -39
  136. data/lib/fzeet/Dialog/PrintDialog.rb +0 -75
  137. data/lib/fzeet/Menu.rb +0 -133
  138. data/lib/fzeet/UIRibbon.rb +0 -417
  139. data/lib/fzeet/Window.rb +0 -5
  140. data/lib/fzeet/windows/common.rb +0 -244
@@ -115,4 +115,154 @@ module Fzeet
115
115
 
116
116
  WebBrowser = COM::Factory[IWebBrowser, GUID['EAB22AC3-30C1-11CF-A7EB-0000C05BAE0B']]
117
117
  end
118
+
119
+ class WebBrowser < Windows::WebBrowser
120
+ def initialize(parent)
121
+ @parent = parent
122
+
123
+ @oips = Windows::OleInPlaceSite.new
124
+
125
+ @oips.instance_variable_set(:@browser, self)
126
+
127
+ class << @oips
128
+ attr_reader :browser
129
+
130
+ def CanInPlaceActivate
131
+ Windows::S_OK
132
+ end
133
+
134
+ def GetWindow(phwnd)
135
+ phwnd.write_pointer(browser.parent.handle)
136
+
137
+ Windows::S_OK
138
+ end
139
+
140
+ def GetWindowContext(pframe, pdoc, prPos, prClip, pinfo)
141
+ pframe.write_pointer(0)
142
+ pdoc.write_pointer(0)
143
+ Windows.GetClientRect(browser.parent.handle, prPos)
144
+ Windows.GetClientRect(browser.parent.handle, prClip)
145
+
146
+ Windows::S_OK
147
+ end
148
+
149
+ def OnPosRectChange(prPos)
150
+ browser.QueryInstance(Windows::OleInPlaceObject) { |oipo|
151
+ oipo.SetObjectRects(prPos, prPos)
152
+ }
153
+
154
+ Windows::S_OK
155
+ end
156
+ end
157
+
158
+ @ocs = Windows::OleClientSite.new
159
+
160
+ @ocs.instance_variable_set(:@browser, self)
161
+
162
+ class << @ocs
163
+ attr_reader :browser
164
+
165
+ def QueryInterface(piid, ppv)
166
+ if Windows::GUID.new(piid) == Windows::IOleInPlaceSite::IID
167
+ ppv.write_pointer(browser.oips); browser.oips.AddRef
168
+
169
+ return Windows::S_OK
170
+ end
171
+
172
+ super
173
+ end
174
+ end
175
+
176
+ super()
177
+
178
+ @events = Windows::WebBrowserEvents.new
179
+
180
+ @events.instance_variable_set(:@browser, self)
181
+
182
+ class << @events
183
+ attr_reader :browser
184
+
185
+ (self::VTBL.members - Windows::IDispatch::VTBL.members).each { |name|
186
+ define_method(name) { |dispParams|
187
+ (handlers = browser.handlers && browser.handlers[name]) && handlers.each { |handler|
188
+ (handler.arity == 0) ? handler.call : handler.call(dispParams)
189
+ }
190
+ }
191
+ }
192
+ end
193
+
194
+ QueryInstance(Windows::ConnectionPointContainer) { |cpc|
195
+ FFI::MemoryPointer.new(:pointer) { |pcp|
196
+ cpc.FindConnectionPoint(Windows::WebBrowserEvents::IID, pcp)
197
+
198
+ @cp = Windows::ConnectionPoint.new(pcp.read_pointer)
199
+ }
200
+ }
201
+
202
+ @cookie = nil
203
+ FFI::MemoryPointer.new(:ulong) { |p| @cp.Advise(@events, p); @cookie = p.get_ulong(0) }
204
+
205
+ QueryInstance(Windows::OleObject) { |oo|
206
+ oo.SetClientSite(@ocs)
207
+ oo.DoVerb(Windows::OLEIVERB_INPLACEACTIVATE, nil, @ocs, 0, @parent.handle, @parent.rect)
208
+ }
209
+
210
+ @parent.
211
+ on(:size) {
212
+ r = @parent.rect
213
+
214
+ put_Top(r[:top]); put_Left(r[:left]); put_Width(r[:right]); put_Height(r[:bottom])
215
+ }.
216
+
217
+ on(:destroy) {
218
+ @oips.Release
219
+ @ocs.Release
220
+ @cp.Unadvise(@cookie)
221
+ @events.Release
222
+ @cp.Release
223
+ Release()
224
+ }.
225
+
226
+ instance_variable_set(:@__WebBrowser__, self)
227
+ end
228
+
229
+ attr_reader :parent, :oips, :ocs, :events, :cp, :handlers
230
+
231
+ def on(event, &block)
232
+ ((@handlers ||= {})[event] ||= []) << block
233
+
234
+ self
235
+ end
236
+
237
+ def goto(where)
238
+ where = Windows.SysAllocString("#{where}\0".encode('utf-16le'))
239
+
240
+ Navigate(where, nil, nil, nil, nil)
241
+
242
+ self
243
+ ensure
244
+ Windows.SysFreeString(where)
245
+ end
246
+
247
+ def back; GoBack(); self; rescue; self end
248
+ def forward; GoForward(); self; rescue; self end
249
+ def home; GoHome(); self end
250
+ def search; GoSearch(); self end
251
+
252
+ def refresh; Refresh(); self end
253
+
254
+ def document
255
+ disp = nil
256
+
257
+ FFI::MemoryPointer.new(:pointer) { |pdisp|
258
+ get_Document(pdisp)
259
+
260
+ disp = Windows::Dispatch.new(pdisp.read_pointer)
261
+
262
+ return disp.QueryInstance(Windows::HTMLDocument2)
263
+ }
264
+ ensure
265
+ disp.Release if disp
266
+ end
267
+ end
118
268
  end
@@ -1,2 +1,2 @@
1
1
  require_relative 'shell/BrowseForFolder'
2
- require_relative 'shell/FileDialog' if Fzeet::Windows::WINVER.AtLeastWindowsVista?
2
+ require_relative 'shell/FileDialog' if Fzeet::Windows::Version >= :vista
@@ -6,6 +6,29 @@ module Fzeet
6
6
  ffi_lib 'shell32'
7
7
  ffi_convention :stdcall
8
8
 
9
+ class PROPERTYKEY < FFI::Struct
10
+ layout \
11
+ :fmtid, GUID,
12
+ :pid, :ulong
13
+
14
+ def self.[](type, index)
15
+ new.tap { |key|
16
+ key[:fmtid].tap { |guid|
17
+ guid[:Data1] = 0x00000000 + index
18
+ guid[:Data2] = 0x7363
19
+ guid[:Data3] = 0x696e
20
+ [0x84, 0x41, 0x79, 0x8a, 0xcf, 0x5a, 0xeb, 0xb7].each_with_index { |part, i|
21
+ guid[:Data4][i] = part
22
+ }
23
+ }
24
+
25
+ key[:pid] = type
26
+ }
27
+ end
28
+
29
+ def ==(other) Windows.memcmp(other, self, size) == 0 end
30
+ end
31
+
9
32
  attach_function :ShellExecute, :ShellExecuteA, [:pointer, :string, :string, :string, :string, :int], :pointer
10
33
 
11
34
  attach_function :SHGetPathFromIDList, :SHGetPathFromIDListA, [:pointer, :pointer], :int
@@ -137,7 +160,7 @@ module Fzeet
137
160
 
138
161
  Initialize: [[:pointer, :pointer, :pointer], :long],
139
162
  Destroy: [[], :long],
140
- SetRect: [[:pointer, RECT], :long],
163
+ SetRect: [[:pointer, RECT.by_value], :long],
141
164
  SetPropertyBag: [[:buffer_in], :long],
142
165
  SetEmptyText: [[:buffer_in], :long],
143
166
  SetFolderSettings: [[:pointer], :long],
@@ -257,7 +280,7 @@ module Fzeet
257
280
  FOLDERID_UserPinned = GUID['9e3995ab-1f9c-4f13-b827-48b24b6c7174']
258
281
  FOLDERID_ImplicitAppShortcuts = GUID['bcb5256f-79f6-4cee-b725-dc34e402fd46']
259
282
 
260
- if WINVER.AtLeastWindowsVista?
283
+ if Version >= :vista
261
284
  attach_function :SHGetKnownFolderIDList, [:pointer, :ulong, :pointer, :pointer], :long
262
285
  end
263
286
 
@@ -290,4 +313,73 @@ module Fzeet
290
313
  SBSP_REDIRECT = 0x40000000
291
314
  SBSP_INITIATEDBYHLINKFRAME = 0x80000000
292
315
  end
316
+
317
+ def shell(name, args = nil, dir = nil, verb = 'open')
318
+ raise 'ShellExecute failed.' unless Windows.ShellExecute(nil, verb, name, args, dir, Windows::SW_NORMAL).to_i > 32
319
+ end
320
+
321
+ module_function :shell
322
+
323
+ class ExplorerBrowser < Windows::ExplorerBrowser
324
+ def initialize(parent)
325
+ @parent = parent
326
+
327
+ super()
328
+
329
+ @events = Windows::ExplorerBrowserEvents.new
330
+
331
+ @events.instance_variable_set(:@browser, self)
332
+
333
+ class << @events
334
+ attr_reader :browser
335
+
336
+ (self::VTBL.members - Windows::IUnknown::VTBL.members).each { |name|
337
+ define_method(name) { |*args|
338
+ (handlers = browser.handlers && browser.handlers[name]) && handlers.each { |handler|
339
+ (handler.arity == 0) ? handler.call : handler.call(*args)
340
+ }
341
+
342
+ Windows::S_OK
343
+ }
344
+ }
345
+ end
346
+
347
+ @cookie = nil
348
+ FFI::MemoryPointer.new(:ulong) { |p| Advise(@events, p); @cookie = p.get_ulong(0) }
349
+
350
+ Initialize(@parent.handle, parent.rect, nil)
351
+
352
+ @parent.
353
+ on(:size) { SetRect(nil, @parent.rect) }.
354
+ on(:destroy) { Unadvise(@cookie); @events.Release; Destroy(); Release() }.
355
+
356
+ instance_variable_set(:@__ExplorerBrowser__, self)
357
+ end
358
+
359
+ attr_reader :parent, :events, :handlers
360
+
361
+ def on(event, &block)
362
+ ((@handlers ||= {})["On#{event}".to_sym] ||= []) << block
363
+
364
+ self
365
+ end
366
+
367
+ def goto(where)
368
+ pidl = nil
369
+
370
+ FFI::MemoryPointer.new(:pointer) { |p|
371
+ Windows.SHGetKnownFolderIDList(Windows.const_get("FOLDERID_#{where}"), 0, nil, p)
372
+
373
+ BrowseToIDList(pidl = p.read_pointer, 0)
374
+ }
375
+
376
+ self
377
+ ensure
378
+ Windows.CoTaskMemFree(pidl)
379
+ end
380
+
381
+ def back; BrowseToIDList(nil, Windows::SBSP_NAVIGATEBACK); self end
382
+ def forward; BrowseToIDList(nil, Windows::SBSP_NAVIGATEFORWARD); self end
383
+ def up; BrowseToIDList(nil, Windows::SBSP_PARENT); self end
384
+ end
293
385
  end
@@ -1,4 +1,4 @@
1
- require_relative 'common'
1
+ require_relative 'core'
2
2
 
3
3
  module Fzeet
4
4
  module Windows
@@ -1,4 +1,6 @@
1
1
  require_relative 'ole'
2
+ require_relative 'oleaut'
3
+ require_relative 'shell'
2
4
 
3
5
  module Fzeet
4
6
  module Windows
@@ -385,4 +387,418 @@ module Fzeet
385
387
 
386
388
  module_function :UI_MAKEAPPMODE
387
389
  end
390
+
391
+ class Windows::PropertyStore
392
+ def uiprop(*args)
393
+ args[0] = Windows.const_get("UI_PKEY_#{args[0]}")
394
+
395
+ prop(*args)
396
+ end
397
+
398
+ def update(from)
399
+ case from
400
+ when Windows::LOGFONT
401
+ uiprop(:FontProperties_Family, Windows::PROPVARIANT[:wstring, from.face])
402
+ uiprop(:FontProperties_Size, Windows::PROPVARIANT[:decimal, from.size.round])
403
+ uiprop(:FontProperties_Bold, Windows::PROPVARIANT[:uint, (from.bold?) ? 2 : 1])
404
+ uiprop(:FontProperties_Italic, Windows::PROPVARIANT[:uint, (from.italic?) ? 2 : 1])
405
+ uiprop(:FontProperties_Underline, Windows::PROPVARIANT[:uint, (from.underline?) ? 2 : 1])
406
+ uiprop(:FontProperties_Strikethrough, Windows::PROPVARIANT[:uint, (from.strikeout?) ? 2 : 1])
407
+ else raise ArgumentError
408
+ end
409
+
410
+ self
411
+ end
412
+ end
413
+
414
+ class Windows::UISimplePropertySet
415
+ def get(k) Windows::PROPVARIANT.new.tap { |v| GetValue(k, v) } end
416
+
417
+ def prop(*args)
418
+ case args.length
419
+ when 1; get(*args)
420
+ else raise ArgumentError
421
+ end
422
+ end
423
+
424
+ def uiprop(*args)
425
+ args[0] = Windows.const_get("UI_PKEY_#{args[0]}")
426
+
427
+ prop(*args)
428
+ end
429
+ end
430
+
431
+ class UIRibbon
432
+ class Command
433
+ include Toggle
434
+
435
+ def initialize(ribbon, id)
436
+ @ribbon, @id = ribbon, id
437
+ end
438
+
439
+ attr_reader :ribbon, :id
440
+
441
+ def [](k) Windows::PROPVARIANT.new.tap { |v| ribbon.uif.GetUICommandProperty(id, k, v) } end
442
+ def []=(k, v) ribbon.uif.SetUICommandProperty(id, k, v) end
443
+
444
+ def enabled?; self[Windows::UI_PKEY_Enabled].bool end
445
+ def enabled=(enabled) self[Windows::UI_PKEY_Enabled] = Windows::PROPVARIANT[:bool, enabled] end
446
+
447
+ def checked?; self[Windows::UI_PKEY_BooleanValue].bool end
448
+ def checked=(checked) self[Windows::UI_PKEY_BooleanValue] = Windows::PROPVARIANT[:bool, checked] end
449
+ end
450
+
451
+ def [](id) Command.new(self, id) end
452
+
453
+ module Color
454
+ def self.enhance(hsb, ribbon, method)
455
+ hsb.instance_variable_set(:@ribbon, ribbon)
456
+ hsb.instance_variable_set(:@method, method)
457
+
458
+ class << hsb
459
+ attr_reader :ribbon, :method
460
+
461
+ include Color
462
+ end
463
+
464
+ hsb
465
+ end
466
+
467
+ def darken(amount) self[2] -= amount; ribbon.send("#{method}=", self); self end
468
+ def lighten(amount) self[2] += amount; ribbon.send("#{method}=", self); self end
469
+
470
+ def saturate(amount) self[1] += amount; ribbon.send("#{method}=", self); self end
471
+ def bleach(amount) self[1] -= amount; ribbon.send("#{method}=", self); self end
472
+
473
+ def shift(amount) self[0] += amount; ribbon.send("#{method}=", self); self end
474
+ end
475
+
476
+ def background
477
+ hsb = nil
478
+
479
+ uif.QueryInstance(Windows::PropertyStore) { |ps|
480
+ hsb = ps.uiprop(:GlobalBackgroundColor).uint
481
+ }
482
+
483
+ Color.enhance([Windows::UI_GetHValue(hsb), Windows::UI_GetSValue(hsb), Windows::UI_GetBValue(hsb)], self, __method__)
484
+ end
485
+
486
+ def background=(hsb)
487
+ uif.QueryInstance(Windows::PropertyStore) { |ps|
488
+ ps.uiprop(:GlobalBackgroundColor, Windows::PROPVARIANT[:uint, Windows::UI_HSB(*hsb)]).commit
489
+ }
490
+ end
491
+
492
+ def color
493
+ hsb = nil
494
+
495
+ uif.QueryInstance(Windows::PropertyStore) { |ps|
496
+ hsb = ps.uiprop(:GlobalTextColor).uint
497
+ }
498
+
499
+ Color.enhance([Windows::UI_GetHValue(hsb), Windows::UI_GetSValue(hsb), Windows::UI_GetBValue(hsb)], self, __method__)
500
+ end
501
+
502
+ def color=(hsb)
503
+ uif.QueryInstance(Windows::PropertyStore) { |ps|
504
+ ps.uiprop(:GlobalTextColor, Windows::PROPVARIANT[:uint, Windows::UI_HSB(*hsb)]).commit
505
+ }
506
+ end
507
+
508
+ def highlight
509
+ hsb = nil
510
+
511
+ uif.QueryInstance(Windows::PropertyStore) { |ps|
512
+ hsb = ps.uiprop(:GlobalHighlightColor).uint
513
+ }
514
+
515
+ Color.enhance([Windows::UI_GetHValue(hsb), Windows::UI_GetSValue(hsb), Windows::UI_GetBValue(hsb)], self, __method__)
516
+ end
517
+
518
+ def highlight=(hsb)
519
+ uif.QueryInstance(Windows::PropertyStore) { |ps|
520
+ ps.uiprop(:GlobalHighlightColor, Windows::PROPVARIANT[:uint, Windows::UI_HSB(*hsb)]).commit
521
+ }
522
+ end
523
+
524
+ class GalleryItem < Windows::UISimplePropertySetCallback
525
+ def initialize(label, categoryId = 0, image = nil)
526
+ @label, @categoryId, @image = label, categoryId, image
527
+
528
+ super()
529
+ end
530
+
531
+ attr_reader :label, :categoryId, :image
532
+
533
+ def GetValue(pkey, pvalue)
534
+ key, value = Windows::PROPERTYKEY.new(pkey), Windows::PROPVARIANT.new(pvalue)
535
+
536
+ case key
537
+ when Windows::UI_PKEY_CategoryId
538
+ value.uint = @categoryId; Windows::S_OK
539
+ when Windows::UI_PKEY_Label
540
+ value.wstring = @label; Windows::S_OK
541
+ when Windows::UI_PKEY_ItemImage
542
+ FFI::MemoryPointer.new(:pointer) { |punk|
543
+ Windows::UIImageFromBitmap.new.CreateImage(PARGB32.new(@image).handle, Windows::UI_OWNERSHIP_TRANSFER, punk)
544
+
545
+ unk = Windows::Unknown.new(punk.read_pointer)
546
+ value.unknown = unk
547
+ unk.Release
548
+ }
549
+
550
+ Windows::S_OK
551
+ else
552
+ Windows::E_NOTIMPL
553
+ end
554
+ end
555
+ end
556
+
557
+ def initialize(_window, opts = {})
558
+ handlers = {}
559
+
560
+ opts.delete_if { |k, v|
561
+ next false unless v.kind_of?(Proc)
562
+
563
+ handlers[k] = v; true
564
+ }
565
+
566
+ _opts = {
567
+ name: Application.name,
568
+ resname: 'APPLICATION_RIBBON'
569
+ }
570
+ badopts = opts.keys - _opts.keys; raise "Bad option(s): #{badopts.join(', ')}." unless badopts.empty?
571
+ _opts.merge!(opts)
572
+
573
+ @creates = []
574
+ @destroys = []
575
+ @sizes = []
576
+ @executesAllVerbs = {}
577
+ @executesExecute = {}
578
+ @executesPreview = {}
579
+ @executesCancelPreview = {}
580
+ @updatesAllKeys = {}
581
+
582
+ @window = _window
583
+
584
+ window.instance_variable_set(:@ribbon, self)
585
+
586
+ class << window
587
+ attr_reader :ribbon
588
+ end
589
+
590
+ @uich = Windows::UICommandHandler.new
591
+
592
+ uich.instance_variable_set(:@ribbon, self)
593
+
594
+ class << uich
595
+ attr_reader :ribbon
596
+
597
+ def Execute(*args) ribbon.execute(*args); Windows::S_OK end
598
+ def UpdateProperty(*args) ribbon.update(*args); Windows::S_OK end
599
+ end
600
+
601
+ @uia = Windows::UIApplication.new
602
+
603
+ uia.instance_variable_set(:@uich, @uich)
604
+
605
+ class << uia
606
+ attr_reader :uich, :uir
607
+
608
+ def OnViewChanged(viewId, typeId, view, verb, reason)
609
+ return Windows::S_OK unless typeId == Windows::UI_VIEWTYPE_RIBBON
610
+
611
+ args = {
612
+ viewId: viewId,
613
+ typeId: typeId,
614
+ view: view,
615
+ verb: verb,
616
+ reason: reason,
617
+ ribbon: self,
618
+ sender: self
619
+ }
620
+
621
+ case verb
622
+ when Windows::UI_VIEWVERB_CREATE
623
+ @uir = Windows::Unknown.new(view).QueryInstance(Windows::UIRibbon)
624
+
625
+ uir.instance_variable_set(:@height, 0)
626
+
627
+ class << uir
628
+ attr_accessor :height
629
+ end
630
+
631
+ uich.ribbon.instance_variable_get(:@creates).each { |handler|
632
+ (handler.arity == 0) ? handler.call : handler.call(args)
633
+ }
634
+ when Windows::UI_VIEWVERB_DESTROY
635
+ uich.ribbon.instance_variable_get(:@destroys).each { |handler|
636
+ (handler.arity == 0) ? handler.call : handler.call(args)
637
+ }
638
+
639
+ uir.Release
640
+ when Windows::UI_VIEWVERB_SIZE
641
+ FFI::MemoryPointer.new(:uint) { |p| uir.GetHeight(p); uir.height = p.read_int }
642
+
643
+ uich.ribbon.instance_variable_get(:@sizes).each { |handler|
644
+ (handler.arity == 0) ? handler.call : handler.call(args)
645
+ }
646
+ end
647
+
648
+ Windows::S_OK
649
+ rescue
650
+ Fzeet.message %Q{#{$!}\n\n#{$!.backtrace.join("\n")}}, icon: :error
651
+
652
+ Windows::S_OK
653
+ end
654
+
655
+ def OnCreateUICommand(*args) uich.QueryInterface(uich.class::IID, args[-1]); Windows::S_OK end
656
+ end
657
+
658
+ @hdll = Windows.LoadRibbonDll(_opts[:name])
659
+
660
+ handlers.each { |k, v|
661
+ k[1] = Object.const_get(k[1]) if k.length > 1
662
+
663
+ on(*k, &v)
664
+ }
665
+
666
+ @uif = Windows::UIFramework.new
667
+
668
+ uif.Initialize(window.handle, uia)
669
+ uif.LoadUI(@hdll, "#{_opts[:resname]}\0".encode('utf-16le'))
670
+
671
+ window.on(:destroy) {
672
+ raise unless uif.Destroy == Windows::S_OK; raise unless uif.Release == 0
673
+ raise unless uia.Release == 0
674
+ raise unless uich.Release == 0
675
+ }
676
+ end
677
+
678
+ attr_reader :hdll, :window, :uich, :uia, :uif
679
+
680
+ def height; uia.uir.height end
681
+
682
+ def execute(commandId, verb, key, value, props)
683
+ args = {
684
+ commandId: commandId,
685
+ verb: verb,
686
+ key: (key.null?) ? nil : Windows::PROPERTYKEY.new(key),
687
+ value: (value.null?) ? nil : Windows::PROPVARIANT.new(value),
688
+ props: (props.null?) ? nil : Windows::UISimplePropertySet.new(props),
689
+ ribbon: self,
690
+ sender: Command.new(self, commandId)
691
+ }
692
+
693
+ (handlers = @executesAllVerbs[commandId]) and handlers.each { |handler|
694
+ (handler.arity == 0) ? handler.call : handler.call(args)
695
+ }
696
+
697
+ case verb
698
+ when Windows::UI_EXECUTIONVERB_EXECUTE
699
+ (handlers = @executesExecute[commandId]) and handlers.each { |handler|
700
+ (handler.arity == 0) ? handler.call : handler.call(args)
701
+ }
702
+ when Windows::UI_EXECUTIONVERB_PREVIEW
703
+ (handlers = @executesPreview[commandId]) and handlers.each { |handler|
704
+ (handler.arity == 0) ? handler.call : handler.call(args)
705
+ }
706
+ when Windows::UI_EXECUTIONVERB_CANCELPREVIEW
707
+ (handlers = @executesCancelPreview[commandId]) and handlers.each { |handler|
708
+ (handler.arity == 0) ? handler.call : handler.call(args)
709
+ }
710
+ end
711
+
712
+ self
713
+ rescue
714
+ Fzeet.message %Q{#{$!}\n\n#{$!.backtrace.join("\n")}}, icon: :error
715
+
716
+ self
717
+ end
718
+
719
+ def update(commandId, key, value, newValue)
720
+ args = {
721
+ commandId: commandId,
722
+ key: (key.null?) ? nil : Windows::PROPERTYKEY.new(key),
723
+ value: (value.null?) ? nil : Windows::PROPVARIANT.new(value),
724
+ newValue: (newValue.null?) ? nil : Windows::PROPVARIANT.new(newValue),
725
+ ribbon: self,
726
+ sender: Command.new(self, commandId)
727
+ }
728
+
729
+ (handlers = @updatesAllKeys[commandId]) and handlers.each { |handler|
730
+ (handler.arity == 0) ? handler.call : handler.call(args)
731
+ }
732
+
733
+ self
734
+ rescue
735
+ Fzeet.message %Q{#{$!}\n\n#{$!.backtrace.join("\n")}}, icon: :error
736
+
737
+ self
738
+ end
739
+
740
+ def invalidate(commandId, flags = Windows::UI_INVALIDATIONS_ALLPROPERTIES, key = nil)
741
+ @uif.InvalidateUICommand(commandId, flags, key)
742
+
743
+ self
744
+ end
745
+
746
+ def on(*args, &block)
747
+ case args.size
748
+ when 1
749
+ case args[0]
750
+ when /^create$/i; @creates << block
751
+ when /^destroy$/i; @destroys << block
752
+ when /^size$/i; @sizes << block
753
+ when Integer; (@executesAllVerbs[args[0]] ||= []) << block
754
+ else raise ArgumentError
755
+ end
756
+ when 2
757
+ case args[0]
758
+ when /^execute$/i; (@executesExecute[args[1]] ||= []) << block
759
+ when /^preview$/i; (@executesPreview[args[1]] ||= []) << block
760
+ when /^cancelpreview$/i; (@executesCancelPreview[args[1]] ||= []) << block
761
+ when /^update$/i; (@updatesAllKeys[args[1]] ||= []) << block
762
+ else raise ArgumentError
763
+ end
764
+ else raise ArgumentError
765
+ end
766
+
767
+ self
768
+ end
769
+
770
+ def fontPropsUpdate(args)
771
+ return self unless args[:key] == Windows::UI_PKEY_FontProperties
772
+
773
+ args[:value].unknown { |current|
774
+ current.QueryInstance(Windows::PropertyStore) { |ps|
775
+ yield ps
776
+
777
+ args[:newValue].unknown = current
778
+ }
779
+ }
780
+
781
+ self
782
+ end
783
+
784
+ def fontPropsChanged(args)
785
+ return self unless args[:key] == Windows::UI_PKEY_FontProperties
786
+
787
+ args[:props].uiprop(:FontProperties_ChangedProperties).unknown { |changed|
788
+ changed.QueryInstance(Windows::PropertyStore) { |ps|
789
+ yield ps
790
+ }
791
+ }
792
+
793
+ self
794
+ end
795
+
796
+ def contextualUI(id, x, y)
797
+ uif.UseInstance(Windows::UIContextualUI, :GetView, id) { |view|
798
+ view.ShowAtLocation(x, y)
799
+ }
800
+
801
+ self
802
+ end
803
+ end
388
804
  end