fzeet 0.5.3 → 0.6.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.
Files changed (91) hide show
  1. data/examples/Command.rbw +2 -2
  2. data/examples/Control/Button.rbw +33 -11
  3. data/examples/Control/ComboBox.rbw +30 -0
  4. data/examples/Control/ComboBoxEx.rbw +30 -0
  5. data/examples/Control/DateTimePicker.rbw +9 -0
  6. data/examples/Control/Edit.rbw +18 -0
  7. data/examples/Control/Header.rbw +9 -0
  8. data/examples/Control/ListBox.rbw +30 -0
  9. data/examples/Control/ListView.rbw +11 -0
  10. data/examples/Control/MonthCalendar.rbw +9 -0
  11. data/examples/Control/ProgressBar.rbw +22 -0
  12. data/examples/Control/PropertySheet.rbw +50 -0
  13. data/examples/Control/Static.rbw +14 -0
  14. data/examples/Control/SysLink.rbw +9 -0
  15. data/examples/Control/TreeView.rbw +28 -0
  16. data/examples/Control/UpDown.rbw +12 -0
  17. data/examples/Dialog/Dialog.rbw +9 -9
  18. data/examples/Dialog/DialogApplication.rbw +1 -1
  19. data/examples/Menu/ContextMenu.rbw +3 -1
  20. data/examples/Menu/MenuPARGB32.rbw +6 -6
  21. data/examples/Paint.rbw +9 -0
  22. data/examples/UIRibbon/ContextPopup.rbw +7 -4
  23. data/examples/UIRibbon/Control/Button.dll +0 -0
  24. data/examples/UIRibbon/Control/Button.rb +91 -0
  25. data/examples/UIRibbon/Control/Button.rbw +20 -0
  26. data/examples/UIRibbon/Control/Button.xml +247 -0
  27. data/examples/UIRibbon/Size.rbw +13 -0
  28. data/examples/res/audio-volume-muted-big.bmp +0 -0
  29. data/examples/res/audio-volume-muted-small.bmp +0 -0
  30. data/examples/res/audio-volume-muted.bmp +0 -0
  31. data/examples/res/go-down-big.bmp +0 -0
  32. data/examples/res/go-down-small.bmp +0 -0
  33. data/examples/res/go-down.bmp +0 -0
  34. data/examples/res/go-jump-big.bmp +0 -0
  35. data/examples/res/go-jump-small.bmp +0 -0
  36. data/examples/res/go-jump.bmp +0 -0
  37. data/examples/res/media-playback-pause-big.bmp +0 -0
  38. data/examples/res/media-playback-pause-small.bmp +0 -0
  39. data/examples/res/media-playback-pause.bmp +0 -0
  40. data/lib/fzeet/Application.rb +4 -2
  41. data/lib/fzeet/Common.rb +44 -2
  42. data/lib/fzeet/Control/Button.rb +17 -0
  43. data/lib/fzeet/Control/ComboBox.rb +46 -0
  44. data/lib/fzeet/Control/ComboBoxEx.rb +35 -0
  45. data/lib/fzeet/Control/Common.rb +2 -0
  46. data/lib/fzeet/Control/DateTimePicker.rb +38 -0
  47. data/lib/fzeet/Control/Edit.rb +53 -0
  48. data/lib/fzeet/Control/Header.rb +46 -0
  49. data/lib/fzeet/Control/ListBox.rb +72 -0
  50. data/lib/fzeet/Control/ListView.rb +90 -0
  51. data/lib/fzeet/Control/MonthCalendar.rb +38 -0
  52. data/lib/fzeet/Control/ProgressBar.rb +40 -0
  53. data/lib/fzeet/Control/Static.rb +34 -0
  54. data/lib/fzeet/Control/SysLink.rb +40 -0
  55. data/lib/fzeet/Control/TreeView.rb +32 -0
  56. data/lib/fzeet/Control/UpDown.rb +36 -0
  57. data/lib/fzeet/Control.rb +13 -0
  58. data/lib/fzeet/UIRibbon.rb +91 -31
  59. data/lib/fzeet/Window/Common.rb +22 -1
  60. data/lib/fzeet/Window/View.rb +15 -0
  61. data/lib/fzeet/Window/WindowMethods.rb +26 -1
  62. data/lib/fzeet/Window.rb +1 -0
  63. data/lib/fzeet/windows/comctl/Button.rb +3 -0
  64. data/lib/fzeet/windows/comctl/ComboBox.rb +12 -0
  65. data/lib/fzeet/windows/comctl/ComboBoxEx.rb +65 -0
  66. data/lib/fzeet/windows/comctl/Common.rb +52 -1
  67. data/lib/fzeet/windows/comctl/DateTimePicker.rb +54 -0
  68. data/lib/fzeet/windows/comctl/Edit.rb +20 -0
  69. data/lib/fzeet/windows/comctl/Header.rb +128 -0
  70. data/lib/fzeet/windows/comctl/ListView.rb +317 -0
  71. data/lib/fzeet/windows/comctl/MonthCalendar.rb +62 -0
  72. data/lib/fzeet/windows/comctl/ProgressBar.rb +31 -0
  73. data/lib/fzeet/windows/comctl/PropertySheet.rb +205 -0
  74. data/lib/fzeet/windows/comctl/SysLink.rb +34 -0
  75. data/lib/fzeet/windows/comctl/TreeView.rb +198 -0
  76. data/lib/fzeet/windows/comctl/UpDown.rb +43 -0
  77. data/lib/fzeet/windows/comctl.rb +12 -0
  78. data/lib/fzeet/windows/common.rb +74 -2
  79. data/lib/fzeet/windows/gdi.rb +2 -0
  80. data/lib/fzeet/windows/libc.rb +4 -0
  81. data/lib/fzeet/windows/ole.rb +0 -22
  82. data/lib/fzeet/windows/shell/Common.rb +2 -0
  83. data/lib/fzeet/windows/user/Control/Button.rb +6 -0
  84. data/lib/fzeet/windows/user/Control/ComboBox.rb +72 -0
  85. data/lib/fzeet/windows/user/Control/Common.rb +1 -1
  86. data/lib/fzeet/windows/user/Control/Edit.rb +71 -0
  87. data/lib/fzeet/windows/user/Control/ListBox.rb +78 -0
  88. data/lib/fzeet/windows/user/Control/Static.rb +49 -0
  89. data/lib/fzeet/windows/user/Control.rb +4 -0
  90. data/lib/fzeet/windows/user/Window.rb +47 -0
  91. metadata +66 -4
