Mouse Event, opposite of action Click?

G

Guest

The subject line sounds a little funny, let me quickly explain:

I have created a custom control using ComboBox. But inside my class, I need
to know when the user does NOT click my control.

Of course, I can capture the event Click when someone clicks on the actual
control, but not when they click off of it.

Right now I am using the event handler myCustomControl.LostFocus, but that
requires someone to click on another button or text field before it will fire
that event. I want to be able to have the user be able to click on some
blank space anywhere outside the control and the event to fire. I have also
set up a Click event on my parent control, and that works as long as the user
clicks inside that parent control, but doesn't if they click on the parent of
the parent.

Is there some kind of all encompassing Click event I can capture no matter
where the mouse is clicked in my app?

Does anyone know how to do this? It sounds simple enough, but it is causing
a big headache. Thank you all for reading this.

Rob K
 
B

bobbychopra

Is this for a WebApplication?
Since it is your own custom control, just add an EventHandler called
OnBlurEventHandler, which you will set to fire as ...

string postback = Page.GetPostBackEventReference(this);

protected override void Render(HtmlTextWriter writer)
{
writer.WriteAttribute("onblur", postback);
}

Which will cause your custom control to postback when the user clicks
and changes its value of when the user tabs out of the control.

Sincerely,
Bobby
 
J

JustinC

One possibility would be to override the global windows click message.
This would let you know when the user has clicked ANYWHERE. Then check
if the mouse coordinates of that click are in your application and
respond accordingly. I am not positive what the function is that you
have to override to find out whenever the mouse is clicked, but I do
know it exists. If you're having trouble finding info just reply to
this and I'll see what I can find.

Best of luck ~ Justin
 
G

Guest

Bobby, Thank you very much for responding. Actually, I am just using C# in a
Windows Application. I wish there was an OnBlur action. Seems like that
would work. But the best I can find is LostFocus.

this.myCustomControl.LostFocus += new
System.EventHandler(this.HideOtherControls);

