Looking for some help on a problem Im having
sorry if this question has already been asked, I can not find anything similar.
The idea is when a picturebox is clicked changed the image to ON.
If the picture box is held for more than 2 seconds to open a new form and leave the picturebox as OFF.
However if the picturebox is clicked ON and then held for 2 seconds and then returns i need the picturebox state to remain ON.
Here is what I have tried so far.
I believe for this to work correctly I need to stop MouseUp event from occuring.
Is there a way I can stop MouseUp when Tick occurs?
Is there a easier / better way to do this?
Any help would be appreciated.
private void time_HoldDownInternal_Tick(object sender, EventArgs e)
{
time_HoldDownInternal.Enabled = false;
time_HoldDownInternal.Interval = 1000;
form1show.Visible = true;
}
private void pb_pictureBoxTest_MouseDown(object sender, MouseEventArgs e)
{
mainMenuVariables.mousedown = true;
time_HoldDownInternal.Enabled = true;
}
private void pb_pictureBoxTest_MouseUp(object sender, MouseEventArgs e)
{
mainMenuVariables.mousedown = false;
//MessageBox.Show("mouse up");
time_HoldDownInternal.Enabled = false;
time_HoldDownInternal.Interval = 1000;
}
private void pb_pictureBoxTest_Click(object sender, EventArgs e)
{
if (mainMenuVariables.mousedown == true)
{
if (mainMenuVariables.pictureBox == false)
{
mainMenuVariables.pictureBox = true;
pb_pictureBoxTest.Image = new Bitmap(mainMenuVariables.pictureBoxOn);
return;
}
if (mainMenuVariables.pictureBox == true)
{
mainMenuVariables.pictureBox = false;
pb_pictureBoxTest.Image = new Bitmap(mainMenuVariables.pictureBoxOff);
return;
}
}
if (mainMenuVariables.mousedown == false)
{
//nothing
}
}
Rather than starting a timer, just record the current time on mouse down. Then in mouse up, check if it has been 2 seconds. e.g:
private void pb_pictureBoxTest_MouseDown(object sender, MouseEventArgs e)
{
mainMenuVariables.mousedown = true;
mainMenuVariables.mousedowntime = DateTime.Now;
}
private void pb_pictureBoxTest_MouseUp(object sender, MouseEventArgs e)
{
mainMenuVariables.mousedown = false;
var clickDuration = DateTime.Now - mainMenuVariables.mousedowntime;
if ( clickDuration > TimeSpan.FromSeconds(2))
{
// Do 'hold' logic (e.g. open dialog, etc)
}
else
{
// Do normal click logic (e.g. toggle 'On'/'Off' image)
}
}
Related
This question already has answers here:
Long pressed button
(5 answers)
Closed 2 years ago.
I have a timer developed with c# and WinForms controlled by an external button
when I press the button, the time starts, this is the main action! I would like to know
if is it possible to recognize a long press in this button so I can program the action to stop
I am very new to C#, by programming language side is it possible to recognize this long press?
my solution:
create a public datetime variable and add button_mousedown and button_mouseup event to your form.
put the following code in there:
private void button1_MouseDown(object sender, MouseEventArgs e)
{
dt = DateTime.Now;
}
private void button1_MouseUp(object sender, MouseEventArgs e)
{
var diff= ( DateTime.Now-dt).TotalMilliseconds;
if(diff > x) // x is the minimum time you want the mouse to be down on the button
{
// do stuff
}
}
when you do a click on the button, the exact time is stored in the "dt" variable.
when the click is over, the mouseup event is triggered and there you can compare the time, when you pressed the button with the currenttime and you can get a difference in milliseconds with my code
You can use the button MouseDown and MouseUp events.
Here is one way to create a counter with textbox and button with "Long Press" event:
private bool IsTargetButtonClicked = false;
private Timer HoldButtonTimer;
private void TargerButton_MouseUp(object sender, MouseEventArgs e)
{
IsTargetButtonClicked = false;
}
private void TargerButton_MouseDown(object sender, MouseEventArgs e)
{
IsTargetButtonClicked = true;
InitHoldButtonTimer();
}
private void InitHoldButtonTimer()
{
if (HoldButtonTimer == null)
{
HoldButtonTimer = new Timer();
HoldButtonTimer.Interval = 100;
HoldButtonTimer.Tick += HoldButtonTimer_Tick;
}
HoldButtonTimer.Start();
}
private int SomeIntValueToAdvance = 0;
private void HoldButtonTimer_Tick(object sender, EventArgs e)
{
if (IsTargetButtonClicked)
{
SomeIntValueToAdvance++;
textBox1.Invoke(new Action(() =>
{
textBox1.Text = SomeIntValueToAdvance.ToString();
}));
}
else
{
KillHoldButtonTimer();
}
}
private void KillHoldButtonTimer()
{
if (HoldButtonTimer == null)
{
HoldButtonTimer.Tick -= HoldButtonTimer_Tick;
HoldButtonTimer.Stop();
HoldButtonTimer.Dispose();
}
}
OUTPUT:
I have an application for kiosk machine that appears always on the top and fullscreen. Also, I have to turn off explorer.exe.
Therefore, I will not be able to access anything without a keyboard.
I'm thinking to make gestures or invincible buttons so that I can turn on explorer.exe without keyboard.
I would like to know if there is a way to detect if two buttons are clicked at the same time. I've tried using the following code but it is not working.
PS: I can't debug it line by line as my PC do not have touchscreen.
Therefore, I cannot find out which line causes the problem.
private bool button1WasClicked = false;
private bool button2WasClicked = false;
private void button1_MouseDown(object sender, MouseEventArgs e)
{
button1WasClicked = true;
}
private void button1_MouseUp(object sender, MouseEventArgs e)
{
button1WasClicked = false;
}
private void button2_MouseUp(object sender, MouseEventArgs e)
{
button2WasClicked = false;
}
private void button2_MouseDown(object sender, MouseEventArgs e)
{
if (button1WasClicked == true)
{
Process.Start(Path.Combine(Environment.GetEnvironmentVariable("windir"), "explorer.exe"));
Application.Exit();
button1WasClicked = false;
}
}
You can't click two buttons at once with a mouse or keyboard, and if you're talking about using a touchscreen, the WinForms framework doesn't support them (taps will simply be interpreted as individual mouse clicks at best). You'll want to look at using the Surface SDK or something else instead.
I've found a different solution where the buttons(panels) have to be clicked in a certain sequence to achieve what I wanted. I've also added a timer. Below is my code.
private bool panel1WasClicked = false;
private bool panel2WasClicked = false;
int second = 0;
private void panel1_Click(object sender, EventArgs e)
{
MaintenanceTimer.Interval = 500;
MaintenanceTimer.Start();
second = 0;
if (panel1WasClicked == false)
{
panel1WasClicked = true;
}
else
{
panel1WasClicked = false;
}
}
private void panel2_Click(object sender, EventArgs e)
{
if (panel2WasClicked == false && panel1WasClicked == true)
{
panel2WasClicked = true;
}
else
{
panel2WasClicked = false;
}
}
private void panel3_Click(object sender, EventArgs e)
{
if (panel1WasClicked && panel2WasClicked == true)
{
//Do something
}
panel1WasClicked = false;
panel2WasClicked = false;
MaintenanceTimer.Stop();
}
private void MaintenanceTimer_Tick(object sender, EventArgs e)
{
second += 1;
if (second >= 5)
{
MaintenanceTimer.Stop();
second = 0;
panel1WasClicked = false;
panel2WasClicked = false;
}
}
int sn = 0;
private void Form1_Load(object sender, EventArgs e)
{
label1.Text = "Konfigürasyon Yükleniyor.";
timer1.Interval = 1000;
timer1.Enabled = true;
timer1.Start();
}
private void timer1_Tick(object sender, EventArgs e)
{
if (sn == 3)
{
label1.Text = "Ayarlar Alınıyor";
}
if (sn == 5)
{
label1.Text = "Program Başlatılıyor";
}
sn++;
timer1.Stop();
}
When I open the form I want to change the label when I select the text range.
I assume that event handler is attached in designer to this timer1.
As far as I can understand, this label is never set, because you stop Timer after it hits first time.
In this case variable sn = 0 so non of if condition from your event handler is met.
I think to solve problem you sould remove this timer1.Stop() from event handler.
You probably want
private void timer1_Tick(object sender, EventArgs e) {
if (sn == 3)
label1.Text = "Ayarlar Alınıyor";
else if (sn == 5) {
label1.Text = "Program Başlatılıyor";
timer1.Stop(); // <- stop timer here on the 5th second, not on the 1st one
}
sn++;
}
I'm currently writing a program that holds down a mouse button when initially clicked, and continues to hold it until the user presses the mouse button for a second time.
The program works by detecting input globally using a MouseHookListener and then uses an input simulator to hold down the mouse button that has been pressed.
The program is able to hold down the mouse as intended, but there is an issue with the original mouse click that signals the program to simulate the button being held; it still gets carried out. I know that the MouseHookListener uses low level hooks to operate, but it's HookCallBack() method can't be overridden due to it being protected.
Is there any way to block out the original mouse input? Or is there a way to make the original input held in until the mouse is clicked once more?
This is the code I've produced, thus far (note - the mListener is being activated in a forum else where):
public MouseHold()
{
mListener = new MouseHookListener(new GlobalHooker());
mListener.MouseClick += mListener_MouseClick;
}
private bool isDown;
private int count = 0;
private InputSimulator sim = new InputSimulator();
public MouseHookListener mListener;
private void mListener_MouseClick(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
if (isDown)
{
isDown = false;
Console.Out.WriteLine(count);
}
else
{
Console.Out.WriteLine(count);
isDown = true;
sim.Mouse.LeftButtonDown();
}
}
}
I am the author of the library you mentioned https://github.com/gmamaladze/globalmousekeyhook.
To enable your usecase I have extended the library by one more event. Please note that the construction of listener has also slightly changed in the new version.
I beleave that with the example below you are able to accomplish your scenario without involving InputSimulator library.
How it works?
First mouse down set the flag m_SupressNextUp - down is fired.
Mouse button up which follows previous down is supressed and set the flag m_SupressNextDown
Second down is supressed too and reset the flag m_SupressNextUp
Second up is fired and reset m_SupressNextDown
System is returned to initial state.
internal class Sample
{
private IKeyboardMouseEvents m_GlobalHook;
private bool m_SupressNextUp;
private bool m_SupressNextDown;
public void Subscribe()
{
m_GlobalHook = Hook.GlobalEvents();
m_GlobalHook.MouseDownExt += GlobalHookMouseDownExt;
m_GlobalHook.MouseUpExt += GlobalHook_MouseUpExt;
}
void GlobalHook_MouseUpExt(object sender, MouseEventExtArgs e)
{
if (e.Button == MouseButtons.Left)
{
if (m_SupressNextUp)
{
Console.WriteLine(#"First mouse up supress.");
e.Handled = true;
m_SupressNextDown = true;
}
else
{
Console.WriteLine(#"Second mouse up - make it heppen.");
m_SupressNextDown = false;
}
}
}
private void GlobalHookMouseDownExt(object sender, MouseEventExtArgs e)
{
if (e.Button == MouseButtons.Left)
{
if (m_SupressNextDown)
{
Console.WriteLine(#"Second mouse down supress.");
e.Handled = true;
m_SupressNextUp = false;
}
else
{
Console.WriteLine(#"First mouse down - make it heppen.");
m_SupressNextUp = true;
}
}
}
public void Unsubscribe()
{
m_GlobalHook.MouseDownExt -= GlobalHookMouseDownExt;
m_GlobalHook.MouseUpExt -= GlobalHook_MouseUpExt;
m_GlobalHook.Dispose();
}
}
after reviewing the documentation for the input simulator I am guessing you need to reverse the mouse down input.
the source code for the input simulator has a mouse up method
private void mListener_MouseClick(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
if (isDown)
{
isDown = false;
Console.Out.WriteLine(count);
sim.Mouse.LeftButtonUp(); //maybe try this
}
else
{
Console.Out.WriteLine(count);
isDown = true;
sim.Mouse.LeftButtonDown();
}
}
}
I have a button on which a click and it takes a screenshot which i display in my Picture Box. I dont face issue with this code:
private void btnScreenShot_Click(object sender, EventArgs e)
{
btnSave.Visible = true;
sendto_bmpbox.Image = CaptureScreen();
}
However when i loop the entire Form freezes and i cannot click on anything:
private void btnScreenShot_Click(object sender, EventArgs e)
{
// Freezes here
btnSave.Visible = true;
while(flag == 0)
{
sendto_bmpbox.Image = CaptureScreen();
}
}
How do i fix this problem?
That's because your while() is infinite. What makes flag change from capture to capture?
In case you want to infinitely capture the screen - never use the main thread for such things, as it will cause it to hang and prevent your application from updating the UI.
Use the BackgroundWorker class for things like that, you can use this example.
private void button1_Click(object sender, EventArgs e)
{
btnSave.Visible = true;
Thread thread = new Thread(new ThreadStart(threadWork));
thread.Start();
}
int flag = 0;
private void threadWork()
{
while (flag == 0)
{
UpdateImage();
}
}
private void UpdateImage()
{
if (this.InvokeRequired)
{
this.Invoke(UpdateImage);
}
else
{
sendto_bmpbox.Image = CaptureScreen();
}
}
Try Application.DoEvents in loop. I think this can help you...
private void btnScreenShot_Click(object sender, EventArgs e)
{
// Freezes here
btnSave.Visible = true;
while(flag == 0)
{
Application.DoEvents();
sendto_bmpbox.Image = CaptureScreen();
}
}