From: Allen Mitchell Date: 2003-07-14T21:16:39+09:00 Subject: Re: programming a bird -- yes! Interesting... I played with it for a couple of minutes and got it to work as you indicated. I downloaded the docs and there is a reference to a "Register" function. It states that you must create a AgentNotifySink and register it before you can get events. I'm not sure how to do this in Ruby. If you get it working, please post the code. Good luck. -----Original Message----- From: Gerard A.W. Vreeswijk [mailto:gv@cs.uu.nl] Sent: July 14, 2003 7:10 AM To: ruby-talk ML Subject: programming a bird -- yes! Hello all, Hi all, Serious (but possibly less attracting) subject title: Win32ole event loop with MSAgent. Thanks to Suketa Masaki for doing such a good job on giving us 'win32ole'. It relieves us from Microsoft's RSI-stimulating clickfests. Inspired by Rubytalk 36676, Shusaku : http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-list/36676 I decided I wanted to beef up my Agent-app with MSAgent (sorry, Unix): http://www.microsoft.com/msagent/downloads/user.asp (download merlin + speech engine + maybe more, depending on your hardware) Tried out the script below. All works fine --- as a matter of fact, I showed one of the characters who happens to be a bird called Peedy to my 4-year old son pronouncing my son's name. He ran down to his mom and said that a bird talked to him and knew his name :-) Anyway: ====================================================================== #!/usr/bin/ruby require 'win32ole' agent = WIN32OLE.new('Agent.Control.1') agent.Connected = true agent.Characters.Load("some random string, 'peedy' or so", "peedy.acs") peedy = agent.Characters("some random string, 'peedy' or so") # The way we should officialy check when we're done: ev = WIN32OLE_EVENT.new(agent, nil) ev.on_event("RequestComplete") { |rRequest| # rRequest.ole_obj_help.name -> "IAgentCtlRequest" # rRequest.ole_obj_help.typekind -> 4 ( TKIND_DISPATCH ) # rRequest.ole_obj_help.ole_type -> "Dispatch" # rRequest.ID -> 197 ( ?? ) if rRequest.ID == $peedySpeak.ID peedy.Hide # or exit, or move on, or .. end } peedy.Show # You can program gestures here. Nothing fancy at the moment, just speak. $peedySpeak = peedy.Speak < WIN32OLE_METHOD # speak.return_vtype #=> 26 # speak.return_type #=> "IAgentCtlRequest" # speak.return_type_detail #=> ["PTR", "USERDEFINED", "IAgentCtlRequest"] # More mundane check to see when we're done: loop do $stderr.puts $peedySpeak.Status $stderr.flush # status should become 0 or so, see # http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msagent/pac ontrol_3tws.asp break if $peedySpeak.Status != 2 sleep 1 end # never get here :-( ====================================================================== As you see, the WIN32OLE_EVENT-loop doesn't seem to recognize events, which is needed to recognize that an action is over. Also, the "Status" attribute does not work. Status could also be used to see that an action is over. Currently, Status keeps returning 2's. This is different from Perl's, foreach my $animation ($c->AnimationNames) { my $request = $c->Play($animation); $c->Speak($animation); my $i = 0; while (($request->Status == 2) || ($request->Status == 4)) { $c->Stop($request) if $i >10; sleep(1); $i++} } where it *does** work (not the events, though). (Thanks, Jouke). See http://www.cpan.org/modules/by-authors/id/J/JO/JOUKE/ Examined Suketa Masaki "ienavi.rb" example for inspiration. There must be some "DWebBrowserEvents" event sink identifier for MSAgent as well, but which?? Thanks. Gerard