fzeet 0.6.5 → 0.6.6

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 (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
@@ -40,4 +40,37 @@ module Fzeet
40
40
  :iDelta, :int
41
41
  end
42
42
  end
43
+
44
+ module UpDownMethods
45
+ def buddy=(buddy) sendmsg(:setbuddy, buddy.handle) end
46
+
47
+ def range=(range) sendmsg(:setrange, 0, Windows.MAKELONG(*range.reverse)) end
48
+
49
+ def position=(position) sendmsg(:setpos32, 0, position) end
50
+ end
51
+
52
+ class UpDown < Control
53
+ include UpDownMethods
54
+
55
+ Prefix = {
56
+ xstyle: [:ws_ex_],
57
+ style: [:uds_, :ws_],
58
+ message: [:udm_, :ccm_, :wm_],
59
+ notification: [:udn_, :nm_]
60
+ }
61
+
62
+ def self.crackNotification(args) end
63
+
64
+ def initialize(parent, id, opts = {}, &block)
65
+ super('msctls_updown32', parent, id, opts)
66
+
67
+ @parent.on(:notify, @id, &block) if block
68
+ end
69
+
70
+ def on(notification, &block)
71
+ @parent.on(:notify, @id, Fzeet.constant(notification, *self.class::Prefix[:notification]), &block)
72
+
73
+ self
74
+ end
75
+ end
43
76
  end
@@ -1,4 +1,5 @@
1
1
  require_relative 'comdlg/FileDialog'
2
+ require_relative 'comdlg/ShellFileDialog' if Fzeet::Windows::Version >= :vista
2
3
  require_relative 'comdlg/FontDialog'
3
4
  require_relative 'comdlg/ColorDialog'
4
5
  require_relative 'comdlg/FindReplaceDialog'
@@ -31,4 +31,45 @@ module Fzeet
31
31
 
32
32
  attach_function :ChooseColor, :ChooseColorA, [:pointer], :int
33
33
  end
34
+
35
+ class ColorDialog < CommonDialog
36
+ DialogStruct = Windows::CHOOSECOLOR
37
+
38
+ HookProc = -> *args { CommonDialog::HookProc.(*args.unshift(DialogStruct)) }
39
+
40
+ def initialize(opts = {})
41
+ _opts = {
42
+
43
+ }
44
+ badopts = opts.keys - _opts.keys; raise "Bad option(s): #{badopts.join(', ')}." unless badopts.empty?
45
+ _opts.merge!(opts)
46
+
47
+ @struct = DialogStruct.new
48
+
49
+ @struct[:lStructSize] = @struct.size
50
+ @struct[:hInstance] = Windows.GetModuleHandle(nil)
51
+ @struct[:lpCustColors] = @buf = FFI::MemoryPointer.new(:ulong, 16)
52
+ @struct[:Flags] = Fzeet.flags(:enablehook, :cc_)
53
+ @struct[:lCustData] = object_id
54
+ @struct[:lpfnHook] = HookProc
55
+
56
+ super()
57
+
58
+ begin
59
+ yield self
60
+ ensure
61
+ dispose
62
+ end if block_given?
63
+ end
64
+
65
+ def dispose; @buf.free end
66
+
67
+ def show(window = Application.window)
68
+ @struct[:hwndOwner] = window.handle
69
+
70
+ DialogResult.new((Windows.ChooseColor(@struct) == 0) ? Windows::IDCANCEL : Windows::IDOK)
71
+ end
72
+
73
+ def color; result = @struct[:rgbResult]; [Windows.GetRValue(result), Windows.GetBValue(result), Windows.GetBValue(result)] end
74
+ end
34
75
  end
@@ -1,5 +1,6 @@
1
1
  require_relative '../user'
2
2
  require_relative '../com'
3
+ require_relative '../shell'
3
4
 
4
5
  module Fzeet
5
6
  module Windows
@@ -42,4 +43,90 @@ module Fzeet
42
43
  CD_LBSELSUB = 1
43
44
  CD_LBSELADD = 2
44
45
  end
46
+
47
+ class CommonDialog < Handle
48
+ include WindowMethods
49
+
50
+ HookProc = -> klass, hwnd, uMsg, wParam, lParam {
51
+ begin
52
+ if klass == Windows::BROWSEINFO
53
+ if uMsg == Windows::BFFM_IUNKNOWN
54
+ instance = ObjectSpace._id2ref(lParam)
55
+
56
+ if @@instances.include?(hwnd.to_i)
57
+ @@instances.delete(hwnd.to_i)
58
+ else
59
+ @@instances[hwnd.to_i] = instance
60
+
61
+ @@instances[hwnd.to_i].instance_variable_set(:@handle, hwnd)
62
+ end
63
+ end
64
+ else
65
+ if uMsg == Windows::WM_INITDIALOG
66
+ @@instances[hwnd.to_i] = ObjectSpace._id2ref(
67
+ klass.new(FFI::Pointer.new(lParam))[:lCustData].to_i
68
+ )
69
+
70
+ @@instances[hwnd.to_i].instance_variable_set(:@handle, hwnd)
71
+ end
72
+ end
73
+
74
+ result = @@instances[hwnd.to_i].hookProc(hwnd, uMsg, wParam, lParam) if @@instances[hwnd.to_i]
75
+ rescue
76
+ answer = Fzeet.message %Q{#{$!}\n\n#{$!.backtrace.join("\n")}}, buttons: [:abort, :retry, :ignore], icon: :error
77
+
78
+ Application.quit if answer.abort?
79
+ ensure
80
+ if uMsg == Windows::WM_NCDESTROY
81
+ @@instances.delete(hwnd.to_i)
82
+ end
83
+ end
84
+
85
+ result || 0
86
+ }
87
+
88
+ def self.crackMessage(hwnd, uMsg, wParam, lParam)
89
+ window = @@instances[hwnd.to_i]
90
+
91
+ args = {
92
+ hwnd: hwnd,
93
+ uMsg: uMsg,
94
+ wParam: wParam,
95
+ lParam: lParam,
96
+ result: 0,
97
+ window: window,
98
+ sender: window
99
+ }
100
+
101
+ args
102
+ end
103
+
104
+ def initialize
105
+ @messages = {}
106
+ end
107
+
108
+ attr_reader :struct
109
+
110
+ def hookProc(hwnd, uMsg, wParam, lParam)
111
+ args, result = nil, nil
112
+
113
+ if (handlers = @messages[uMsg])
114
+ args ||= self.class.crackMessage(hwnd, uMsg, wParam, lParam)
115
+
116
+ handlers.each { |handler|
117
+ (handler.arity == 0) ? handler.call : handler.call(args)
118
+
119
+ result = args[:result]
120
+ }
121
+ end
122
+
123
+ result
124
+ end
125
+
126
+ def on(msg, &block)
127
+ (@messages[Fzeet.constant(msg, :wm_)] ||= []) << block
128
+
129
+ self
130
+ end
131
+ end
45
132
  end
@@ -104,4 +104,137 @@ module Fzeet
104
104
  :pidl, :pointer
105
105
  end
106
106
  end
107
+
108
+ class FileDialog < CommonDialog
109
+ DialogStruct = Windows::OPENFILENAME
110
+
111
+ HookProc = -> *args { CommonDialog::HookProc.(*args.unshift(DialogStruct)) }
112
+
113
+ def initialize(opts = {})
114
+ _opts = {
115
+ filter: nil,
116
+ customFilter: nil,
117
+ filterIndex: 0,
118
+ fileTitle: nil,
119
+ initialDir: nil,
120
+ title: nil,
121
+ flags: 0,
122
+ fileExtension: nil,
123
+ defExt: nil,
124
+ custData: 0,
125
+ hook: nil,
126
+ templateName: nil,
127
+ xflags: 0
128
+ }
129
+ badopts = opts.keys - _opts.keys; raise "Bad option(s): #{badopts.join(', ')}." unless badopts.empty?
130
+ _opts.merge!(opts)
131
+
132
+ @struct = DialogStruct.new
133
+
134
+ @struct[:lStructSize] = @struct.size
135
+ @struct[:hInstance] = Windows.GetModuleHandle(nil)
136
+ @struct[:lpstrFile] = @buf = FFI::MemoryPointer.new(:char, 4096)
137
+ @struct[:nMaxFile] = @buf.size
138
+ @struct[:Flags] = Fzeet.flags([:enablehook, :explorer, :enablesizing, :overwriteprompt] + [*_opts[:flags]], :ofn_)
139
+ @struct[:lCustData] = object_id
140
+ @struct[:lpfnHook] = HookProc
141
+
142
+ super()
143
+
144
+ begin
145
+ yield self
146
+ ensure
147
+ dispose
148
+ end if block_given?
149
+ end
150
+
151
+ def dispose; @buf.free end
152
+
153
+ def path; @buf.read_string end
154
+ end
155
+
156
+ class FileOpenDialog < FileDialog
157
+ def show(window = Application.window)
158
+ @struct[:hwndOwner] = window.handle
159
+
160
+ DialogResult.new((Windows.GetOpenFileName(@struct) == 0) ? Windows::IDCANCEL : Windows::IDOK)
161
+ end
162
+
163
+ def paths
164
+ return [path] if
165
+ (path = @buf.read_string).length + 1 != @struct[:nFileOffset]
166
+
167
+ result, tip = [], path.length + 1
168
+
169
+ until @buf.get_bytes(tip, 2) == "\0\0"
170
+ result << (name = @buf.get_string(tip))
171
+
172
+ tip += name.length + 1
173
+ end
174
+
175
+ result.map! { |name| "#{path}\\#{name}" }
176
+ end
177
+
178
+ def multiselect=(multiselect)
179
+ (multiselect) ?
180
+ @struct[:Flags] |= Windows::OFN_ALLOWMULTISELECT :
181
+ @struct[:Flags] &= ~Windows::OFN_ALLOWMULTISELECT
182
+ end
183
+ end
184
+
185
+ class FileSaveDialog < FileDialog
186
+ def show(window = Application.window)
187
+ @struct[:hwndOwner] = window.handle
188
+
189
+ DialogResult.new((Windows.GetSaveFileName(@struct) == 0) ? Windows::IDCANCEL : Windows::IDOK)
190
+ end
191
+ end
192
+
193
+ class FolderDialog < CommonDialog
194
+ DialogStruct = Windows::BROWSEINFO
195
+
196
+ HookProc = -> *args { CommonDialog::HookProc.(*args.unshift(DialogStruct)) }
197
+
198
+ def initialize(opts = {})
199
+ _opts = {
200
+ root: nil,
201
+ displayName: nil,
202
+ title: nil,
203
+ flags: 0,
204
+ hook: nil,
205
+ param: 0,
206
+ image: 0
207
+ }
208
+ badopts = opts.keys - _opts.keys; raise "Bad option(s): #{badopts.join(', ')}." unless badopts.empty?
209
+ _opts.merge!(opts)
210
+
211
+ @struct = DialogStruct.new
212
+
213
+ @struct[:ulFlags] = Fzeet.flags([:returnonlyfsdirs, :usenewui], :bif_)
214
+ @struct[:lpfn] = HookProc
215
+ @struct[:lParam] = object_id
216
+
217
+ super()
218
+ end
219
+
220
+ def path; @path && @path.dup end
221
+
222
+ def show(window = Application.window)
223
+ @struct[:hwndOwner] = window.handle
224
+
225
+ @path = nil
226
+
227
+ DialogResult.new(((pidl = Windows.SHBrowseForFolder(@struct)).null?) ? Windows::IDCANCEL : Windows::IDOK).tap { |result|
228
+ next unless result.ok?
229
+
230
+ FFI::MemoryPointer.new(:char, 4096) { |p|
231
+ Windows.SHGetPathFromIDList(pidl, p)
232
+
233
+ @path = p.read_string
234
+ }
235
+ }
236
+ ensure
237
+ Windows.CoTaskMemFree(pidl)
238
+ end
239
+ end
107
240
  end
@@ -47,4 +47,106 @@ module Fzeet
47
47
  attach_function :FindText, :FindTextA, [:pointer], :pointer
48
48
  attach_function :ReplaceText, :ReplaceTextA, [:pointer], :pointer
49
49
  end
50
+
51
+ class FindReplaceDialog < CommonDialog
52
+ DialogStruct = Windows::FINDREPLACE
53
+
54
+ HookProc = -> *args { CommonDialog::HookProc.(*args.unshift(DialogStruct)) }
55
+
56
+ Message = Windows.DetonateLastError(0, :RegisterWindowMessage, Windows::FINDMSGSTRING)
57
+
58
+ def initialize(opts = {})
59
+ _opts = {
60
+
61
+ }
62
+ badopts = opts.keys - _opts.keys; raise "Bad option(s): #{badopts.join(', ')}." unless badopts.empty?
63
+ _opts.merge!(opts)
64
+
65
+ @frNotifies = {}
66
+
67
+ @struct = DialogStruct.new
68
+
69
+ @struct[:lStructSize] = @struct.size
70
+ @struct[:hInstance] = Windows.GetModuleHandle(nil)
71
+ @struct[:Flags] = Fzeet.flags(:enablehook, :fr_)
72
+ @struct[:lpstrFindWhat] = @findbuf = FFI::MemoryPointer.new(:char, 4096)
73
+ @struct[:lpstrReplaceWith] = @replacebuf = FFI::MemoryPointer.new(:char, 4096)
74
+ @struct[:wFindWhatLen] = @findbuf.size
75
+ @struct[:wReplaceWithLen] = @replacebuf.size
76
+ @struct[:lCustData] = object_id
77
+ @struct[:lpfnHook] = HookProc
78
+
79
+ super()
80
+ end
81
+
82
+ def dispose; [@findbuf, @replacebuf].each(&:free) end
83
+
84
+ def findWhat; @findbuf.read_string end
85
+ def replaceWith; @replacebuf.read_string end
86
+
87
+ def frProc(args)
88
+ return unless args[:lParam] == @struct.pointer.address
89
+
90
+ (handlers = @frNotifies[:all]) and handlers.each { |handler|
91
+ (handler.arity == 0) ? handler.call : handler.call(args)
92
+ }
93
+
94
+ if @struct[:Flags] & Windows::FR_DIALOGTERM != 0
95
+ (handlers = @frNotifies[Windows::FR_DIALOGTERM]) and handlers.each { |handler|
96
+ (handler.arity == 0) ? handler.call : handler.call(args)
97
+ }
98
+
99
+ self.dialog = false
100
+
101
+ dispose
102
+ elsif @struct[:Flags] & Windows::FR_FINDNEXT != 0
103
+ (handlers = @frNotifies[Windows::FR_FINDNEXT]) and handlers.each { |handler|
104
+ (handler.arity == 0) ? handler.call : handler.call(args)
105
+ }
106
+ elsif @struct[:Flags] & Windows::FR_REPLACE != 0
107
+ (handlers = @frNotifies[Windows::FR_REPLACE]) and handlers.each { |handler|
108
+ (handler.arity == 0) ? handler.call : handler.call(args)
109
+ }
110
+ elsif @struct[:Flags] & Windows::FR_REPLACEALL != 0
111
+ (handlers = @frNotifies[Windows::FR_REPLACEALL]) and handlers.each { |handler|
112
+ (handler.arity == 0) ? handler.call : handler.call(args)
113
+ }
114
+ end
115
+ end
116
+
117
+ def onNotify(notification, &block)
118
+ notification = Fzeet.constant(notification, :fr_) unless
119
+ notification.kind_of?(Integer) || notification == :all
120
+
121
+ (@frNotifies[notification] ||= []) << block
122
+
123
+ self
124
+ end
125
+ end
126
+
127
+ class FindDialog < FindReplaceDialog
128
+ def show(window = Application.window)
129
+ @struct[:hwndOwner] = window.handle
130
+ @handle = Windows.DetonateLastError(FFI::Pointer::NULL, :FindText, @struct)
131
+
132
+ self.dialog = true
133
+
134
+ window.on(FindReplaceDialog::Message, &method(:frProc))
135
+
136
+ self
137
+ end
138
+ end
139
+
140
+ class ReplaceDialog < FindReplaceDialog
141
+ def show(window = Application.window)
142
+ @struct[:hwndOwner] = window.handle
143
+ @handle = Windows.DetonateLastError(FFI::Pointer::NULL, :ReplaceText, @struct)
144
+
145
+ self.dialog = true
146
+
147
+ window.on(FindReplaceDialog::Message, &method(:frProc))
148
+
149
+ self
150
+ end
151
+ end
50
152
  end
@@ -75,4 +75,40 @@ module Fzeet
75
75
  WM_CHOOSEFONT_SETLOGFONT = WM_USER + 101
76
76
  WM_CHOOSEFONT_SETFLAGS = WM_USER + 102
77
77
  end
78
+
79
+ class FontDialog < CommonDialog
80
+ DialogStruct = Windows::CHOOSEFONT
81
+
82
+ HookProc = -> *args { CommonDialog::HookProc.(*args.unshift(DialogStruct)) }
83
+
84
+ def initialize(opts = {})
85
+ _opts = {
86
+ font: Control::Font,
87
+ color: 0
88
+ }
89
+ badopts = opts.keys - _opts.keys; raise "Bad option(s): #{badopts.join(', ')}." unless badopts.empty?
90
+ _opts.merge!(opts)
91
+
92
+ @struct = DialogStruct.new
93
+
94
+ @struct[:lStructSize] = @struct.size
95
+ @struct[:hInstance] = Windows.GetModuleHandle(nil)
96
+ @struct[:lpLogFont] = _opts[:font].logfont.pointer
97
+ @struct[:Flags] = Fzeet.flags([:enablehook, :both, :inittologfontstruct, :effects], :cf_)
98
+ @struct[:rgbColors] = _opts[:color]
99
+ @struct[:lCustData] = object_id
100
+ @struct[:lpfnHook] = HookProc
101
+
102
+ super()
103
+ end
104
+
105
+ def show(window = Application.window)
106
+ @struct[:hwndOwner] = window.handle
107
+
108
+ DialogResult.new((Windows.ChooseFont(@struct) == 0) ? Windows::IDCANCEL : Windows::IDOK)
109
+ end
110
+
111
+ def font; IndirectFont.new(Windows::LOGFONT.new(@struct[:lpLogFont])) end
112
+ def color; @struct[:rgbColors] end
113
+ end
78
114
  end