Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options
 
PerlMonks  

Re^2: Unable to capture mouse events in Win32::Console

by fireblood (Scribe)
on Apr 26, 2022 at 03:50 UTC ( #11143297=note: print w/replies, xml ) Need Help??


in reply to Re: Unable to capture mouse events in Win32::Console
in thread Unable to capture mouse events in Win32::Console

Hi Anonymous, thanks for replying so quickly. Actually, I had seen that sample code previously, and had downloaded and run it, and found that although it displayed amazing graphics, it too did not respond to my mouse clicks. I also noticed that it did not have a $console -> Alloc () instruction anywhere, which I initially thought might be why neither it nor my program responded to mouse events, because I did not have a $console -> Alloc either. However, when I added a $console -> Alloc () instruction to my code, the window in which my program was running would instantly vanish as soon as the $console -> Alloc instruction was reached. So I fiddled with $console -> Free () with it for a while, to no avail, and finally removed the $console -> Alloc instruction again.

I have now revised my code to eliminate the 1-second sleep. By commenting one instruction or not, I can make it sleep only a hundredth of a second or not sleep at all, with the results being the same, viz. no mouse events are detected. This is the revised code:

use strict; use warnings; use Time::HiRes qw (usleep); use Win32; use Win32::Console; my $console; my @console_event; undef $/; unless ($console = new Win32::Console STD_INPUT_HANDLE) { print STDERR "\nSomething has gone wrong with the Win32::Conso +le constructor: $!\n\n"; die; } $console -> Mode (ENABLE_MOUSE_INPUT); print "Perl version $^V running on ", join (" ", Win32::GetOSName), ". +\n\n"; print "Your mouse has ", $console->MouseButtons(), " buttons.\n\n"; print "Go ahead, make my day ...\n\n"; my $start_time = time (); my $when_to_stop_waiting = $start_time + 15; while (time () < $when_to_stop_waiting) { if ($console -> GetEvents ()) { @console_event = $console -> Input (); print "A console event has been detected. Its attribu +tes are the following:\n\n"; print "$_\n" for @console_event; print "\nGood job.\n"; exit; # exit the program, do not fall through to t +hat final print instruction } else { usleep 100; # sleep for 10 milliseconds, i.e. a +hundredth of a second, to prevent # this program from getting into a r +eally tight loop and crowding out # everyone else, but even without th +is usleep instruction the mouse # clicks are still not detected } } print "The time to stop waiting has been reached. Your input was not d +etected.\n"; print "Better luck after seeking the wisdom of the monks.\n";

When I run this revised version and press any key, the following is generated:

Go ahead, make my day ... A console event has been detected. Its attributes are the following: 1 1 1 70 33 102 32 Good job.

But as before, I can click on the mouse all night, and this is what is generated:

H:\sandbox>perl capture_mouse_events.pl Perl version v5.32.0 running on Win10 Build 18363 (64-bit). Your mouse has 16 buttons. Go ahead, make my day ... The time to stop waiting has been reached. Your input was not detected +. Better luck after seeking the wisdom of the monks. H:\sandbox>

I've thought about re-writing my application in Win32::GUI but it would involve writing a lot more code creating and managing the window entirely within the program, not just hooking into a pre-existing console as with Win32::Console.

Replies are listed 'Best First'.
Re^3: Unable to capture mouse events in Win32::Console
by vr (Curate) on Apr 26, 2022 at 07:18 UTC

    replacing your Mode call with the following works for me.

    my $save = $console-> Mode; END { $console-> Mode( $save )}; $console-> Mode(( $save | 0x0010 ) & ~0x0040 ); # +MOUSE, -QUICK_EDIT

    Edit. Looks like either ENABLE_INSERT_MODE or ENABLE_EXTENDED_FLAGS are necessary in the mask (i.e. passing 0x30 or 0x90 as argument would work). Without them console continues to behave as if ENABLE_QUICK_EDIT_MODE is still on i.e. mouse selects text.

      Hi vr, This is really excellent. I made the changes that you recommended and now I am capturing mouse events in addition to keyboard events. I have one remaining question. I recall that there was a way to specify that mouse movements would not be captured, but everything else that was mouse-related, in particular mouse clicks, would be captured. I checked https://docs.microsoft.com/en-us/windows/console/setconsolemode but could not find it. I know that programmatically I can filter out mouse movement events, but then there would be a huge amount of CPU time spent in doing so. Is there a value that can be "or"ed or "and"ed to the values already being sent to the mode () method that prevents mouse movement events from being detected? Thanks again for your solution.
        I can filter out mouse movement events, but then there would be a huge amount of CPU time spent in doing so.

        There wouldn't. To begin with, Input blocks, you don't have to GetEvents at all, nor sleep/usleep. Next, if "event" is generated (or "message" is sent to application) in case of mouse motion, say, 20* times per second until motion ceases, it's "huge" amount of messages for a human, but your computer/CPU would hardly notice it has spent any time doing so and processing these messages per your instructions -- unless you yourself, as programmer, inadvertently put something time consuming/blocking into event loop.

        Have a look at e.g. Term::Choose (which works on top of guess-what Perl module when on Windows), where mouse motion is simply discarded ("filtered") every time, if I'm reading the source correctly. Plus, by the way, I was going to suggest it as kind of higher-level/friendlier/cross-platform/feature-rich text-mode UI toolkit instead of you rolling out your own event loop application with Win32::Console.

        (*) I'm sorry, I said "20", but can't, off the top of my hat, provide the exact figure (which probably depends on speed/distance) without googling.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://11143297]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others surveying the Monastery: (6)
As of 2022-12-01 16:01 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Notices?