Class: WIN32COMGen

Inherits:
Object
  • Object
show all
Defined in:
sample/olegen.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(typelib) ⇒ WIN32COMGen

Returns a new instance of WIN32COMGen.



9
10
11
12
# File 'sample/olegen.rb', line 9

def initialize(typelib)
  @typelib = typelib
  @reciever = ""
end

Instance Attribute Details

#typelibObject (readonly)

Returns the value of attribute typelib



13
14
15
# File 'sample/olegen.rb', line 13

def typelib
  @typelib
end

Instance Method Details

#class_name(klass) ⇒ Object



239
240
241
242
243
244
245
246
247
248
249
250
# File 'sample/olegen.rb', line 239

def class_name(klass)
  klass_name = klass.name
  if klass.ole_type == "Class" &&
     klass.guid &&
     klass.progid
     klass_name = klass.progid.gsub(/\./, '_')
  end
  if /^[A-Z]/ !~ klass_name || Module.constants.include?(klass_name)
    klass_name = 'OLE' + klass_name
  end
  klass_name
end

#define_class(klass, io = STDOUT) ⇒ Object



284
285
286
287
288
289
290
291
292
293
# File 'sample/olegen.rb', line 284

def define_class(klass, io = STDOUT)
  io.puts "class #{class_name(klass)} # #{klass.name}"
  io.puts define_include
  io.puts define_instance_variables
  io.puts "  attr_reader :dispatch"
  io.puts "  attr_reader :clsid"
  io.puts "  attr_reader :progid"
  io.puts define_initialize(klass)
  io.puts define_method_missing
end

#define_includeObject



267
268
269
# File 'sample/olegen.rb', line 267

def define_include
  "  include WIN32OLE::VARIANT"
end

#define_initialize(klass) ⇒ Object



252
253
254
255
256
257
258
259
260
261
262
263
264
265
# File 'sample/olegen.rb', line 252

def define_initialize(klass)
  <<STR

def initialize(obj = nil)
  @clsid = "#{klass.guid}"
  @progid = "#{klass.progid}"
  if obj.nil?
    @dispatch = WIN32OLE.new @progid
  else
    @dispatch = obj
  end
end
STR
end

#define_instance_variablesObject



271
272
273
# File 'sample/olegen.rb', line 271

def define_instance_variables
  "  attr_reader :lastargs"
end

#define_method_missingObject



275
276
277
278
279
280
281
282
# File 'sample/olegen.rb', line 275

def define_method_missing
  <<STR

def method_missing(cmd, *arg)
  @dispatch.method_missing(cmd, *arg)
end
STR
end

#define_module(klass, io = STDOUT) ⇒ Object



295
296
297
298
299
# File 'sample/olegen.rb', line 295

def define_module(klass, io = STDOUT)
  io.puts "module #{class_name(klass)}"
  io.puts define_include
  io.puts define_instance_variables
end

#generate(io = STDOUT) ⇒ Object



317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
# File 'sample/olegen.rb', line 317

def generate(io = STDOUT)
  io.puts "require 'win32ole'"
  io.puts "require 'win32ole/property'"

  ole_classes(typelib).select{|klass|
    klass.visible? &&
    (klass.ole_type == "Class" ||
     klass.ole_type == "Interface" ||
     klass.ole_type == "Dispatch" ||
     klass.ole_type == "Enum")
  }.each do |klass|
    generate_class(klass, io)
  end
  begin
    @ole.quit if @ole
  rescue
  end
end

#generate_args(method) ⇒ Object



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'sample/olegen.rb', line 24

def generate_args(method)
  args = []
  if method.size_opt_params >= 0
    size_required_params = method.size_params - method.size_opt_params
  else
    size_required_params = method.size_params - 1
  end
  size_required_params.times do |i|
    if method.params[i] && method.params[i].optional?
      args.push "arg#{i}=nil"
    else
      args.push "arg#{i}"
    end
  end
  if method.size_opt_params >= 0
    method.size_opt_params.times do |i|
      args.push "arg#{i + size_required_params}=nil"
    end
  else
    args.push "*arg"
  end
  args.join(", ")
