win32console 1.3.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,336 @@
1
+ # encoding: utf-8
2
+
3
+ #
4
+ # Win32::Console::ANSI
5
+ #
6
+ # Copyright 2004 - Gonzalo Garramuno
7
+ # Licensed under GNU General Public License or Perl's Artistic License
8
+ #
9
+ # Based on Perl's Win32::Console::ANSI
10
+ # Copyright (c) 2003 Jean-Louis Morel <jl_morel@bribes.org>
11
+ # Licensed under GNU General Public License or Perl's Artistic License
12
+ #
13
+ require "Win32/Console"
14
+
15
+
16
+ module Kernel
17
+
18
+ # Kernel#putc is equivalent to $stdout.putc, but
19
+ # it doesn't use $stdout.putc. We redefine it to do that
20
+ # so that it will buffer the escape sequences properly.
21
+ # See Win32::Console::ANSI::IO#putc
22
+ remove_method :putc
23
+ def putc(int)
24
+ $stdout.putc(int)
25
+ end
26
+
27
+ end
28
+
29
+ module Win32
30
+ class Console
31
+ module ANSI
32
+
33
+ class IO < IO
34
+
35
+ VERSION = '0.05'
36
+ DEBUG = nil
37
+
38
+ require "win32/registry"
39
+
40
+ include Win32::Console::Constants
41
+
42
+ # @todo: encode is another perl module
43
+ EncodeOk = false
44
+
45
+ # Retrieving the codepages
46
+ cpANSI = nil
47
+ Win32::Registry::HKEY_LOCAL_MACHINE.open('SYSTEM\CurrentControlSet\Control\Nls\CodePage' ) { |reg|
48
+ cpANSI = reg['ACP']
49
+ }
50
+
51
+ STDERR.puts "Unable to read Win codepage #{cpANSI}" if DEBUG && !cpANSI
52
+
53
+
54
+ cpANSI = 'cp'+(cpANSI ? cpANSI : '1252') # Windows codepage
55
+ OEM = Win32::Console::OutputCP()
56
+ cpOEM = 'cp' + OEM.to_s # DOS codepage
57
+ @@cp = cpANSI + cpOEM
58
+
59
+ STDERR.puts "EncodeOk=#{EncodeOk} cpANSI=#{cpANSI} "+
60
+ "cpOEM=#{cpOEM}" if DEBUG
61
+
62
+ @@color = { 30 => 0, # black foreground
63
+ 31 => FOREGROUND_RED, # red foreground
64
+ 32 => FOREGROUND_GREEN, # green foreground
65
+ 33 => FOREGROUND_RED|FOREGROUND_GREEN, # yellow foreground
66
+ 34 => FOREGROUND_BLUE, # blue foreground
67
+ 35 => FOREGROUND_BLUE|FOREGROUND_RED, # magenta foreground
68
+ 36 => FOREGROUND_BLUE|FOREGROUND_GREEN, # cyan foreground
69
+ 37 => FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE, # white foreground
70
+ 40 => 0, # black background
71
+ 41 => BACKGROUND_RED, # red background
72
+ 42 => BACKGROUND_GREEN, # green background
73
+ 43 => BACKGROUND_RED|BACKGROUND_GREEN, # yellow background
74
+ 44 => BACKGROUND_BLUE, # blue background
75
+ 45 => BACKGROUND_BLUE|BACKGROUND_RED, # magenta background
76
+ 46 => BACKGROUND_BLUE|BACKGROUND_GREEN, # cyan background
77
+ 47 => BACKGROUND_RED|BACKGROUND_GREEN|BACKGROUND_BLUE, # white background
78
+ }
79
+
80
+ def initialize
81
+ super(1,'w')
82
+ @Out = Win32::Console.new(STD_OUTPUT_HANDLE)
83
+ @x = @y = 0 # to save cursor position
84
+ @foreground = 7
85
+ @background = 0
86
+ @bold =
87
+ @underline =
88
+ @revideo =
89
+ @concealed = nil
90
+ @conv = 1 # char conversion by default
91
+ @buffer = []
92
+ STDERR.puts "Console Mode=#{@Out.Mode}" if DEBUG
93
+ end
94
+
95
+ # this redefined #putc buffers escape sequences but passes
96
+ # other values to #write as normal.
97
+ def putc(int)
98
+ if @buffer.empty?
99
+ unless int == ?\e
100
+ write(int.chr)
101
+ else
102
+ @buffer << int
103
+ end
104
+ else
105
+ @buffer << int
106
+ case int
107
+ when ?m, ?J, ?L, ?M, ?@, ?P, ?A, ?B, ?C, ?D,
108
+ ?E, ?F, ?G, ?H, ?f, ?s, ?u, ?U, ?K, ?X
109
+ write(@buffer.pack("c*"))
110
+ @buffer.clear
111
+ end
112
+ end
113
+ end
114
+
115
+ # #write checks if $stdout is going to the console
116
+ # or if it's being redirected.
117
+ # When to the console, it passes the string to
118
+ # _PrintString to be parsed for escape codes.
119
+ #
120
+ # When redirected, it passes to WriteFile to allow escape
121
+ # codes and all to be output. The application that is
122
+ # handling the redirected IO should handle coloring.
123
+ # For Ruby applications, this means requiring Win32Conole again.
124
+ def write(*s)
125
+ if redirected?
126
+ s.each{ |x| @Out.WriteFile(x.dup.to_s) }
127
+ else
128
+ s.each{ |x| _PrintString(x) }
129
+ end
130
+ end
131
+
132
+ # returns true if outputs is being redirected.
133
+ def redirected?
134
+ @Out.Mode > 31
135
+ end
136
+
137
+ private
138
+
139
+ def _PrintString(t)
140
+ s = t.dup.to_s
141
+ while s != ''
142
+ if s.sub!( /([^\e]*)?\e([\[\(])([0-9\;\=]*)([a-zA-Z@])(.*)/, '\5')
143
+ @Out.Write((_conv("#$1")))
144
+ if $2 == '['
145
+ case $4
146
+ when 'm' # ESC[#;#;....;#m Set display attributes
147
+ attributs = $3.split(';')
148
+ attributs.push(nil) unless attributs # ESC[m == ESC[;m ==...==ESC[0m
149
+ attributs.each do |attr|
150
+ atv = attr.to_i
151
+ case atv
152
+ when 0 # ESC[0m reset
153
+ @foreground = 7
154
+ @background = 0
155
+ @bold =
156
+ @underline =
157
+ @revideo =
158
+ @concealed = nil
159
+ when 1
160
+ @bold = 1
161
+ when 21
162
+ @bold = nil
163
+ when 4
164
+ @underline = 1
165
+ when 24
166
+ @underline = nil
167
+ when 7
168
+ @revideo = 1
169
+ when 27
170
+ @revideo = nil
171
+ when 8
172
+ @concealed = 1
173
+ when 28
174
+ @concealed = nil
175
+ when 30..37
176
+ @foreground = atv - 30
177
+ when 40..47
178
+ @background = atv - 40
179
+ end
180
+ end
181
+
182
+ if @revideo
183
+ attribut = @@color[40+@foreground] |
184
+ @@color[30+@background]
185
+ else
186
+ attribut = @@color[30+@foreground] |
187
+ @@color[40+@background]
188
+ end
189
+ attribut |= FOREGROUND_INTENSITY if @bold
190
+ attribut |= BACKGROUND_INTENSITY if @underline
191
+ @Out.Attr(attribut)
192
+ when 'J'
193
+ if !$3 or $3 == '' # ESC[0J from cursor to end of display
194
+ info = @Out.Info()
195
+ s = ' ' * ((info[1]-info[3]-1)*info[0]+info[0]-info[2]-1)
196
+ @Out.WriteChar(s, info[2], info[3])
197
+ @Out.Cursor(info[2], info[3])
198
+ elsif $3 == '1' # ESC[1J erase from start to cursor.
199
+ info = @Out.Info()
200
+ s = ' ' * (info[3]*info[0]+info[2]+1)
201
+ @Out.WriteChar(s, 0, 0)
202
+ @Out.Cursor(info[2], info[3])
203
+ elsif $3 == '2' # ESC[2J Clear screen and home cursor
204
+ @Out.Cls()
205
+ @Out.Cursor(0, 0)
206
+ else
207
+ STDERR.print "\e#$2#$3#$4" if DEBUG # if ESC-code not implemented
208
+ end
209
+ when 'K'
210
+ info = @Out.Info()
211
+ if !$3 or $3 == '' # ESC[0K Clear to end of line
212
+ s = ' ' * (info[7]-info[2]+1)
213
+ @Out.Write(s)
214
+ @Out.Cursor(info[2], info[3])
215
+ elsif $3=='1' # ESC[1K Clear from start of line to cursor
216
+ s = ' '*(info[2]+1)
217
+ @Out.WriteChar(s, 0, info[3])
218
+ @Out.Cursor(info[2], info[3])
219
+ elsif $3=='2' # ESC[2K Clear whole line.
220
+ s = ' '* info[0]
221
+ @Out.WriteChar(s, 0, info[3])
222
+ @Out.Cursor(info[2], info[3])
223
+ end
224
+ when 'L' # ESC[#L Insert # blank lines.
225
+ n = $3 == ''? 1 : $3.to_i # ESC[L == ESC[1L
226
+ info = @Out.Info()
227
+ @Out.Scroll(0, info[3], info[0]-1, info[1]-1,
228
+ 0, info[3] + n.to_i,
229
+ ' '[0], @Out.Attr(),
230
+ 0, 0, 10000, 10000)
231
+ @Out.Cursor(info[2], info[3])
232
+ when 'M' # ESC[#M Delete # line.
233
+ n = $3 == ''? 1 : $3.to_i # ESC[M == ESC[1M
234
+ info = @Out.Info();
235
+ @Out.Scroll(0, info[3]+n, info[0]-1, info[1]-1,
236
+ 0, info[3],
237
+ ' '[0], @Out.Attr(),
238
+ 0, 0, 10000, 10000)
239
+ @Out.Cursor(info[2], info[3])
240
+ when 'P' # ESC[#P Delete # characters.
241
+ n = $3 == ''? 1 : $3.to_i # ESC[P == ESC[1P
242
+ info = @Out.Info()
243
+ n = info[0]-info[2] if info[2]+n > info[0]-1
244
+ @Out.Scroll(info[2]+n, info[3] , info[0]-1, info[3],
245
+ info[2], info[3],
246
+ ' '[0], @Out.Attr(),
247
+ 0, 0, 10000, 10000)
248
+ s = ' ' * n
249
+ @Out.Cursor(info[0]-n, info[3])
250
+ @Out.Write(s)
251
+ @Out.Cursor(info[2], info[3])
252
+ when '@' # ESC[#@ Insert # blank Characters
253
+ s = ' ' * $3.to_i
254
+ info = @Out.Info()
255
+ s << @Out.ReadChar(info[7]-info[2]+1, info[2], info[3])
256
+ s = s[0..-($3.to_i)]
257
+ @Out.Write(s);
258
+ @Out.Cursor(info[2], info[3])
259
+ when 'A' # ESC[#A Moves cursor up # lines
260
+ (x, y) = @Out.Cursor()
261
+ n = $3 == ''? 1 : $3.to_i; # ESC[A == ESC[1A
262
+ @Out.Cursor(x, y-n)
263
+ when 'B' # ESC[#B Moves cursor down # lines
264
+ (x, y) = @Out.Cursor()
265
+ n = $3 == ''? 1 : $3.to_i; # ESC[B == ESC[1B
266
+ @Out.Cursor(x, y+n)
267
+ when 'C' # ESC[#C Moves cursor forward # spaces
268
+ (x, y) = @Out.Cursor()
269
+ n = $3 == ''? 1 : $3.to_i; # ESC[C == ESC[1C
270
+ @Out.Cursor(x+n, y)
271
+ when 'D' # ESC[#D Moves cursor back # spaces
272
+ (x, y) = @Out.Cursor()
273
+ n = $3 == ''? 1 : $3.to_i; # ESC[D == ESC[1D
274
+ @Out.Cursor(x-n, y)
275
+ when 'E' # ESC[#E Moves cursor down # lines, column 1.
276
+ x, y = @Out.Cursor()
277
+ n = $3 == ''? 1 : $3.to_i; # ESC[E == ESC[1E
278
+ @Out.Cursor(0, y+n)
279
+ when 'F' # ESC[#F Moves cursor up # lines, column 1.
280
+ x, y = @Out.Cursor()
281
+ n = $3 == ''? 1 : $3.to_i; # ESC[F == ESC[1F
282
+ @Out.Cursor(0, y-n)
283
+ when 'G' # ESC[#G Moves cursor column # in current row.
284
+ x, y = @Out.Cursor()
285
+ n = $3 == ''? 1 : $3.to_i; # ESC[G == ESC[1G
286
+ @Out.Cursor(n-1, y)
287
+ when 'f' # ESC[#;#f Moves cursor to line #, column #
288
+ y, x = $3.split(';')
289
+ x = 1 unless x # ESC[;5H == ESC[1;5H ...etc
290
+ y = 1 unless y
291
+ @Out.Cursor(x.to_i-1, y.to_i-1) # origin (0,0) in DOS console
292
+ when 'H' # ESC[#;#H Moves cursor to line #, column #
293
+ y, x = $3.split(';')
294
+ x = 1 unless x # ESC[;5H == ESC[1;5H ...etc
295
+ y = 1 unless y
296
+ @Out.Cursor(x.to_i-1, y.to_i-1) # origin (0,0) in DOS console
297
+ when 's' # ESC[s Saves cursor position for recall later
298
+ (@x, @y) = @Out.Cursor()
299
+ when 'u' # ESC[u Return to saved cursor position
300
+ @Out.Cursor(@x, @y)
301
+ when 'U' # ESC(U no mapping
302
+ @conv = nil
303
+ when 'K' # ESC(K mapping if it exist
304
+ @Out.OutputCP(OEM) # restore original codepage
305
+ @conv = 1
306
+ when 'X' # ESC(#X codepage **EXPERIMENTAL**
307
+ @conv = nil
308
+ @Out.OutputCP($3)
309
+ else
310
+ STDERR.puts "\e#$2#$3#$4 not implemented" if DEBUG # ESC-code not implemented
311
+ end
312
+ end
313
+ else
314
+ @Out.Write(_conv(s))
315
+ s=''
316
+ end
317
+ end
318
+ end
319
+
320
+ def _conv(s)
321
+ if @concealed
322
+ s.gsub!( /\S/,' ')
323
+ end
324
+ return s
325
+ end
326
+
327
+ end
328
+
329
+ # end print overloading
330
+
331
+ end
332
+ end
333
+ end
334
+
335
+ $stdout = Win32::Console::ANSI::IO.new()
336
+
@@ -0,0 +1,342 @@
1
+
2
+ # The actual api to access windows functions
3
+ module Win32
4
+ class Console
5
+ class API
6
+ require 'Win32API'
7
+
8
+ class << self
9
+
10
+ def constant(t)
11
+ begin
12
+ return Win32::Console::Constants.const_get(t)
13
+ rescue
14
+ return nil
15
+ end
16
+ end
17
+
18
+ def AllocConsole()
19
+ @AllocConsole ||= Win32API.new( "kernel32", "AllocConsole", [], 'l' )
20
+ @AllocConsole.call()
21
+ end
22
+
23
+ def CreateConsoleScreenBuffer( dwDesiredAccess, dwShareMode, dwFlags )
24
+ @CreateConsoleScreenBuffer ||= Win32API.new( "kernel32", "CreateConsoleScreenBuffer", ['l', 'l', 'p', 'l', 'p'], 'l' )
25
+ @CreateConsoleScreenBuffer.call( dwDesiredAccess, dwShareMode, nil, dwFlags, nil )
26
+ end
27
+
28
+ def FillConsoleOutputAttribute( hConsoleOutput, wAttribute, nLength, col, row )
29
+ @FillConsoleOutputAttribute ||= Win32API.new( "kernel32", "FillConsoleOutputAttribute", ['l', 'i', 'l', 'l', 'p'], 'l' )
30
+ dwWriteCoord = (row << 16) + col
31
+ lpNumberOfAttrsWritten = ' ' * 4
32
+ @FillConsoleOutputAttribute.call( hConsoleOutput, wAttribute, nLength, dwWriteCoord, lpNumberOfAttrsWritten )
33
+ return lpNumberOfAttrsWritten.unpack('L')
34
+ end
35
+
36
+ def FillConsoleOutputCharacter( hConsoleOutput, cCharacter, nLength, col, row )
37
+ @FillConsoleOutputCharacter ||= Win32API.new( "kernel32", "FillConsoleOutputCharacter", ['l', 'i', 'l', 'l', 'p'], 'l' )
38
+ dwWriteCoord = (row << 16) + col
39
+ lpNumberOfAttrsWritten = ' ' * 4
40
+ @FillConsoleOutputCharacter.call( hConsoleOutput, cCharacter, nLength, dwWriteCoord, lpNumberOfAttrsWritten )
41
+ return lpNumberOfAttrsWritten.unpack('L')
42
+ end
43
+
44
+ def FlushConsoleInputBuffer( hConsoleInput )
45
+ @FlushConsoleInputBuffer ||= Win32API.new( "kernel32", "FillConsoleInputBuffer", ['l'], 'l' )
46
+ @FlushConsoleInputBuffer.call( hConsoleInput )
47
+ end
48
+
49
+ def FreeConsole()
50
+ @FreeConsole ||= Win32API.new( "kernel32", "FreeConsole", [], 'l' )
51
+ @FreeConsole.call()
52
+ end
53
+
54
+ def GenerateConsoleCtrlEvent( dwCtrlEvent, dwProcessGroupId )
55
+ @GenerateConsoleCtrlEvent ||= Win32API.new( "kernel32", "GenerateConsoleCtrlEvent", ['l', 'l'], 'l' )
56
+ @GenerateConsoleCtrlEvent.call( dwCtrlEvent, dwProcessGroupId )
57
+ end
58
+
59
+ def GetConsoleCP()
60
+ @GetConsoleCP ||= Win32API.new( "kernel32", "GetConsoleCP", [], 'l' )
61
+ @GetConsoleCP.call()
62
+ end
63
+
64
+ def GetConsoleCursorInfo( hConsoleOutput )
65
+ @GetConsoleCursorInfo ||= Win32API.new( "kernel32", "GetConsoleCursorInfo", ['l', 'p'], 'l' )
66
+ lpConsoleCursorInfo = ' ' * 8
67
+ @GetConsoleCursorInfo.call( hConsoleOutput, lpConsoleCursorInfo )
68
+ return lpConsoleCursorInfo.unpack('LL')
69
+ end
70
+
71
+ def GetConsoleMode( hConsoleHandle )
72
+ @GetConsoleMode ||= Win32API.new( "kernel32", "GetConsoleMode", ['l', 'p'], 'l' )
73
+ lpMode = ' ' * 4
74
+ @GetConsoleMode.call( hConsoleHandle, lpMode )
75
+ return lpMode.unpack('L').first
76
+ end
77
+
78
+ def GetConsoleOutputCP()
79
+ @GetConsoleOutputCP ||= Win32API.new( "kernel32", "GetConsoleOutputCP", [], 'l' )
80
+ @GetConsoleOutputCP.call()
81
+ end
82
+
83
+ def GetConsoleScreenBufferInfo( hConsoleOutput )
84
+ @GetConsoleScreenBufferInfo ||= Win32API.new( "kernel32", "GetConsoleScreenBufferInfo", ['l', 'p'], 'l' )
85
+ lpBuffer = ' ' * 22
86
+ @GetConsoleScreenBufferInfo.call( hConsoleOutput, lpBuffer )
87
+ return lpBuffer.unpack('SSSSSssssSS')
88
+ end
89
+
90
+ def GetConsoleTitle()
91
+ @GetConsoleTitle ||= Win32API.new( "kernel32", "GetConsoleTitle", ['p', 'l'], 'l' )
92
+ nSize = 120
93
+ lpConsoleTitle = ' ' * nSize
94
+ @GetConsoleTitle.call( lpConsoleTitle, nSize )
95
+ return lpConsoleTitle.strip
96
+ end
97
+
98
+ def GetConsoleWindow()
99
+ @GetConsoleWindow ||= Win32API.new( "kernel32", "GetConsoleWindow",[], 'l' )
100
+ @GetConsoleWindow.call()
101
+ end
102
+
103
+ def GetLargestConsoleWindowSize( hConsoleOutput )
104
+ @GetLargestConsoleWindowSize ||= Win32API.new( "kernel32", "GetLargestConsoleWindowSize", ['l'], 'l' )
105
+ coord = @GetLargestConsoleWindowSize.call( hConsoleOutput )
106
+ x = coord >> 16
107
+ y = coord & 0x0000ffff
108
+ return [x,y]
109
+ end
110
+
111
+ def GetNumberOfConsoleInputEvents( hConsoleInput )
112
+ @GetNumberOfConsoleInputEvents ||= Win32API.new( "kernel32", "GetNumberOfConsoleInputEvents", ['l', 'p'], 'l' )
113
+ lpcNumberOfEvents = 0
114
+ @GetNumberOfConsoleInputEvents.call( hConsoleInput, lpcNumberOfEvents )
115
+ return lpcNumberOfEvents
116
+ end
117
+
118
+ def GetNumberOfConsoleMouseButtons( )
119
+ @GetNumberOfConsoleMouseButtons ||= Win32API.new( "kernel32", "GetNumberOfConsoleMouseButtons", ['p'], 'l' )
120
+ lpNumberOfMouseButtons = 0
121
+ @GetNumberOfConsoleMouseButtons.call( lpNumberOfMouseButtons )
122
+ return lpNumberOfMouseButtons
123
+ end
124
+
125
+ def GetStdHandle( nStdHandle )
126
+ @GetStdHandle ||= Win32API.new( "kernel32", "GetStdHandle", ['l'], 'l' )
127
+ @GetStdHandle.call( nStdHandle )
128
+ end
129
+
130
+ # <<HandlerRoutine>> : This is not an actual API function, just a concept description in the SDK.
131
+
132
+ def PeekConsoleInput( hConsoleInput )
133
+ @PeekConsoleInput ||= Win32API.new( "kernel32", "PeekConsoleInput", ['l', 'p', 'l', 'p'], 'l' )
134
+ lpNumberOfEventsRead = ' ' * 4
135
+ lpBuffer = ' ' * 20
136
+ nLength = 20
137
+ @PeekConsoleInput.call( hConsoleInput, lpBuffer, nLength, lpNumberOfEventsRead )
138
+ type = lpBuffer.unpack('s')[0]
139
+
140
+ case type
141
+ when KEY_EVENT
142
+ return lpBuffer.unpack('sSSSSCS')
143
+ when MOUSE_EVENT
144
+ return lpBuffer.unpack('sSSSS')
145
+ when WINDOW_BUFFER_SIZE_EVENT
146
+ return lpBuffer.unpack('sS')
147
+ when MENU_EVENT
148
+ return lpBuffer.unpack('sS')
149
+ when FOCUS_EVENT
150
+ return lpBuffer.unpack('sS')
151
+ else
152
+ return []
153
+ end
154
+ end
155
+
156
+ def ReadConsole( hConsoleInput, lpBuffer, nNumberOfCharsToRead )
157
+ @ReadConsole ||= Win32API.new( "kernel32", "ReadConsole", ['l', 'p', 'l', 'p', 'p'], 'l' )
158
+ lpBuffer = ' ' * nNumberOfCharsToRead unless lpBuffer
159
+ lpNumberOfCharsRead = ' ' * 4
160
+ lpReserved = ' ' * 4
161
+ @ReadConsole.call( hConsoleInput, lpBuffer, nNumberOfCharsToRead, lpNumberOfCharsRead, lpReserved )
162
+ return lpNumberOfCharsRead.unpack('L')
163
+ end
164
+
165
+ def ReadConsoleInput( hConsoleInput )
166
+ @ReadConsoleInput ||= Win32API.new( "kernel32", "ReadConsoleInput", ['l', 'p', 'l', 'p'], 'l' )
167
+ lpNumberOfEventsRead = ' ' * 4
168
+ lpBuffer = ' ' * 20
169
+ nLength = 20
170
+ @ReadConsoleInput.call( hConsoleInput, lpBuffer, nLength,
171
+ lpNumberOfEventsRead )
172
+ type = lpBuffer.unpack('s')[0]
173
+
174
+ case type
175
+ when KEY_EVENT
176
+ return lpBuffer.unpack('sSSSSCS')
177
+ when MOUSE_EVENT
178
+ return lpBuffer.unpack('sSSSS')
179
+ when WINDOW_BUFFER_SIZE_EVENT
180
+ return lpBuffer.unpack('sS')
181
+ when MENU_EVENT
182
+ return lpBuffer.unpack('sS')
183
+ when FOCUS_EVENT
184
+ return lpBuffer.unpack('sS')
185
+ else
186
+ return []
187
+ end
188
+ end
189
+
190
+ def ReadConsoleOutput( hConsoleOutput, lpBuffer, cols, rows, bufx, bufy, left, top, right, bottom )
191
+ @ReadConsoleOutput ||= Win32API.new( "kernel32", "ReadConsoleOutput", ['l', 'p', 'l', 'l', 'p'], 'l' )
192
+ dwBufferSize = cols * rows * 4
193
+ lpBuffer = ' ' * dwBufferSize
194
+ dwBufferCoord = (bufy << 16) + bufx
195
+ lpReadRegion = [ left, top, right, bottom ].pack('ssss')
196
+ @ReadConsoleOutput.call( hConsoleOutput, lpBuffer, dwBufferSize,
197
+ dwBufferCoord, lpReadRegion )
198
+ end
199
+
200
+ def ReadConsoleOutputAttribute( hConsoleOutput, nLength, col, row )
201
+ @ReadConsoleOutputAttribute ||= Win32API.new( "kernel32", "ReadConsoleOutputAttribute", ['l', 'p', 'l', 'l', 'p'], 'l' )
202
+ lpAttribute = ' ' * nLength
203
+ dwReadCoord = (row << 16) + col
204
+ lpNumberOfAttrsRead = ' ' * 4
205
+ @ReadConsoleOutputAttribute.call( hConsoleOutput, lpAttribute, nLength, dwReadCoord, lpNumberOfAttrsRead )
206
+ return lpAttribute
207
+ end
208
+
209
+ def ReadConsoleOutputCharacter( hConsoleOutput, lpCharacter, nLength, col, row )
210
+ @ReadConsoleOutputCharacter ||= Win32API.new( "kernel32", "ReadConsoleOutputCharacter", ['l', 'p', 'l', 'l', 'p'], 'l' )
211
+ dwReadCoord = (row << 16) + col
212
+ lpNumberOfCharsRead = ' ' * 4
213
+ @ReadConsoleOutputCharacter.call( hConsoleOutput, lpCharacter, nLength, dwReadCoord, lpNumberOfCharsRead )
214
+ return lpNumberOfCharsRead.unpack('L')
215
+ end
216
+
217
+ def ScrollConsoleScreenBuffer( hConsoleOutput, left1, top1, right1, bottom1,col, row, char, attr, left2, top2, right2, bottom2 )
218
+ @ScrollConsoleScreenBuffer ||= Win32API.new( "kernel32", "ScrollConsoleScreenBuffer", ['l', 'p', 'p', 'l', 'p'], 'l' )
219
+ lpScrollRectangle = [left1, top1, right1, bottom1].pack('ssss')
220
+ lpClipRectangle = [left2, top2, right2, bottom2].pack('ssss')
221
+ dwDestinationOrigin = (row << 16) + col
222
+ lpFill = [char, attr].pack('ss')
223
+ @ScrollConsoleScreenBuffer.call( hConsoleOutput, lpScrollRectangle, lpClipRectangle, dwDestinationOrigin, lpFill )
224
+ end
225
+
226
+ def SetConsoleActiveScreenBuffer( hConsoleOutput )
227
+ @SetConsoleActiveScreenBuffer ||= Win32API.new( "kernel32", "SetConsoleActiveScreenBuffer", ['l'], 'l' )
228
+ @SetConsoleActiveScreenBuffer.call( hConsoleOutput )
229
+ end
230
+
231
+ # <<SetConsoleCtrlHandler>>: Will probably not be implemented.
232
+
233
+ def SetConsoleCP( wCodePageID )
234
+ @SetConsoleCP ||= Win32API.new( "kernel32", "SetConsoleCP", ['l'], 'l' )
235
+ @SetConsoleCP.call( wCodePageID )
236
+ end
237
+
238
+ def SetConsoleCursorInfo( hConsoleOutput, col, row )
239
+ @SetConsoleCursorInfo ||= Win32API.new( "kernel32", "SetConsoleCursorInfo", ['l', 'p'], 'l' )
240
+ lpConsoleCursorInfo = [size,visi].pack('LL')
241
+ @SetConsoleCursorInfo.call( hConsoleOutput, lpConsoleCursorInfo )
242
+ end
243
+
244
+ def SetConsoleCursorPosition( hConsoleOutput, col, row )
245
+ @SetConsoleCursorPosition ||= Win32API.new( "kernel32", "SetConsoleCursorPosition", ['l', 'p'], 'l' )
246
+ dwCursorPosition = (row << 16) + col
247
+ @SetConsoleCursorPosition.call( hConsoleOutput, dwCursorPosition )
248
+ end
249
+
250
+ def SetConsoleMode( hConsoleHandle, lpMode )
251
+ @SetConsoleMode ||= Win32API.new( "kernel32", "SetConsoleMode", ['l', 'p'], 'l' )
252
+ @SetConsoleMode.call( hConsoleHandle, lpMode )
253
+ end
254
+
255
+ def SetConsoleOutputCP( wCodePageID )
256
+ @SetConsoleOutputCP ||= Win32API.new( "kernel32", "GetConsoleOutputCP", ['l'], 'l' )
257
+ @SetConsoleOutputCP.call( wCodePageID )
258
+ end
259
+
260
+ def SetConsoleScreenBufferSize( hConsoleOutput, col, row )
261
+ @SetConsoleScreenBufferSize ||= Win32API.new( "kernel32", "SetConsoleScreenBufferSize", ['l', 'l'], 'l' )
262
+ dwSize = (row << 16) + col
263
+ @SetConsoleScreenBufferSize.call( hConsoleOutput, dwSize )
264
+ end
265
+
266
+ def SetConsoleTextAttribute( hConsoleOutput, wAttributes )
267
+ @SetConsoleTextAttribute ||= Win32API.new( "kernel32", "SetConsoleTextAttribute", ['l', 'i'], 'l' )
268
+ @SetConsoleTextAttribute.call( hConsoleOutput, wAttributes )
269
+ end
270
+
271
+ def SetConsoleTitle( lpConsoleTitle )
272
+ @SetConsoleTitle ||= Win32API.new( "kernel32", "SetConsoleTitle", ['p'], 'l' )
273
+ @SetConsoleTitle.call( lpConsoleTitle )
274
+ end
275
+
276
+ def SetConsoleWindowInfo( hConsoleOutput, bAbsolute, left, top, right, bottom )
277
+ @SetConsoleWindowInfo ||= Win32API.new( "kernel32", "SetConsoleWindowInfo", ['l', 'l', 'p'], 'l' )
278
+ lpConsoleWindow = [ left, top, right, bottom ].pack('ssss')
279
+ @SetConsoleWindowInfo.call( hConsoleOutput, bAbsolute, lpConsoleWindow )
280
+ end
281
+
282
+ def SetStdHandle( nStdHandle, hHandle )
283
+ @SetStdHandle ||= Win32API.new( "kernel32", "SetStdHandle", ['l', 'l'], 'l' )
284
+ @SetStdHandle.call( nStdHandle, hHandle )
285
+ end
286
+
287
+ def WriteConsole( hConsoleOutput, lpBuffer )
288
+ @WriteConsole ||= Win32API.new( "kernel32", "WriteConsole", ['l', 'p', 'l', 'p', 'p'], 'l' )
289
+ nNumberOfCharsToWrite = lpBuffer.length()
290
+ lpNumberOfCharsWritten = ' ' * 4
291
+ lpReserved = ' ' * 4
292
+ @WriteConsole.call( hConsoleOutput, lpBuffer, nNumberOfCharsToWrite, lpNumberOfCharsWritten, lpReserved )
293
+ return lpNumberOfCharsWritten
294
+ end
295
+
296
+ def WriteFile( hConsoleOutput, lpBuffer )
297
+ @WriteFile ||= Win32API.new( "kernel32", "WriteFile", ['l', 'p', 'l', 'p', 'p'], 'l' )
298
+ nNumberOfBytesToWrite = lpBuffer.length()
299
+ lpNumberOfBytesWritten = ' ' * 4
300
+ lpReserved = nil
301
+ @WriteFile.call( hConsoleOutput, lpBuffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, lpReserved )
302
+ return lpNumberOfBytesWritten.unpack('L')
303
+ end
304
+
305
+ def WriteConsoleInput( hConsoleInput, lpBuffer )
306
+ @WriteConsoleInput ||= Win32API.new( "kernel32", "WriteConsoleInput", ['l', 'p', 'l', 'p'], 'l' )
307
+ @WriteConsoleInput.call( hConsoleInput, lpBuffer, nLength, lpNumberOfEventsWritten )
308
+ end
309
+
310
+ # @@ Todo: Test this
311
+ def WriteConsoleOutput( hConsoleOutput, buffer, cols, rows, bufx, bufy, left, top, right, bottom )
312
+ @WriteConsoleOutput ||= Win32API.new( "kernel32", "WriteConsoleOutput", ['l', 'p', 'l', 'l', 'p'], 'l' )
313
+ lpBuffer = buffer.flatten.pack('ss' * buffer.length() * 2)
314
+ dwBufferSize = (buffer.length() << 16) + 2
315
+ dwBufferCoord = (row << 16) + col
316
+ lpWriteRegion = [ left, top, right, bottom ].pack('ssss')
317
+ @WriteConsoleOutput.call( hConsoleOutput, lpBuffer, dwBufferSize, dwBufferCoord, lpWriteRegion )
318
+ end
319
+
320
+ def WriteConsoleOutputAttribute( hConsoleOutput, lpAttribute, col, row )
321
+ @WriteConsoleOutputAttribute ||= Win32API.new( "kernel32", "WriteConsoleOutputAttribute", ['l', 'p', 'l', 'l', 'p'], 'l' )
322
+ nLength = lpAttribute.length()
323
+ dwWriteCoord = (row << 16) + col
324
+ lpNumberOfAttrsWritten = ' ' * 4
325
+ @WriteConsoleOutputAttribute.call( hConsoleOutput, lpAttribute, nLength, dwWriteCoord, lpNumberOfAttrsWritten )
326
+ return lpNumberOfAttrsWritten.unpack('L')
327
+ end
328
+
329
+ def WriteConsoleOutputCharacter( hConsoleOutput, lpCharacter, col, row )
330
+ @WriteConsoleOutputCharacter ||= Win32API.new( "kernel32", "WriteConsoleOutputCharacter", ['l', 'p', 'l', 'l', 'p'], 'l' )
331
+ nLength = lpCharacter.length()
332
+ dwWriteCoord = (row << 16) + col
333
+ lpNumberOfCharsWritten = ' ' * 4
334
+ @WriteConsoleOutputCharacter.call( hConsoleOutput, lpCharacter, nLength, dwWriteCoord, lpNumberOfCharsWritten )
335
+ return lpNumberOfCharsWritten.unpack('L')
336
+ end
337
+
338
+ end
339
+ end
340
+ end
341
+
342
+ end