зеркало из https://github.com/github/ruby.git
* ext/win32ole/win32ole.c (Init_win32ole): add
WIN32OLE_EVENT#handler=, WIN32OLE_EVENT#handler * test/win32ole/test_win32ole_event.rb: ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@18225 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
Родитель
b403a1760c
Коммит
2e400ad1b8
|
@ -1,3 +1,10 @@
|
|||
Sat Jul 26 21:17:18 2008 Masaki Suketa <masaki.suketa@nifty.ne.jp>
|
||||
|
||||
* ext/win32ole/win32ole.c (Init_win32ole): add
|
||||
WIN32OLE_EVENT#handler=, WIN32OLE_EVENT#handler
|
||||
|
||||
* test/win32ole/test_win32ole_event.rb: ditto.
|
||||
|
||||
Sat Jul 26 07:44:14 2008 Masaki Suketa <masaki.suketa@nifty.ne.jp>
|
||||
|
||||
* ext/win32ole/win32ole.c (add_event_call_back): remove unused
|
||||
|
|
|
@ -118,7 +118,7 @@
|
|||
|
||||
#define WC2VSTR(x) ole_wc2vstr((x), TRUE)
|
||||
|
||||
#define WIN32OLE_VERSION "1.2.9"
|
||||
#define WIN32OLE_VERSION "1.3.0"
|
||||
|
||||
typedef HRESULT (STDAPICALLTYPE FNCOCREATEINSTANCEEX)
|
||||
(REFCLSID, IUnknown*, DWORD, COSERVERINFO*, DWORD, MULTI_QI*);
|
||||
|
@ -499,6 +499,7 @@ static VALUE foleparam_default(VALUE self);
|
|||
static VALUE foleparam_inspect(VALUE self);
|
||||
static long ole_search_event_at(VALUE ary, VALUE ev);
|
||||
static VALUE ole_search_event(VALUE ary, VALUE ev, BOOL *is_default);
|
||||
static VALUE ole_search_handler_method(VALUE handler, VALUE ev, BOOL *is_default_handler);
|
||||
static void ole_delete_event(VALUE ary, VALUE ev);
|
||||
static void hash2ptr_dispparams(VALUE hash, ITypeInfo *pTypeInfo, DISPID dispid, DISPPARAMS *pdispparams);
|
||||
static VALUE hash2result(VALUE hash);
|
||||
|
@ -520,6 +521,8 @@ static VALUE fev_on_event(int argc, VALUE *argv, VALUE self);
|
|||
static VALUE fev_on_event_with_outargs(int argc, VALUE *argv, VALUE self);
|
||||
static VALUE fev_off_event(int argc, VALUE *argv, VALUE self);
|
||||
static VALUE fev_unadvise(VALUE self);
|
||||
static VALUE fev_set_handler(VALUE self, VALUE val);
|
||||
static VALUE fev_get_handler(VALUE self);
|
||||
static VALUE evs_push(VALUE ev);
|
||||
static VALUE evs_delete(long i);
|
||||
static VALUE evs_entry(long i);
|
||||
|
@ -7434,6 +7437,23 @@ ole_search_event(VALUE ary, VALUE ev, BOOL *is_default)
|
|||
}
|
||||
return def_event;
|
||||
}
|
||||
static VALUE
|
||||
ole_search_handler_method(VALUE handler, VALUE ev, BOOL *is_default_handler)
|
||||
{
|
||||
VALUE mid;
|
||||
|
||||
*is_default_handler = FALSE;
|
||||
mid = rb_to_id(rb_sprintf("on%s", StringValuePtr(ev)));
|
||||
if (rb_respond_to(handler, mid)) {
|
||||
return mid;
|
||||
}
|
||||
mid = rb_intern("method_missing");
|
||||
if (rb_respond_to(handler, mid)) {
|
||||
*is_default_handler = TRUE;
|
||||
return mid;
|
||||
}
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
static void
|
||||
ole_delete_event(VALUE ary, VALUE ev)
|
||||
|
@ -7502,8 +7522,9 @@ exec_callback(VALUE arg)
|
|||
{
|
||||
VALUE *parg = (VALUE *)arg;
|
||||
VALUE handler = parg[0];
|
||||
VALUE args = parg[1];
|
||||
return rb_apply(handler, rb_intern("call"), args);
|
||||
VALUE mid = parg[1];
|
||||
VALUE args = parg[2];
|
||||
return rb_apply(handler, mid, args);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
|
@ -7540,9 +7561,11 @@ STDMETHODIMP EVENTSINK_Invoke(
|
|||
unsigned int i;
|
||||
ITypeInfo *pTypeInfo;
|
||||
VARIANT *pvar;
|
||||
VALUE ary, obj, event, handler, args, outargv, ev, result;
|
||||
VALUE arg[2];
|
||||
VALUE is_outarg;
|
||||
VALUE ary, obj, event, args, outargv, ev, result;
|
||||
VALUE handler = Qnil;
|
||||
VALUE arg[3];
|
||||
VALUE mid;
|
||||
VALUE is_outarg = Qfalse;
|
||||
BOOL is_default_handler = FALSE;
|
||||
int state;
|
||||
|
||||
|
@ -7564,9 +7587,21 @@ STDMETHODIMP EVENTSINK_Invoke(
|
|||
}
|
||||
ev = WC2VSTR(bstr);
|
||||
event = ole_search_event(ary, ev, &is_default_handler);
|
||||
if (NIL_P(event)) {
|
||||
return NOERROR;
|
||||
if (TYPE(event) == T_ARRAY) {
|
||||
handler = rb_ary_entry(event, 0);
|
||||
mid = rb_intern("call");
|
||||
is_outarg = rb_ary_entry(event, 3);
|
||||
} else {
|
||||
handler = rb_ivar_get(obj, rb_intern("handler"));
|
||||
if (handler == Qnil) {
|
||||
return NOERROR;
|
||||
}
|
||||
mid = ole_search_handler_method(handler, ev, &is_default_handler);
|
||||
}
|
||||
if (handler == Qnil || mid == Qnil) {
|
||||
return NOERROR;
|
||||
}
|
||||
|
||||
args = rb_ary_new();
|
||||
if (is_default_handler) {
|
||||
rb_ary_push(args, ev);
|
||||
|
@ -7577,8 +7612,6 @@ STDMETHODIMP EVENTSINK_Invoke(
|
|||
pvar = &pdispparams->rgvarg[pdispparams->cArgs-i-1];
|
||||
rb_ary_push(args, ole_variant2val(pvar));
|
||||
}
|
||||
handler = rb_ary_entry(event, 0);
|
||||
is_outarg = rb_ary_entry(event, 3);
|
||||
outargv = Qnil;
|
||||
if (is_outarg == Qtrue) {
|
||||
outargv = rb_ary_new();
|
||||
|
@ -7593,7 +7626,8 @@ STDMETHODIMP EVENTSINK_Invoke(
|
|||
* and exit ruby process by Win32OLE itself.
|
||||
*/
|
||||
arg[0] = handler;
|
||||
arg[1] = args;
|
||||
arg[1] = mid;
|
||||
arg[2] = args;
|
||||
result = rb_protect(exec_callback, (VALUE)arg, &state);
|
||||
if (state != 0) {
|
||||
rescue_callback(Qnil);
|
||||
|
@ -8260,6 +8294,64 @@ evs_length()
|
|||
return rb_funcall(ary_ole_event, rb_intern("length"), 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* WIN32OLE_EVENT#handler=
|
||||
*
|
||||
* sets event handler object. If handler object has onXXX
|
||||
* method according to XXX event, then onXXX method is called
|
||||
* when XXX event occurs.
|
||||
*
|
||||
* If handler object has method_missing and there is no
|
||||
* method according to the event, then method_missing
|
||||
* called and 1-st argument is event name.
|
||||
*
|
||||
* If handler object has onXXX method and there is block
|
||||
* defined by WIN32OLE_EVENT#on_event('XXX'){},
|
||||
* then block is executed but handler object method is not called
|
||||
* when XXX event occurs.
|
||||
*
|
||||
* class Handler
|
||||
* def onStatusTextChange(text)
|
||||
* puts "StatusTextChanged"
|
||||
* end
|
||||
* def onPropertyChange(prop)
|
||||
* puts "PropertyChanged"
|
||||
* end
|
||||
* def method_missing(ev, *arg)
|
||||
* puts "other event #{ev}"
|
||||
* end
|
||||
* end
|
||||
*
|
||||
* handler = Handler.new
|
||||
* ie = WIN32OLE.new('InternetExplorer.Application')
|
||||
* ev = WIN32OLE_EVENT.new(ie)
|
||||
* ev.on_event("StatusTextChange") {|*args|
|
||||
* puts "this block executed."
|
||||
* puts "handler.onStatusTextChange method is not called."
|
||||
* }
|
||||
* ev.handler = handler
|
||||
*
|
||||
*/
|
||||
static VALUE
|
||||
fev_set_handler(VALUE self, VALUE val)
|
||||
{
|
||||
return rb_ivar_set(self, rb_intern("handler"), val);
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* WIN32OLE_EVENT#handler
|
||||
*
|
||||
* returns handler object.
|
||||
*
|
||||
*/
|
||||
static VALUE
|
||||
fev_get_handler(VALUE self)
|
||||
{
|
||||
return rb_ivar_get(self, rb_intern("handler"));
|
||||
}
|
||||
|
||||
static void
|
||||
olevariant_free(struct olevariantdata *pvar)
|
||||
{
|
||||
|
@ -8896,6 +8988,8 @@ Init_win32ole()
|
|||
rb_define_method(cWIN32OLE_EVENT, "on_event_with_outargs", fev_on_event_with_outargs, -1);
|
||||
rb_define_method(cWIN32OLE_EVENT, "off_event", fev_off_event, -1);
|
||||
rb_define_method(cWIN32OLE_EVENT, "unadvise", fev_unadvise, 0);
|
||||
rb_define_method(cWIN32OLE_EVENT, "handler=", fev_set_handler, 1);
|
||||
rb_define_method(cWIN32OLE_EVENT, "handler", fev_get_handler, 0);
|
||||
|
||||
cWIN32OLE_VARIANT = rb_define_class("WIN32OLE_VARIANT", rb_cObject);
|
||||
rb_define_alloc_func(cWIN32OLE_VARIANT, folevariant_s_allocate);
|
||||
|
|
|
@ -6,6 +6,8 @@ require 'test/unit'
|
|||
|
||||
if defined?(WIN32OLE_EVENT)
|
||||
class TestWIN32OLE_EVENT < Test::Unit::TestCase
|
||||
module IE
|
||||
end
|
||||
def create_temp_html
|
||||
fso = WIN32OLE.new('Scripting.FileSystemObject')
|
||||
dummy_file = fso.GetTempName + ".html"
|
||||
|
@ -22,10 +24,18 @@ if defined?(WIN32OLE_EVENT)
|
|||
sleep 0.1
|
||||
end
|
||||
|
||||
def wait_ie
|
||||
while @ie.readyState != IE::READYSTATE_COMPLETE
|
||||
message_loop
|
||||
end
|
||||
end
|
||||
|
||||
def setup
|
||||
WIN32OLE_EVENT.message_loop
|
||||
@ie = WIN32OLE.new("InternetExplorer.Application")
|
||||
message_loop
|
||||
if !defined?(IE::READYSTATE_COMPLETE)
|
||||
WIN32OLE.const_load(@ie, IE)
|
||||
end
|
||||
@ie.visible = true
|
||||
message_loop
|
||||
@event = ""
|
||||
|
@ -61,11 +71,7 @@ if defined?(WIN32OLE_EVENT)
|
|||
ev = WIN32OLE_EVENT.new(@ie, 'DWebBrowserEvents')
|
||||
ev.on_event {|*args| default_handler(*args)}
|
||||
@ie.navigate("file:///#{@f}")
|
||||
while @ie.busy
|
||||
WIN32OLE_EVENT.new(@ie, 'DWebBrowserEvents')
|
||||
GC.start
|
||||
message_loop
|
||||
end
|
||||
wait_ie
|
||||
assert_match(/BeforeNavigate/, @event)
|
||||
assert_match(/NavigateComplete/, @event)
|
||||
end
|
||||
|
@ -75,9 +81,7 @@ if defined?(WIN32OLE_EVENT)
|
|||
ev.on_event('BeforeNavigate') {|*args| handler1}
|
||||
ev.on_event('BeforeNavigate') {|*args| handler2}
|
||||
@ie.navigate("file:///#{@f}")
|
||||
while @ie.busy
|
||||
message_loop
|
||||
end
|
||||
wait_ie
|
||||
assert_equal("handler2", @event2)
|
||||
end
|
||||
|
||||
|
@ -86,9 +90,7 @@ if defined?(WIN32OLE_EVENT)
|
|||
ev.on_event {|*args| handler1}
|
||||
ev.on_event {|*args| handler2}
|
||||
@ie.navigate("file:///#{@f}")
|
||||
while @ie.busy
|
||||
message_loop
|
||||
end
|
||||
wait_ie
|
||||
assert_equal("handler2", @event2)
|
||||
end
|
||||
|
||||
|
@ -98,9 +100,7 @@ if defined?(WIN32OLE_EVENT)
|
|||
ev.on_event{|*args| handler2}
|
||||
ev.on_event('NavigateComplete'){|*args| handler3(*args)}
|
||||
@ie.navigate("file:///#{@f}")
|
||||
while @ie.busy
|
||||
message_loop
|
||||
end
|
||||
wait_ie
|
||||
assert(@event3!="")
|
||||
assert("handler2", @event2)
|
||||
end
|
||||
|
@ -110,9 +110,7 @@ if defined?(WIN32OLE_EVENT)
|
|||
ev.on_event {|*args| default_handler(*args)}
|
||||
ev.on_event('NavigateComplete'){|*args| handler3(*args)}
|
||||
@ie.navigate("file:///#{@f}")
|
||||
while @ie.busy
|
||||
message_loop
|
||||
end
|
||||
wait_ie
|
||||
assert_match(/BeforeNavigate/, @event)
|
||||
assert(/NavigateComplete/ !~ @event)
|
||||
assert(@event!="")
|
||||
|
@ -122,16 +120,12 @@ if defined?(WIN32OLE_EVENT)
|
|||
ev = WIN32OLE_EVENT.new(@ie, 'DWebBrowserEvents')
|
||||
ev.on_event {|*args| default_handler(*args)}
|
||||
@ie.navigate("file:///#{@f}")
|
||||
while @ie.busy
|
||||
message_loop
|
||||
end
|
||||
wait_ie
|
||||
assert_match(/BeforeNavigate/, @event)
|
||||
ev.unadvise
|
||||
@event = ""
|
||||
@ie.navigate("file:///#{@f}")
|
||||
while @ie.busy
|
||||
message_loop
|
||||
end
|
||||
wait_ie
|
||||
assert_equal("", @event);
|
||||
assert_raise(WIN32OLERuntimeError) {
|
||||
ev.on_event {|*args| default_handler(*args)}
|
||||
|
@ -158,9 +152,7 @@ if defined?(WIN32OLE_EVENT)
|
|||
}
|
||||
bl = @ie.locationURL
|
||||
@ie.navigate("file:///#{@f}")
|
||||
while @ie.busy
|
||||
message_loop
|
||||
end
|
||||
wait_ie
|
||||
assert_equal(bl, @ie.locationURL)
|
||||
end
|
||||
|
||||
|
@ -171,9 +163,7 @@ if defined?(WIN32OLE_EVENT)
|
|||
}
|
||||
bl = @ie.locationURL
|
||||
@ie.navigate("file:///#{@f}")
|
||||
while @ie.busy
|
||||
message_loop
|
||||
end
|
||||
wait_ie
|
||||
assert_equal(bl, @ie.locationURL)
|
||||
end
|
||||
|
||||
|
@ -184,9 +174,7 @@ if defined?(WIN32OLE_EVENT)
|
|||
}
|
||||
bl = @ie.locationURL
|
||||
@ie.navigate("file:///#{@f}")
|
||||
while @ie.busy
|
||||
message_loop
|
||||
end
|
||||
wait_ie
|
||||
assert_equal(bl, @ie.locationURL)
|
||||
end
|
||||
|
||||
|
@ -197,9 +185,7 @@ if defined?(WIN32OLE_EVENT)
|
|||
}
|
||||
bl = @ie.locationURL
|
||||
@ie.navigate("file:///#{@f}")
|
||||
while @ie.busy
|
||||
message_loop
|
||||
end
|
||||
wait_ie
|
||||
assert_equal(bl, @ie.locationURL)
|
||||
end
|
||||
|
||||
|
@ -210,9 +196,7 @@ if defined?(WIN32OLE_EVENT)
|
|||
}
|
||||
bl = @ie.locationURL
|
||||
@ie.navigate("file:///#{@f}")
|
||||
while @ie.busy
|
||||
message_loop
|
||||
end
|
||||
wait_ie
|
||||
assert_equal(bl, @ie.locationURL)
|
||||
end
|
||||
|
||||
|
@ -223,9 +207,7 @@ if defined?(WIN32OLE_EVENT)
|
|||
}
|
||||
bl = @ie.locationURL
|
||||
@ie.navigate("file:///#{@f}")
|
||||
while @ie.busy
|
||||
message_loop
|
||||
end
|
||||
wait_ie
|
||||
assert_equal(bl, @ie.locationURL)
|
||||
end
|
||||
|
||||
|
@ -234,10 +216,7 @@ if defined?(WIN32OLE_EVENT)
|
|||
ev.on_event{handler1}
|
||||
ev.off_event
|
||||
@ie.navigate("file:///#{@f}")
|
||||
while @ie.busy
|
||||
message_loop
|
||||
end
|
||||
WIN32OLE_EVENT.message_loop
|
||||
wait_ie
|
||||
assert_equal("", @event2)
|
||||
end
|
||||
|
||||
|
@ -246,10 +225,7 @@ if defined?(WIN32OLE_EVENT)
|
|||
ev.on_event('BeforeNavigate2'){handler1}
|
||||
ev.off_event('BeforeNavigate2')
|
||||
@ie.navigate("file:///#{@f}")
|
||||
while @ie.busy
|
||||
message_loop
|
||||
end
|
||||
WIN32OLE_EVENT.message_loop
|
||||
wait_ie
|
||||
assert_equal("", @event2)
|
||||
end
|
||||
|
||||
|
@ -267,6 +243,7 @@ if defined?(WIN32OLE_EVENT)
|
|||
|
||||
def teardown
|
||||
@ie.quit
|
||||
message_loop
|
||||
@ie = nil
|
||||
i = 0
|
||||
begin
|
||||
|
@ -280,5 +257,58 @@ if defined?(WIN32OLE_EVENT)
|
|||
GC.start
|
||||
message_loop
|
||||
end
|
||||
|
||||
class Handler1
|
||||
attr_reader :val1, :val2, :val3, :val4
|
||||
def initialize
|
||||
@val1 = nil
|
||||
@val2 = nil
|
||||
@val3 = nil
|
||||
@val4 = nil
|
||||
end
|
||||
def onStatusTextChange(t)
|
||||
@val1 = t
|
||||
end
|
||||
def onProgressChange(p, pmax)
|
||||
@val2 = p
|
||||
@val3 = pmax
|
||||
end
|
||||
def onPropertyChange(p)
|
||||
@val4 = p
|
||||
end
|
||||
end
|
||||
|
||||
class Handler2
|
||||
attr_reader :ev
|
||||
def initialize
|
||||
@ev = ""
|
||||
end
|
||||
def method_missing(ev, *arg)
|
||||
@ev += ev
|
||||
end
|
||||
end
|
||||
|
||||
def test_handler1
|
||||
ev = WIN32OLE_EVENT.new(@ie)
|
||||
h1 = Handler1.new
|
||||
ev.handler = h1
|
||||
@ie.navigate("file:///#{@f}")
|
||||
wait_ie
|
||||
assert(h1.val1)
|
||||
assert_equal(h1.val1, ev.handler.val1)
|
||||
assert(h1.val2)
|
||||
assert(h1.val3)
|
||||
assert(h1.val4)
|
||||
end
|
||||
|
||||
def test_handler2
|
||||
ev = WIN32OLE_EVENT.new(@ie)
|
||||
h2 = Handler2.new
|
||||
ev.handler = h2
|
||||
@ie.navigate("file:///#{@f}")
|
||||
wait_ie
|
||||
assert(h2.ev != "")
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
Загрузка…
Ссылка в новой задаче