Создание всплывающей подсказки из приложения только в системном трее

2

Итак, я пытаюсь создать подсказку в какой-то момент на экране.

ToolTip tip = new ToolTip();
tip.Show("foobar", **IWin32Window window**, new Point(100, 100))

Проблема заключается в том, что я не знаю, что вставить в качестве параметра window в приведенном выше. Мое приложение полностью выходит из системного трея и не имеет других элементов GUI. Он называется notifyIcon1. Это создается через Form1. Ни одно из этих значений не работает при подключении к tip.Show().

Как создать всплывающую подсказку в любом месте экрана, используя только системный лоток?

Спасибо.

  • 0
    Если вы хотите, чтобы наконечник плавал над лотком, то вам нужно использовать ручку окна лотка.
  • 0
    Я хочу, чтобы всплывающая подсказка направлялась туда, куда я хочу, через параметр Point. Поэтому мне все равно, как это называется или с какой формой оно связано и т. Д. Я просто хочу, чтобы это работало. Что вы подразумеваете под "ручкой окна в трее"?
Показать ещё 3 комментария
Теги:
tooltip
system-tray

2 ответа

2

Интерфейс IWin32Window - это простой интерфейс, который предоставляет только свойство IntPtr с именем Handle. Возможно, что-то подобное должно работать:

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 (как?) или что:

...
private void button1_Click(object sender, EventArgs e)
{
    WindowWrapper windowWrapper = new WindowWrapper(this.Handle);
    ToolTip toolTip = new ToolTip();
    toolTip.Show("Blah blah... Blah blah... Blah blah...", windowWrapper, 1, 1, 10000);
}
...

Здесь вы идете, используйте прозрачную, максимизированную форму, которую вы BringToFront() перед показом ToolTip

Код формы:

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

Код конструктора Form1:. Вы можете увидеть свойства форм:

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;

    }
}
  • 0
    Я не думаю, что это так сложно, я смутно помню, что вы можете получить IWin32Window из формы, не реализуя свой собственный класс.
  • 0
    Правильно, Form реализует интерфейс IWin32Window , вот что происходит, когда я IWin32Window this которое является моим объектом Form1. Проблема в том, что он хочет нарисовать всплывающую подсказку в любом месте экрана (т. Е. На рабочем столе). Который по своей природе является просто другим окном. Я пошел по пути p / invoke, потому что у меня был способ получить дескриптор рабочего стола.
Показать ещё 5 комментариев
1

Присоединение к вечеринке:

Если вы предпочитаете/должны иметь окно 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();

Результат:

Изображение 174551

Я не реализовал событие Mouse leave, так как использовал короткую продолжительность отображения.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню