多くのメニュー項目を含むメニューがいくつかあります。マウスホイールはそれらをスクロールしません。キーボードの矢印を使用するか、上下の矢印をクリックする必要があります。マウスホイールを使用してツールストリップメニュー項目をスクロールすることは可能ですか?ありがとう
質問する
5170 次
4 に答える
5
このクラスを使用して、アプリケーション全体で有効にすることができます。
public class DropDownMenuScrollWheelHandler : System.Windows.Forms.IMessageFilter
{
private static DropDownMenuScrollWheelHandler Instance;
public static void Enable(bool enabled)
{
if (enabled)
{
if (Instance == null)
{
Instance = new DropDownMenuScrollWheelHandler();
Application.AddMessageFilter(Instance);
}
}
else
{
if (Instance != null)
{
Application.RemoveMessageFilter(Instance);
Instance = null;
}
}
}
private IntPtr activeHwnd;
private ToolStripDropDown activeMenu;
public bool PreFilterMessage(ref Message m)
{
if (m.Msg == 0x200 && activeHwnd != m.HWnd) // WM_MOUSEMOVE
{
activeHwnd = m.HWnd;
this.activeMenu = Control.FromHandle(m.HWnd) as ToolStripDropDown;
}
else if (m.Msg == 0x20A && this.activeMenu != null) // WM_MOUSEWHEEL
{
int delta = (short)(ushort)(((uint)(ulong)m.WParam) >> 16);
handleDelta(this.activeMenu, delta);
return true;
}
return false;
}
private static readonly Action<ToolStrip, int> ScrollInternal
= (Action<ToolStrip, int>)Delegate.CreateDelegate(typeof(Action<ToolStrip, int>),
typeof(ToolStrip).GetMethod("ScrollInternal",
System.Reflection.BindingFlags.NonPublic
| System.Reflection.BindingFlags.Instance));
private void handleDelta(ToolStripDropDown ts, int delta)
{
if (ts.Items.Count == 0)
return;
var firstItem = ts.Items[0];
var lastItem = ts.Items[ts.Items.Count - 1];
if (lastItem.Bounds.Bottom < ts.Height && firstItem.Bounds.Top > 0)
return;
delta = delta / -4;
if (delta < 0 && firstItem.Bounds.Top - delta > 9)
{
delta = firstItem.Bounds.Top - 9;
}
else if (delta > 0 && delta > lastItem.Bounds.Bottom - ts.Height + 9)
{
delta = lastItem.Bounds.Bottom - owner.Height + 9;
}
if (delta != 0)
ScrollInternal(ts, delta);
}
}
于 2014-12-09T22:22:53.920 に答える
4
実用的なソリューション:
MouseWheel
フォームのDropDownClosed
イベントとルートのイベントMenuStripItem
(ここではrootItem)をLoad
フォームのイベントに登録しますthis.MouseWheel += Form3_MouseWheel; rootItem.DropDownOpened += rootItem_DropDownOpened; rootItem.DropDownClosed += rootItem_DropDownClosed;
Keyboard
キーの押下をシミュレートするクラスのコードを追加しますpublic static class Keyboard { [DllImport("user32.dll")] static extern uint keybd_event(byte bVk, byte bScan, int dwFlags, int dwExtraInfo); const byte VK_UP = 0x26; // Arrow Up key const byte VK_DOWN = 0x28; // Arrow Down key const int KEYEVENTF_EXTENDEDKEY = 0x0001; //Key down flag, the key is going to be pressed const int KEYEVENTF_KEYUP = 0x0002; //Key up flag, the key is going to be released public static void KeyDown() { keybd_event(VK_DOWN, 0, KEYEVENTF_EXTENDEDKEY, 0); keybd_event(VK_DOWN, 0, KEYEVENTF_KEYUP, 0); } public static void KeyUp() { keybd_event(VK_UP, 0, KEYEVENTF_EXTENDEDKEY, 0); keybd_event(VK_UP, 0, KEYEVENTF_KEYUP, 0); } }
DropDownOpened
、、イベントのコードを追加しDropDownClosed
ます。MouseWheel
bool IsMenuStripOpen = false; void rootItem_DropDownOpened(object sender, EventArgs e) { IsMenuStripOpen = true; } void rootItem_DropDownClosed(object sender, EventArgs e) { IsMenuStripOpen = false; } void Form3_MouseWheel(object sender, MouseEventArgs e) { if (IsMenuStripOpen) { if (e.Delta > 0) { Keyboard.KeyUp(); } else { Keyboard.KeyDown(); } } }
于 2012-10-30T18:37:22.707 に答える
0
これは、コンテキストメニューのサブメニュー( )を使用するだけです。ToolStripMenuItem
form1
(またはUserControl
)とcontextMenuStrip1
:を使用すると仮定します
private void form1_Load( object sender , EventArgs e )
{
//this.MouseWheel -= When_MouseWheel;
this.MouseWheel += When_MouseWheel;
}
void When_MouseWheel( object sender , MouseEventArgs e )
{
if ( this.contextMenuStrip1.IsDropDown ) {
//this.Focus();
if ( e.Delta > 0 ) SendKeys.SendWait( "{UP}" );
else SendKeys.SendWait( "{DOWN}" );
}
}
于 2015-07-05T07:27:07.537 に答える
0
Mohsen Afshinの回答を変更して、上下のキーを押す代わりに上下の矢印をクリックするようにしました。私のアプリケーションにはContextMenuStrip
と呼ばれるものがありましたmenu
。これがコードです。
初期化では:
menu.VisibleChanged += (s, e) =>
{
if (menu.Visible)
{
MouseWheel += ScrollMenu;
menu.MouseWheel += ScrollMenu;
}
else
{
MouseWheel -= ScrollMenu;
menu.MouseWheel -= ScrollMenu;
}
};
ScrollMenu関数:
[System.Runtime.InteropServices.DllImport("user32.dll")]
private static extern void mouse_event(uint dwFlags, uint dx, uint dy, uint cButtons, uint dwExtraInfo);
private void ScrollMenu(object sender, MouseEventArgs e)
{
Point origin = Cursor.Position;
int clicks;
if (e.Delta < 0)
{
Cursor.Position = menu.PointToScreen(new Point(menu.DisplayRectangle.Left + 5, menu.DisplayRectangle.Bottom + 5));
clicks = e.Delta / -40;
}
else
{
Cursor.Position = menu.PointToScreen(new Point(menu.DisplayRectangle.Left + 5, menu.DisplayRectangle.Top - 5));
clicks = e.Delta / 40;
}
for (int i = 0; i < clicks; i++)
mouse_event(0x0006, 0, 0, 0, 0);//Left mouse button up and down on cursor position
Cursor.Position = origin;
}
関数で特定の場所をクリックするのに問題があったmouse_event
ので、カーソルを移動してクリックし、カーソルを元に戻しました。きれいではないようですが、機能します。
于 2017-11-10T13:30:14.770 に答える