C# 如何从非表单应用程序制作 BalloonToolTip

C# How to Make a BalloonToolTip from a Non-Form Application

好的,所以我正在尝试制作一个简单的屏幕截图程序,我需要该程序在拍摄屏幕截图时以及程序在启动时设置为 运行 时显示 BalloonToolTip。下面的代码展示了我的整个程序,没有表格,也没有设计器。只是 运行 来自 Program.cs 的程序,它不是控制台应用程序。

using System;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Windows;
using FullscreenShot.Properties;
using GlobalHotKey;
using System.Windows.Input;
using System.Timers;
using System.Threading.Tasks;
using Microsoft.Win32;

namespace FullscreenShot
{
class Program
{
    private static NotifyIcon notifyIcon;
    private static HotKeyManager hotKeyManager;

    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
        System.Windows.Forms.Application.EnableVisualStyles();
        System.Windows.Forms.Application.SetCompatibleTextRenderingDefault(false);
        // We need to dispose here, or the icon will not remove until the 
        // system tray is updated.
        System.Windows.Forms.Application.ApplicationExit += delegate{ notifyIcon.Dispose(); };
        CreateNotifyIcon();
        System.Windows.Forms.Application.Run();
    }

    /// <summary>
    /// Creates the icon that sits in the system tray.
    /// </summary>

    private static void CreateNotifyIcon()
    {
        notifyIcon = new NotifyIcon
        {
            Icon = Resources.AppIcon,
            ContextMenu = GetContextMenu()
        };
        notifyIcon.Visible = true;
/*------------------------------------------------------------*/
        hotKeyManager = new HotKeyManager();//Creates Hotkey manager from GlobalHotKey

        var hotKey = hotKeyManager.Register(Key.F12, ModifierKeys.Control); // Sets Hotkey to Control + F12, ModifierKeys must be pressed first/

        hotKeyManager.KeyPressed += HotKeyManagerPressed; //Creates void for "HotKeyManagerPressed"

        void HotKeyManagerPressed(object sender, KeyPressedEventArgs e) //Checks to see if hotkey is pressed
        {
            if(e.HotKey.Key == Key.F12)

            {
                TakeFullScreenShotAsync();
                BalloonTip();
               // MessageBox.Show("Screenshot Taken");
            }
        }

    }

    /// <summary>
    /// Creates BalloonTip to notify you that your Screenshot was taken.
    /// </summary>
    private static void BalloonTip()
    {
        notifyIcon.Visible = true;
        notifyIcon.Icon = SystemIcons.Information;
        notifyIcon.ShowBalloonTip(740, "Important From Screenshot", "Screenshot Taken", ToolTipIcon.Info);
    }

    private static void BalloonTip2()
    {
        notifyIcon.Visible = true;
        notifyIcon.Icon = SystemIcons.Information;
        notifyIcon.ShowBalloonTip(1, "Important From Screenshot", "Screenshot will now begin on startup", ToolTipIcon.Info);
    }

    ///<summary>
    ///Creates the contextmenu for the Icon
    ///<summary>
    private static ContextMenu GetContextMenu()
    {
        string myPath = System.AppDomain.CurrentDomain.BaseDirectory.ToString();
        System.Diagnostics.Process prc = new System.Diagnostics.Process();
        prc.StartInfo.FileName = myPath;
        ContextMenu menu = new ContextMenu();
        menu.MenuItems.Add("Take Screenshot (Ctrl+F12)", delegate { TakeFullScreenShotAsync(); });
        menu.MenuItems.Add("Open Folder", delegate { prc.Start(); });
        menu.MenuItems.Add("Exit", delegate { System.Windows.Forms.Application.Exit(); });
        menu.MenuItems.Add("Run On Startup", delegate { RunOnStartup(); });

        return menu;

    }

    /// <summary>
    /// Simple function that finds Registry and adds the Application to the startup
    /// </summary>
    private static void RunOnStartup()
    {
        RegistryKey reg = Registry.CurrentUser.OpenSubKey("SOFTWARE\Microsoft\Windows\CurrentVersion\Run", true);
        reg.SetValue("MyApp", Application.ExecutablePath.ToString());
        BalloonTip2();
        MessageBox.Show("The Program will now start on startup");
    }


    /// <summary>
    /// Gets points for the screen uses those points to build a bitmap of the screen and saves it.
    /// </summary>
    private static async void TakeFullScreenShotAsync()
    {
        await Task.Delay(750);//Allows task to be waited on for .75ths of a second. Time In ms.


        int width = Screen.PrimaryScreen.Bounds.Width;
        int height = Screen.PrimaryScreen.Bounds.Height;

        using (Bitmap screenshot = new Bitmap(width, height, PixelFormat.Format32bppArgb))
        {
            using (Graphics graphics = Graphics.FromImage(screenshot))
            {
                System.Drawing.Point origin = new System.Drawing.Point(0, 0);
                System.Drawing.Size screenSize = Screen.PrimaryScreen.Bounds.Size;
                //Copy Entire screen to entire bitmap.
                graphics.CopyFromScreen(origin, origin, screenSize);
            }

            //Check to see if the file exists, if it does, append.
            int append = 1;

            while (File.Exists($"Screenshot{append}.jpg"))
                append++;

            string fileName = $"Screenshot{append}.jpg";
            screenshot.Save(fileName, ImageFormat.Jpeg);
        }
    }
}
}

现在你可能不需要所有这些,但我想确保我没有在这个过程中搞砸任何事情,是的,我的资源正在被发现并且图标已设置,我只是不明白为什么这不起作用。

您尚未在 TakeFullScreenShotAsync() 方法中调用 BalloonTip() 方法。

    private static async void TakeFullScreenShotAsync()
    {
        await Task.Delay(750);//Allows task to be waited on for .75ths of a second. Time In ms.


        int width = Screen.PrimaryScreen.Bounds.Width;
        int height = Screen.PrimaryScreen.Bounds.Height;

        using (Bitmap screenshot = new Bitmap(width, height, PixelFormat.Format32bppArgb))
        {
            using (Graphics graphics = Graphics.FromImage(screenshot))
            {
                System.Drawing.Point origin = new System.Drawing.Point(0, 0);
                System.Drawing.Size screenSize = Screen.PrimaryScreen.Bounds.Size;
                //Copy Entire screen to entire bitmap.
                graphics.CopyFromScreen(origin, origin, screenSize);
            }

            //Check to see if the file exists, if it does, append.
            int append = 1;

            while (File.Exists($"Screenshot{append}.jpg"))
                append++;

            string fileName = $"Screenshot{append}.jpg";
            screenshot.Save(fileName, ImageFormat.Jpeg);

            // Call the Show Tip Message Here...
            BalloonTip();
        }
    }

行:hotKeyManager.Register(...) 抛出一个错误,因为我已经注册了一个热键,因此我将其更改为对我有用的其他东西。

我刚刚复制了你所有的代码有一个小问题,不确定是你复制粘贴错误你需要把 HotKeyManagerPressed 放在外面。它对我有用,我看到了我的通知,它是 windows 10 通知。

using System;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Windows;
using GlobalHotKey;
using System.Windows.Input;
using System.Timers;
using System.Threading.Tasks;
using Microsoft.Win32;
using FullScreenShot.Properties;

namespace FullScreenShot
{
    class Program
    {
        private static NotifyIcon notifyIcon;
        private static HotKeyManager hotKeyManager;

        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            System.Windows.Forms.Application.EnableVisualStyles();
            System.Windows.Forms.Application.SetCompatibleTextRenderingDefault(false);
            // We need to dispose here, or the icon will not remove until the 
            // system tray is updated.
            System.Windows.Forms.Application.ApplicationExit += delegate { notifyIcon.Dispose(); };
            CreateNotifyIcon();
            System.Windows.Forms.Application.Run();
        }

        /// <summary>
        /// Creates the icon that sits in the system tray.
        /// </summary>

