Counting every mouseclick on a form and its elements - c#

I want to count all the mouseclicks that are made in a window. I want the counter to increase on every single object i click on, even if its a button, the form it self or a textbox etc. etc.
I have this so far but I cant seem to get it to work:
int mouseCounter = 0;
private void Form1_Load(object sender, EventArgs e)
{
foreach (Control c in this.Controls)
{
c.Click += ClickCounter;
}
}
void ClickCounter(object sender, EventArgs e)
{
mouseCounter++;
label8.Text = mouseCounter.ToString();
}
The counter only respond to click on the controls for now and not the form it self. How can I simply fix that?

You may use a message filter, to filter out mouse clicks on your (main)form.
You basically get the message before it is dispatched to the control and may do whatever you want (in your case: increase a counter).
The return value of PreFilterMessage(ref Message m) determines wether the message will be dispatched to the control: false means you didn't filter the message and it will be dispatched.
See the documentation for details.
public partial class Form1 : Form, IMessageFilter
{
public Form1()
{
InitializeComponent();
label1.Text = "0";
Application.AddMessageFilter(this);
}
public bool PreFilterMessage(ref Message m)
{
if (m.Msg == 0x201) //wm_lbuttondown
{
label1.Text = "" + (Int32.Parse(label1.Text) + 1);
}
return false;
}
}
Tested with .NET4.0 and a form full of various controls.

You have to use some Application-Wide Click message with an IMessageFilter like this:
public partial class Form1 : Form, IMessageFilter
{
int mouseCounter;
public Form1()
{
InitializeComponent();
Application.AddMessageFilter(this);
}
public bool PreFilterMessage(ref Message msg)
{
if(msg.Msg == 0x202) //WM_LBUTTONUP
{
mouseCounter++;
label8.Text = mouseCounter.ToString();
}
return false;
}
}

Use this:
namespace TicTacToe
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
button1.Visible = false;
}
}
}

Related

Cannot implicitly convert type 'bool' to System.Windows.Forms.RadioButton

public partial class Form2 : Form
{
public bool male {get; set;}
{
InitializeComponent();
}
private void Form2_Load(object sender, EventArgs e)
{
maleGender_rb1 = male;
}
}
I want to display the radio buttton result from form1 to form2 using also radio buttons
The best solution is to setup an event in the child form and for the RadioButton controls subscribe to CheckedChanged. The CheckedChange event determines which RadioButton was checked and sends notification to any listeners.
Child form:
namespace PassStringFromChildToParentForm
{
public partial class ChildForm : Form
{
public delegate void OnPassData(bool isMale);
public event OnPassData PassData;
public ChildForm()
{
InitializeComponent();
MaleRadioButton.Checked = true;
MaleRadioButton.CheckedChanged += RadioButton_CheckedChanged;
FemaleRadioButton.CheckedChanged += RadioButton_CheckedChanged;
}
private void RadioButton_CheckedChanged(object sender, EventArgs e)
{
var radioButton = (RadioButton)sender;
if (radioButton.Checked)
{
PassData?.Invoke(radioButton == MaleRadioButton);
}
}
public void UpdateRadioButton(bool isMale)
{
if (isMale)
{
MaleRadioButton.Checked = true;
}
else
{
FemaleRadioButton.Checked = true;
}
}
}
}
Main Form:
Here we subscribe to the child form event and determine which RadioButton to check based on the bool value passed.
namespace PassStringFromChildToParentForm
{
public partial class MainForm : Form
{
private ChildForm _childForm;
public MainForm()
{
InitializeComponent();
MaleRadioButton.CheckedChanged += RadioButton_CheckedChanged;
FemaleRadioButton.CheckedChanged += RadioButton_CheckedChanged;
}
private void RadioButton_CheckedChanged(object sender, EventArgs e)
{
if (Application.OpenForms.OfType<ChildForm>().Count() != 1) return;
var radioButton = (RadioButton)sender;
if (!radioButton.Checked) return;
if (!radioButton.Checked) return;
_childForm.UpdateRadioButton(MaleRadioButton.Checked);
}
private void ShowChildForm_Click(object sender, EventArgs e)
{
_childForm = new ChildForm();
_childForm.PassData += ChildForm_PassData; ;
_childForm.Show(this);
}
private void ChildForm_PassData(bool isMale)
{
if (isMale)
{
MaleRadioButton.Checked = true;
}
else
{
FemaleRadioButton.Checked = true;
}
}
}
}
You can't convert bool to RadioButton. I think you need to use Checked property of radio button to pass boolean value to it.
For example:
maleGender_rb1.Checked = true;// or false

