File: win32.xml

package info (click to toggle)
rubybook 0.2.1-1
  • links: PTS
  • area: non-free
  • in suites: etch, etch-m68k, lenny, squeeze, wheezy
  • size: 4,248 kB
  • ctags: 1,042
  • sloc: xml: 60,486; makefile: 25
file content (315 lines) | stat: -rw-r--r-- 12,083 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
<ppdoc>
<copyright>
    Copyright (c) 2001 by Addison Wesley Longman.  This
    material may be distributed only subject to the terms and
    conditions set forth in the Open Publication License, v1.0 or
    later (the latest version is presently available at
    http://www.opencontent.org/openpub/).
</copyright>
<chapter name="Ruby and Microsoft Windows">
<p/>
Ruby is written for POSIX environments, which means that it can
take advantage of all of the system calls and libraries 
that Unix programmers are familiar with.
<p/>
But there are a number of features and extensions designed to make
Ruby more useful in a Microsoft Windows environment, too.  In this
chapter, we'll look at these features and share some secrets to using
Ruby effectively under Windows.
<section>Ruby Ports</section>
<p/>
Windows does not provide a POSIX environment by itself, so some sort
of emulation library is required in order to provide the necessary
functions.  There are several ports of Ruby for
Windows: the most commonly used one relies on the GNU Win32
environment, and is called the ``cygwin32'' port.  The cygwin32 port
works well with extension libraries, and is available on the Web as a
precompiled binary.
Another port, ``mswin32,'' does not rely on cygwin.  It is currently
available as source code only. The remainder
of this chapter will refer to the cygwin32 port.
<section>Running Ruby Under Windows</section>
<p/>
There are two executables provided with the cygwin32 Ruby distribution:
<tt>ruby.exe</tt> and <tt>rubyw.exe</tt>.
<p/>
<tt>ruby.exe</tt> is meant to be used at a command prompt (a DOS shell),
just as in the Unix version.  For applications that read and write to
the standard input and output, this is fine.
But that also means that anytime you run <tt>ruby.exe</tt>, you'll get a
DOS shell even if you don't want one---Windows will create a new
command prompt window and display it while Ruby is running.  This
might not be appropriate behavior if, for example,
you double-click on a Ruby script that uses a graphical interface
(such as Tk), or if you are running a Ruby script as a background
task, or from inside another program.
<p/>
In these cases, you'll want to use <tt>rubyw.exe</tt>.  It is the same as
<tt>ruby.exe</tt> except that it does not provide standard in, standard
out, or standard error, and does not launch a DOS shell when run.
<p/>
You can set a file association<footnote>Using
  <tt>View/Options/Filetypes</tt> from Explorer.</footnote>
so that files with the extension ``<tt>.rb</tt>'' will
automatically use <tt>rubyw.exe</tt>.  By doing this, you can double-click
on Ruby scripts and they will simply run without popping up a DOS
shell.
<section>Win32API</section>
<p/>
If you plan on doing Ruby programming that needs to access
some Windows 32 API functions directly, or to use the entry points in some
other DLLs, we've got good news for you---the <classname>Win32API</classname> extension.
<p/>
The <classname>Win32API</classname> module is documented beginning on page 512,
but here's a quick peek at how it works.
<p/>
You create a <classname>Win32API</classname> object that represents a call to a
particular DLL entry point by specifying the name of the function, the
name of the DLL that contains the function, and the function signature (argument
types and return type).  The resulting object can then be used to make
the function call.
<p/>
Many of the arguments to DLL functions are binary structures
of some form.  <classname>Win32API</classname> handles this by using Ruby <classname>String</classname>
objects to pass the binary data back and forth.  You will need to pack
and unpack these strings as necessary (see the example
on page 512).
<section>Windows Automation</section>
<p/>
If groveling around in the low-level Windows API doesn't interest you,
Windows automation might---you can use Ruby as a client for Windows
Automation thanks to a Ruby extension called <classname>WIN32OLE</classname>, written by
Masaki Suketa.
The examples in this section are taken from those
provided in the <classname>WIN32OLE</classname> distribution.
<p/>
Windows automation
allows an
automation controller (a client) to issue commands and queries against
an automation server, such as Microsoft Excel, Word, PowerPoint, and
so on.
<p/>
You can execute a method of an automation server by calling a method
of the same name from a <tt>WIN32OLE</tt> object.  For instance, you can
create a new <classname>WIN32OLE</classname> client that launches a fresh copy of
Internet Explorer and commands it to visit the home page.
<p/>
<codefragment>
<alltt><fullcode><![CDATA[  ie = WIN32OLE.new('InternetExplorer.Application')
  ie.visible = true
  ie.gohome
]]></fullcode>
ie<nbsp/>=<nbsp/>WIN32OLE.new('InternetExplorer.Application')
ie.visible<nbsp/>=<nbsp/>true
ie.gohome
</alltt>
</codefragment>
<p/>
Methods that aren't known to <classname>WIN32OLE</classname> (such as <tt>visible</tt> or
<tt>gohome</tt>) are passed on to the <cim><front>WIN32OLE</front><back>invoke</back></cim> method, which sends the
proper commands to the server.  The <classname>WIN32OLE</classname> reference
beginning on page 509 describes the class in detail, but
we'll go over a few of its features here.
<subsection>Getting and Setting Properties</subsection>
<p/>
You can set and get <em>properties</em> from the server using normal
Ruby hash notation.  For example, to set the <tt>Rotation</tt> property 
in an Excel chart, you might write
<p/>
<codefragment>
<alltt><fullcode><![CDATA[  excel = WIN32OLE.new("excel.application")
  excelchart = excel.Charts.Add()
  ...
  excelchart['Rotation'] = 45
  puts excelchart['Rotation']
]]></fullcode>
excel<nbsp/>=<nbsp/>WIN32OLE.new("excel.application")
excelchart<nbsp/>=<nbsp/>excel.Charts.Add()
...
excelchart['Rotation']<nbsp/>=<nbsp/>45
puts<nbsp/>excelchart['Rotation']
</alltt>
</codefragment>
<p/>
An OLE object's parameters are automatically set up as attributes of
the <classname>WIN32OLE</classname> object. This means that you can set a parameter by
assigning to an object attribute.
<p/>
<codefragment>
<alltt><fullcode><![CDATA[  excelchart.rotation = 45
  r = excelchart.rotation
]]></fullcode>
excelchart.rotation<nbsp/>=<nbsp/>45
r<nbsp/>=<nbsp/>excelchart.rotation
</alltt>
</codefragment>
<p/>
Because these attributes are conventional Ruby accessor
methods, attribute names cannot start with a capital letter.
In this example, we have to use <tt>rotation</tt> instead of <tt>Rotation</tt>.
<subsection>Named Arguments</subsection>
<p/>
Other automation client languages such as Visual Basic have the
concept of <em>named arguments</em>.  Suppose you had a Visual Basic
routine with the signature:
<p/>
<codefragment>
<alltt><fullcode><![CDATA[  Song(artist, title, length):    rem Visual Basic
]]></fullcode>
Song(artist,<nbsp/>title,<nbsp/>length):<nbsp/><nbsp/><nbsp/><nbsp/>rem<nbsp/>Visual<nbsp/>Basic
</alltt>
</codefragment>
<p/>
Instead of calling it with all three arguments in the order specified,
you could use named arguments.
<p/>
<codefragment>
<alltt><fullcode><![CDATA[  Song title := 'Get It On':      rem Visual Basic
]]></fullcode>
Song<nbsp/>title<nbsp/>:=<nbsp/>'Get<nbsp/>It<nbsp/>On':<nbsp/><nbsp/><nbsp/><nbsp/><nbsp/><nbsp/>rem<nbsp/>Visual<nbsp/>Basic
</alltt>
</codefragment>
<p/>
This is equivalent to the call <tt>Song(nil, 'Get It On', nil)</tt>.
<p/>
In Ruby, you can use this feature by passing a hash with the named
arguments.
<p/>
<codefragment>
<alltt><fullcode><![CDATA[  Song.new( 'title' => 'Get It On' )
]]></fullcode>
Song.new(<nbsp/>'title'<nbsp/>=&gt;<nbsp/>'Get<nbsp/>It<nbsp/>On'<nbsp/>)
</alltt>
</codefragment>
<subsection>for each</subsection>
<p/>
Where Visual Basic has a ``for each'' statement to iterate over a
collection of items in a server, a <classname>WIN32OLE</classname> object has an
<tt>each</tt> method (which takes a block) to accomplish the same
thing.
<subsection>An Example</subsection>
<p/>
The following example, using Microsoft Excel,
illustrates most of
these concepts.  First, we create a new <tt>WIN32OLE</tt> object attached
to Excel and set some cell values. Next we select
a range of cells and create a chart.  We set the <tt>Type</tt> property in 
the <tt>excelchart</tt> object to make it a 3D chart. Next we'll loop
through and change the chart rotation, 10&#176; at a time. We'll add 
a few charts, and we'll use <tt>each</tt> to step through and print them out.
Finally, we'll close down the Excel application and exit.
<p/>
<codefragment>
<alltt><fullcode><![CDATA[require 'win32ole'

# -4100 is the value for the Excel constant xl3DColumn.
ChartTypeVal = -4100;

# Creates OLE object to Excel
excel = WIN32OLE.new("excel.application")

# Create and rotate the chart

excel['Visible'] = TRUE;
workbook = excel.Workbooks.Add();
excel.Range("a1")['Value'] = 3;
excel.Range("a2")['Value'] = 2;
excel.Range("a3")['Value'] = 1;
excel.Range("a1:a3").Select();
excelchart = workbook.Charts.Add();
excelchart['Type'] = ChartTypeVal;

30.step(180, 10) do |rot|
    excelchart['Rotation'] = rot
end

excelchart2 = workbook.Charts.Add();
excelchart3 = workbook.Charts.Add();

charts = workbook.Charts
charts.each { |i| puts i }

excel.ActiveWorkbook.Close(0);
excel.Quit();
]]></fullcode>
require<nbsp/>'win32ole'
<p/>
#<nbsp/>-4100<nbsp/>is<nbsp/>the<nbsp/>value<nbsp/>for<nbsp/>the<nbsp/>Excel<nbsp/>constant<nbsp/>xl3DColumn.
ChartTypeVal<nbsp/>=<nbsp/>-4100;
<p/>
#<nbsp/>Creates<nbsp/>OLE<nbsp/>object<nbsp/>to<nbsp/>Excel
excel<nbsp/>=<nbsp/>WIN32OLE.new("excel.application")
<p/>
#<nbsp/>Create<nbsp/>and<nbsp/>rotate<nbsp/>the<nbsp/>chart
<p/>
excel['Visible']<nbsp/>=<nbsp/>TRUE;
workbook<nbsp/>=<nbsp/>excel.Workbooks.Add();
excel.Range("a1")['Value']<nbsp/>=<nbsp/>3;
excel.Range("a2")['Value']<nbsp/>=<nbsp/>2;
excel.Range("a3")['Value']<nbsp/>=<nbsp/>1;
excel.Range("a1:a3").Select();
excelchart<nbsp/>=<nbsp/>workbook.Charts.Add();
excelchart['Type']<nbsp/>=<nbsp/>ChartTypeVal;
<p/>
30.step(180,<nbsp/>10)<nbsp/>do<nbsp/>|rot|
<nbsp/><nbsp/><nbsp/><nbsp/>excelchart['Rotation']<nbsp/>=<nbsp/>rot
end
<p/>
excelchart2<nbsp/>=<nbsp/>workbook.Charts.Add();
excelchart3<nbsp/>=<nbsp/>workbook.Charts.Add();
<p/>
charts<nbsp/>=<nbsp/>workbook.Charts
charts.each<nbsp/>{<nbsp/>|i|<nbsp/>puts<nbsp/>i<nbsp/>}
<p/>
excel.ActiveWorkbook.Close(0);
excel.Quit();
</alltt>
</codefragment>
<subsection>Optimizing</subsection>
<p/>
As with most (if not all) high-level languages, it can be all too easy
to churn out code that is unbearably slow, but that can be easily
fixed with a little thought.
<p/>
With <classname>WIN32OLE</classname>, you need to be careful with unnecessary dynamic
lookups.  Where possible, it is better to assign a <classname>WIN32OLE</classname> object
to a variable and then reference elements from it, rather than
creating a long chain of ``.'' expressions.
<p/>
For example, instead of writing
<p/>
<codefragment>
<alltt><fullcode><![CDATA[      workbook.Worksheets(1).Range("A1").value = 1
      workbook.Worksheets(1).Range("A2").value = 2
      workbook.Worksheets(1).Range("A3").value = 4
      workbook.Worksheets(1).Range("A4").value = 8
]]></fullcode>
workbook.Worksheets(1).Range("A1").value<nbsp/>=<nbsp/>1
workbook.Worksheets(1).Range("A2").value<nbsp/>=<nbsp/>2
workbook.Worksheets(1).Range("A3").value<nbsp/>=<nbsp/>4
workbook.Worksheets(1).Range("A4").value<nbsp/>=<nbsp/>8
</alltt>
</codefragment>
<p/>
we can eliminate the common subexpressions by
saving the first part of the expression to a temporary
variable and then make calls from that variable:
<p/>
<codefragment>
<alltt><fullcode><![CDATA[      worksheet = workbook.Worksheets(1)

      worksheet.Range("A1").value = 1
      worksheet.Range("A2").value = 2
      worksheet.Range("A3").value = 4
      worksheet.Range("A4").value = 8
]]></fullcode>
worksheet<nbsp/>=<nbsp/>workbook.Worksheets(1)
<p/>
worksheet.Range("A1").value<nbsp/>=<nbsp/>1
worksheet.Range("A2").value<nbsp/>=<nbsp/>2
worksheet.Range("A3").value<nbsp/>=<nbsp/>4
worksheet.Range("A4").value<nbsp/>=<nbsp/>8
</alltt>
</codefragment>
</chapter>
</ppdoc>