/* * Greenshot - a free and open source screenshot tool * Copyright (C) 2007-2015 Thomas Braun, Jens Klingen, Robin Krom * * For more information see: http://getgreenshot.org/ * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/ * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 1 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ using Greenshot.IniFile; using Greenshot.Plugin; using GreenshotPlugin.UnmanagedHelpers; using Microsoft.Win32; using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.IO; using System.Windows.Forms; namespace GreenshotPlugin.Core { /// /// Description of PluginUtils. /// public static class PluginUtils { private static readonly CoreConfiguration conf = IniConfig.GetIniSection(); private const string PATH_KEY = @"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\"; private static readonly IDictionary exeIconCache = new Dictionary(); static PluginUtils() { conf.PropertyChanged += OnIconSizeChanged; } /// /// Simple global property to get the Greenshot host /// public static IGreenshotHost Host { get; set; } /// /// Clear icon cache /// /// /// private static void OnIconSizeChanged(object sender, PropertyChangedEventArgs e) { if (e.PropertyName == "IconSize") { List cachedImages = new List(); lock (exeIconCache) { foreach (string key in exeIconCache.Keys) { cachedImages.Add(exeIconCache[key]); } exeIconCache.Clear(); } foreach (Image cachedImage in cachedImages) { if (cachedImage != null) { cachedImage.Dispose(); } } } } /// /// Get the path of an executable /// /// e.g. cmd.exe /// Path to file public static string GetExePath(string exeName) { using (RegistryKey key = Registry.LocalMachine.OpenSubKey(PATH_KEY + exeName, false)) { if (key != null) { // "" is the default key, which should point to the requested location return (string)key.GetValue(""); } } foreach (string pathEntry in (Environment.GetEnvironmentVariable("PATH") ?? "").Split(';')) { try { string path = pathEntry.Trim(); if (!String.IsNullOrEmpty(path) && File.Exists(path = Path.Combine(path, exeName))) { return Path.GetFullPath(path); } } catch (Exception) { LOG.WarnFormat("Problem with path entry '{0}'.", pathEntry); } } return null; } /// /// Get icon for executable, from the cache /// /// path to the exe or dll /// index of the icon /// Bitmap with the icon or null if something happended public static Image GetCachedExeIcon(string path, int index) { string cacheKey = string.Format("{0}:{1}", path, index); Image returnValue; lock (exeIconCache) { if (!exeIconCache.TryGetValue(cacheKey, out returnValue)) { lock (exeIconCache) { if (!exeIconCache.TryGetValue(cacheKey, out returnValue)) { returnValue = GetExeIcon(path, index); if (returnValue != null) { exeIconCache.Add(cacheKey, returnValue); } } } } } return returnValue; } /// /// Get icon for executable /// /// path to the exe or dll /// index of the icon /// Bitmap with the icon or null if something happended private static Bitmap GetExeIcon(string path, int index) { if (!File.Exists(path)) { return null; } try { using (Icon appIcon = ImageHelper.ExtractAssociatedIcon(path, index, conf.UseLargeIcons)) { if (appIcon != null) { return appIcon.ToBitmap(); } } using (Icon appIcon = Shell32.GetFileIcon(path, conf.UseLargeIcons ? Shell32.IconSize.Large : Shell32.IconSize.Small, false)) { if (appIcon != null) { return appIcon.ToBitmap(); } } } catch (Exception exIcon) { LOG.Error("error retrieving icon: ", exIcon); } return null; } /// /// Helper method to add a MenuItem to the File MenuItem of an ImageEditor /// /// Image to display in the menu /// Text to display in the menu /// The TAG value /// Keys which can be used as shortcut /// The onclick handler public static void AddToFileMenu(IImageEditor imageEditor, Image image, string text, object tag, Keys? shortcutKeys, EventHandler handler) { ToolStripMenuItem item = new ToolStripMenuItem(); item.Image = image; item.Text = text; item.Tag = tag; if (shortcutKeys.HasValue) { item.ShortcutKeys = shortcutKeys.Value; } item.Click += handler; AddToFileMenu(imageEditor, item); } /// /// Helper method to add a MenuItem to the File MenuItem of an ImageEditor /// /// /// public static void AddToFileMenu(IImageEditor imageEditor, ToolStripMenuItem item) { ToolStripMenuItem toolStripMenuItem = imageEditor.GetFileMenuItem(); bool added = false; for (int i = 0; i < toolStripMenuItem.DropDownItems.Count; i++) { if (toolStripMenuItem.DropDownItems[i].GetType() == typeof(ToolStripSeparator)) { toolStripMenuItem.DropDownItems.Insert(i, item); added = true; break; } } if (!added) { toolStripMenuItem.DropDownItems.Add(item); } } /// /// Helper method to add a MenuItem to the Plugin MenuItem of an ImageEditor /// /// /// public static void AddToPluginMenu(IImageEditor imageEditor, ToolStripMenuItem item) { ToolStripMenuItem toolStripMenuItem = imageEditor.GetPluginMenuItem(); bool added = false; for (int i = 0; i < toolStripMenuItem.DropDownItems.Count; i++) { if (toolStripMenuItem.DropDownItems[i].GetType() == typeof(ToolStripSeparator)) { toolStripMenuItem.DropDownItems.Insert(i, item); added = true; break; } } if (!added) { toolStripMenuItem.DropDownItems.Add(item); } } /// /// Helper method to add a plugin MenuItem to the Greenshot context menu /// /// /// public static void AddToContextMenu(IGreenshotHost host, ToolStripMenuItem item) { // Here we can hang ourselves to the main context menu! ContextMenuStrip contextMenu = host.MainMenu; bool addedItem = false; // Try to find a separator, so we insert ourselves after it for (int i = 0; i < contextMenu.Items.Count; i++) { if (contextMenu.Items[i].GetType() == typeof(ToolStripSeparator)) { // Check if we need to add a new separator, which is done if the first found has a Tag with the value "PluginsAreAddedBefore" if ("PluginsAreAddedBefore".Equals(contextMenu.Items[i].Tag)) { ToolStripSeparator separator = new ToolStripSeparator(); separator.Tag = "PluginsAreAddedAfter"; separator.Size = new Size(305, 6); contextMenu.Items.Insert(i, separator); } else if (!"PluginsAreAddedAfter".Equals(contextMenu.Items[i].Tag)) { continue; } contextMenu.Items.Insert(i + 1, item); addedItem = true; break; } } // If we didn't insert the item, we just add it... if (!addedItem) { contextMenu.Items.Add(item); } } } }