@@ -0,0 +1,72 @@
1
+ require_relative 'Common'
2
+
3
+ module Fzeet
4
+ module ListBoxMethods
5
+ def textlen(i) raise "GETTEXTLEN failed." if (len = sendmsg(:gettextlen, i)) == -1; len end
6
+
7
+ def [](i)
8
+ i = sendmsg(:getcursel) if i == :selected
9
+
10
+ return '' if i == -1 || (len = textlen(i) + 1) == 1
11
+
12
+ ''.tap { |item|
13
+ FFI::MemoryPointer.new(:char, len) { |buf|
14
+ raise "GETTEXT failed." if sendmsg(:gettext, i, buf) == -1
15
+
16
+ item << buf.read_string
17
+ }
18
+ }
19
+ end
20
+
21
+ def clear; sendmsg(:resetcontent); self end
22
+
23
+ def append(item)
24
+ [*item].each { |item|
25
+ p = FFI::MemoryPointer.from_string(item.to_s)
26
+
27
+ raise 'ADDSTRING failed.' if [-1, -2].include?(sendmsg(:addstring, 0, p).tap { p.free })
28
+ }
29
+
30
+ self
31
+ end
32
+
33
+ def selected=(i)
34
+ i = case i
35
+ when -1; 0xffffffff
36
+ when :first; 0
37
+ when :last; length - 1
38
+ else i
39
+ end
40
+
41
+ raise 'SETCURSEL failed.' if sendmsg(:setcursel, i) == -1 && i != 0xffffffff
42
+
43
+ self
44
+ end
45
+
46
+ def length; raise 'GETCOUNT failed.' if (len = sendmsg(:getcount)) == -1; len end
47
+ def each; length.times { |i| yield self[i] }; self end
48
+ end
49
+
50
+ class ListBox < Control
51
+ include ListBoxMethods
52
+
53
+ Prefix = {
54
+ xstyle: [:ws_ex_],
55
+ style: [:lbs_, :ws_],
56
+ message: [:lb_, :wm_],
57
+ notification: [:lbn_]
58
+ }
59
+
60
+ def initialize(parent, id, opts = {}, &block)
61
+ super('ListBox', parent, id, opts)
62
+
63
+ @parent.on(:command, @id, &block) if block
64
+ end
65
+
66
+ def on(notification, &block)
67
+ @parent.on(:command, @id, Fzeet.constant(notification, *self.class::Prefix[:notification]), &block)
68
+
69
+ self
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,90 @@
1
+ require_relative 'Common'
2
+
3
+ module Fzeet
4
+ module ListViewMethods
5
+ class ExStyle
6
+ def initialize(listview) @listview = listview end
7
+
8
+ def <<(xstyle)
9
+ @listview.sendmsg(:setextendedlistviewstyle, 0,
10
+ @listview.sendmsg(:getextendedlistviewstyle) | Fzeet.constant(xstyle, *@listview.class::Prefix[:xstyle])
11
+ )
12
+
13
+ self
14
+ end
15
+
16
+ def >>(xstyle)
17
+ @listview.sendmsg(:setextendedlistviewstyle, 0,
18
+ @listview.sendmsg(:getextendedlistviewstyle) & ~Fzeet.constant(xstyle, *@listview.class::Prefix[:xstyle])
19
+ )
20
+
21
+ self
22
+ end
23
+
24
+ def toggle(what) send((@listview.xstyle?(what)) ? :>> : :<<, what); self end
25
+ end
26
+
27
+ def xstyle?(xstyle) (sendmsg(:getextendedlistviewstyle) & (xstyle = Fzeet.constant(xstyle, *self.class::Prefix[:xstyle]))) == xstyle end
28
+ def xstyle; ExStyle.new(self) end
29
+
30
+ def insertColumn(i, text, width)
31
+ lvc = Windows::LVCOLUMN.new
32
+
33
+ lvc[:mask] = Fzeet.flags([:fmt, :width, :text, :subitem], :lvcf_)
34
+ lvc[:fmt] = Fzeet.flags(:left, :lvcfmt_)
35
+ lvc[:cx] = width
36
+ lvc[:pszText] = ptext = FFI::MemoryPointer.from_string(text)
37
+ lvc[:iSubItem] = i
38
+
39
+ sendmsg(:insertcolumn, 0, lvc.pointer)
40
+
41
+ self
42
+ ensure
43
+ ptext.free if ptext
44
+ end
45
+
46
+ def insertItem(i, j, text)
47
+ lvi = Windows::LVITEM.new
48
+
49
+ lvi[:mask] = Fzeet.flags(:text, :lvif_)
50
+ lvi[:iItem] = i
51
+ lvi[:iSubItem] = j
52
+ lvi[:pszText] = ptext = FFI::MemoryPointer.from_string(text)
53
+
54
+ if j > 0
55
+ sendmsg(:setitem, 0, lvi.pointer)
56
+ else
57
+ sendmsg(:insertitem, 0, lvi.pointer)
58
+ end
59
+
60
+ self
61
+ ensure
62
+ ptext.free if ptext
63
+ end
64
+ end
65
+
66
+ class ListView < Control
67
+ include ListViewMethods
68
+
69
+ Prefix = {
70
+ xstyle: [:lvs_ex_, :ws_ex_],
71
+ style: [:lvs_, :ws_],
72
+ message: [:lvm_, :ccm_, :wm_],
73
+ notification: [:lvn_, :nm_]
74
+ }
75
+
76
+ def self.crackNotification(args) end
77
+
78
+ def initialize(parent, id, opts = {}, &block)
79
+ super('SysListView32', parent, id, opts)
80
+
81
+ @parent.on(:notify, @id, &block) if block
82
+ end
83
+
84
+ def on(notification, &block)
85
+ @parent.on(:notify, @id, Fzeet.constant(notification, *self.class::Prefix[:notification]), &block)
86
+
87
+ self
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,38 @@
1
+ require_relative 'Common'
2
+
3
+ module Fzeet
4
+ module MonthCalendarMethods
5
+
6
+ end
7
+
8
+ class MonthCalendar < Control
9
+ include MonthCalendarMethods
10
+
11
+ Prefix = {
12
+ xstyle: [:ws_ex_],
13
+ style: [:mcs_, :ws_],
14
+ message: [:mcm_, :ccm_, :wm_],
15
+ notification: [:mcn_, :nm_]
16
+ }
17
+
18
+ def self.crackNotification(args)
19
+ case args[:notification]
20
+ when Windows::MCN_SELCHANGE
21
+ args[:sc] = Windows::NMSELCHANGE.new(FFI::Pointer.new(args[:lParam]))
22
+ args[:st1], args[:st2] = args[:sc][:stSelStart], args[:sc][:stSelEnd]
23
+ end
24
+ end
25
+
26
+ def initialize(parent, id, opts = {}, &block)
27
+ super('SysMonthCal32', parent, id, opts)
28
+
29
+ @parent.on(:notify, @id, &block) if block
30
+ end
31
+
32
+ def on(notification, &block)
33
+ @parent.on(:notify, @id, Fzeet.constant(notification, *self.class::Prefix[:notification]), &block)
34
+
35
+ self
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,40 @@
1
+ require_relative 'Common'
2
+
3
+ module Fzeet
4
+ module ProgressBarMethods
5
+ def step=(step) sendmsg(:setstep, step) end
6
+ def step!; sendmsg(:stepit) end
7
+
8
+ def position=(position) sendmsg(:setpos, position) end
9
+
10
+ def marquee?; @marquee end
11
+ def marquee=(marquee) sendmsg(:setmarquee, (@marquee = marquee) ? 1 : 0) end
12
+ end
13
+
14
+ class ProgressBar < Control
15
+ include ProgressBarMethods
16
+
17
+ Prefix = {
18
+ xstyle: [:ws_ex_],
19
+ style: [:pbs_, :ws_],
20
+ message: [:pbm_, :ccm_, :wm_],
21
+ notification: [:nm_]
22
+ }
23
+
24
+ def self.crackNotification(args) end
25
+
26
+ def initialize(parent, id, opts = {}, &block)
27
+ super('msctls_progress32', parent, id, opts)
28
+
29
+ @marquee = false
30
+
31
+ @parent.on(:notify, @id, &block) if block
32
+ end
33
+
34
+ def on(notification, &block)
35
+ @parent.on(:notify, @id, Fzeet.constant(notification, *self.class::Prefix[:notification]), &block)
36
+
37
+ self
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,34 @@
1
+ require_relative 'Common'
2
+
3
+ module Fzeet
4
+ module StaticMethods
5
+ def clear; self.text = ''; self end
6
+
7
+ def image=(image) sendmsg(:setimage, Windows::IMAGE_BITMAP, image.handle) end
8
+ end
9
+
10
+ class Static < Control
11
+ include StaticMethods
12
+
13
+ Prefix = {
14
+ xstyle: [:ws_ex_],
15
+ style: [:ss_, :ws_],
16
+ message: [:stm_, :wm_],
17
+ notification: [:stn_]
18
+ }
19
+
20
+ def initialize(parent, id, opts = {}, &block)
21
+ super('Static', parent, id, opts)
22
+
23
+ style >> :tabstop
24
+
25
+ @parent.on(:command, @id, &block) if block
26
+ end
27
+
28
+ def on(notification, &block)
29
+ @parent.on(:command, @id, Fzeet.constant(notification, *self.class::Prefix[:notification]), &block)
30
+
31
+ self
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,40 @@
1
+ require_relative 'Common'
2
+
3
+ module Fzeet
4
+ module SysLinkMethods
5
+
6
+ end
7
+
8
+ class SysLink < Control
9
+ include SysLinkMethods
10
+
11
+ Prefix = {
12
+ xstyle: [:ws_ex_],
13
+ style: [:lws_, :ws_],
14
+ message: [:lm_, :ccm_, :wm_],
15
+ notification: [:nm_]
16
+ }
17
+
18
+ def self.crackNotification(args)
19
+ case args[:notification]
20
+ when Windows::NM_CLICK
21
+ args[:link] = Windows::NMLINK.new(FFI::Pointer.new(args[:lParam]))
22
+
23
+ args[:id] = Windows.WCSTOMBS(args[:link][:item][:szID])
24
+ args[:url] = Windows.WCSTOMBS(args[:link][:item][:szUrl])
25
+ end
26
+ end
27
+
28
+ def initialize(parent, id, opts = {}, &block)
29
+ super('SysLink', parent, id, opts)
30
+
31
+ @parent.on(:notify, @id, &block) if block
32
+ end
33
+
34
+ def on(notification, &block)
35
+ @parent.on(:notify, @id, Fzeet.constant(notification, *self.class::Prefix[:notification]), &block)
36
+
37
+ self
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,32 @@
1
+ require_relative 'Common'
2
+
3
+ module Fzeet
4
+ module TreeViewMethods
5
+
6
+ end
7
+
8
+ class TreeView < Control
9
+ include TreeViewMethods
10
+
11
+ Prefix = {
12
+ xstyle: [:tvs_ex, :ws_ex_],
13
+ style: [:tvs_, :ws_],
14
+ message: [:tvm_, :ccm_, :wm_],
15
+ notification: [:tvn_, :nm_]
16
+ }
17
+
18
+ def self.crackNotification(args) end
19
+
20
+ def initialize(parent, id, opts = {}, &block)
21
+ super('SysTreeView32', parent, id, opts)
22
+
23
+ @parent.on(:notify, @id, &block) if block
24
+ end
25
+
26
+ def on(notification, &block)
27
+ @parent.on(:notify, @id, Fzeet.constant(notification, *self.class::Prefix[:notification]), &block)
28
+
29
+ self
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,36 @@
1
+ require_relative 'Common'
2
+
3
+ module Fzeet
4
+ module UpDownMethods
5
+ def buddy=(buddy) sendmsg(:setbuddy, buddy.handle) end
6
+
7
+ def range=(range) sendmsg(:setrange, 0, Windows.MAKELONG(*range.reverse)) end
8
+
9
+ def position=(position) sendmsg(:setpos32, 0, position) end
10
+ end
11
+
12
+ class UpDown < Control
13
+ include UpDownMethods
14
+
15
+ Prefix = {
16
+ xstyle: [:ws_ex_],
17
+ style: [:uds_, :ws_],
18
+ message: [:udm_, :ccm_, :wm_],
19
+ notification: [:udn_, :nm_]
20
+ }
21
+
22
+ def self.crackNotification(args) end
23
+
24
+ def initialize(parent, id, opts = {}, &block)
25
+ super('msctls_updown32', parent, id, opts)
26
+
27
+ @parent.on(:notify, @id, &block) if block
28
+ end
29
+
30
+ def on(notification, &block)
31
+ @parent.on(:notify, @id, Fzeet.constant(notification, *self.class::Prefix[:notification]), &block)
32
+
33
+ self
34
+ end
35
+ end
36
+ end
data/lib/fzeet/Control.rb CHANGED
@@ -1 +1,14 @@
1
1
  require_relative 'Control/Button'
