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
@@ -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