# This program displays details about console events that occur in the window in # wnich this program is running. This program creates a file called "event_log.txt" # in the current directory. # # References: # # https://docs.microsoft.com/en-us/windows/console/reading-input-buffer-events # # Definitions and values of constants such as ENABLE_* are available at the # following URL: # # https://docs.microsoft.com/en-us/windows/console/setconsolemode # BEGIN { select STDERR; $|++; # do not buffer STDERR select STDOUT; $|++; # do not buffer STDOUT system ("cls"); print "\n\n\tInitializing the environment ...\n\n\t"; }; use strict; use warnings; # The following package provides access to basic information about the runtime environment # such as the release of Windows under which this program is running use Win32; # The following package provides access to console events such as key presses and mouse clicks use Win32::Console; my $console; my @console_event; my @info; my $log_file = "event_log.txt"; my $fh_log_file; unless (open ($fh_log_file, ">", $log_file)) { print STDERR "\nCould not open $log_file: $!\n\n"; die; } unless ($console = Win32::Console -> new (STD_INPUT_HANDLE)) { print STDERR "\nSomething has gone wrong with the Win32::Console constructor: $!\n\n"; die; } $console -> Flush (); my $starting_console_mode_setting = $console -> Mode; END {$console -> Mode ($starting_console_mode_setting)}; # The following instruction is based on expertise provided by vr # at https://www.perlmonks.org/?node_id=11143316 $console -> Mode ((($starting_console_mode_setting | 0x0010 ) & ~0x0040 ) & ~ENABLE_PROCESSED_INPUT); print "Perl version $^V running on ", join (" ", Win32::GetOSName), ".\n\n"; print $fh_log_file "Perl version $^V running on ", join (" ", Win32::GetOSName), ".\n\n"; # The following is to demonstrate that the $console environment has been set up print "Your mouse has ", $console->MouseButtons(), " buttons.\n\n"; print $fh_log_file "Your mouse has ", $console->MouseButtons(), " buttons.\n\n"; print "Enter keyboard activity or mouse events ...\n\n"; print $fh_log_file "Enter keyboard activity or mouse events ...\n\n"; my $start_time = time (); my $when_to_stop_listening = $start_time + 15; while (time () < $when_to_stop_listening) { if ($console -> GetEvents ()) # This may be unnecessary, can simply invoke Input () # and check if it has returned anything { @console_event = $console -> Input (); print "A console event has been detected. Its attributes are the following:\n\n"; print $fh_log_file "A console event has been detected. Its attributes are the following:\n\n"; print "Time of event: ", time (), "\n"; print $fh_log_file "Time of event: ", time (), "\n"; print "Type of event: "; print $fh_log_file "Type of event: "; if (defined ($console_event [0])) { if ($console_event [0] == 1) { print "Keyboard event.\n"; print $fh_log_file "Keyboard event.\n"; print "Key down: ", $console_event[1], "\n"; print $fh_log_file "Key down: ", $console_event[1], "\n"; print "Repeat count: ", $console_event[2], "\n"; print $fh_log_file "Repeat count: ", $console_event[2], "\n"; print "Virtual key code: ", $console_event[3], "\n"; print $fh_log_file "Virtual key code: ", $console_event[3], "\n"; print "Virtual scan code: ", $console_event[4], "\n"; print $fh_log_file "Virtual scan code: ", $console_event[4], "\n"; print "ASCII code: ", $console_event[5], "\n"; print $fh_log_file "ASCII code: ", $console_event[5], "\n"; print "ASCII code letter: ", chr $console_event[5], "\n"; print $fh_log_file "ASCII code letter: ", chr $console_event[5], "\n"; print "Control key state: ", $console_event[6], "\n"; print $fh_log_file "Control key state: ", $console_event[6], "\n"; } elsif ($console_event [0] == 2) { print "Mouse event.\n"; print $fh_log_file "Mouse event.\n"; print "Mouse X coord: ", $console_event[1], "\n"; print $fh_log_file "Mouse X coord: ", $console_event[1], "\n"; print "Mouse Y coord: ", $console_event[2], "\n"; print $fh_log_file "Mouse Y coord: ", $console_event[2], "\n"; print "Mouse button state: ", $console_event[3], "\n"; print $fh_log_file "Mouse button state: ", $console_event[3], "\n"; print "Control key state: ", $console_event[4], "\n"; print $fh_log_file "Control key state: ", $console_event[4], "\n"; print "Event flags: ", $console_event[5], "\n"; print $fh_log_file "Event flags: ", $console_event[5], "\n"; } else { print "Unknown type \"$console_event[0]\".\n"; print $fh_log_file "Unknown type \"$console_event[0]\".\n"; } print "\nAdditional information:\n"; print $fh_log_file "A\ndditional information:\n"; @info = $console -> Info (); # @info is supposed to contain the following elements: # # $info[0]: columns (X size) of the console buffer. # $info[1]: rows (Y size) of the console buffer. # $info[2]: current column (X position) of the cursor. # $info[3]: current row (Y position) of the cursor. # $info[4]: current attribute used for Write. # $info[5]: left column (X of the starting point) of the current console window. # $info[6]: top row (Y of the starting point) of the current console window. # $info[7]: right column (X of the final point) of the current console window. # $info[8]: bottom row (Y of the final point) of the current console window. # $info[9]: maximum number of columns for the console window, given the current buffer size, font and the screen size. # $info[10]: maximum number of rows for the console window, given the current buffer size, font and the screen size. # # but look at what is actually happening: print "The size of \@info is ", scalar @info, ".\n"; print $fh_log_file "The size of \@info is ", scalar @info, ".\n"; print "The value of \$info[0] is \"", $info[0], "\".\n"; print $fh_log_file "The value of \$info[0] is \"", $info[0], "\".\n"; print "\n"; print $fh_log_file "\n"; } else { print "undefined event type.\n"; print $fh_log_file "undefined event type.\n"; } print "\n"; print $fh_log_file "\n"; } } print "The time to stop listening has been reached. Program is ending.\n\n"; print $fh_log_file "The time to stop listening has been reached. Program is ending.\n\n";