How do I interrupt this?

G

Guest

I have a problem where I am sending a series of commands using P/Invoke's
SendInput function which may last up to a minute long. I want to offer the
user a way to break the commands by pressing the Pause/Break button. The
problem I have is it seems that my SendInput commands are being quickly
accepted and added to a buffer, because the only time my program ever
processes the Pause/Break key press event is after my SendInput commands are
done...

I use a Global System Hook to catch keyboard commands, and it is on at all
times listening to Pause/Break

Then elsewhere I am looping through a list of commands which get sent to
SendInput. They are not sent in an array but individually, and each call to
SendInput returns an int which I check to see if there was an error. Also,
prior to each SendInput command I do a Thread.sleep for times ranging from 20
to 800 ms depending on how the commands were recorded

No matter what I do, the only time my program even receives the key event
for Pause/Break as I press it is after I loop through all my SendInput
commands...

So what can I do to interrupt this? Why isn't it working?

If you are familiar with the code posted on codeproject.com in regard to
global system hook, you'll understand the following method I use to capture
key events for the whole system:

private void keyboardHook_KeyboardEvent(Kennedy.ManagedHooks.KeyboardEvents
kEvent, Keys key)
{

if (key == Keys.Pause)
{
Console.WriteLine("PAUSE/BREAK");
isPlaying = false;
}
}

I removed alot of logic for simplicity. Just showing that in the very
beginning, before doing any other checks I do a Console WriteLine when the
pause button is pressed. When I initially load my app, I can confirm thsi
whenever I press the button.

But then here is example of my code doing sendINput commands:

foreach (REvent ev in recording)
{
Thread.Sleep(ev.delay);

if (!isPlaying) return;

sendInput( --- );
}

this is also trimmed down for simplicity... its just a loop going through
each individual command in my recording, and I first sleep for a certain
amount of time, then I check the flag isPlaying which would have been turned
off if the keyEvent above was triggered, and only if the flag was on do I
continue to the next sendInput command.

But it never works. It goes through the entire recording and I can press
Pause/Break during the recording with no reaction. Finally once the recording
is done, do I see a whole bunch of Consoel WriteLines for every time I
pressed the Pause/Break button while the recording was being played....

why??
 
A

Arnshea

I have a problem where I am sending a series of commands using P/Invoke's
SendInput function which may last up to a minute long. I want to offer the
user a way to break the commands by pressing the Pause/Break button. The
problem I have is it seems that my SendInput commands are being quickly
accepted and added to a buffer, because the only time my program ever
processes the Pause/Break key press event is after my SendInput commands are
done...

I use a Global System Hook to catch keyboard commands, and it is on at all
times listening to Pause/Break

Then elsewhere I am looping through a list of commands which get sent to
SendInput. They are not sent in an array but individually, and each call to
SendInput returns an int which I check to see if there was an error. Also,
prior to each SendInput command I do a Thread.sleep for times ranging from 20
to 800 ms depending on how the commands were recorded

No matter what I do, the only time my program even receives the key event
for Pause/Break as I press it is after I loop through all my SendInput
commands...

So what can I do to interrupt this? Why isn't it working?

If you are familiar with the code posted on codeproject.com in regard to
global system hook, you'll understand the following method I use to capture
key events for the whole system:

private void keyboardHook_KeyboardEvent(Kennedy.ManagedHooks.KeyboardEvents
kEvent, Keys key)
{

if (key == Keys.Pause)
{
Console.WriteLine("PAUSE/BREAK");
isPlaying = false;
}
}

I removed alot of logic for simplicity. Just showing that in the very
beginning, before doing any other checks I do a Console WriteLine when the
pause button is pressed. When I initially load my app, I can confirm thsi
whenever I press the button.

But then here is example of my code doing sendINput commands:

foreach (REvent ev in recording)
{
Thread.Sleep(ev.delay);

if (!isPlaying) return;

sendInput( --- );
}

this is also trimmed down for simplicity... its just a loop going through
each individual command in my recording, and I first sleep for a certain
amount of time, then I check the flag isPlaying which would have been turned
off if the keyEvent above was triggered, and only if the flag was on do I
continue to the next sendInput command.

But it never works. It goes through the entire recording and I can press
Pause/Break during the recording with no reaction. Finally once the recording
is done, do I see a whole bunch of Consoel WriteLines for every time I
pressed the Pause/Break button while the recording was being played....

why??

Your UI thread is busy iterating over your list (recording). It won't
process the other messages (e.g., your key presses) until it's done.

If you want to be able to interrupt the method that's iterating over
your list you'll need to run that method on a separate thread.
Remember to marshal any UI method calls back onto their creating
thread.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top