While MouseDown
-
I am trying to do some events while the mouse button is down. Here is what I have private static bool IsKeyDown = false; private void button1_MouseDown(object sender, MouseEventArgs e) { IsKeyDown = true; while (IsKeyDown) { Winamp.Winamp.VolumeDown(); } } private void button1_MouseUp(object sender, MouseEventArgs e) { IsKeyDown = false; } The problem is when it hits the mouse down event It continues to run the while loop and does not hit the mouse up event. I don't want to use a timer to do this. I did see some code that I think will work better in my app but I cant seem to get it to work can some one please help. http://stackoverflow.com/questions/1152525/c-winform-looping-event-on-press-button[^] private bool mouseDown = false; private void buttonScrollUp_MouseDown(object sender, MouseEventArgs e) { mouseDown = true; new Thread(() => { while (mouseDown) { Invoke(new MethodInvoker(() => [DO_THE_SCROLLING_HERE)); Thread.Sleep([SET_AUTOREPEAT_TIMEOUT_HERE); } }) .Start(); } private void buttonScrollUp_MouseUp(object sender, MouseEventArgs e) { mouseDown = false; }
-
I am trying to do some events while the mouse button is down. Here is what I have private static bool IsKeyDown = false; private void button1_MouseDown(object sender, MouseEventArgs e) { IsKeyDown = true; while (IsKeyDown) { Winamp.Winamp.VolumeDown(); } } private void button1_MouseUp(object sender, MouseEventArgs e) { IsKeyDown = false; } The problem is when it hits the mouse down event It continues to run the while loop and does not hit the mouse up event. I don't want to use a timer to do this. I did see some code that I think will work better in my app but I cant seem to get it to work can some one please help. http://stackoverflow.com/questions/1152525/c-winform-looping-event-on-press-button[^] private bool mouseDown = false; private void buttonScrollUp_MouseDown(object sender, MouseEventArgs e) { mouseDown = true; new Thread(() => { while (mouseDown) { Invoke(new MethodInvoker(() => [DO_THE_SCROLLING_HERE)); Thread.Sleep([SET_AUTOREPEAT_TIMEOUT_HERE); } }) .Start(); } private void buttonScrollUp_MouseUp(object sender, MouseEventArgs e) { mouseDown = false; }
-
Zap-Man wrote:
private static bool IsKeyDown = false;
Confused. Can this variable be changed ever? Correct me if I am wrong...:)
yes it changes on the mouse down to true. but the mouse up event never fires because the loop has not finished. but it will change in the mouse up event. if the value never changed then I would have to set it to const or read only. A static variable will change. private means this variable is not accessible from another class. when the form is initialized the variable is set to false. When the mouseDown event is fired then the variable is set to true. This is working. the problem lies in the loop. Because it is in the loop the MouseUp event never executes.
-
I am trying to do some events while the mouse button is down. Here is what I have private static bool IsKeyDown = false; private void button1_MouseDown(object sender, MouseEventArgs e) { IsKeyDown = true; while (IsKeyDown) { Winamp.Winamp.VolumeDown(); } } private void button1_MouseUp(object sender, MouseEventArgs e) { IsKeyDown = false; } The problem is when it hits the mouse down event It continues to run the while loop and does not hit the mouse up event. I don't want to use a timer to do this. I did see some code that I think will work better in my app but I cant seem to get it to work can some one please help. http://stackoverflow.com/questions/1152525/c-winform-looping-event-on-press-button[^] private bool mouseDown = false; private void buttonScrollUp_MouseDown(object sender, MouseEventArgs e) { mouseDown = true; new Thread(() => { while (mouseDown) { Invoke(new MethodInvoker(() => [DO_THE_SCROLLING_HERE)); Thread.Sleep([SET_AUTOREPEAT_TIMEOUT_HERE); } }) .Start(); } private void buttonScrollUp_MouseUp(object sender, MouseEventArgs e) { mouseDown = false; }
Zap-Man wrote:
IsKeyDown = true; while (IsKeyDown) { Winamp.Winamp.VolumeDown(); }
This loop will never terminate so your event handler
button1_MouseDown
will never notify the framework that it is complete. This blocks your application from doing anything else, so you need to separate the functions somehow. BTW it helps if you put <pre></pre> tags around your code snippet so it is easier to read. -
I am trying to do some events while the mouse button is down. Here is what I have private static bool IsKeyDown = false; private void button1_MouseDown(object sender, MouseEventArgs e) { IsKeyDown = true; while (IsKeyDown) { Winamp.Winamp.VolumeDown(); } } private void button1_MouseUp(object sender, MouseEventArgs e) { IsKeyDown = false; } The problem is when it hits the mouse down event It continues to run the while loop and does not hit the mouse up event. I don't want to use a timer to do this. I did see some code that I think will work better in my app but I cant seem to get it to work can some one please help. http://stackoverflow.com/questions/1152525/c-winform-looping-event-on-press-button[^] private bool mouseDown = false; private void buttonScrollUp_MouseDown(object sender, MouseEventArgs e) { mouseDown = true; new Thread(() => { while (mouseDown) { Invoke(new MethodInvoker(() => [DO_THE_SCROLLING_HERE)); Thread.Sleep([SET_AUTOREPEAT_TIMEOUT_HERE); } }) .Start(); } private void buttonScrollUp_MouseUp(object sender, MouseEventArgs e) { mouseDown = false; }
Hi, this is all wrong. 1. event handlers get executed on the main thread (aka GUI thread), hence MouseUp cannot do anything as long as MouseDown is active. 2. Your while loop will never exit. 3. Your while loop has no delay, so at what rate will VolumeDown be called? 4. Using Thread.Sleep would not be a good approach as that blocks the GUI; using a timer (a Windows.Forms.Timer) is the perfect solution: start the timer on MouseDown, stop it on MouseUp (or better yet have the Tick handler check Control.MouseButtons).
Zap-Man wrote:
I don't want to use a timer
why? because you don't understand them? because you don't like a clean and natural solution? :)
Luc Pattyn
I only read code that is properly indented, and rendered in a non-proportional font; hint: use PRE tags in forum messages
Local announcement (Antwerp region): Lange Wapper? Neen!
-
I am trying to do some events while the mouse button is down. Here is what I have private static bool IsKeyDown = false; private void button1_MouseDown(object sender, MouseEventArgs e) { IsKeyDown = true; while (IsKeyDown) { Winamp.Winamp.VolumeDown(); } } private void button1_MouseUp(object sender, MouseEventArgs e) { IsKeyDown = false; } The problem is when it hits the mouse down event It continues to run the while loop and does not hit the mouse up event. I don't want to use a timer to do this. I did see some code that I think will work better in my app but I cant seem to get it to work can some one please help. http://stackoverflow.com/questions/1152525/c-winform-looping-event-on-press-button[^] private bool mouseDown = false; private void buttonScrollUp_MouseDown(object sender, MouseEventArgs e) { mouseDown = true; new Thread(() => { while (mouseDown) { Invoke(new MethodInvoker(() => [DO_THE_SCROLLING_HERE)); Thread.Sleep([SET_AUTOREPEAT_TIMEOUT_HERE); } }) .Start(); } private void buttonScrollUp_MouseUp(object sender, MouseEventArgs e) { mouseDown = false; }
private AutoResetEvent autoEvent = null; private void OnMouseDown(object sender, MouseEventArgs e) { autoEvent = new AutoResetEvent(false); ThreadPool.QueueUserWorkItem(VolumeDown); } private void OnMouseUp(object sender, MouseEventArgs e) { autoEvent.Set(); } private void VolumeDown(object state) { bool lowerVolume = true; do { BeginInvoke(new MethodInvoker(delegate() { Winamp.Winamp.VolumeDown(); }), null); if(autoEvent.WaitOne(100)) lowerVolume = false; } while(lowerVolume); }
only two letters away from being an asset
-
Hi, this is all wrong. 1. event handlers get executed on the main thread (aka GUI thread), hence MouseUp cannot do anything as long as MouseDown is active. 2. Your while loop will never exit. 3. Your while loop has no delay, so at what rate will VolumeDown be called? 4. Using Thread.Sleep would not be a good approach as that blocks the GUI; using a timer (a Windows.Forms.Timer) is the perfect solution: start the timer on MouseDown, stop it on MouseUp (or better yet have the Tick handler check Control.MouseButtons).
Zap-Man wrote:
I don't want to use a timer
why? because you don't understand them? because you don't like a clean and natural solution? :)
Luc Pattyn
I only read code that is properly indented, and rendered in a non-proportional font; hint: use PRE tags in forum messages
Local announcement (Antwerp region): Lange Wapper? Neen!
-
private AutoResetEvent autoEvent = null; private void OnMouseDown(object sender, MouseEventArgs e) { autoEvent = new AutoResetEvent(false); ThreadPool.QueueUserWorkItem(VolumeDown); } private void OnMouseUp(object sender, MouseEventArgs e) { autoEvent.Set(); } private void VolumeDown(object state) { bool lowerVolume = true; do { BeginInvoke(new MethodInvoker(delegate() { Winamp.Winamp.VolumeDown(); }), null); if(autoEvent.WaitOne(100)) lowerVolume = false; } while(lowerVolume); }
only two letters away from being an asset
-
:thumbsup:Thank you Mark This is excatly what Im looking for. Congrats to you!!!:thumbsup:
You're welcome
only two letters away from being an asset
-
Look I am not looking for Critics. If you cant help then don't bother posting. I understand timers perfectly. My app has a timer which runs a massive about of code. I understand what the program is doing. I am looking for a way around it.
This response is uncalled for, Luc's comments are valid.
only two letters away from being an asset
-
I am trying to do some events while the mouse button is down. Here is what I have private static bool IsKeyDown = false; private void button1_MouseDown(object sender, MouseEventArgs e) { IsKeyDown = true; while (IsKeyDown) { Winamp.Winamp.VolumeDown(); } } private void button1_MouseUp(object sender, MouseEventArgs e) { IsKeyDown = false; } The problem is when it hits the mouse down event It continues to run the while loop and does not hit the mouse up event. I don't want to use a timer to do this. I did see some code that I think will work better in my app but I cant seem to get it to work can some one please help. http://stackoverflow.com/questions/1152525/c-winform-looping-event-on-press-button[^] private bool mouseDown = false; private void buttonScrollUp_MouseDown(object sender, MouseEventArgs e) { mouseDown = true; new Thread(() => { while (mouseDown) { Invoke(new MethodInvoker(() => [DO_THE_SCROLLING_HERE)); Thread.Sleep([SET_AUTOREPEAT_TIMEOUT_HERE); } }) .Start(); } private void buttonScrollUp_MouseUp(object sender, MouseEventArgs e) { mouseDown = false; }
First, the reason your original idea doesn't work is that the event handlers are all on the same thread. The mouseup handler cannot run until mousedown returns, and mousedown doesn't return until mouseup has run, so you're basically deadlocking yourself with only one thread! :D Depending on what you do in those handlers you may be able to do it in another thread instead. But if you want to do anything to the GUI itself, you aren't allowed to do so on any thread but the "gui thread", which is the same thread that is raising the events. So you have to use another hook... to marshal the call back to the UI thread again! Here's an example of how to do this. To run it, create a new windows forms application and replace Form1.cs with:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;namespace WindowsFormsApplication2
{
public partial class Form1 : Form
{
long n;
MouseButtons buttons;
Label label1;public Form1() { label1 = new Label(); label1.Text = "here"; Controls.Add(label1); label1.MouseUp += new MouseEventHandler(label1\_MouseUp); label1.MouseDown += new MouseEventHandler(label1\_MouseDown); } void label1\_MouseDown(object sender, MouseEventArgs e) { buttons = e.Button; new Thread(run).Start(); } void label1\_MouseUp(object sender, MouseEventArgs e) { buttons = MouseButtons.None; } void run() { var upd = new Action(update); while (buttons != MouseButtons.None) label1.Invoke(upd); } void update() { n = (buttons == MouseButtons.Left ? --n : ++n); label1.Text = n.ToString(); } }
}