Class: Dde::Client

Inherits:
App
  • Object
show all
Defined in:
lib/dde/client.rb

Overview

Class encapsulates DDE Client that requests connection with DDE server and exchanges data with it via DDE

Instance Attribute Summary collapse

Attributes inherited from App

#id, #init_flags

Instance Method Summary collapse

Methods inherited from App

#dde_active?, #error, #initialize, #start_dde, #stop_dde, #try

Constructor Details

This class inherits a constructor from Dde::App

Instance Attribute Details

#conversationObject (readonly)

active DDE conversation that client is engaged in



6
7
8
# File 'lib/dde/client.rb', line 6

def conversation
  @conversation
end

#itemObject (readonly)

active DDE conversation that client is engaged in



6
7
8
# File 'lib/dde/client.rb', line 6

def item
  @item
end

#serviceObject (readonly)

active DDE conversation that client is engaged in



6
7
8
# File 'lib/dde/client.rb', line 6

def service
  @service
end

#topicObject (readonly)

active DDE conversation that client is engaged in



6
7
8
# File 'lib/dde/client.rb', line 6

def topic
  @topic
end

Instance Method Details

#conversation_active?Boolean

Returns:

  • (Boolean)


98
99
100
# File 'lib/dde/client.rb', line 98

def conversation_active?
  !!@conversation
end

#send_data(data, format = CF_TEXT, item = "") ⇒ Object

Sends XTYP_POKE transaction to server if conversation was already established.

data

data being sent (will be coerced to String unless is already a (packed) String)

format

standard clipboard format of submitted data item (default CF_TEXT)



52
53
54
55
56
# File 'lib/dde/client.rb', line 52

def send_data( data, format = CF_TEXT, item = "" )
  data_pointer = FFI::MemoryPointer.from_string(data.to_s)
  result, trans_id = start_transaction(XTYP_POKE, data_pointer, data_pointer.size, format, item)
  result
end

#start_conversation(service = nil, topic = nil) ⇒ Object

Establish a conversation with a server application that supports the specified service name and topic name pair.



18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/dde/client.rb', line 18

def start_conversation( service=nil, topic=nil )
  try "Starting conversation #{service} #{topic}", Dde::Errors::ClientError do
    error "DDE is not initialized" unless dde_active?
    error "Another conversation already established" if conversation_active?

    # Create DDE strings for service and topic unless they are omitted
    @service = Dde::DdeString.new(@id, service) if service
    @topic = Dde::DdeString.new(@id, topic) if topic

    # Initiate new DDE conversation, returns conversation handle or nil 
    error unless @conversation = dde_connect(@id, @service.handle, @topic.handle)
  end
end

#start_transaction(transaction_type, data_pointer = nil, cb = data_pointer ? data_pointer.size : 0, format = CF_TEXT, item = 0, timeout = 1000) ⇒ Object

Initiates transaction to server if conversation was already established.

transaction_type

XTYP_ADVSTART, XTYP_ADVSTOP, XTYP_EXECUTE, XTYP_POKE, XTYP_REQUEST

data_pointer

pointer to data being sent (either FFI::MemoryPointer or DDE data_handle)

cb

data set size (or -1 to indicate that data_pointer is in fact DDE data_handle)

format

standard clipboard format of submitted data item (default CF_TEXT)

item

item to which transaction is related (String, DdeString or DDE string handle)

timeout

timeout in milliseconds or TIMEOUT_ASYNC to indicate async transaction

Returns

A pair of [result, trans_id]. Result is nil for failed transactions,

DDE data handle for synchronous transactions in which the client expects data from the server, nonzero for successful transactions where clients does not expect data from server. Trans_id: for asynchronous transactions, a unique transaction identifier for use with the DdeAbandonTransaction function and the XTYP_XACT_COMPLETE transaction. For synchronous transactions, the low-order word of this variable contains any applicable DDE_ flags resulting from the transaction.



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/dde/client.rb', line 73

def start_transaction( transaction_type, data_pointer=nil, cb = data_pointer ? data_pointer.size : 0,
        format=CF_TEXT, item=0, timeout=1000)

  result = nil
  trans_id = FFI::MemoryPointer.new(:uint32).put_uint32(0,0)

  try "Sending data to server", Dde::Errors::ClientError do
    error "DDE not started" unless dde_active?
    error "Conversation not started" unless conversation_active?

    item_handle = case item
      when String
        Dde::DdeString.new(@id, service).handle
      when DdeString
        item.handle
      else
        item
    end

    error unless result = dde_client_transaction(data_pointer, cb, @conversation, item_handle,
                                                 format, transaction_type, timeout, trans_id)
  end
  [result, trans_id.get_uint32(0)]
end

#stop_conversationObject

Stops active conversation, raises error if no conversations active



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/dde/client.rb', line 33

def stop_conversation
  try "Stopping conversation", Dde::Errors::ClientError do
    error "DDE not started" unless dde_active?
    error "Conversation not started" unless conversation_active?

    error unless dde_disconnect(@conversation) &&    # Stop DDE conversation
    dde_free_string_handle(@id, @service.handle) &&  # Free string handles for service name
    dde_free_string_handle(@id, @topic.handle)       # Free string handles for topic name

    # Unset attributes for conversation, service and topic
    @conversation = nil
    @service = nil
    @topic = nil
  end
end