I need to display a modeless message box whenever a user hovers over a menu item. I can't use messagebox.show(...) because it is a modal. So what I did was create a seperate windows form and display the form using the hover event on the menu item. I have 2 problems:
每当用户将鼠标悬停在菜单项上时,我都需要显示无模式消息框。我不能使用messagebox.show(...),因为它是一个模态。所以我所做的是创建一个单独的窗体,并使用菜单项上的悬停事件显示窗体。我有两个问题:
1) When the windows form displays the menu loses its visibility.
2) The windows form does not appear next to the menu item like how a tooltip would.
1)当窗体显示时,菜单失去了可见性。 2)窗口表单不会出现在菜单项旁边,就像工具提示一样。
Any ideas on how I could custmize a component's tooltip that will make it look and act like a windows form?
关于如何定制组件的工具提示以使其外观和行为类似于Windows窗体的任何想法?
2 个解决方案
#1
To answer your second problem:
要回答你的第二个问题:
If you set the form.StartPosition
property to FormStartPosition.Manual
then you can position the form at the cursor (for example):
如果将form.StartPosition属性设置为FormStartPosition.Manual,则可以将表单放在光标处(例如):
form.StartPosition = FormStartPosition.Manual;
form.Location = new Point(Cursor.Position.X - 1, Cursor.Position.Y - 1);
This might help with your first problem too.
这也可能有助于解决您的第一个问题。
If you want the form to behave like a tooltip then if you add the following event handler code it might give you want you want:
如果您希望表单的行为类似于工具提示,那么如果您添加以下事件处理程序代码,它可能会让您想要:
private void Form_MouseLeave(object sender, EventArgs e)
{
// Only close if cursor actually outside the popup and not over a label
if (Cursor.Position.X < Location.X || Cursor.Position.Y < Location.Y ||
Cursor.Position.X > Location.X + Width - 1 || Cursor.Position.Y > Location.Y + Height - 1)
{
Close();
}
}
This explains the -1
in setting the form position. It ensures that the cursor is actually on the form when it first displays.
这解释了设置表格位置时的-1。它确保光标在首次显示时实际位于表单上。
#2
Since Form class is just a wrapper around native window, you can use the following snippet to create your own popup form, that looks almost as tooltip window:
由于Form类只是本机窗口的包装器,因此您可以使用以下代码段创建自己的弹出窗体,它几乎看起来像工具提示窗口:
public class PopupForm : Form
{
private const int SWP_NOSIZE = 0x0001;
private const int SWP_NOMOVE = 0x0002;
private const int SWP_NOACTIVATE = 0x0010;
private const int WS_POPUP = unchecked((int)0x80000000);
private const int WS_BORDER = 0x00800000;
private const int WS_EX_TOPMOST = 0x00000008;
private const int WS_EX_NOACTIVATE = 0x08000000;
private const int CS_DROPSHADOW = 0x00020000;
private static readonly IntPtr HWND_TOPMOST = (IntPtr)(-1);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
public PopupForm()
{
InitializeComponent();
SetStyle(ControlStyles.Selectable, false);
Visible = false;
}
protected virtual void InitializeComponent()
{
FormBorderStyle = FormBorderStyle.None;
StartPosition = FormStartPosition.Manual;
ShowInTaskbar = false;
BackColor = SystemColors.Info;
// ...
}
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.Style |= WS_POPUP;
cp.Style |= WS_BORDER;
cp.ExStyle |= WS_EX_TOPMOST | WS_EX_NOACTIVATE;
//if (Microsoft.OS.IsWinXP && SystemInformation.IsDropShadowEnabled)
// cp.ClassStyle |= CS_DROPSHADOW;
return cp;
}
}
protected override bool ShowWithoutActivation
{
get { return true; }
}
public new void Show()
{
SetWindowPos(Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE);
base.Show();
}
public void Show(Point p)
{
Location = p;
Show();
}
}
Control this form with Show() and Hide() methods from the outside code.
使用外部代码中的Show()和Hide()方法控制此表单。
#1
To answer your second problem:
要回答你的第二个问题:
If you set the form.StartPosition
property to FormStartPosition.Manual
then you can position the form at the cursor (for example):
如果将form.StartPosition属性设置为FormStartPosition.Manual,则可以将表单放在光标处(例如):
form.StartPosition = FormStartPosition.Manual;
form.Location = new Point(Cursor.Position.X - 1, Cursor.Position.Y - 1);
This might help with your first problem too.
这也可能有助于解决您的第一个问题。
If you want the form to behave like a tooltip then if you add the following event handler code it might give you want you want:
如果您希望表单的行为类似于工具提示,那么如果您添加以下事件处理程序代码,它可能会让您想要:
private void Form_MouseLeave(object sender, EventArgs e)
{
// Only close if cursor actually outside the popup and not over a label
if (Cursor.Position.X < Location.X || Cursor.Position.Y < Location.Y ||
Cursor.Position.X > Location.X + Width - 1 || Cursor.Position.Y > Location.Y + Height - 1)
{
Close();
}
}
This explains the -1
in setting the form position. It ensures that the cursor is actually on the form when it first displays.
这解释了设置表格位置时的-1。它确保光标在首次显示时实际位于表单上。
#2
Since Form class is just a wrapper around native window, you can use the following snippet to create your own popup form, that looks almost as tooltip window:
由于Form类只是本机窗口的包装器,因此您可以使用以下代码段创建自己的弹出窗体,它几乎看起来像工具提示窗口:
public class PopupForm : Form
{
private const int SWP_NOSIZE = 0x0001;
private const int SWP_NOMOVE = 0x0002;
private const int SWP_NOACTIVATE = 0x0010;
private const int WS_POPUP = unchecked((int)0x80000000);
private const int WS_BORDER = 0x00800000;
private const int WS_EX_TOPMOST = 0x00000008;
private const int WS_EX_NOACTIVATE = 0x08000000;
private const int CS_DROPSHADOW = 0x00020000;
private static readonly IntPtr HWND_TOPMOST = (IntPtr)(-1);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
public PopupForm()
{
InitializeComponent();
SetStyle(ControlStyles.Selectable, false);
Visible = false;
}
protected virtual void InitializeComponent()
{
FormBorderStyle = FormBorderStyle.None;
StartPosition = FormStartPosition.Manual;
ShowInTaskbar = false;
BackColor = SystemColors.Info;
// ...
}
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.Style |= WS_POPUP;
cp.Style |= WS_BORDER;
cp.ExStyle |= WS_EX_TOPMOST | WS_EX_NOACTIVATE;
//if (Microsoft.OS.IsWinXP && SystemInformation.IsDropShadowEnabled)
// cp.ClassStyle |= CS_DROPSHADOW;
return cp;
}
}
protected override bool ShowWithoutActivation
{
get { return true; }
}
public new void Show()
{
SetWindowPos(Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE);
base.Show();
}
public void Show(Point p)
{
Location = p;
Show();
}
}
Control this form with Show() and Hide() methods from the outside code.
使用外部代码中的Show()和Hide()方法控制此表单。