Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. While MouseDown

While MouseDown

Scheduled Pinned Locked Moved C#
helpcom
11 Posts 6 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • Z Zap Man

    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; }

    L Offline
    L Offline
    Lyon Sun
    wrote on last edited by
    #2

    Zap-Man wrote:

    private static bool IsKeyDown = false;

    Confused. Can this variable be changed ever? Correct me if I am wrong...:)

    Z 1 Reply Last reply
    0
    • L Lyon Sun

      Zap-Man wrote:

      private static bool IsKeyDown = false;

      Confused. Can this variable be changed ever? Correct me if I am wrong...:)

      Z Offline
      Z Offline
      Zap Man
      wrote on last edited by
      #3

      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.

      1 Reply Last reply
      0
      • Z Zap Man

        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; }

        L Offline
        L Offline
        Lost User
        wrote on last edited by
        #4

        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.

        1 Reply Last reply
        0
        • Z Zap Man

          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; }

          L Offline
          L Offline
          Luc Pattyn
          wrote on last edited by
          #5

          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!


          Z 1 Reply Last reply
          0
          • Z Zap Man

            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; }

            N Offline
            N Offline
            Not Active
            wrote on last edited by
            #6

            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

            Z 1 Reply Last reply
            0
            • L Luc Pattyn

              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!


              Z Offline
              Z Offline
              Zap Man
              wrote on last edited by
              #7

              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.

              N 1 Reply Last reply
              0
              • N Not Active

                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

                Z Offline
                Z Offline
                Zap Man
                wrote on last edited by
                #8

                :thumbsup:Thank you Mark This is excatly what Im looking for. Congrats to you!!!:thumbsup:

                N 1 Reply Last reply
                0
                • Z Zap Man

                  :thumbsup:Thank you Mark This is excatly what Im looking for. Congrats to you!!!:thumbsup:

                  N Offline
                  N Offline
                  Not Active
                  wrote on last edited by
                  #9

                  You're welcome


                  only two letters away from being an asset

                  1 Reply Last reply
                  0
                  • Z Zap Man

                    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.

                    N Offline
                    N Offline
                    Not Active
                    wrote on last edited by
                    #10

                    This response is uncalled for, Luc's comments are valid.


                    only two letters away from being an asset

                    1 Reply Last reply
                    0
                    • Z Zap Man

                      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; }

                      D Offline
                      D Offline
                      dojohansen
                      wrote on last edited by
                      #11

                      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();
                          }
                      }
                      

                      }

                      1 Reply Last reply
                      0
                      Reply
                      • Reply as topic
                      Log in to reply
                      • Oldest to Newest
                      • Newest to Oldest
                      • Most Votes


                      • Login

                      • Don't have an account? Register

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • World
                      • Users
                      • Groups