C# 从仅限系统托盘的应用程序创建工具提示
所以我试图在屏幕上的某个点创建一个工具提示C# 从仅限系统托盘的应用程序创建工具提示,c#,tooltip,system-tray,C#,Tooltip,System Tray,所以我试图在屏幕上的某个点创建一个工具提示 ToolTip tip = new ToolTip(); tip.Show("foobar", **IWin32Window window**, new Point(100, 100)) 问题是我不知道在上面的窗口中插入什么作为参数。我的应用程序完全用光了系统托盘,没有其他GUI元素。它被称为notifyIcon1。这是通过表单1创建的。插入到tip.Show()时,这两个值都不起作用 如何仅使用系统托盘在屏幕上的任何位置生成工具提示 谢谢。iwin
ToolTip tip = new ToolTip();
tip.Show("foobar", **IWin32Window window**, new Point(100, 100))
问题是我不知道在上面的窗口中插入什么作为参数。我的应用程序完全用光了系统托盘,没有其他GUI元素。它被称为notifyIcon1
。这是通过表单1
创建的。插入到tip.Show()时,这两个值都不起作用
如何仅使用系统托盘在屏幕上的任何位置生成工具提示
谢谢。iwin32窗口界面是一个简单的界面,只提供名为句柄的IntPtr
属性。可行的话,类似这样的方法应该会起作用:
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace SO_ToolTip
{
public partial class Form1 : Form
{
[DllImport("user32.dll")]
public static extern IntPtr GetDesktopWindow();
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
WindowWrapper windowWrapper = new WindowWrapper(GetDesktopWindow());
ToolTip toolTip = new ToolTip();
toolTip.Show("Blah blah... Blah blah... Blah blah...", windowWrapper, 1, 1, 10000);
}
}
public class WindowWrapper : IWin32Window
{
public WindowWrapper(IntPtr handle)
{
Handle = handle;
}
public IntPtr Handle { get; protected set; }
}
}
但事实并非如此。它抱怨出现了NullReferenceException,我还没有进一步调试。这确实有效:
...
private void button1_Click(object sender, EventArgs e)
{
ToolTip toolTip = new ToolTip();
toolTip.Show("Blah blah... Blah blah... Blah blah...", this, 1, 1, 10000);
}
...
虽然位置是相对于当前窗体的。也许这会让你走上正确的方向
编辑:即使这样也不起作用,所以我不确定这是WindowWrapper(如何?)还是什么问题:
现在开始,在显示工具提示之前,使用一个透明的最大化表单,BringToFront()
表格1代码:
using System;
using System.Windows.Forms;
namespace SO_ToolTip
{
public partial class Form1 : Form
{
Random _Random = new Random();
ToolTip _ToolTip = new ToolTip();
public Form1()
{
InitializeComponent();
}
private void timer1_Tick(object sender, EventArgs e)
{
BringToFront();
_ToolTip.Show("Blah blah... Blah blah... Blah blah...", this, _Random.Next(0, Width), _Random.Next(0, Height), 10000);
}
}
}
表单1设计器代码:因此您可以查看表单属性:
namespace SO_ToolTip
{
partial class Form1
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.timer1 = new System.Windows.Forms.Timer(this.components);
this.SuspendLayout();
//
// timer1
//
this.timer1.Enabled = true;
this.timer1.Interval = 1000;
this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(284, 264);
this.ControlBox = false;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "Form1";
this.Opacity = 0;
this.ShowIcon = false;
this.ShowInTaskbar = false;
this.WindowState = System.Windows.Forms.FormWindowState.Maximized;
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.Timer timer1;
}
}
namespace SO\u工具提示
{
部分类Form1
{
///
///必需的设计器变量。
///
private System.ComponentModel.IContainer components=null;
///
///清理所有正在使用的资源。
///
///如果应释放托管资源,则为true;否则为false。
受保护的覆盖无效处置(布尔处置)
{
if(处理和(组件!=null))
{
组件。Dispose();
}
基地。处置(处置);
}
#区域Windows窗体设计器生成的代码
///
///设计器支持所需的方法-不修改
///此方法的内容与代码编辑器一起使用。
///
私有void InitializeComponent()
{
this.components=new System.ComponentModel.Container();
this.timer1=新系统.Windows.Forms.Timer(this.components);
这个.SuspendLayout();
//
//定时器1
//
this.timer1.Enabled=true;
this.timer1.Interval=1000;
this.timer1.Tick+=新的System.EventHandler(this.timer1\u Tick);
//
//表格1
//
此.AutoScaleDimensions=新系统.Drawing.SizeF(6F,13F);
this.AutoScaleMode=System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize=新系统.Drawing.Size(284264);
this.ControlBox=false;
this.ebox=false;
this.ebox=false;
this.Name=“Form1”;
这个。不透明度=0;
this.ShowIcon=false;
this.ShowInTaskbar=false;
this.WindowState=System.Windows.Forms.FormWindowState.Maximized;
此选项为.resume布局(false);
}
#端区
private System.Windows.Forms.Timer timer1;
}
}
迟到入党:
如果您喜欢/需要WPF窗口:
private class ToolTipWPFWindow : Window
{
private readonly TextBlock m_txtToDisplay = new TextBlock();
private readonly DispatcherTimer m_timer = new DispatcherTimer();
public ToolTipWindow(string p_strStringToDisplay, int p_intXOnScreen = 0, int p_intYOnScreen = 0, double p_dblDurationInMilliSeconds = 1500)
{
if (p_intXOnScreen == 0 && p_intYOnScreen == 0)
{
p_intXOnScreen = System.Windows.Forms.Cursor.Position.X;
p_intYOnScreen = System.Windows.Forms.Cursor.Position.Y;
}
m_txtToDisplay.Text = p_strStringToDisplay;
m_txtToDisplay.Margin = new Thickness(3);
Background = new SolidColorBrush(Colors.LightGoldenrodYellow);
ShowInTaskbar = false;
ResizeMode = System.Windows.ResizeMode.NoResize;
Topmost = true;
// Location on screen - As Set
WindowStartupLocation = WindowStartupLocation.Manual;
Left = p_intXOnScreen;
Top = p_intYOnScreen;
WindowStyle = WindowStyle.None;
SizeToContent = SizeToContent.WidthAndHeight;
Content = m_txtToDisplay;
m_timer.Interval = TimeSpan.FromMilliseconds(p_dblDurationInMilliSeconds);
m_timer.Tick += timer_Tick;
m_timer.Start();
}
private void timer_Tick(object sender, EventArgs e)
{
if (m_timer != null)
{
m_timer.Stop();
m_timer.Tick -= timer_Tick;
}
Close();
}
用法:
// Display the ToolTip Window to the right of the Cursor
int intX = Cursor.Position.X + 20;
int intY = Cursor.Position.Y;
ToolTipWindow wpfWindow = new ToolTipWindow("Text To Display", intX, intY, 800);
wpfWindow.Show();
结果:
我没有实现鼠标离开事件,因为我使用了较短的显示持续时间 如果希望提示浮动在托盘上方,则需要使用托盘的窗口控制柄。我希望工具提示通过Point参数移动到我希望它移动到的任何位置。所以我不在乎它是如何被调用的,或者它链接到什么形式,等等。我只想让它工作。你说的“托盘的窗口把手”是什么意思?事实上,我现在看到你有了一个表单,对吗?表单是一个窗口,因此您应该使用表单。也许你应该发布一些代码。我的答案让你得到了你需要的吗?谢谢,现在回顾一下,但看起来不错!我不认为它有那么复杂,我模糊地记得你可以从表单中获得一个IWin32Window,而无需实现你自己的类。正确,form
实现了IWin32Window
接口,这就是当我传递这个
时发生的事情,它是我的Form1对象。问题是他想在屏幕上的任何地方(例如:桌面)绘制工具提示。从本质上来说,这只是另一扇窗户。我之所以选择p/invoke路径,是因为我已经有了一个获取桌面句柄的方法BringToFront()
将工具提示带到最前面,当然,也会使我正在编写的文本框失去焦点。不太理想。这看起来比它应该的难多了。我用自动热键做了这个程序的原型。AHK有一个工具提示(“foo”,10,10)
方法,可以将工具提示放在任何你想要的地方。使用更强大的C#并不是那么容易,这有点疯狂。NullReferenceException
之所以被提出,是因为System.Windows.Forms.ToolTip.IsWindowActive(…)
正试图将IWin32Window强制转换为System.Windows.Forms.Control
并检查下一条语句windowControl.ShowParams&0xF)!=NativeMethods.SW_SHOWNOACTIVATE
。你可以看到
// Display the ToolTip Window to the right of the Cursor
int intX = Cursor.Position.X + 20;
int intY = Cursor.Position.Y;
ToolTipWindow wpfWindow = new ToolTipWindow("Text To Display", intX, intY, 800);
wpfWindow.Show();