end

#generate_argtype(typedetails) ⇒ Object



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'sample/olegen.rb', line 48

def generate_argtype(typedetails)
  ts = ''
  typedetails.each do |t|
    case t
    when 'CARRAY', 'VOID', 'UINT', 'RESULT', 'DECIMAL', 'I8', 'UI8'
#	  raise "Sorry type\"" + t + "\" not supported"
    ts << "\"??? NOT SUPPORTED TYPE:`#{t}'\""
    when 'USERDEFINED', 'Unknown Type 9'
      ts << 'VT_DISPATCH'
      break;
    when 'SAFEARRAY'
      ts << 'VT_ARRAY|'
    when 'PTR'
      ts << 'VT_BYREF|'
    when 'INT'
      ts << 'VT_I4'
    else
      if String === t
        ts << 'VT_' + t
      end
    end
  end
  if ts.empty?
    ts = 'VT_VARIANT'
  elsif ts[-1] == ?|
	ts += 'VT_VARIANT'
  end
  ts
end

#generate_argtypes(method, proptypes) ⇒ Object



78
79
80
81
82
83
84
85
86
87
# File 'sample/olegen.rb', line 78

def generate_argtypes(method, proptypes)
  types = method.params.collect{|param|
    generate_argtype(param.ole_type_detail)
  }.join(", ")
  if proptypes
    types += ", " if types.size > 0
    types += generate_argtype(proptypes)
  end
  types
end

#generate_class(klass, io = STDOUT) ⇒ Object



301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
# File 'sample/olegen.rb', line 301

def generate_class(klass, io = STDOUT)
  io.puts "\n# #{klass.helpstring}"
  if klass.ole_type == "Class" &&
     klass.guid &&
     klass.progid
    @reciever = "@dispatch."
    define_class(klass, io)
  else
    @reciever = ""
    define_module(klass, io)
  end
  generate_constants(klass, io)
  generate_methods(klass, io)
  io.puts "end"
end

#generate_constants(klass, io = STDOUT) ⇒ Object



228
229
230
231
232
233
234
235
236
237
# File 'sample/olegen.rb', line 228

def generate_constants(klass, io = STDOUT)
  klass.variables.select {|v|
    v.visible? && v.variable_kind == 'CONSTANT'
  }.each do |v|
    io.print "  "
    io.print v.name.sub(/^./){$&.upcase}
    io.print " = "
    io.puts  v.value
  end
end

#generate_func_methods(klass, io = STDOUT) ⇒ Object



212
213
214
215
216
217
218
# File 'sample/olegen.rb', line 212

def generate_func_methods(klass, io = STDOUT)
  klass.ole_methods.select {|method|
    method.invoke_kind == "FUNC" && method.visible?
  }.each do |method|
    generate_method(method, '_invoke', io)
  end
end

#generate_method(method, disptype, io = STDOUT, types = nil) ⇒ Object



141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'sample/olegen.rb', line 141

def generate_method(method, disptype, io = STDOUT, types = nil)
  io.puts "\n"
  io.puts  generate_method_help(method)
  if method.invoke_kind == 'PROPERTYPUT'
    io.print "  def #{method.name}=("
  else
    io.print "  def #{method.name}("
  end
  io.print generate_args(method)
  io.puts ")"
  io.puts generate_method_body(method, disptype, types)
  io.puts "  end"
end

#generate_method_args_help(method) ⇒ Object



123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'sample/olegen.rb', line 123

def generate_method_args_help(method)
  args = []
  method.params.each_with_index {|param, i|
    h = "  #   #{param.ole_type} arg#{i} --- #{param.name}"
    inout = []
    inout.push "IN" if param.input?
    inout.push "OUT" if param.output?
    h += " [#{inout.join('/')}]"
    h += " ( = #{param.default})" if param.default
    args.push h
  }
  if args.size > 0
    args.join("\n")
  else
    nil
  end
end

#generate_method_body(method, disptype, types = nil) ⇒ Object



89
90
91
92
93
94
95
96
97
# File 'sample/olegen.rb', line 89

