fzeet 0.5.3 → 0.6.0

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