How do i create an event in a mdi parent form and catch it in a child form

I've found a fair amount of information on this subject and stolen most of my current code from other threads on this forum but don't seem to be able to put it all together correctly. I've created a main form "Form1" that is a mdi container. I can create a child form "formStripChart" from a menu item on Form1. I'd like to fire my own event that gets fired every time a timer_tick handler fires in Form1 and catch my event in an event hander in formStripChart to update a chart control. I can see that Form1 is calling the "UpdateStatus" method but OnUpdateStatus is always null so the "UpdateStatus" event handler in formStripChart never gets called. Seems like I'm not doing whatever needs to be done in formStripChart to make Form1 realize someone is listening to the event but I haven't been able to figure out what.
Here's the relevant code in Form 1
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public delegate void StatusUpdateHandler(object sender, ProgressEventArgs e);
public event StatusUpdateHandler OnUpdateStatus;
private static double depthValue = 0.0;
private static Random randomValue = new Random();
private void timerData_Tick(object sender, EventArgs e)
{
depthValue = depthValue + randomValue.NextDouble() - 0.5;
iusblEventArgs.xValue = 0.0;
iusblEventArgs.yValue = 0.0;
iusblEventArgs.zValue = depthValue;
iusblEventArgs.timeStamp = DateTime.Now;
ProgressEventArgs args = new ProgressEventArgs("test status");
UpdateStatus("sent from timerData_tick");
}
private void UpdateStatus(string status)
{
// Make sure someone is listening to event
if (OnUpdateStatus == null) return;
ProgressEventArgs args = new ProgressEventArgs(status);
OnUpdateStatus(this, args);
}
public class ProgressEventArgs : EventArgs
{
public string Status { get; private set; }
public ProgressEventArgs(string status)
{
Status = status;
}
}
private void btnGo_Click(object sender, EventArgs e)
{
timerData.Enabled = true;
}
and here's the relevant code in formStripChart
public partial class FormStripChart : Form
{
private Form1 form1;
public FormStripChart()
{
InitializeComponent();
form1 = new Form1();
form1.OnUpdateStatus += new Form1.StatusUpdateHandler(UpdateStatus);
}
private void UpdateStatus(object sender, Form1.ProgressEventArgs e)
{
Console.Write("Update the chart here");
}
}
Thanks for any help.
It might be easier to pass form1 to the constructor of your child form like this:
Public void FormStripChart(Form1 f)
{
form1 = f;
form1.OnUpdateStatus += new Form1.StatusUpdateHandler(UpdateStatus);
}
This way your child form knows what instance of the main form to use.

Why value on textbox is not updated in Form1.cs