2
+ require_relative 'Control/SysLink' if Fzeet::Windows::WINVER.AtLeastWindowsXP?
3
+ require_relative 'Control/Static'
4
+ require_relative 'Control/Edit'
5
+ require_relative 'Control/UpDown'
6
+ require_relative 'Control/MonthCalendar'
7
+ require_relative 'Control/DateTimePicker'
8
+ require_relative 'Control/ListBox'
9
+ require_relative 'Control/ComboBox'
10
+ require_relative 'Control/ComboBoxEx'
11
+ require_relative 'Control/Header'
12
+ require_relative 'Control/ListView'
13
+ require_relative 'Control/TreeView'
14
+ require_relative 'Control/ProgressBar'
@@ -24,6 +24,9 @@ module Fzeet
24
24
 
25
25
  def enabled?; self[Windows::UI_PKEY_Enabled].bool end
26
26
  def enabled=(enabled) self[Windows::UI_PKEY_Enabled] = Windows::PROPVARIANT[:bool, enabled] end
27
+
28
+ def checked?; self[Windows::UI_PKEY_BooleanValue].bool end
29
+ def checked=(checked) self[Windows::UI_PKEY_BooleanValue] = Windows::PROPVARIANT[:bool, checked] end
27
30
  end
28
31
 
29
32
  def [](id) Command.new(self, id) end