def generate_method_body(method, disptype, types=nil)
  "    ret = #{@reciever}#{disptype}(#{method.dispid}, [" +
  generate_args(method).gsub("=nil", "") +
  "], [" +
  generate_argtypes(method, types) +
  "])\n" +
  "    @lastargs = WIN32OLE::ARGV\n" +
  "    ret"
end

#generate_method_help(method, type = nil) ⇒ Object



99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'sample/olegen.rb', line 99

def generate_method_help(method, type = nil)
  str = "  # "
  if type
    str += type
  else
    str += method.return_type
  end
  str += " #{method.name}"
  if method.event?
    str += " EVENT"
    str += " in #{method.event_interface}"
  end
  if method.helpstring && method.helpstring != ""
    str += "\n  # "
    str += method.helpstring
  end
  args_help = generate_method_args_help(method)
  if args_help
    str += "\n"
    str += args_help
  end
  str
end

#generate_methods(klass, io = STDOUT) ⇒ Object



220
221
222
223
224
225
226
# File 'sample/olegen.rb', line 220

def generate_methods(klass, io = STDOUT)
  generate_propget_methods(klass, io)
  generate_propput_methods(klass, io)
  generate_properties_with_args(klass, io)
  generate_func_methods(klass, io)
#   generate_propputref_methods(klass, io)
end

#generate_properties_with_args(klass, io = STDOUT) ⇒ Object



163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
# File 'sample/olegen.rb', line 163

def generate_properties_with_args(klass, io = STDOUT)
  klass.ole_methods.select {|method|
    method.invoke_kind == 'PROPERTYGET' &&
    method.visible? &&
    method.size_params > 0
  }.each do |method|
    types = method.return_type_detail
    io.puts "\n"
    io.puts  generate_method_help(method, types[0])
    io.puts  "  def #{method.name}"
    if klass.ole_type == "Class"
      io.print "    OLEProperty.new(@dispatch, #{method.dispid}, ["
    else
      io.print "    OLEProperty.new(self, #{method.dispid}, ["
    end
    io.print generate_argtypes(method, nil)
    io.print "], ["
    io.print generate_argtypes(method, types)
    io.puts "])"
    io.puts  "  end"
  end
end

#generate_propget_methods(klass, io = STDOUT) ⇒ Object



203
204
205
206
207
208
209
210
# File 'sample/olegen.rb', line 203

def generate_propget_methods(klass, io = STDOUT)
  klass.ole_methods.select {|method|
    method.invoke_kind == 'PROPERTYGET' && method.visible? &&
    method.size_params == 0
  }.each do |method|
    generate_method(method, '_getproperty', io)
  end
end

#generate_propput_methods(klass, io = STDOUT) ⇒ Object



186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
# File 'sample/olegen.rb', line 186

def generate_propput_methods(klass, io = STDOUT)
  klass.ole_methods.select {|method|
    method.invoke_kind == 'PROPERTYPUT' && method.visible? &&
    method.size_params == 1
  }.each do |method|
    ms = klass.ole_methods.select {|m|
      m.invoke_kind == 'PROPERTYGET' &&
      m.dispid == method.dispid
    }
    types = []
    if ms.size == 1
      types = ms[0].return_type_detail
    end
    generate_method(method, '_setproperty', io, types)
  end
end

#generate_propputref_methods(klass, io = STDOUT) ⇒ Object



155
156
157
158
159
160
161
# File 'sample/olegen.rb', line 155

def generate_propputref_methods(klass, io = STDOUT)
  klass.ole_methods.select {|method|
    method.invoke_kind == 'PROPERTYPUTREF' && method.visible?
  }.each do |method|
    generate_method(method, io)
  end
end

#ole_classes(typelib) ⇒ Object



15
16
17
18
19
20
21
22
# File 'sample/olegen.rb', line 15

def ole_classes(typelib)
  begin
    @ole = WIN32OLE.new(typelib)
    [@ole.ole_obj_help]
  rescue
    WIN32OLE_TYPE.ole_classes(typelib)
  end
end