-3

I tried to make a system which runs loop anytime when left mouse click is pressed, not pressed on button or label, but anytime!!!. But here is the code:

 
        [DllImport("user32.dll")]
        static extern void mouse_event(int dwFlags, int dx, int dy,
                      int dwData, int dwExtraInfo);
        [Flags]
        public enum MouseEventFlags
        {
            LEFTDOWN = 0x00000002,
            LEFTUP = 0x00000004,
            MIDDLEDOWN = 0x00000020,
            MIDDLEUP = 0x00000040,
            MOVE = 0x00000001,
            ABSOLUTE = 0x00008000,
            RIGHTDOWN = 0x00000008,
            RIGHTUP = 0x00000010
       }          
    private void Form1_Load(object sender, EventArgs e)
    {
         click.Enabled = false;      //click is timer which i added to forms!
         click.Interval = 1000;      
    }
    //it should do loop when left mouse click i just pressed NOT ON LABEL OR BUTTON!
    private void Loop_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                click.Enabled = true;
            }
        }

        private void Loop_MouseUp(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                click.Enabled = false;
            }
        }
                
    private void click_Tick(object sender, EventArgs e)
    {
        mouse_event((int)(MouseEventFlags.LEFTDOWN), 0, 0, 0, 0);
        mouse_event((int)(MouseEventFlags.LEFTUP), 0, 0, 0, 0);
    }
And can someone tell me why I got so much dislikes to this question if there are 0 working answers? And there is the same type question like this, but this question point ISN'T the same. This question point is if the left mouse click is pressed anytime like in the application, on the desktop, anywhere!
Petter Friberg
  • 21,252
  • 9
  • 60
  • 109

5 Answers5

8

You don't need a loop at all. Simply change the click.Enabled to true on the MouseDown event and back to false on the MouseUp event:

private void Loop_MouseDown(object sender, MouseEventArgs e)
{
    if(e.Button == MouseButtons.Left)
    {
        click.Enabled = true;
    }
}

private void Loop_MouseUp(object sender, MouseEventArgs e)
{
    if(e.Button == MouseButtons.Left)
    {
        click.Enabled = false;
    }
}

