I want to have it such that left clicking on the NotifyIcon also causes the context menu (set with the ContextMenuStrip property) to open as well. How would I achieve this? Do I have to handle Click and figure out the positioning myself?
Edit: showing the menu with trayIcon.ContextMenuStrip.Show() results is a few undesirable behaviors:
The menu is not shown at the same location as if right click the NotifyIcon (it appears that you can't set the x and y coords to where the taskbar is, at least on Windows 7 which is what I'm running). It will appear above the task bar (not that big of a deal, but consistency would be nice).
While the menu is shown, there is an extra icon added to the task bar.
Clicking somewhere other than the menu does not close it (whereas if you right click to bring up the context menu clicking else where automatically closes the context menu).
Is it at all possible to just invoke the menu however the built in right click handler is doing it?
You would normally handle the MouseClick event to detect the click and call the ContextMenuStrip.Show() method:
private void notifyIcon1_MouseClick(object sender, MouseEventArgs e) {
contextMenuStrip1.Show(Control.MousePosition);
}
But that doesn't actually work properly, the CMS won't close when you click outside of it. Underlying issue is a Windows quirk (aka "bug") that is described in this KB article.
Invoking this workaround in your own code is pretty painful, the pinvoke is unpleasant. The NotifyIcon class has this workaround in its ShowContextMenu() method, they just made it difficult to get to since it is a private method. Reflection can bypass that restriction. I discovered this hack 5 years ago and nobody reported a problem with it yet. Set the NFI's ContextMenuStrip property and implement the MouseUp event like this:
using System.Reflection;
...
private void notifyIcon1_MouseUp(object sender, MouseEventArgs e) {
if (e.Button == MouseButtons.Left) {
MethodInfo mi = typeof(NotifyIcon).GetMethod("ShowContextMenu", BindingFlags.Instance | BindingFlags.NonPublic);
mi.Invoke(notifyIcon1, null);
}
}
If you handle MouseUp rather than Click, you will be able to tell which button was clicked, as well as the location of the click. You can use this location as the location to show the ContextMenu
notifyIcon.MouseUp += new MouseEventHandler(delegate(object sender, MouseEventArgs e) { contextMenu.Show(e.Location); });
You can wire in a onClick event for notify icon then call show in the on click
private void wire()
{
notifyIcon1.Click += new EventHandler(notifyIcon1_Click);
}
void notifyIcon1_Click(object sender, EventArgs e)
{
contextMenuStrip1.Show(Cursor.Position);
}
use the following code to show context menu on both right and left click on notifyicon, if you find any issue then text me at arshad_mcs786#hotmail.com (arshad from Islamabd)
//System.Runtime.InteropServices use thi as reference
[DllImport("User32.dll", ExactSpelling = true, CharSet = CharSet.Auto)]
public static extern bool SetForegroundWindow(HandleRef hWnd);
private void notifyIcon1_Click(object sender, EventArgs e)
{
SetForegroundWindow(new HandleRef(this, this.Handle));
int x = Control.MousePosition.X;
int y = Control.MousePosition.Y;
x = x - 10;
y = y - 40;
this.contextMenuStrip1.Show(x,y );
//this.PointToClient(Cursor.Position)
}
Related
I have a simple .Net 5.0 WinForm form which is automatically hidden after the application started:
private void form_Shown (object sender, EventArgs e)
{
Hide ();
}
It only creates a notify icon. This notify icon has a context menu strip that is shown by a left mouse click:
private void notifyIcon_Click (object sender, EventArgs e)
{
contextMenuStrip.Show (MousePosition);
}
This works fine, but as long as the context menu strip is visible, a dummy taskbar icon appears:
This doesn't happen if the form is not hidden or the context menu strip is shown by a right mouse click (via ContextMenuStrip property).
How can I prevent this icon?
I finally found a solution myself:
[DllImport ("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
private static extern bool SetForegroundWindow (HandleRef hWnd);
private void notifyIcon_Click (object sender, EventArgs e)
{
SetForegroundWindow (new HandleRef (notifyIcon.ContextMenuStrip, notifyIcon.ContextMenuStrip.Handle));
notifyIcon.ContextMenuStrip.Show (MousePosition);
}
Try Me.Hide()
lets see the outcome
Try assign your context menu to the notifyicons .ContextMenu property like and use the notifyicons .Visible property to show it instead of using the .Show method.
So I'm trying to detect the location of my mouse click when I click a hyperlink inside my Rich Text Box in WinForms, how would I do this? I was thinking like a global mouse click for anywhere at anytime in the form would be the solution, however using forms or even panels mouse click events it only occurs when I don't click a control, which isnt what I want.
You can try the following code to achieve the global mouse position when you click the hyperlink in the richtextbox.
You can use winapi GetCursorPos to get the goobal mouse position.
[DllImport("user32.dll")]
static extern bool GetCursorPos(ref Point lpPoint);
private void Form1_Load(object sender, EventArgs e)
{
richTextBox1.AppendText(
#"Google:http://www.google.cn/ c#:https://learn.microsoft.com/en-us/dotnet/csharp/ testsssssssssssHelo,worldssssssssssssssssssssssssssssssssssssssssss");
richTextBox1.LinkClicked += RichTextBox1_LinkClicked;
}
private void RichTextBox1_LinkClicked(object sender, LinkClickedEventArgs e)
{
var pt = new Point();
GetCursorPos(ref pt);
textBox1.Text = pt.X.ToString();
textBox2.Text = pt.Y.ToString();
}
Example:
Hey guys so I figured out a solution that worked for me
private void dropDownBoxSite2Term2_LinkClicked(object sender, LinkClickedEventArgs e)
{
//I use and bool to check if any link inside the rtb was clicked, and also grab //the text:
subRTBLinkClicked = true;
subRTBLinkText = e.LinkText;
}
//This is the rtb im using:
private void dropDownBoxSite2Term3_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
//This is how i grabbed the client position:
RTBDropDownLMBLocation = panel2.PointToClient(dropDownBoxSite2Term3.PointToScreen(new Point(e.X, e.Y)));
//Using the bool from above i make an action occur
if (subRTBLinkClicked)
{
//make action happen that i need and use RTBDropDownLMBLocation
//for desired needs, like instantiate another textbox at click //position if needed for example
}
}
Hope this helps someone out there!
I build an UserControl in C# form.
And I use MouseMove event in the event list.
Everything works properly.
Then,I want to detect if right or left button of mouse is pressed.
The MouseEventArgs provide Button status to use.
The issue is when left button on mouse is already pressed somewhere outside the UserControl ,then move the cursor on to the UserControl,MouseMove event just won't trigger.
Is there any solution for this?
This is because the MouseDown has happened somewhere else and therefore the MouseMove of that other place still keeps happening.
This is a good thing so you don't lose the event just because you happen to slip aside, eg from a scrollbar.
If you really want to prevent the good thing happening at that special place you can release the mouse capture that is going on..:
private void theOtherPlace_MouseMove(object sender, MouseEventArgs e)
{
if (! theOtherPlace.ClientRectangle.Contains(e.Location))
{
User32_DLL.ReleaseCapture();
}
}
Using this helper class:
using System.Runtime.InteropServices;
..
public static class User32_DLL
{
[DllImportAttribute("user32.dll")]
public static extern bool ReleaseCapture();
}
Not sure if it is a good idea, though! I for one am always very happy if I can rely on the pressed mousebutton to still work the way it should..
Or you could trigger the MouseMove of the UserControl from the other MouseMove, passing in the UC as sender and a modified MouseEventArgs:
private void theOtherPlace_MouseMove(object sender, MouseEventArgs e)
{
if (! theOtherPlace.ClientRectangle.Contains(e.Location))
{
Point pt = yourUserControl.PointToClient(Control.MousePosition);
if (yourUserControl.ClientRectangle.Contains(pt))
{
yourUserControl_MouseMove(listView1,
new MouseEventArgs(e.Button, e.Clicks, pt.X, pt.Y, e.Delta ) );
}
}
}
I want to have it such that left clicking on the NotifyIcon also causes the context menu (set with the ContextMenuStrip property) to open as well. How would I achieve this? Do I have to handle Click and figure out the positioning myself?
Edit: showing the menu with trayIcon.ContextMenuStrip.Show() results is a few undesirable behaviors:
The menu is not shown at the same location as if right click the NotifyIcon (it appears that you can't set the x and y coords to where the taskbar is, at least on Windows 7 which is what I'm running). It will appear above the task bar (not that big of a deal, but consistency would be nice).
While the menu is shown, there is an extra icon added to the task bar.
Clicking somewhere other than the menu does not close it (whereas if you right click to bring up the context menu clicking else where automatically closes the context menu).
Is it at all possible to just invoke the menu however the built in right click handler is doing it?
You would normally handle the MouseClick event to detect the click and call the ContextMenuStrip.Show() method:
private void notifyIcon1_MouseClick(object sender, MouseEventArgs e) {
contextMenuStrip1.Show(Control.MousePosition);
}
But that doesn't actually work properly, the CMS won't close when you click outside of it. Underlying issue is a Windows quirk (aka "bug") that is described in this KB article.
Invoking this workaround in your own code is pretty painful, the pinvoke is unpleasant. The NotifyIcon class has this workaround in its ShowContextMenu() method, they just made it difficult to get to since it is a private method. Reflection can bypass that restriction. I discovered this hack 5 years ago and nobody reported a problem with it yet. Set the NFI's ContextMenuStrip property and implement the MouseUp event like this:
using System.Reflection;
...
private void notifyIcon1_MouseUp(object sender, MouseEventArgs e) {
if (e.Button == MouseButtons.Left) {
MethodInfo mi = typeof(NotifyIcon).GetMethod("ShowContextMenu", BindingFlags.Instance | BindingFlags.NonPublic);
mi.Invoke(notifyIcon1, null);
}
}
If you handle MouseUp rather than Click, you will be able to tell which button was clicked, as well as the location of the click. You can use this location as the location to show the ContextMenu
notifyIcon.MouseUp += new MouseEventHandler(delegate(object sender, MouseEventArgs e) { contextMenu.Show(e.Location); });
You can wire in a onClick event for notify icon then call show in the on click
private void wire()
{
notifyIcon1.Click += new EventHandler(notifyIcon1_Click);
}
void notifyIcon1_Click(object sender, EventArgs e)
{
contextMenuStrip1.Show(Cursor.Position);
}
use the following code to show context menu on both right and left click on notifyicon, if you find any issue then text me at arshad_mcs786#hotmail.com (arshad from Islamabd)
//System.Runtime.InteropServices use thi as reference
[DllImport("User32.dll", ExactSpelling = true, CharSet = CharSet.Auto)]
public static extern bool SetForegroundWindow(HandleRef hWnd);
private void notifyIcon1_Click(object sender, EventArgs e)
{
SetForegroundWindow(new HandleRef(this, this.Handle));
int x = Control.MousePosition.X;
int y = Control.MousePosition.Y;
x = x - 10;
y = y - 40;
this.contextMenuStrip1.Show(x,y );
//this.PointToClient(Cursor.Position)
}
Is there a way to disable the exit button on a windows form without having to import the some external .dll's? I disable the exit button by importing dll's using the following code but I don't like it. Is there a simpler (built-in) way?
public Form1()
{
InitializeComponent();
hMenu = GetSystemMenu(this.Handle, false);
}
private const uint SC_CLOSE = 0xf060;
private const uint MF_GRAYED = 0x01;
private IntPtr hMenu;
[DllImport("user32.dll")]
private static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert);
[DllImport("user32.dll")]
private static extern int EnableMenuItem(IntPtr hMenu, uint wIDEnableItem, uint wEnable);
// handle the form's Paint and Resize events
private void Form1_Paint(object sender, PaintEventArgs e)
{
EnableMenuItem(hMenu, SC_CLOSE, MF_GRAYED);
}
private void Form1_Resize(object sender, EventArgs e)
{
EnableMenuItem(hMenu, SC_CLOSE, MF_GRAYED);
}
You can't easily disable the exit button (the one in the top right that closes the form).
You can, however, hide the button completely, by setting the ControlBox property to false.
ControlBox can be turned on and off at any time, so you can use this if you want to dynamically allow closing at some times, and not at others.
Alternatively, you can handle the FormClosing event and cancel the close if you choose.
Here's a demo.
Create a new Windows Forms project.
Drop a CheckBox control on the form, with Text "ControlBox". Hook up its Click event to this:
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
ControlBox = checkBox1.Checked;
}
Then, drop a second CheckBox control on the form with Text "Cancel Close". Hook up the FormClosing event of the form to this:
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
e.Cancel = checkBox2.Checked;
}
Run the application and start playing around with the checkboxes. You'll soon see how things work.
To disable the close button on the form just write the below code on the form closing event.
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
e.Cancel = true;
}
A little poking around found this handy helper class:
Disable Close Button and Prevent Form Being Moved (C# version)
It actually does more than what you're looking for, but essentially does it very nearly the same way you do in your sample code. The helper class hooks into the load/resize events for you so you don't have to remember to do it yourself.
Yes.
Setting the form.ControlBox = false will hide the close button. Although, it will also hide the minimize and maximize button.
You can also set form.FormBorderStyle = FormBorderStyle.None, which will hide the whole title bar.
If you want to show the X button but just stop the form from closing, override OnClosing and set the e.Cancel property to true.
Catch the FormClosing event and cancel it in the arguments.
Using visual studio select the form go to the properties and set the ControlBox property to false or try this.ControlBox = false; or frmMainForm.ControlBox = false;
Disabling the button is possible without importing dlls. ControlBox = false causes minimise and maximise buttons and the border to disappear as well and it does not disable the close 'X' button - it hides. This solution disables it:
private const int CP_NOCLOSE_BUTTON = 0x200;
protected override CreateParams CreateParams
{
get
{
CreateParams myCp = base.CreateParams;
myCp.ClassStyle = myCp.ClassStyle | CP_NOCLOSE_BUTTON ;
return myCp;
}
}
Source: https://www.codeproject.com/kb/cs/disableclose.aspx