Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从仅限系统托盘的应用程序创建工具提示_C#_Tooltip_System Tray - Fatal编程技术网

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();