2010-02-07 1 views
2

Так что я пытаюсь создать всплывающую подсказку в какой-то момент на экране.Создание всплывающей подсказки только из приложения системного лотка

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

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

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

Спасибо.

+0

Если вы хотите, чтобы наконечник плавал над лотком, вам необходимо использовать ручку окна лотка. –

+0

Я хочу, чтобы всплывающая подсказка проходила везде, где я хочу, чтобы она проходила через параметр Point. Поэтому мне все равно, как это называется, или с какой формой оно связано, и т. Д. Я просто хочу, чтобы он работал. Что вы понимаете под «ручкой окна лотка»?' – cksubs

+0

На самом деле я вижу теперь, что у вас есть форма, это правильно? форма - это окно, поэтому вы должны использовать свою форму. Может быть, вы должны опубликовать код. –

ответ

2

Интерфейс IWin32Window - это простой интерфейс, который предоставляет только свойство с именем 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); 
} 
... 

Хотя позиция относительно текущей формы. Возможно, это заставит вас идти в правильном направлении.

Edit: Даже это не работает, так что я не уверен, если это проблема с 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

Form1 Код:

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 Designer Код: Таким образом, вы можете увидеть формы свойства:

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', вот что происходит, когда я передаю 'this', который является моим объектом Form1. Проблема в том, что он хочет нарисовать всплывающую подсказку в любом месте экрана (то есть: на рабочем столе). Который по своей природе является еще одним окном. Я отправил маршрут p/invoke, потому что у меня был способ получить дескриптор рабочего стола. –

+0

Получил это. Продолжайте;) –

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

Результат:

wpf tooltip contains "Text To Display"

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