Here is a complete, working, tested example. This code also include the designer generated code:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WorkingSolution
{
    public class Form1 : Form
    {
        private int _NumOfTicks;
        public Form1()
        {
            InitializeComponent();
        }

        private void label1_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == System.Windows.Forms.MouseButtons.Left)
            {
                _NumOfTicks = 0;
                click.Enabled = true;
            }

        }

        private void label1_MouseUp(object sender, MouseEventArgs e)
        {
            if (e.Button == System.Windows.Forms.MouseButtons.Left)
            {
                click.Enabled = false;
            }
        }

        private void click_Tick(object sender, EventArgs e)
        {
            this.lblTickCount.Text = _NumOfTicks.ToString();
            _NumOfTicks++;
        }

        #region designer code

        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.components = new System.ComponentModel.Container();
            this.click = new System.Windows.Forms.Timer(this.components);
            this.label1 = new System.Windows.Forms.Label();
            this.label2 = new System.Windows.Forms.Label();
            this.lblTickCount = new System.Windows.Forms.Label();
            this.SuspendLayout();
            // 
            // click
            // 
            this.click.Interval = 1000;
            this.click.Tick += new System.EventHandler(this.click_Tick);
            // 
            // label1
            // 
            this.label1.BackColor = System.Drawing.Color.Firebrick;
            this.label1.ForeColor = System.Drawing.Color.White;
            this.label1.Location = new System.Drawing.Point(37, 24);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(207, 78);
            this.label1.TabIndex = 0;
            this.label1.Text = "Hold left mouse button over me";
            this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
            this.label1.MouseDown += new System.Windows.Forms.MouseEventHandler(this.label1_MouseDown);
            this.label1.MouseUp += new System.Windows.Forms.MouseEventHandler(this.label1_MouseUp);
            // 
            // label2
            // 
            this.label2.AutoSize = true;
            this.label2.Location = new System.Drawing.Point(37, 149);
            this.label2.Name = "label2";
            this.label2.Size = new System.Drawing.Size(109, 13);
            this.label2.TabIndex = 1;
            this.label2.Text = "Number of timer ticks:";
            // 
            // lblTickCount
            // 
            this.lblTickCount.AutoSize = true;
            this.lblTickCount.Location = new System.Drawing.Point(152, 149);
            this.lblTickCount.Name = "lblTickCount";
            this.lblTickCount.Size = new System.Drawing.Size(0, 13);
            this.lblTickCount.TabIndex = 2;
            // 
            // Form1
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(284, 262);
            this.Controls.Add(this.lblTickCount);
            this.Controls.Add(this.label2);
            this.Controls.Add(this.label1);
            this.Name = "Form1";
            this.Text = "Form1";
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private System.Windows.Forms.Timer click;
        private System.Windows.Forms.Label label1;
        private System.Windows.Forms.Label label2;
        private System.Windows.Forms.Label lblTickCount;

        #endregion designer code
    }
}
Zohar Peled
  • 79,642
  • 10
  • 69
  • 121
  • @HappyFrog please provide more information than just `It´s not working` nobody can read you mind to find the actual problem. – Tim Schmidt Jul 26 '17 at 13:39
  • It does not say any problem **but it is not working** –  Jul 26 '17 at 13:43
  • I think it cant fire loop, because it need timer elapsed but i dont know how it works. –  Jul 26 '17 at 13:48
  • @HappyFrog What about debugging the code to clearify what exactly is not working, nobody can help you just by the fact thats not woring! What I could imagin that you don´t even have an event that on mouseButton will trigger the `Loop_MouseDown` method, but if you want the help of anyone, you have to provide more information. – Tim Schmidt Jul 26 '17 at 13:48
  • FatTony it is not doing loop I can't give more information. –  Jul 26 '17 at 13:52
  • "It is not working" is not a problem description. The code you shared in the question have nothing inside the Tick event of the timer. Perhaps that's the problem? – Zohar Peled Jul 26 '17 at 14:08
  • Yes but i put in the loop 'MessageBox.Show("...");' –  Jul 26 '17 at 14:13
  • I've edited my answer with a complete, tested example. – Zohar Peled Jul 26 '17 at 14:19
  • The `MessageBox.Show` kinda ruins everything. Seems like once the form is no longer the active form, you have to click the label in order for the MouseUp event handler to work. – Zohar Peled Jul 26 '17 at 14:22
  • I needed Loop, when you click ONLY LEFT CLICK NOT LABEL OR BUTTON. –  Jul 27 '17 at 07:20
  • Well, I did my best, including a complete example (that's working). As I wrote before, the `MessageBox.Show` is killing this solution. perhaps someone else might come up with a better solution then mine. – Zohar Peled Jul 27 '17 at 07:23
  • Yes your is working if left mouse click is pressed ON LABEL, but none of answers is working if left mouse click is just pressed. –  Jul 27 '17 at 07:55
  • Well, you can catch mouse events for every element on the form, check out [this answer](https://stackoverflow.com/questions/3926644/handling-a-click-event-anywhere-inside-a-panel-in-c-sharp) by Hans Passant. – Zohar Peled Jul 27 '17 at 08:03
1

You need to add an event handler to fire the timer

click.Elapsed += new ElapsedEventHandler(click_Tick);

Here is the complete code

private void Form1_Load(object sender, EventArgs e)
{
    click.Enabled = false;      //click is timer which i added to forms!
    click.Interval = 1000;    
    click.Elapsed += new ElapsedEventHandler(click_Tick);
}
private void Loop_MouseDown(object sender, MouseEventArgs e)
{
while (e.Button == MouseButtons.Left)
    {
        click.Enabled = true;
    }
}

private void click_Tick(object sender, ElapsedEventArgs e)
{
      //Here is the loop!
}
David Lindon
  • 305
  • 2
  • 8
0

You seem to have your loops mixed up. The loop is this part:

while (e.Button == MouseButtons.Left)
{
    click.Enabled = true;
}

That code will keep doing the part inside the { } while the condition is true: e.Button == MouseButtons.Left. You never change the value of e.Button, which means that it keeps going round and round forever.

At a guess, you don't want to set click.Enabled = true; while the condition is true; you want to set it if the condition is true. Change the while to an if and it'll only happen once, and your program won't get stuck in an infinite loop.

anaximander
  • 7,083
  • 3
  • 44
  • 62
0

Just to clear this whole thing up, I write the code with everything neccesary for this to work, this includes some of the already posted answers:

For the Timer and the MouseButton Events you need to add this above your class:

using System.Windows.Forms;

private Timer click;
private Int16 testCounter;

private void Form1_Load(object sender, EventArgs e) {
    testCounter = 0;

    click = new Timer();
    click.Interval = 1000;
    click.Tick += new EventHandler(click_Tick);

    this.MouseDown += new MouseEventHandler(Loop_MouseDown);
    this.MouseUp += new MouseEventHandler(Loop_MouseUp);
}
private void Loop_MouseDown(object sender, MouseEventArgs e) {
    if(e.Button == MouseButtons.Left) {
        click.Start();
    }
}
private void Loop_MouseUp(object sender, MouseEventArgs e) {
    if(e.Button == MouseButtons.Left) {
        click.Stop();
    }
}

private void click_Tick(object sender, EventArgs e) {
    testCounter++;
}

Once the you press down the mouseButton, the method Loop_MouseDown will be fired, which will start the timer.

Once the mouseButton is released the method Loop_MouseUp will be fired, which will stop (and reset) the timer.

As long as the timer is active, every 1000ms (1s) the method click_Tick will be called, which will increase the counter by 1;

So in conclusion: For every whole secon the mouseButton has been held down, the counter will be increased by 1.


Also If you are not able to debug the code you are writing and are not able to provide the information needed for people to help you, you may consider to start with more simple programs to learn everything you need.


EDIT: Of course there is Timer in System.Windows.Forms: enter image description here

Tim Schmidt
  • 1,297
  • 1
  • 15
  • 30
  • 'Timer' does not contain a definition for 'Tick' and no extension method 'Tick' accepting a first argument of type 'Timer' could be found (are you missing a using directive or an assembly reference? ~Error –  Jul 26 '17 at 14:17
  • I don´t know if you are using some other timer than me, but I´m using the one from `System.Windows.Forms` – Tim Schmidt Jul 26 '17 at 14:23
  • im using that timer which you created 'click = new Timer();' and there is no timer in the forms. –  Jul 26 '17 at 14:29
  • Yes there is, see Screenshot. – Tim Schmidt Jul 26 '17 at 14:33
  • 2 timers called click?? It is impossible. And if you have timer in forms why you did 'click = new Timer();' –  Jul 26 '17 at 14:35
  • Your code says, 'private Timer click;' and 'click = new Timer();' and you say I need to make timer called click to forms? I lost already 50% of my braincells. I got it without errors, but it is not doing loop when i press my leftclick. –  Jul 26 '17 at 14:42
  • `private Timer click;` is a declaration `click = new Timer();` is an initialisation. Since you say your time has now `.tick` i told you exactly which timer I used, there is literally nothing that could be missunderstood. – Tim Schmidt Jul 26 '17 at 14:45
  • It is not working, obviously what it means, it is not doing loop. If you didint get yet program idea, it is if user hold left click ANYTIME it will spamm loop. –  Jul 26 '17 at 14:52
0

This has already been answered. Check this out and you should be able to come up with a solution.

C# how to loop while mouse button is held down

KL_
  • 293
  • 6
  • 22
  • I know. I saw that, but there is no working answer for me and I can't ask there because not enough reputations. –  Jul 26 '17 at 14:01