[#36686] 1.1 < 61.1 - 60.0 — Shin-ichiro HARA <sinara@...>

原です。

19 messages 2002/12/06

[#36770] www.ruby-lang.orgリニューアル準備のお知らせ — TADA Tadashi <sho@...>

ruby-lang.orgのwebmasterチームでは、タイムリーな情報提供と使いやすい

11 messages 2002/12/16

[ruby-list:36676] WIN32OLE と IAgentCtlRequest

From: Shusaku <tsyk@...>
Date: 2002-12-05 09:47:48 UTC
List: ruby-list #36676
Shusakuです。

Microsoft Agent <http://www.microsoft.com/msagent/> で遊んで
いるのですが、WIN32OLEの使い方で判らない部分があります。

あるキャラクタに動作を要求すると、それはキューに貯まってから
非同期で処理されます。要求完了イベントを捕まえて、どの要求が
完了したのかを検査する場合、VBScriptでは以下のように Request
オブジェクトどうしを単純に比較すれば良いようです。

--- VBScriptサンプル (抜粋) -----------
Sub AgentControl_RequestComplete(ByVal Request)

   ' TypeName(Request)  -> IAgentCtlRequest
   ' VarType(Request)   -> 3     ( vbLong : 長整数型 )
   ' IsObject(Request)  -> True  ※ Automation object であり、
   ' IsNumeric(Request) -> True     かつ、数値でもある!?!?
   ' Request.ID         -> 126   ( 要求毎に異なる unique な ID )
   ' Request            -> 126   ( 数値として評価すると ID と同じ値 )

   If Request = gRobbySpeak Then
      Robby.Hide
   End If

End Sub

Sub window_OnLoad
   AgentControl.Connected = True
   AgentControl.Characters.Load "Robby", "robby.acs"
   Set Robby = AgentControl.Characters("Robby")
   Robby.Show
   Set gRobbySpeak = Robby.Speak "Hello!"
End Sub
---------------------------------------

しかし、Ruby+WIN32OLEの場合は、明示的にIDプロパティで比較する
方法を探し当てるまで、やりかたが判りませんでした。
どうしてVBではIDプロパティを使わずに比較ができるのでしょうか?
暗黙的に呼び出すような仕組みになってるなのかなぁ…  

RubyでもIDプロパティを読み出さずに比較する(ように見せる?)方法は
あるのでしょうか?

--- Rubyサンプル (抜粋) ---------------
agent = WIN32OLE.new('Agent.Control.1')
agent.Connected = true
agent.Characters.Load("Robby", "robby.acs")

Robby = agent.Characters("Robby")

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  ( 要求毎に異なる unique な ID )

  if rRequest.ID == $RobbySpeak.ID
    Robby.Hide
  end

}

Robby.Show
$RobbySpeak = Robby.Speak "Hello!"

speak = Robby.ole_method("Speak")  #=> WIN32OLE_METHOD
speak.return_vtype        #=> 26
speak.return_type         #=> "IAgentCtlRequest"
speak.return_type_detail  #=> ["PTR", "USERDEFINED", "IAgentCtlRequest"]
---------------------------------------

このRequestオブジェクトは、他に Status, Number, Description の
プロパティがあって、ID だけが 'hidden' で、VB のオブジェクト・
ブラウザでは隠されて見えないので、OLEVIEW.EXE で見ました。

--- OLE/COM Object Viewer の表示 ------
dispinterface _AgentEvents {
    properties:
    methods:
        [id(0x0000000b)]
        void RequestComplete([in] IDispatch* Request);
    ...
};

dispinterface IAgentCtlCharacterEx {
    properties:
    methods:
        [id(0x0000000f)]
        IAgentCtlRequest* Speak(
                        [in, optional] VARIANT Text, 
                        [in, optional] VARIANT Url);
    ...
};

dispinterface IAgentCtlRequest {
    properties:
    methods:
        [id(00000000), propget, hidden]
        long ID();
        [id(0x00000001), propget]
        long Status();
    ...
}

--- <agtsvr.h> ------------------------
IAgentCharacter : public IDispatch
{
public:
    virtual HRESULT STDMETHODCALLTYPE Speak( 
        /* [in] */ BSTR bszText,
        /* [in] */ BSTR bszUrl,
        /* [out] */ long __RPC_FAR *pdwReqID) = 0;
    ...
};

IAgentNotifySink : public IDispatch
{
public:
    virtual HRESULT STDMETHODCALLTYPE RequestComplete( 
        /* [in] */ long dwRequestID,
        /* [in] */ long hrStatus) = 0;
    ...
};

--- <agtctl.h> ------------------------
IAgentCtlCharacter : public IDispatch
{
public:
    virtual /* [id] */ HRESULT STDMETHODCALLTYPE Speak( 
        /* [optional][in] */ VARIANT Text,
        /* [optional][in] */ VARIANT Url,
        /* [retval][out] */ IAgentCtlRequest __RPC_FAR *__RPC_FAR *Request) = 0;
    ...
};

IAgentCtlRequest : public IDispatch
{
public:
    virtual /* [hidden][propget][id] */ HRESULT STDMETHODCALLTYPE get_ID( 
        /* [retval][out] */ long __RPC_FAR *ID) = 0;
    virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_Status( 
        /* [retval][out] */ long __RPC_FAR *Status) = 0;
    ...
};

---------------------------------------


-- 
Shusaku <tsyk@yk.rim.or.jp>


In This Thread

Prev Next