        private static void CreateNotifyIcon()
        {
            notifyIcon = new NotifyIcon
            {
                Icon = Resources.AppIcon,
                ContextMenu = GetContextMenu()
            };
            notifyIcon.Visible = true;
            /*------------------------------------------------------------*/
            hotKeyManager = new HotKeyManager();//Creates Hotkey manager from GlobalHotKey

            var hotKey = hotKeyManager.Register(Key.F12, ModifierKeys.Control); // Sets Hotkey to Control + F12, ModifierKeys must be pressed first/

            hotKeyManager.KeyPressed += HotKeyManagerPressed; //Creates void for "HotKeyManagerPressed"



    }
      private static void HotKeyManagerPressed(object sender, KeyPressedEventArgs e) //Checks to see if hotkey is pressed
        {
            if (e.HotKey.Key == Key.F12)

            {
                TakeFullScreenShotAsync();
                BalloonTip();
                // MessageBox.Show("Screenshot Taken");
            }
        }
        /// <summary>
        /// Creates BalloonTip to notify you that your Screenshot was taken.
        /// </summary>
        private static void BalloonTip()
        {
            notifyIcon.Visible = true;
            notifyIcon.Icon = SystemIcons.Information;
            notifyIcon.ShowBalloonTip(740, "Important From Screenshot", "Screenshot Taken", ToolTipIcon.Info);
        }

        private static void BalloonTip2()
        {
            notifyIcon.Visible = true;
            notifyIcon.Icon = SystemIcons.Information;
            notifyIcon.ShowBalloonTip(1, "Important From Screenshot", "Screenshot will now begin on startup", ToolTipIcon.Info);
        }

        ///<summary>
        ///Creates the contextmenu for the Icon
        ///<summary>
        private static ContextMenu GetContextMenu()
        {
            string myPath = System.AppDomain.CurrentDomain.BaseDirectory.ToString();
            System.Diagnostics.Process prc = new System.Diagnostics.Process();
            prc.StartInfo.FileName = myPath;
            ContextMenu menu = new ContextMenu();
            menu.MenuItems.Add("Take Screenshot (Ctrl+F12)", delegate { TakeFullScreenShotAsync(); });
            menu.MenuItems.Add("Open Folder", delegate { prc.Start(); });
            menu.MenuItems.Add("Exit", delegate { System.Windows.Forms.Application.Exit(); });
            menu.MenuItems.Add("Run On Startup", delegate { RunOnStartup(); });

            return menu;

        }

        /// <summary>
        /// Simple function that finds Registry and adds the Application to the startup
        /// </summary>
        private static void RunOnStartup()
        {
            RegistryKey reg = Registry.CurrentUser.OpenSubKey("SOFTWARE\Microsoft\Windows\CurrentVersion\Run", true);
            reg.SetValue("MyApp", Application.ExecutablePath.ToString());
            BalloonTip2();
            MessageBox.Show("The Program will now start on startup");
        }


        /// <summary>
        /// Gets points for the screen uses those points to build a bitmap of the screen and saves it.
        /// </summary>
        private static async void TakeFullScreenShotAsync()
        {
            await Task.Delay(750);//Allows task to be waited on for .75ths of a second. Time In ms.


            int width = Screen.PrimaryScreen.Bounds.Width;
            int height = Screen.PrimaryScreen.Bounds.Height;

            using (Bitmap screenshot = new Bitmap(width, height, PixelFormat.Format32bppArgb))
            {
                using (Graphics graphics = Graphics.FromImage(screenshot))
                {
                    System.Drawing.Point origin = new System.Drawing.Point(0, 0);
                    System.Drawing.Size screenSize = Screen.PrimaryScreen.Bounds.Size;
                    //Copy Entire screen to entire bitmap.
                    graphics.CopyFromScreen(origin, origin, screenSize);
                }

                //Check to see if the file exists, if it does, append.
                int append = 1;

                while (File.Exists($"Screenshot{append}.jpg"))
                    append++;

                string fileName = $"Screenshot{append}.jpg";
                screenshot.Save(fileName, ImageFormat.Jpeg);
            }
        }
    }
}

查看图片