0

I have a very simple C# WinForm sample:

private System.Windows.Forms.ContextMenuStrip ct1;

var header = new ToolStripMenuItem("Header with long test like Lorem Ipsum");
header.Enabled = false;

var txt = new ToolStripTextBox();
txt.Text = "changeme";

ct1.Items.Clear();
ct1.Items.Add(header);
ct1.Items.Add(txt);

ct1.Show(x,y);

Now I have two issues with this:

  1. How can I ask the textbox to fill the full width of the menu (i.e. be as large as the largest item)? enter image description here

  2. If I press the Alt key, the menu closes. I can prevent it by handling the Closing event:

Like this:

private void ct1_Closing(object sender, ToolStripDropDownClosingEventArgs e)
{
    e.Cancel = (e.CloseReason == ToolStripDropDownCloseReason.Keyboard);
}

However I want to be able to close by pressing Escape, and I also want to be able to use Alt key as input.

But now Alt and Escape are all or nothing. How can I differentiate between them?

Tried even on KeyDown event for the TextBox and also for ct1, but Alt key is not forwarded to there.

Daniel
  • 2,318
  • 2
  • 22
  • 53

1 Answers1

1

For your first question,

While it may require some tweaking, this will allow you to set the width of the text box to a good degree:

First, give your textbox a name and attach to these event handlers. This is required because the width of the context menu is not determined until it is shown.

txt.Name = "changeNameTextBox";
ct1.Opening += ct1_Opening;
ct1.Closed += ct1_Closed;

Then implement those event handlers:

void ct1_Opening(object sender, EventArgs e)
{
    ToolStripTextBox txt = ct1.Items.Find("changeNameTextBox", false)[0] as ToolStripTextBox;
    txt.Size = new Size(ct1.Width - 50, txt.Height);
}

void ct1_Closed(object sender, ToolStripDropDownClosedEventArgs e)
{
    ToolStripTextBox txt = ct1.Items.Find("changeNameTextBox", false)[0] as ToolStripTextBox;
    txt.Size = new Size(0, 25);
}

As for your second question, you almost made it.

Have that onClosing event, and modify its body like this:

void ct1_Closing(object sender, ToolStripDropDownClosingEventArgs e)
{
    e.Cancel =
        e.CloseReason == ToolStripDropDownCloseReason.Keyboard
        && 
        Control.ModifierKeys.HasFlag(Keys.Alt); 
}

Hope this helps.

Oguz Ozgul
  • 6,809
  • 1
  • 14
  • 26
  • Regarding 1: `ct1.Width - 50`: with 50 it works OK, but where is that 50 coming from? Is that a margin for some items? Thank you – Daniel Apr 29 '20 at 06:13
  • 50 is just trial/error. When we set the size of the text box (.Width does not work, only .Size works), the context menu size also increases. There is an area on the left of the context menu for icons, this part is included in the width of the context menu, there is also an area on the right which we cannot use (text box width will never get into that area and the context menu width is increased instead). There can be ways to get the size of the icon part (like winapi calls, or some feature of forms) which I don't know – Oguz Ozgul Apr 29 '20 at 06:17
  • Okay, thanks, it's good this way. Regarding 2: it does not seem to work, when I press Alt, the menu closes immediately – Daniel Apr 29 '20 at 06:23
  • And one more thing for 2: the goal is not to prevent Alt from being pressed. The goal is to be able to use Alt to input special characters, and let Escape close the menu. – Daniel Apr 29 '20 at 06:24
  • Escape closes the menu, Alt is prevented for now but we can SendMessage to the text box to make it work. Do you mean AltGr key? And characters like #, $ etc? – Oguz Ozgul Apr 29 '20 at 06:29
  • Of course you mean AltGr key right? It handles the Left ALT key right now – Oguz Ozgul Apr 29 '20 at 06:30
  • Yes, I wanted AltGr and those #$, yes! Sorry. – Daniel Apr 29 '20 at 06:35
  • Ok, I made an overkill here. You onClosing is fine, you just need to get which key caused the evet. Updating my question. – Oguz Ozgul Apr 29 '20 at 06:37
  • This is perfect now, thank you. Just for curiosity, what would be the codes for `AtlGr` in `IMessageFilter`? – Daniel Apr 29 '20 at 06:59
  • 1
    Bit 24 of lparam would be set, accorging to this: https://learn.microsoft.com/en-us/windows/win32/inputdev/wm-keydown – Oguz Ozgul Apr 29 '20 at 08:53