I am working on c# window forms and stuck since long ago to solve a situation.
The situation is :
I have a GUI Form1.cs[Design] which consists of a Button and textbox (txtmsg here).
I have created a class Testing.cs in the visual studio winform project which contains the code like this :
namespace smallTesting
{
class Testing
{
public Testing()
{
MessageBox.Show("Connection String Did not found");
Form1 frm = new Form1(); //I do this in order to have access to
//renderMessage() so that i will be able to update my output to
//textbox(txtMsg) in this function definition by calling it.
int i = 1;
for(;;)
{
if (i == 50)
{
break;
}
frm.renderMessage(i.ToString());
i++;
}
}
}
}
And Form1.cs class is:
namespace smallTesting
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btnStart_Click(object sender, EventArgs e) //It should work on button click.
{
btnStart.Enabled = false;
Testing tst = new Testing();//Instantiate the class
}
private void btnClose_Click(object sender, EventArgs e)
{
this.Close();
}
public void renderMessage(string str)
{
this.txtMsg.Text = str;
MessageBox.Show("str :" + txtMsg.Text); //It should update my Textbox by 1 to 50 . BUT IT DONT DO.Whereas i can see the counting in the message box popuped.
}
}
}
I was expecting the function call to renderMessage(string str) from class Testing must have updated the txtMsg but it don't do so. Why ? (whereas messagebox popuped shows that the string is updated for every call to this function) . Why the txtMsg is not updated in my GUI for each call? How to update it.
Note: Please note that this txtMsg box updation mechanism must go from testing.cs to Form1.cs (Not Form1.cs to Testing.cs)
Change your Testing class to receive the instance of Form1 that you want to update the textbox
namespace smallTesting
{
class Testing
{
public Testing(Form1 currentInstance)
{
MessageBox.Show("Connection String Did not found");
int i = 1;
while(i < 50)
{
currentInstance.renderMessage(i.ToString());
i++;
}
}
}
}
Now in the Form1 constructore change how do you initialize the Testing instance
namespace smallTesting
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btnStart_Click(object sender, EventArgs e) //It should work on button click.
{
btnStart.Enabled = false;
// Pass the reference of the instance of Form1 that you
// want to update. Do not let the Testing class creates its
// own instance of form1, instead use THIS ONE.
Testing tst = new Testing(this);
}
......
}
}

Enter Data to main form

I Made an application. The Main form Name is Form1.
And the other Form is called PoP.
public partial class pops : Form
{
public pops()
{
InitializeComponent();
CenterToScreen();
}
private void pops_Load(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
Close();
}
private void lblAdminNo_Click(object sender, EventArgs e)
{
}
}
Make two public properties on popup form and retrieve them from parent form.
string username = string.Empty;
string password = string.Empty;
using (LoginForm form = new LoginForm ())
{
DialogResult result = form.ShowDialog();
if (result == DialogResult.Ok)
{
username = form.Username;
password = form.Password;
}
}
It all depends on from where are you calling the Pop form.
If it is called from the Form1 itself, then the Popform's object itself would provide you the value.
Pop popFrm = new Pop();
if(popFrm.ShowDialog() == Ok)
{
string userName = popFrm.TextBox1.Text;
}
If the Pop is invoked from a different area/part of application, you may have to store it somewhere common to both the forms.
This can be done through events. This approach is particularly useful when data to be posted even when the child form is kept open.
The technique is- From parent form, subscribe to a child from event. Fire the event when child form closes, to send data
----- SAMPLE CODE-----
Note: In the Parent Form add a Button:button1
namespace WindowsFormsApplication2
{
public delegate void PopSaveClickedHandler(String text);
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Pops p = new Pops();
p.PopSaveClicked += new PopSaveClickedHandler(p_PopSaveClicked);//Subscribe
p.ShowDialog();
}
void p_PopSaveClicked(string text)
{
this.Text = text;//you have the value in parent form now, use it appropriately here.
}
}
Note: In the Pops Form add a TextBox:txtUserName and a Button:btnSave
namespace WindowsFormsApplication2
{
public partial class Pops : Form
{
public event PopSaveClickedHandler PopSaveClicked;
public Pops()
{
InitializeComponent();
}
private void btnSave_Click(object sender, EventArgs e)
{
if(PopSaveClicked!=null)
{
this.PopSaveClicked(txtUserName.Text);
}
}
}
}
Summary:
1.Add a delegate(place where it available to both parent and child form) :
public delegate void PopSaveClickedHandler(String text);
2.In form:Pops, Add an event:
public event PopSaveClickedHandler PopSaveClicked;
3.Subscribe to the event in Parent Form:
p.PopSaveClicked += new PopSaveClickedHandler(p_PopSaveClicked);
4.Invoke the event in form:Pops Save Button Click
if(PopSaveClicked!=null)
{
this.PopSaveClicked(txtUserName.Text);
}
You can send data to the form object before you display it. Create a method to call, send the info through the constructor... etc.

