fzeet 0.6.3 → 0.6.4
Sign up to get free protection for your applications and to get access to all the features.
- data/examples/Control/ExplorerBrowser.rbw +32 -0
- data/examples/Control/WebBrowser.rbw +33 -0
- data/examples/Dialog/FileDialog.rbw +3 -1
- data/examples/MDI.rbw +112 -10
- data/examples/Raw/UIRibbon/Command.rbw +27 -27
- data/examples/Raw/UIRibbon/Minimal.rbw +18 -18
- data/lib/fzeet/Control/Common.rb +18 -3
- data/lib/fzeet/Control/ExplorerBrowser.rb +66 -0
- data/lib/fzeet/Control/Scintilla.rb +8 -0
- data/lib/fzeet/Control/WebBrowser.rb +174 -0
- data/lib/fzeet/Control.rb +2 -0
- data/lib/fzeet/Dialog/FileDialog.rb +7 -1
- data/lib/fzeet/Dialog/ShellFileDialog.rb +12 -0
- data/lib/fzeet/Window/Common.rb +36 -4
- data/lib/fzeet/Window/MDI.rb +12 -0
- data/lib/fzeet/windows/com.rb +33 -1
- data/lib/fzeet/windows/kernel.rb +2 -0
- data/lib/fzeet/windows/ole - Copy.rb +446 -0
- data/lib/fzeet/windows/ole.rb +187 -0
- data/lib/fzeet/windows/shdocvw - Copy.rb +171 -0
- data/lib/fzeet/windows/shdocvw.rb +102 -0
- data/lib/fzeet/windows/shell/Common.rb +181 -0
- data/lib/fzeet/windows/user/Window.rb +11 -0
- data/lib/fzeet/windows.rb +1 -0
- metadata +11 -4
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'fzeet'
|
2
|
+
|
3
|
+
include Fzeet
|
4
|
+
|
5
|
+
Application.run { |window|
|
6
|
+
window.menu = Menu.new.
|
7
|
+
append(:popup, '&Go To', PopupMenu.new.
|
8
|
+
append(:string, '&Back', :back).
|
9
|
+
append(:string, '&Forward', :forward).
|
10
|
+
append(:string, '&Up', :up)
|
11
|
+
)
|
12
|
+
|
13
|
+
(browser = ExplorerBrowser.new(window)).
|
14
|
+
SetOptions(Windows::EBO_SHOWFRAMES)
|
15
|
+
|
16
|
+
def (browser.events).OnNavigationComplete(pidl)
|
17
|
+
FFI::MemoryPointer.new(:char, 4096) { |p|
|
18
|
+
Windows.SHGetPathFromIDList(pidl, p)
|
19
|
+
|
20
|
+
message p.read_string
|
21
|
+
}
|
22
|
+
|
23
|
+
Windows::S_OK
|
24
|
+
end
|
25
|
+
|
26
|
+
browser.goto(:Desktop)
|
27
|
+
|
28
|
+
window.
|
29
|
+
on(:command, :back, &browser.method(:back)).
|
30
|
+
on(:command, :forward, &browser.method(:forward)).
|
31
|
+
on(:command, :up, &browser.method(:up))
|
32
|
+
}
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'fzeet'
|
2
|
+
|
3
|
+
include Fzeet
|
4
|
+
|
5
|
+
Application.run { |window|
|
6
|
+
window.menu = Menu.new.
|
7
|
+
append(:popup, '&View', PopupMenu.new.
|
8
|
+
append(:string, '&Refresh', :refresh)
|
9
|
+
).
|
10
|
+
|
11
|
+
append(:popup, '&Go To', PopupMenu.new.
|
12
|
+
append(:string, '&Back', :back).
|
13
|
+
append(:string, '&Forward', :forward).
|
14
|
+
append(:string, '&Home', :home).
|
15
|
+
append(:string, '&Search', :search)
|
16
|
+
)
|
17
|
+
|
18
|
+
browser = WebBrowser.new(window)
|
19
|
+
|
20
|
+
def (browser.events).NavigateComplete(url)
|
21
|
+
message Windows.WCSTOMBS(url)
|
22
|
+
end
|
23
|
+
|
24
|
+
browser.search
|
25
|
+
|
26
|
+
window.
|
27
|
+
on(:command, :refresh, &browser.method(:refresh)).
|
28
|
+
|
29
|
+
on(:command, :back, &browser.method(:back)).
|
30
|
+
on(:command, :forward, &browser.method(:forward)).
|
31
|
+
on(:command, :home, &browser.method(:home)).
|
32
|
+
on(:command, :search, &browser.method(:search))
|
33
|
+
}
|
@@ -24,7 +24,9 @@ Application.run { |window|
|
|
24
24
|
}.
|
25
25
|
|
26
26
|
on(:command, :openMultiple) {
|
27
|
-
FileOpenDialog.new
|
27
|
+
FileOpenDialog.new { |dialog|
|
28
|
+
dialog.multiselect = true
|
29
|
+
|
28
30
|
message dialog.paths.join("\n") if dialog.show.ok?
|
29
31
|
}
|
30
32
|
}.
|
data/examples/MDI.rbw
CHANGED
@@ -3,28 +3,130 @@ require 'fzeet'
|
|
3
3
|
include Fzeet
|
4
4
|
|
5
5
|
Application.run(Frame.new) { |window|
|
6
|
-
children, total = [], 0
|
7
|
-
|
8
6
|
window.menu.
|
9
7
|
append(:popup, '&File', PopupMenu.new.
|
10
|
-
append(:string,
|
8
|
+
append(:string, "&New\tCtrl+N", :new).
|
9
|
+
append(:string, "&Open...\tCtrl+O", :open).
|
10
|
+
append(:string, "&Save\tCtrl+S", :save).
|
11
|
+
append(:string, "Save &As...\tCtrl+Shift+S", :saveAs)
|
11
12
|
)
|
12
13
|
|
14
|
+
Application.accelerators << AcceleratorTable.new(
|
15
|
+
[:control, :n, :new],
|
16
|
+
[:control, :o, :open],
|
17
|
+
[:control, :s, :save],
|
18
|
+
[[:control, :shift], :s, :saveAs]
|
19
|
+
)
|
20
|
+
|
13
21
|
window.
|
14
22
|
on(:command, :new) {
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
23
|
+
child = MDIChild.new(window.client, caption: 'Untitled')
|
24
|
+
|
25
|
+
Scintilla.new(child, :sci, style: :border, position: child.rect.to_a, anchor: :ltrb)
|
26
|
+
|
27
|
+
child[:sci].focus = true
|
28
|
+
|
29
|
+
child[:sci].font = 'Courier New'
|
30
|
+
child[:sci].fontSize = 10
|
31
|
+
|
32
|
+
child[:sci].tabWidth = 2
|
33
|
+
|
34
|
+
child.on(:close) { |args|
|
35
|
+
if args[:sender][:sci].dirty?
|
36
|
+
answer = args[:sender].question(%Q{
|
37
|
+
File not saved:
|
38
|
+
#{args[:sender].text}
|
39
|
+
|
40
|
+
Press Yes to save it and close the window
|
41
|
+
Press No to close the window without saving
|
42
|
+
Press Cancel to leave the window open
|
43
|
+
}, buttons: [:yes, :no, :Cancel], icon: :warning)
|
44
|
+
|
45
|
+
window.sendmsg(:command, Command[:save]) if answer.yes?
|
46
|
+
|
47
|
+
args[:result] = nil unless answer.cancel?
|
48
|
+
else
|
49
|
+
args[:result] = nil
|
50
|
+
end
|
51
|
+
}
|
52
|
+
}.
|
53
|
+
|
54
|
+
on(:command, :open) {
|
55
|
+
((Windows::WINVER.AtLeastWindowsVista?) ? ShellFileOpenDialog : FileOpenDialog).new { |dialog|
|
56
|
+
dialog.multiselect = true
|
57
|
+
|
58
|
+
next unless dialog.show.ok?
|
59
|
+
|
60
|
+
dialog.paths.each { |path|
|
61
|
+
window.sendmsg(:command, Command[:new])
|
19
62
|
|
20
|
-
|
63
|
+
child = window.activeChild
|
64
|
+
|
65
|
+
child.text, child[:sci].text = path, File.read(path)
|
66
|
+
|
67
|
+
child[:sci].toggle(:dirty).sendmsg(:emptyundobuffer)
|
68
|
+
}
|
69
|
+
}
|
70
|
+
}.
|
71
|
+
|
72
|
+
on(:command, :saveAs) {
|
73
|
+
((Windows::WINVER.AtLeastWindowsVista?) ? ShellFileSaveDialog : FileSaveDialog).new { |dialog|
|
74
|
+
next unless dialog.show.ok?
|
75
|
+
|
76
|
+
child = window.activeChild
|
77
|
+
|
78
|
+
File.open(child.text = dialog.path, 'w') { |f| f << child[:sci].text; child[:sci].dirty = false }
|
79
|
+
}
|
80
|
+
}.
|
81
|
+
|
82
|
+
on(:command, :save) {
|
83
|
+
child = window.activeChild
|
84
|
+
|
85
|
+
(child.text == 'Untitled') ?
|
86
|
+
window.sendmsg(:command, Command[:saveAs]) :
|
87
|
+
File.open(child.text, 'w') { |f| f << child[:sci].text; child[:sci].dirty = false }
|
88
|
+
}.
|
89
|
+
|
90
|
+
on(:command, :saveAll) {
|
91
|
+
window.client.eachChild { |child|
|
92
|
+
next unless child.kind_of?(MDIChild)
|
93
|
+
|
94
|
+
window.
|
95
|
+
activate(child).
|
96
|
+
sendmsg(:command, Command[:save])
|
97
|
+
}
|
98
|
+
}.
|
99
|
+
|
100
|
+
on(:initmenupopup) {
|
101
|
+
child = window.activeChild
|
102
|
+
|
103
|
+
[:save, :saveAs].each { |command| window.menu[command].enabled = !child.nil? }
|
21
104
|
}.
|
22
105
|
|
23
106
|
on(:close) {
|
107
|
+
dirties = []
|
108
|
+
|
24
109
|
window.client.eachChild { |child|
|
25
|
-
|
110
|
+
next unless child.kind_of?(MDIChild)
|
111
|
+
|
112
|
+
dirties << child if child[:sci].dirty?
|
26
113
|
}
|
27
114
|
|
28
|
-
|
115
|
+
if dirties.length > 0
|
116
|
+
answer = window.question(%Q{
|
117
|
+
File#{(dirties.length > 1) ? 's' : ''} not saved:
|
118
|
+
#{dirties.map(&:text).join("\n ")}
|
119
|
+
|
120
|
+
Press Yes to save #{(dirties.length > 1) ? 'them' : 'it'} and close the application
|
121
|
+
Press No to close the application without saving
|
122
|
+
Press Cancel to leave the application open
|
123
|
+
}, buttons: [:yes, :no, :Cancel], icon: :warning)
|
124
|
+
|
125
|
+
window.sendmsg(:command, Command[:saveAll]) if answer.yes?
|
126
|
+
|
127
|
+
window.dispose unless answer.cancel?
|
128
|
+
else
|
129
|
+
window.dispose
|
130
|
+
end
|
29
131
|
}
|
30
132
|
}
|
@@ -2,44 +2,44 @@ require 'fzeet'
|
|
2
2
|
|
3
3
|
include Fzeet::Windows
|
4
4
|
|
5
|
-
|
6
|
-
|
5
|
+
Fzeet::Application.run { |window|
|
6
|
+
def onItem1(*args)
|
7
|
+
Fzeet.message __method__
|
7
8
|
|
8
|
-
|
9
|
-
|
10
|
-
end
|
9
|
+
UIF.SetUICommandProperty(CmdButton1, UI_PKEY_Enabled, PROPVARIANT[:bool, true])
|
10
|
+
UIF.SetUICommandProperty(CmdItem1, UI_PKEY_Enabled, PROPVARIANT[:bool, false])
|
11
|
+
end
|
11
12
|
|
12
|
-
def onButton1(*args)
|
13
|
-
|
13
|
+
def onButton1(*args)
|
14
|
+
Fzeet.message __method__
|
14
15
|
|
15
|
-
|
16
|
-
|
17
|
-
end
|
16
|
+
UIF.SetUICommandProperty(CmdItem1, UI_PKEY_Enabled, PROPVARIANT[:bool, true])
|
17
|
+
UIF.SetUICommandProperty(CmdButton1, UI_PKEY_Enabled, PROPVARIANT[:bool, false])
|
18
|
+
end
|
18
19
|
|
19
|
-
UICH = UICommandHandler.new
|
20
|
+
UICH = UICommandHandler.new
|
20
21
|
|
21
|
-
def UICH.Execute(*args)
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
22
|
+
def UICH.Execute(*args)
|
23
|
+
case args[0]
|
24
|
+
when CmdItem1
|
25
|
+
onItem1(*args)
|
26
|
+
when CmdButton1
|
27
|
+
onButton1(*args)
|
28
|
+
end
|
28
29
|
|
29
|
-
|
30
|
-
end
|
30
|
+
S_OK
|
31
|
+
end
|
31
32
|
|
32
|
-
UIA = UIApplication.new
|
33
|
+
UIA = UIApplication.new
|
33
34
|
|
34
|
-
def UIA.OnCreateUICommand(*args)
|
35
|
-
|
35
|
+
def UIA.OnCreateUICommand(*args)
|
36
|
+
UICH.QueryInterface(UICH.class::IID, args[-1])
|
36
37
|
|
37
|
-
|
38
|
-
end
|
38
|
+
S_OK
|
39
|
+
end
|
39
40
|
|
40
|
-
UIF = UIFramework.new
|
41
|
+
UIF = UIFramework.new
|
41
42
|
|
42
|
-
Fzeet::Application.run { |window|
|
43
43
|
UIF.Initialize(window.handle, UIA)
|
44
44
|
UIF.LoadUI(LoadRibbonDll(), "APPLICATION_RIBBON\0".encode('utf-16le'))
|
45
45
|
|
@@ -2,32 +2,32 @@ require 'fzeet'
|
|
2
2
|
|
3
3
|
include Fzeet::Windows
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
Fzeet::Application.run { |window|
|
6
|
+
def onButton1(*args)
|
7
|
+
Fzeet.message __method__
|
8
|
+
end
|
8
9
|
|
9
|
-
UICH = UICommandHandler.new
|
10
|
+
UICH = UICommandHandler.new
|
10
11
|
|
11
|
-
def UICH.Execute(*args)
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
12
|
+
def UICH.Execute(*args)
|
13
|
+
case args[0]
|
14
|
+
when CmdButton1
|
15
|
+
onButton1(*args)
|
16
|
+
end
|
16
17
|
|
17
|
-
|
18
|
-
end
|
18
|
+
S_OK
|
19
|
+
end
|
19
20
|
|
20
|
-
UIA = UIApplication.new
|
21
|
+
UIA = UIApplication.new
|
21
22
|
|
22
|
-
def UIA.OnCreateUICommand(*args)
|
23
|
-
|
23
|
+
def UIA.OnCreateUICommand(*args)
|
24
|
+
UICH.QueryInterface(UICH.class::IID, args[-1])
|
24
25
|
|
25
|
-
|
26
|
-
end
|
26
|
+
S_OK
|
27
|
+
end
|
27
28
|
|
28
|
-
UIF = UIFramework.new
|
29
|
+
UIF = UIFramework.new
|
29
30
|
|
30
|
-
Fzeet::Application.run { |window|
|
31
31
|
UIF.Initialize(window.handle, UIA)
|
32
32
|
UIF.LoadUI(LoadRibbonDll(), "APPLICATION_RIBBON\0".encode('utf-16le'))
|
33
33
|
|
data/lib/fzeet/Control/Common.rb
CHANGED
@@ -60,9 +60,24 @@ module Fzeet
|
|
60
60
|
handlers.each { |k, v| on(k, &v) }
|
61
61
|
|
62
62
|
case _opts[:anchor]
|
63
|
-
when :ltr
|
64
|
-
|
65
|
-
|
63
|
+
when :ltr
|
64
|
+
@parent.on(:size) { |args|
|
65
|
+
self.position = @parent.rect.tap { |r| r[:bottom] = _opts[:height] }.to_a
|
66
|
+
|
67
|
+
args[:result] = nil if @parent.class == MDIChild
|
68
|
+
}
|
69
|
+
when :lrb
|
70
|
+
@parent.on(:size) { |args|
|
71
|
+
self.position = @parent.rect.tap { |r| r[:top] = r[:bottom] - _opts[:height]; r[:bottom] = _opts[:height] }.to_a
|
72
|
+
|
73
|
+
args[:result] = nil if @parent.class == MDIChild
|
74
|
+
}
|
75
|
+
when :ltrb
|
76
|
+
@parent.on(:size) { |args|
|
77
|
+
self.position = @parent.rect.to_a
|
78
|
+
|
79
|
+
args[:result] = nil if @parent.class == MDIChild
|
80
|
+
}
|
66
81
|
else raise ArgumentError, "Bad anchor spec: #{_opts[:anchor]}."
|
67
82
|
end if _opts[:anchor]
|
68
83
|
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require_relative 'Common'
|
2
|
+
|
3
|
+
module Fzeet
|
4
|
+
class ExplorerBrowser < Windows::ExplorerBrowser
|
5
|
+
def initialize(parent)
|
6
|
+
@parent = parent
|
7
|
+
|
8
|
+
super()
|
9
|
+
|
10
|
+
@events = Windows::ExplorerBrowserEvents.new
|
11
|
+
|
12
|
+
@events.instance_variable_set(:@browser, self)
|
13
|
+
|
14
|
+
class << @events
|
15
|
+
attr_reader :browser
|
16
|
+
|
17
|
+
def OnNavigationPending(*args)
|
18
|
+
Windows::S_OK
|
19
|
+
end
|
20
|
+
|
21
|
+
def OnViewCreated(*args)
|
22
|
+
Windows::S_OK
|
23
|
+
end
|
24
|
+
|
25
|
+
def OnNavigationComplete(*args)
|
26
|
+
Windows::S_OK
|
27
|
+
end
|
28
|
+
|
29
|
+
def OnNavigationFailed(*args)
|
30
|
+
Windows::S_OK
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
@cookie = nil
|
35
|
+
FFI::MemoryPointer.new(:ulong) { |p| Advise(@events, p); @cookie = p.get_ulong(0) }
|
36
|
+
|
37
|
+
Initialize(@parent.handle, parent.rect, nil)
|
38
|
+
|
39
|
+
@parent.
|
40
|
+
on(:size) { SetRect(nil, @parent.rect) }.
|
41
|
+
on(:destroy) { Unadvise(@cookie); @events.Release; Destroy(); Release() }.
|
42
|
+
|
43
|
+
instance_variable_set(:@__ExplorerBrowser__, self)
|
44
|
+
end
|
45
|
+
|
46
|
+
attr_reader :parent, :events
|
47
|
+
|
48
|
+
def goto(where)
|
49
|
+
pidl = nil
|
50
|
+
|
51
|
+
FFI::MemoryPointer.new(:pointer) { |p|
|
52
|
+
Windows.SHGetKnownFolderIDList(Windows.const_get("FOLDERID_#{where}"), 0, nil, p)
|
53
|
+
|
54
|
+
BrowseToIDList(pidl = p.read_pointer, 0)
|
55
|
+
}
|
56
|
+
|
57
|
+
self
|
58
|
+
ensure
|
59
|
+
Windows.CoTaskMemFree(pidl)
|
60
|
+
end
|
61
|
+
|
62
|
+
def back; BrowseToIDList(nil, Windows::SBSP_NAVIGATEBACK); self end
|
63
|
+
def forward; BrowseToIDList(nil, Windows::SBSP_NAVIGATEFORWARD); self end
|
64
|
+
def up; BrowseToIDList(nil, Windows::SBSP_PARENT); self end
|
65
|
+
end
|
66
|
+
end
|
@@ -39,6 +39,9 @@ module Fzeet
|
|
39
39
|
|
40
40
|
def tabWidth; sendmsg(:gettabwidth) end
|
41
41
|
def tabWidth=(tabWidth) sendmsg(:settabwidth, tabWidth) end
|
42
|
+
|
43
|
+
def dirty?; @dirty end
|
44
|
+
def dirty=(dirty) (dirty) ? @dirty = true : sendmsg(:setsavepoint) end
|
42
45
|
end
|
43
46
|
|
44
47
|
class Scintilla < Control
|
@@ -88,6 +91,11 @@ module Fzeet
|
|
88
91
|
def initialize(parent, id, opts = {}, &block)
|
89
92
|
super('Scintilla', parent, id, opts)
|
90
93
|
|
94
|
+
@dirty = false
|
95
|
+
|
96
|
+
on(:savepointleft) { @dirty = true }
|
97
|
+
on(:savepointreached) { @dirty = false }
|
98
|
+
|
91
99
|
@parent.on(:notify, @id, &block) if block
|
92
100
|
end
|
93
101
|
|
@@ -0,0 +1,174 @@
|
|
1
|
+
require_relative 'Common'
|
2
|
+
|
3
|
+
module Fzeet
|
4
|
+
class WebBrowser < Windows::WebBrowser
|
5
|
+
def initialize(parent)
|
6
|
+
@parent = parent
|
7
|
+
|
8
|
+
@oips = Windows::OleInPlaceSite.new
|
9
|
+
|
10
|
+
@oips.instance_variable_set(:@browser, self)
|
11
|
+
|
12
|
+
class << @oips
|
13
|
+
attr_reader :browser
|
14
|
+
|
15
|
+
def CanInPlaceActivate
|
16
|
+
Windows::S_OK
|
17
|
+
end
|
18
|
+
|
19
|
+
def GetWindow(phwnd)
|
20
|
+
phwnd.write_pointer(browser.parent.handle)
|
21
|
+
|
22
|
+
Windows::S_OK
|
23
|
+
end
|
24
|
+
|
25
|
+
def GetWindowContext(pframe, pdoc, prPos, prClip, pinfo)
|
26
|
+
pframe.write_pointer(0)
|
27
|
+
pdoc.write_pointer(0)
|
28
|
+
Windows.GetClientRect(browser.parent.handle, prPos)
|
29
|
+
Windows.GetClientRect(browser.parent.handle, prClip)
|
30
|
+
|
31
|
+
Windows::S_OK
|
32
|
+
end
|
33
|
+
|
34
|
+
def OnPosRectChange(prPos)
|
35
|
+
browser.QueryInstance(Windows::OleInPlaceObject) { |oipo|
|
36
|
+
oipo.SetObjectRects(prPos, prPos)
|
37
|
+
}
|
38
|
+
|
39
|
+
Windows::S_OK
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
@ocs = Windows::OleClientSite.new
|
44
|
+
|
45
|
+
@ocs.instance_variable_set(:@browser, self)
|
46
|
+
|
47
|
+
class << @ocs
|
48
|
+
attr_reader :browser
|
49
|
+
|
50
|
+
def QueryInterface(piid, ppv)
|
51
|
+
if Windows::GUID.new(piid) == Windows::IOleInPlaceSite::IID
|
52
|
+
ppv.write_pointer(browser.oips); browser.oips.AddRef
|
53
|
+
|
54
|
+
return Windows::S_OK
|
55
|
+
end
|
56
|
+
|
57
|
+
super
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
super()
|
62
|
+
|
63
|
+
@events = Windows::WebBrowserEvents.new
|
64
|
+
|
65
|
+
@events.instance_variable_set(:@browser, self)
|
66
|
+
|
67
|
+
class << @events
|
68
|
+
attr_reader :browser
|
69
|
+
|
70
|
+
bstrs = []
|
71
|
+
|
72
|
+
params = Class.new(FFI::Struct) {
|
73
|
+
layout \
|
74
|
+
:array, [Windows::PARAMDATA, 1]
|
75
|
+
}.new
|
76
|
+
|
77
|
+
param1 = params[:array][0]
|
78
|
+
|
79
|
+
param1[:szName] = bstrs.push(Windows::SysAllocString("URL\0".encode('utf-16le'))).last
|
80
|
+
param1[:vt] = Windows::VT_BSTR
|
81
|
+
|
82
|
+
methods = Class.new(FFI::Struct) {
|
83
|
+
layout \
|
84
|
+
:array, [Windows::METHODDATA, 1]
|
85
|
+
}.new
|
86
|
+
|
87
|
+
method1 = methods[:array][0]
|
88
|
+
|
89
|
+
method1[:szName] = bstrs.push(Windows::SysAllocString("NavigateComplete\0".encode('utf-16le'))).last
|
90
|
+
method1[:ppdata] = params[:array]
|
91
|
+
method1[:dispid] = Windows::DISPID_NAVIGATECOMPLETE
|
92
|
+
method1[:iMeth] = 8
|
93
|
+
method1[:cc] = Windows::CC_STDCALL
|
94
|
+
method1[:cArgs] = 1
|
95
|
+
method1[:wFlags] = Windows::DISPATCH_METHOD
|
96
|
+
method1[:vtReturn] = Windows::VT_EMPTY
|
97
|
+
|
98
|
+
interface = Windows::INTERFACEDATA.new
|
99
|
+
|
100
|
+
interface[:pmethdata] = methods[:array]
|
101
|
+
interface[:cMembers] = 1
|
102
|
+
|
103
|
+
FFI::MemoryPointer.new(:pointer) { |pinfo|
|
104
|
+
Windows.DetonateHresult(:CreateDispTypeInfo, interface, Windows.GetSystemDefaultLCID, pinfo)
|
105
|
+
|
106
|
+
TypeInfo = pinfo.read_pointer
|
107
|
+
}
|
108
|
+
|
109
|
+
bstrs.each { |bstr| Windows.SysFreeString(bstr) }
|
110
|
+
|
111
|
+
def Invoke(dispid, *rest)
|
112
|
+
return Windows::E_NOTIMPL unless dispid == Windows::DISPID_NAVIGATECOMPLETE
|
113
|
+
|
114
|
+
Windows.DetonateHresult(:DispInvoke, self, TypeInfo, dispid, *rest[2..-1])
|
115
|
+
|
116
|
+
Windows::S_OK
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
QueryInstance(Windows::ConnectionPointContainer) { |cpc|
|
121
|
+
FFI::MemoryPointer.new(:pointer) { |pcp|
|
122
|
+
cpc.FindConnectionPoint(Windows::WebBrowserEvents::IID, pcp)
|
123
|
+
|
124
|
+
@cp = Windows::ConnectionPoint.new(pcp.read_pointer)
|
125
|
+
}
|
126
|
+
}
|
127
|
+
|
128
|
+
@cookie = nil
|
129
|
+
FFI::MemoryPointer.new(:ulong) { |p| @cp.Advise(@events, p); @cookie = p.get_ulong(0) }
|
130
|
+
|
131
|
+
QueryInstance(Windows::OleObject) { |oo|
|
132
|
+
oo.SetClientSite(@ocs)
|
133
|
+
oo.DoVerb(Windows::OLEIVERB_INPLACEACTIVATE, nil, @ocs, 0, @parent.handle, @parent.rect)
|
134
|
+
}
|
135
|
+
|
136
|
+
@parent.
|
137
|
+
on(:size) {
|
138
|
+
r = @parent.rect
|
139
|
+
|
140
|
+
put_Top(r[:top]); put_Left(r[:left]); put_Width(r[:right]); put_Height(r[:bottom])
|
141
|
+
}.
|
142
|
+
|
143
|
+
on(:destroy) {
|
144
|
+
@oips.Release
|
145
|
+
@ocs.Release
|
146
|
+
@cp.Unadvise(@cookie)
|
147
|
+
@events.Release
|
148
|
+
@cp.Release
|
149
|
+
Release()
|
150
|
+
}.
|
151
|
+
|
152
|
+
instance_variable_set(:@__WebBrowser__, self)
|
153
|
+
end
|
154
|
+
|
155
|
+
attr_reader :parent, :oips, :ocs, :events, :cp
|
156
|
+
|
157
|
+
def goto(where)
|
158
|
+
where = Windows.SysAllocString("#{where}\0".encode('utf-16le'))
|
159
|
+
|
160
|
+
Navigate(where, nil, nil, nil, nil)
|
161
|
+
|
162
|
+
self
|
163
|
+
ensure
|
164
|
+
Windows.SysFreeString(where)
|
165
|
+
end
|
166
|
+
|
167
|
+
def back; GoBack(); self; rescue; self end
|
168
|
+
def forward; GoForward(); self; rescue; self end
|
169
|
+
def home; GoHome(); self end
|
170
|
+
def search; GoSearch(); self end
|
171
|
+
|
172
|
+
def refresh; Refresh(); self end
|
173
|
+
end
|
174
|
+
end
|
data/lib/fzeet/Control.rb
CHANGED
@@ -15,3 +15,5 @@ require_relative 'Control/TreeView'
|
|
15
15
|
require_relative 'Control/ProgressBar'
|
16
16
|
require_relative 'Control/PropertySheet'
|
17
17
|
require_relative 'Control/Tab'
|
18
|
+
require_relative 'Control/ExplorerBrowser' if Fzeet::Windows::WINVER.AtLeastWindowsVista?
|
19
|
+
require_relative 'Control/WebBrowser'
|
@@ -31,7 +31,7 @@ module Fzeet
|
|
31
31
|
@struct[:hInstance] = Windows.GetModuleHandle(nil)
|
32
32
|
@struct[:lpstrFile] = @buf = FFI::MemoryPointer.new(:char, 4096)
|
33
33
|
@struct[:nMaxFile] = @buf.size
|
34
|
-
@struct[:Flags] = Fzeet.flags([:enablehook, :explorer, :enablesizing] + [*_opts[:flags]], :ofn_)
|
34
|
+
@struct[:Flags] = Fzeet.flags([:enablehook, :explorer, :enablesizing, :overwriteprompt] + [*_opts[:flags]], :ofn_)
|
35
35
|
@struct[:lCustData] = object_id
|
36
36
|
@struct[:lpfnHook] = HookProc
|
37
37
|
|
@@ -70,6 +70,12 @@ module Fzeet
|
|
70
70
|
|
71
71
|
result.map! { |name| "#{path}\\#{name}" }
|
72
72
|
end
|
73
|
+
|
74
|
+
def multiselect=(multiselect)
|
75
|
+
(multiselect) ?
|
76
|
+
@struct[:Flags] |= Windows::OFN_ALLOWMULTISELECT :
|
77
|
+
@struct[:Flags] &= ~Windows::OFN_ALLOWMULTISELECT
|
78
|
+
end
|
73
79
|
end
|
74
80
|
|
75
81
|
class FileSaveDialog < FileDialog
|
@@ -59,6 +59,18 @@ module Fzeet
|
|
59
59
|
Release()
|
60
60
|
end if block_given?
|
61
61
|
end
|
62
|
+
|
63
|
+
def multiselect=(multiselect)
|
64
|
+
if multiselect
|
65
|
+
SetOptions(Windows::FOS_ALLOWMULTISELECT)
|
66
|
+
else
|
67
|
+
opts = nil
|
68
|
+
|
69
|
+
FFI::MemoryPointer.new(:pointer) { |p| GetOptions(p); opts = p.get_ulong(0) }
|
70
|
+
|
71
|
+
SetOptions(opts & ~Windows::FOS_ALLOWMULTISELECT)
|
72
|
+
end
|
73
|
+
end
|
62
74
|
end
|
63
75
|
|
64
76
|
class ShellFileSaveDialog < Windows::FileSaveDialog
|