@@ -99,79 +102,134 @@ module Fzeet
99
102
  }
100
103
  end
101
104
 
102
- def initialize(window, name = Application.name, resname = 'APPLICATION_RIBBON')
105
+ def initialize(_window, name = Application.name, resname = 'APPLICATION_RIBBON')
106
+ @creates = []
107
+ @destroys = []
108
+ @sizes = []
103
109
  @executesAllVerbs = {}
104
110
 
105
- @window = window
111
+ @window = _window
106
112
 
107
- @window.instance_variable_set(:@ribbon, self)
113
+ window.instance_variable_set(:@ribbon, self)
108
114
 
109
- class << @window
115
+ class << window
110
116
  attr_reader :ribbon
111
117
  end
112
118
 
113
119
  @uich = Windows::UICommandHandler.new
114
120
 
115
- @uich.instance_variable_set(:@ribbon, self)
121
+ uich.instance_variable_set(:@ribbon, self)
116
122
 
117
- class << @uich
123
+ class << uich
118
124
  attr_reader :ribbon
119
125
 
120
- def Execute(*args) @ribbon.execute(*args) end
126
+ def Execute(*args) ribbon.execute(*args); Windows::S_OK end
121
127
  end
122
128
 
123
129
  @uia = Windows::UIApplication.new