Forward a KeyPress-event

I have a TextBox and would like to forward a KeyPress-event from another Form.
So far I have my Form:
private readonly Action<KeyPressEventArgs> m_KeyPress;
public KeyboardForm( Action<KeyPressEventArgs> keyPress )
{
m_KeyPress = keyPress;
}
protected override void OnKeyPress( KeyPressEventArgs e )
{
m_KeyPress( e );
base.OnKeyPress( e );
}
And a derived TextBox, which initializes the Form:
var keyboardForm = new KeyboardForm( OnKeyPress );
keyboardForm.Show();
Now, the OnKeyPress-method gets called as expected (of the Form, then of the TextBox). But nevertheless nothing happens ... when I press 'a' I expected an 'a' to appear in my TextBox ...
Does anyone have an idea what's the problem here?
It is not working with KeyDown, too, and attaching to the regular exposed event KeyPress does not help me either. I think, that the problem is the explicit call of OnKeyPress. Is it allowed?
Form1:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
Form2 f = new Form2();
f.mEvent += new Form2.TestEvent(f_mEvent);
f.Show();
}
void f_mEvent(KeyPressEventArgs e)
{
textBox1.Text += e.KeyChar;
}
}
Form2:
public partial class Form2 : Form
{
public delegate void TestEvent(KeyPressEventArgs e);
public event TestEvent mEvent;
public Form2()
{
InitializeComponent();
}
protected override void OnKeyPress(KeyPressEventArgs e)
{
if (mEvent != null)
{
mEvent(e);
}
base.OnKeyPress(e);
}
}
This should do what you want. Make the text of the buttons on the Keyboard Form based on the SendKey characters. For example, if you want lower case a, just put "a" for the keyboard button text. If you want a backspace button, just put "backspace" as the text of the button. All the keyboard buttons Click events can register for the ButtonClick function
Keyboard Form:
public partial class KeyboardForm : Form
{
public delegate void ButtonPressed(string keyPressed);
public event ButtonPressed ButtonPressedEvent;
public KeyboardForm()
{
InitializeComponent();
}
private void ButtonClick(object sender, EventArgs e)
{
Button button = sender as Button;
if (button != null)
{
if ((ButtonPressedEvent != null))
{
ButtonPressedEvent("{"+button.Text+"}");
}
}
}
}
Form with textbox that the user types things into:
public partial class Form1 : Form
{
private KeyboardForm mKeyboardForm = new KeyboardForm();
private bool mIsKeyboardCode = false;
public Form1()
{
InitializeComponent();
mKeyboardForm.ButtonPressedEvent += new KeyboardForm.ButtonPressed(KeyboardFormButtonPressedEvent);
}
void KeyboardFormButtonPressedEvent(string keyPressed)
{
mIsKeyboardCode = true;
textBox1.Focus();
SendKeys.SendWait(keyPressed.ToString());
mKeyboardForm.Focus();
mIsKeyboardCode = false;
}
private void TextBoxKeyUp(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.ControlKey)
{
if (!mKeyboardForm.Visible)
{
mKeyboardForm.Show(this);
e.Handled = true;
}
}
else if (!mIsKeyboardCode)
{
mKeyboardForm.Hide();
}
}
}
Note: I did not use an extended textbox with a form inside of it. I dont think its a good design to have a form be shown/hidden from a custom textbox.
From this answer: https://social.msdn.microsoft.com/Forums/windows/en-US/92215fdf-8be0-4e3a-b796-dd7c0f131666/keypreview-true-how-do-you-then-detect-enterreturn?forum=winforms
If you have a button on your form that is catching the Enter key presses, you can allow the enter key to be handled as a normal KeyPreview key with the following code:
void button_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
if (e.KeyData == Keys.Enter)
{
e.IsInputKey = true;
}
}

Categories