@@ -159,14 +159,24 @@ def call(*args)
159
159
FILE_NAME_INFO = 2
160
160
ENABLE_VIRTUAL_TERMINAL_PROCESSING = 4
161
161
162
+ # Calling Win32API with console handle is reported to fail after executing some external command.
163
+ # We need to refresh console handle and retry the call again.
164
+ private def call_with_console_handle ( win32func , *args )
165
+ val = win32func . call ( @hConsoleHandle , *args )
166
+ return val if val != 0
167
+
168
+ @hConsoleHandle = @GetStdHandle . call ( STD_OUTPUT_HANDLE )
169
+ win32func . call ( @hConsoleHandle , *args )
170
+ end
171
+
162
172
private def getconsolemode
163
173
mode = "\000 \000 \000 \000 "
164
- @GetConsoleMode . call ( @hConsoleHandle , mode )
174
+ call_with_console_handle ( @GetConsoleMode , mode )
165
175
mode . unpack1 ( 'L' )
166
176
end
167
177
168
178
private def setconsolemode ( mode )
169
- @SetConsoleMode . call ( @hConsoleHandle , mode )
179
+ call_with_console_handle ( @SetConsoleMode , mode )
170
180
end
171
181
172
182
#if @legacy_console
@@ -334,7 +344,7 @@ def get_console_screen_buffer_info
334
344
# [18,2] dwMaximumWindowSize.X
335
345
# [20,2] dwMaximumWindowSize.Y
336
346
csbi = 0 . chr * 22
337
- return if @GetConsoleScreenBufferInfo . call ( @hConsoleHandle , csbi ) == 0
347
+ return if call_with_console_handle ( @GetConsoleScreenBufferInfo , csbi ) == 0
338
348
csbi
339
349
end
340
350
@@ -355,14 +365,14 @@ def cursor_pos
355
365
end
356
366
357
367
def move_cursor_column ( val )
358
- @SetConsoleCursorPosition . call ( @hConsoleHandle , cursor_pos . y * 65536 + val )
368
+ call_with_console_handle ( @SetConsoleCursorPosition , cursor_pos . y * 65536 + val )
359
369
end
360
370
361
371
def move_cursor_up ( val )
362
372
if val > 0
363
373
y = cursor_pos . y - val
364
374
y = 0 if y < 0
365
- @SetConsoleCursorPosition . call ( @hConsoleHandle , y * 65536 + cursor_pos . x )
375
+ call_with_console_handle ( @SetConsoleCursorPosition , y * 65536 + cursor_pos . x )
366
376
elsif val < 0
367
377
move_cursor_down ( -val )
368
378
end
@@ -374,7 +384,7 @@ def move_cursor_down(val)
374
384
screen_height = get_screen_size . first
375
385
y = cursor_pos . y + val
376
386
y = screen_height - 1 if y > ( screen_height - 1 )
377
- @SetConsoleCursorPosition . call ( @hConsoleHandle , ( cursor_pos . y + val ) * 65536 + cursor_pos . x )
387
+ call_with_console_handle ( @SetConsoleCursorPosition , ( cursor_pos . y + val ) * 65536 + cursor_pos . x )
378
388
elsif val < 0
379
389
move_cursor_up ( -val )
380
390
end
@@ -385,8 +395,8 @@ def erase_after_cursor
385
395
attributes = csbi [ 8 , 2 ] . unpack1 ( 'S' )
386
396
cursor = csbi [ 4 , 4 ] . unpack1 ( 'L' )
387
397
written = 0 . chr * 4
388
- @FillConsoleOutputCharacter . call ( @hConsoleHandle , 0x20 , get_screen_size . last - cursor_pos . x , cursor , written )
389
- @FillConsoleOutputAttribute . call ( @hConsoleHandle , attributes , get_screen_size . last - cursor_pos . x , cursor , written )
398
+ call_with_console_handle ( @FillConsoleOutputCharacter , 0x20 , get_screen_size . last - cursor_pos . x , cursor , written )
399
+ call_with_console_handle ( @FillConsoleOutputAttribute , attributes , get_screen_size . last - cursor_pos . x , cursor , written )
390
400
end
391
401
392
402
def scroll_down ( val )
@@ -404,7 +414,7 @@ def scroll_down(val)
404
414
scroll_rectangle = [ 0 , val , buffer_width , buffer_lines - val ] . pack ( 's4' )
405
415
destination_origin = 0 # y * 65536 + x
406
416
fill = [ ' ' . ord , attributes ] . pack ( 'SS' )
407
- @ScrollConsoleScreenBuffer . call ( @hConsoleHandle , scroll_rectangle , nil , destination_origin , fill )
417
+ call_with_console_handle ( @ScrollConsoleScreenBuffer , scroll_rectangle , nil , destination_origin , fill )
408
418
else
409
419
origin_x = x + 1
410
420
origin_y = y - window_top + 1
@@ -423,9 +433,9 @@ def clear_screen
423
433
fill_length = buffer_width * ( window_bottom - window_top + 1 )
424
434
screen_topleft = window_top * 65536
425
435
written = 0 . chr * 4
426
- @FillConsoleOutputCharacter . call ( @hConsoleHandle , 0x20 , fill_length , screen_topleft , written )
427
- @FillConsoleOutputAttribute . call ( @hConsoleHandle , attributes , fill_length , screen_topleft , written )
428
- @SetConsoleCursorPosition . call ( @hConsoleHandle , screen_topleft )
436
+ call_with_console_handle ( @FillConsoleOutputCharacter , 0x20 , fill_length , screen_topleft , written )
437
+ call_with_console_handle ( @FillConsoleOutputAttribute , attributes , fill_length , screen_topleft , written )
438
+ call_with_console_handle ( @SetConsoleCursorPosition , screen_topleft )
429
439
else
430
440
@output . write "\e [2J" "\e [H"
431
441
end
@@ -439,14 +449,14 @@ def hide_cursor
439
449
size = 100
440
450
visible = 0 # 0 means false
441
451
cursor_info = [ size , visible ] . pack ( 'Li' )
442
- @SetConsoleCursorInfo . call ( @hConsoleHandle , cursor_info )
452
+ call_with_console_handle ( @SetConsoleCursorInfo , cursor_info )
443
453
end
444
454
445
455
def show_cursor
446
456
size = 100
447
457
visible = 1 # 1 means true
448
458
cursor_info = [ size , visible ] . pack ( 'Li' )
449
- @SetConsoleCursorInfo . call ( @hConsoleHandle , cursor_info )
459
+ call_with_console_handle ( @SetConsoleCursorInfo , cursor_info )
450
460
end
451
461
452
462
def set_winch_handler ( &handler )
0 commit comments