The user has to actually focus something else before this fires :-(. Ahh,
the quest continues. Do you have any more ideas?

Thanks again,

Rob K
 
M

Mehdi

Hi RobKinney1,

The user has to actually focus something else before this fires :-(. Ahh,
the quest continues. Do you have any more ideas?

What need to do is intercept all the Windows messages sent to your
application before they are being dispatched to whatever control has the
input focus. You can do that by implementing the IMessageFilter interface
(which has only one method: PreFilterMessage) and adding your message
filter to the application using Application.AddMessageFilter().

In the PreMessageFilter method, intercept the WM_LBUTTONDOWN message, which
indicates that the user has clicked the left mouse button somewhere on your
application's form. You can then get the mouse position in screen
coordinates using the MousePosition property of you user control. That's
you pretty much all done. What you do next is up to you. You could for
example transform the mouse coordinates from screen coordinates to client
coordinates using the PointToClient() method of your user control. Using
these coordinates to determine whether the user has clicked inside or
outside your user control should be a straitforward affair.
 
G

Guest

Well, that worked! Thank you very much for the info. I do enjoy using C#
over C++ for reasons like these. Last time I did system hooking in C++, I
had to make a dll file. But this method here you suggested works great.
Thanks again.

Rob K
 
K

Kevin Spencer

Mmm, how about MouseLeave? If the mouse isn't over the Control it certainly
did *not* click it.

--
HTH,

Kevin Spencer
Microsoft MVP
..Net Developer

Presuming that God is "only an idea" -
Ideas exist.
Therefore, God exists.
 
G

Guest

Here is the final solution I used. It was made possible in part by you
people, the people at Experts Exchange, and also by Code Project:

/* File: DropTextBox.cs **** Class: DropTextBox */


using System;
using System.ComponentModel;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace DropTextBox_NS
{
public class DropTextBox : ComboBox
{

// DLLs for mouse capture, Idle_Mind, Experts-Exchange
[DllImport("user32.dll")]
public static extern int SetCapture(IntPtr hWnd);

[DllImport("user32.dll")]
public static extern IntPtr GetCapture();

[DllImport("user32.dll")]
public static extern int ReleaseCapture();

public TextBox myTextBox;
public Panel myPanel;
public Label myLabel;


private String cannotContain; // keeps track of what
characters cannot be accepted in the text box or drop-down


// * * * * * * * * * * * * CLASS Accessors * * * * * * * * * * * * *
* //
public int WidthOfTextBox
{
get
{
return myTextBox.Width;
}

set
{
myTextBox.Width = value;
myPanel.Width = value;
myLabel.Width = value;
}

} // end WidthOfTextBox

public int HeightOfTextBox
{
get
{
return myTextBox.Height;
}
set
{
myTextBox.Height = value;
}
} // end HeightOfTextBox

public String CannotContainChars
{
get
{
return cannotContain;
}
set
{
cannotContain = value;
}
} // end CannotContainChars



// * * * * * * * * * * * * Constructors * * * * * * * * * * * * * *
* //
public DropTextBox()
{
this.DropDownHeight = 1;

this.cannotContain = "";

myLabel = new Label();
myLabel.Text = "Press TAB to Close This Window";

// must create a text box and place it under the drop-down
myTextBox = new TextBox();
this.myTextBox.Multiline = true;
this.myTextBox.Name = "textBox1";
this.myTextBox.Size = new System.Drawing.Size(120, 43);
this.myTextBox.TabIndex = 2;
myTextBox.Visible = false;

//create instructional panel
this.myPanel = new Panel();
this.myPanel.Name = "APanel";
this.myPanel.Size = new System.Drawing.Size(120, 14);
this.myPanel.Visible = false;
this.myPanel.BorderStyle = BorderStyle.FixedSingle;
this.myPanel.BackColor = System.Drawing.Color.AliceBlue;


this.myPanel.Controls.Add(myLabel);

this.myTextBox.LostFocus += new
System.EventHandler(this.HideTextBox);
this.myTextBox.MouseMove += new
MouseEventHandler(this.TextBoxMouseMove); // experts-exchange
this.myTextBox.MouseDown += new
MouseEventHandler(this.TextBoxMouseDown);



// set up filtering for the text box
this.myTextBox.TextChanged += new
System.EventHandler(this.FilterTextBox);

// set up filtering for the drop-down box
this.TextChanged += new System.EventHandler(this.FilterComboBox);



} // end constructor


// * * * * * * * * * * * * OVERRIDEN event handlers * * * * * * * *
* * * * * * * //


// at this point, we can legaly add the control to the parent form
protected override void CreateHandle()
{
base.CreateHandle();

this.Parent.Controls.Add(this.myTextBox);
this.Parent.Controls.Add(this.myPanel);

} // end CreateHandle ()

// this was the last thing we needed to implement in order for the
box to close correctly
protected override void OnDropDownClosed(EventArgs e)
{
base.OnDropDownClosed(e);

myTextBox.Capture = true;
}

// override the drop down so that it brings up our text box instead
protected override void OnDropDown(EventArgs e)
{
base.OnDropDown(e);

// if the text box is already visible, just hide it
if (myTextBox.Visible)
{
myTextBox.Visible = false;
myPanel.Visible = false;
myTextBox.Capture = false;
}
else // if not, show it
{
this.myTextBox.Text = this.Text;

this.myTextBox.Location = new
System.Drawing.Point(this.Location.X, this.Location.Y + this.Size.Height);
this.myPanel.Location = new
System.Drawing.Point(this.Location.X, this.Location.Y + this.Size.Height +
myTextBox.Height + 1);

myTextBox.Visible = true;
myPanel.Visible = true;
myTextBox.Capture = true;

this.myTextBox.BringToFront(); // ensure that it is visible
to the user
this.myTextBox.Focus(); // bring the cursor down to
the text box
}




} // end OnDropDown ()

// * * * * * * * * * * * * * * This section by Idle_Mind, Experts
Exchange * * * * * * * * * * * * * * * //
private void TextBoxMouseMove(object sender, MouseEventArgs e)
{
myTextBox.Capture = true;
}


private void TextBoxMouseDown(object sender, MouseEventArgs e)
{
if (e.X < 0 || e.X > myTextBox.Width || e.Y < 0 || e.Y >
myTextBox.Height)
{
myTextBox.Capture = false;
myTextBox.Visible = false;
}
}

// * * * * * * * * * * * * Helper Procedures * * * * * * * * * * * *
* * * //

//private void HideTextBox_mouseClick(object sender,
System.EventArgs e)
public void HideTextBox_mouseClick()
{
myTextBox.Visible = false;
myPanel.Visible = false;
this.Text = myTextBox.Text;
myTextBox.Capture = false;
}

// hide the text box from view
private void HideTextBox(object sender, System.EventArgs e)
{
myTextBox.Visible = false;
myPanel.Visible = false;
this.Text = myTextBox.Text;
myTextBox.Capture = false;

} // end HideTextBox ()


// called when the text box is modified so we can filter out
unwanted characters
// Adapted from
http://www.codeproject.com/useritems/FilterTextBox.asp#xx1333295xx , Hamed JI
12 Jan 2006
private void FilterTextBox(object sender, System.EventArgs e)
{
// if we do have a filter applied, start filtering
if (this.cannotContain.Length > 0)
{
// for each character in the must not contain field
foreach (char character in this.cannotContain.ToCharArray())
{
// if we find a character contained in the forbidden
string, remove it
if (myTextBox.Text.Contains(character.ToString()))
{
myTextBox.Text =
myTextBox.Text.Replace(character.ToString(), ""); // get rid of the offending
character
myTextBox.SelectionStart = myTextBox.Text.Length;
// put the cursor back to where it was
}
} // end FOREACH character in the forbidden string
} // end IF forbidden string

} // end FilterTextBox ()


// called when the comboBox text is modified so we can filter
unwanted characters
private void FilterComboBox(object sender, System.EventArgs e)
{

// if we do have a filter applied, start filtering
if (this.cannotContain.Length > 0)
{
// for each character in the must not contain field
foreach (char character in this.cannotContain.ToCharArray())
{
// if we find a character contained in the forbidden
string, remove it
if (this.Text.Contains(character.ToString()))
{
this.Text = this.Text.Replace(character.ToString(),
""); // get rid of the offending character
this.SelectionStart = this.Text.Length; // put the
cursor back to where it was
}
} // end FOREACH character in the forbidden string
} // end IF forbidden string

} // end FilterComboBox ()


} // end class DropTextBox ()
} // end _NS

I know the indenting probably will not look right after I post this, but you
get the picture. (Experts-Exchange has such a nice way of displaying code
that was pasted into their forms... why not here?)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top