124
130
 
125
- @uia.instance_variable_set(:@uich, @uich)
131
+ uia.instance_variable_set(:@uich, @uich)
132
+
133
+ class << uia
134
+ attr_reader :uich, :uir
135
+
136
+ def OnViewChanged(viewId, typeId, view, verb, reason)
137
+ return Windows::S_OK unless typeId == Windows::UI_VIEWTYPE_RIBBON
138
+
139
+ args = {
140
+ viewId: viewId,
141
+ typeId: typeId,
142
+ view: view,
143
+ verb: verb,
144
+ reason: reason,
145
+ ribbon: self,
146
+ sender: self
147
+ }
148
+
149
+ case verb
150
+ when Windows::UI_VIEWVERB_CREATE
151
+ @uir = Windows::Unknown.new(view).QueryInstance(Windows::UIRibbon)
126
152
 
127
- class << @uia
128
- attr_reader :uich
153
+ uir.instance_variable_set(:@height, 0)
129
154
 
130
- def OnCreateUICommand(*args) @uich.QueryInterface(@uich.class::IID, args[-1]); Windows::S_OK end
155
+ class << uir
156
+ attr_accessor :height
157
+ end
158
+
159
+ uich.ribbon.instance_variable_get(:@creates).each { |handler|
160
+ (handler.arity == 0) ? handler.call : handler.call(args)
161
+ }
162
+ when Windows::UI_VIEWVERB_DESTROY
163
+ uich.ribbon.instance_variable_get(:@destroys).each { |handler|
164
+ (handler.arity == 0) ? handler.call : handler.call(args)
165
+ }
166
+
167
+ uir.Release
168
+ when Windows::UI_VIEWVERB_SIZE
169
+ FFI::MemoryPointer.new(:uint) { |p| uir.GetHeight(p); uir.height = p.read_int }
170
+
171
+ uich.ribbon.instance_variable_get(:@sizes).each { |handler|
172
+ (handler.arity == 0) ? handler.call : handler.call(args)
173
+ }
174
+ end
175
+
176
+ Windows::S_OK
177
+ rescue
178
+ Fzeet.message %Q{#{$!}\n\n#{$!.backtrace.join("\n")}}, icon: :error
179
+
180
+ Windows::S_OK
181
+ end
182
+
183
+ def OnCreateUICommand(*args) uich.QueryInterface(uich.class::IID, args[-1]); Windows::S_OK end
131
184
  end
132
185
 
133
186
  @uif = Windows::UIFramework.new
134
187
 
135
- @uif.Initialize(@window.handle, @uia)
136
- @uif.LoadUI(@hdll = Windows.LoadRibbonDll(name), "#{resname}\0".encode('utf-16le'))
188
+ uif.Initialize(window.handle, uia)
189
+ uif.LoadUI(@hdll = Windows.LoadRibbonDll(name), "#{resname}\0".encode('utf-16le'))
137
190
 
138
- @window.on(:destroy) {
139
- @uich.Release
140
- @uia.Release
141
- @uif.Destroy; @uif.Release
191
+ window.on(:destroy) {
192
+ uich.Release
193
+ uia.Release
194
+ uif.Destroy; uif.Release
142
195
  }
143
196
  end
144
197
 
145
- attr_reader :window, :uich, :uia, :uif
198
+ attr_reader :hdll, :window, :uich, :uia, :uif
199
+
200
+ def height; uia.uir.height end
146
201
 
147
202
  def execute(commandId, verb, key, value, props)
148
203
  args = {
149
204
  commandId: commandId,
205
+ verb: verb,
206
+ key: key,
207
+ value: value,
208
+ props: props,
150
209
  ribbon: self,
151
210
  sender: Command.new(self, commandId)
152
211
  }
153
212
 
154
- result = Windows::E_NOTIMPL
155
-
156
- begin
157
- if @executesAllVerbs.include?(commandId)
158
- @executesAllVerbs[commandId].each { |handler|
159
- (handler.arity == 0) ? handler.call : handler.call(args)
160
- }
161
-
162
- result = Windows::S_OK
163
- end
164
- rescue
165
- Fzeet.message %Q{#{$!}\n\n#{$!.backtrace.join("\n")}}, icon: :error
213
+ if @executesAllVerbs.include?(commandId)
214
+ @executesAllVerbs[commandId].each { |handler|
215
+ (handler.arity == 0) ? handler.call : handler.call(args)
216
+ }
166
217
  end
167
218
 
168
- result
219
+ self
220
+ rescue
221
+ Fzeet.message %Q{#{$!}\n\n#{$!.backtrace.join("\n")}}, icon: :error
222
+
223
+ self
169
224
  end
170
225
 
171
226
  def on(*args, &block)
172
227
  case args.size
173
228
  when 1
174
229
  case args[0]
230
+ when /^create$/i; @creates << block
231
+ when /^destroy$/i; @destroys << block
232
+ when /^size$/i; @sizes << block
175
233
  when Integer; (@executesAllVerbs[args[0]] ||= []) << block
176
234
  else raise ArgumentError
177
235
  end
@@ -185,6 +243,8 @@ module Fzeet
185
243
  uif.UseInstance(Windows::UIContextualUI, :GetView, id) { |view|
186
244
  view.ShowAtLocation(x, y)
187
245
  }
246
+
247
+ self
188
248
  end
189
249
  end
190
250
  end
@@ -173,6 +173,7 @@ module Fzeet
173
173
  y: Windows::CW_USEDEFAULT,
174
174
  width: Windows::CW_USEDEFAULT,
175
175
  height: Windows::CW_USEDEFAULT,
176
+ position: [],
176
177
  parent: nil,
177
178
  menu: nil
178
179
  }
@@ -184,6 +185,7 @@ module Fzeet
184
185
  _opts[:xstyle] = Fzeet.flags(_opts[:xstyle], *self.class::Prefix[:xstyle])
185
186
  _opts[:caption] = _opts[:caption].to_s
186
187
  _opts[:style] = Fzeet.flags(_opts[:style], *self.class::Prefix[:style])
188
+ _opts[:x], _opts[:y], _opts[:width], _opts[:height] = _opts[:position] unless _opts[:position].empty?
187
189
 
188
190
  @messages ||= {}
189
191
  @commands ||= {}
@@ -214,7 +216,7 @@ module Fzeet
214
216
  end
215
217
  end
216
218
 
217
- attr_reader :parent
219
+ attr_reader :parent, :ribbon
218
220
 
219
221
  def dispose; Windows.DestroyWindow(@handle) end
220
222
 
@@ -291,6 +293,15 @@ module Fzeet
291
293
  end
292
294
 
293
295
  def on(*args, &block)
296
+ args[0] =~ /^draw$/ and
297
+ return onMessage(:paint) { |_args| paint { |dc| dc.select(*args[1..-1]) {
298
+ case block.arity
299
+ when 0; block.call
300
+ when 1; block.call(dc)
301
+ else block.call(dc, _args)
302
+ end
303
+ }}}
304
+
294
305
  case args.length
295
306
  when 1; onMessage(*args, &block)
296
307
  when 2, 3
@@ -302,5 +313,15 @@ module Fzeet
302
313
  else raise ArgumentError
303
314
  end
304
315
  end
316
+
317
+ def stubNotImplementedCommands
318
+ Command.instance_variable_get(:@ids).each { |command, id|
319
+ next if @commands.find { |_id, handlers| _id == id }
320
+
321
+ on(:command, id) { message "Not Implemented (#{command})", icon: :warning }
322
+ }
323
+
324
+ self
325
+ end
305
326
  end
306
327
  end
@@ -0,0 +1,15 @@
1
+ require_relative 'Common'
2
+
3
+ module Fzeet
4
+ View = BasicWindow['Fzeet.View',
5
+ style: [:hredraw, :vredraw]
6
+ ]
7
+
8
+ class View
9
+ def initialize(opts = {})
10
+ (opts[:style] ||= []) << :overlappedwindow << :clipchildren
11
+
12
+ super
13
+ end
14
+ end
15
+ end
@@ -106,6 +106,9 @@ module Fzeet
106
106
 
107
107
  def update; Windows.DetonateLastError(0, :UpdateWindow, @handle); self end
108
108
 
109
+ def focus?; Windows.GetFocus().to_i == @handle.to_i end
110
+ def focus=(focus) Windows.DetonateLastError(FFI::Pointer::NULL, :SetFocus, (focus) ? @handle : nil) end
111
+
109
112
  def textlen; Windows.GetWindowTextLength(@handle) end
110
113
 
111
114
  def text
@@ -120,7 +123,7 @@ module Fzeet
120
123
  }
121
124
  end
122
125
 
123
- def text=(text) Windows.DetonateLastError(0, :SetWindowText, @handle, text) end
126
+ def text=(text) Windows.DetonateLastError(0, :SetWindowText, @handle, text.to_s) end
124
127
 
125
128
  def rect; Windows.DetonateLastError(0, :GetClientRect, @handle, r = Rect.new); r end
126
129
 
@@ -147,6 +150,28 @@ module Fzeet
147
150
  def capture?; Windows.GetCapture().to_i == @handle.to_i end
148
151
  def capture=(capture) (capture) ? Windows.SetCapture(@handle) : Windows.DetonateLastError(0, :ReleaseCapture) end
149
152
 
153
+ def paint
154
+ hdc = Windows.DetonateLastError(FFI::Pointer::NULL, :BeginPaint, @handle, ps = Windows::PAINTSTRUCT.new)
155
+
156
+ begin
157
+ dc = Handle.wrap(hdc, DCMethods)
158
+
159
+ dc.instance_variable_set(:@window, self)
160
+
161
+ class << dc
162
+ attr_reader :window
163
+ end
164
+
165
+ yield dc, ps
166
+ ensure
167
+ Windows.EndPaint(@handle, ps)
168
+ end
169
+
170
+ self
171
+ end
172
+
173
+ def invalidate(rect = rect, erase = 1) Windows.DetonateLastError(0, :InvalidateRect, @handle, rect, erase); self end
174
+
150
175
  def menu; (Handle.instance?(handle = Windows.GetMenu(@handle))) ? Handle.instance(handle) : nil end
151
176
 
152
177
  def menu=(menu)