diff --git a/Greenshot/Forms/AboutForm.cs b/Greenshot/Forms/AboutForm.cs index e195bf87b..5fb784e61 100644 --- a/Greenshot/Forms/AboutForm.cs +++ b/Greenshot/Forms/AboutForm.cs @@ -32,12 +32,13 @@ using Greenshot.Helpers; using Greenshot.Configuration; using GreenshotPlugin.Core; using Greenshot.IniFile; +using GreenshotPlugin.Controls; namespace Greenshot { /// /// The about form /// - public partial class AboutForm : BaseForm { + public partial class AboutForm : AnimatingBaseForm { private static log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(AboutForm)); private Bitmap gBitmap = new Bitmap(90, 90, PixelFormat.Format32bppRgb); private ColorAnimator backgroundAnimation; diff --git a/Greenshot/Forms/AnimatingBaseForm.cs b/Greenshot/Forms/AnimatingBaseForm.cs new file mode 100644 index 000000000..f2cd6fc66 --- /dev/null +++ b/Greenshot/Forms/AnimatingBaseForm.cs @@ -0,0 +1,27 @@ +/* + * Greenshot - a free and open source screenshot tool + * Copyright (C) 2007-2012 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 System; +using GreenshotPlugin.Controls; + +namespace Greenshot { + public class AnimatingBaseForm : AnimatingForm { + } +} diff --git a/Greenshot/Greenshot.csproj b/Greenshot/Greenshot.csproj index 5ba3d9966..08702f8a8 100644 --- a/Greenshot/Greenshot.csproj +++ b/Greenshot/Greenshot.csproj @@ -140,6 +140,9 @@ ImageEditorForm.cs + + Form + Form @@ -186,6 +189,7 @@ + diff --git a/Greenshot/Helpers/HookHelper.cs b/Greenshot/Helpers/HookHelper.cs new file mode 100644 index 000000000..7ba3d5ece --- /dev/null +++ b/Greenshot/Helpers/HookHelper.cs @@ -0,0 +1,96 @@ +/* + * Greenshot - a free and open source screenshot tool + * Copyright (C) 2007-2012 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 System; +using System.Collections.Generic; +using System.Text; +using GreenshotPlugin.UnmanagedHelpers; +using System.Diagnostics; +using GreenshotPlugin.Core; + +namespace Greenshot.Helpers { + public class HookHelper { + private static readonly log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(HookHelper)); + private static List hooks = new List(); + private static WinEventDelegate _winEventProc; + private static uint oleEventThread = 0; + + /// + /// Remove the made hooks + /// + public static void Unhook() { + LOG.Debug("Cleaning winEvent hooks"); + foreach (IntPtr hook in hooks) { + if (hook != IntPtr.Zero) { + User32.UnhookWinEvent(hook); + } + } + } + + /// + /// Hook the WinEvents we are interested in + /// + public static void Hook() { + LOG.Debug("Starting winEvent hooks"); + _winEventProc = new WinEventDelegate(WinEventProc); + int processID = 0; //Process.GetCurrentProcess().Id; + hooks.Add(User32.SetWinEventHook(WinEvent.EVENT_OBJECT_CREATE, WinEvent.EVENT_OBJECT_HIDE, IntPtr.Zero, _winEventProc, processID, 0, WinEventHookFlags.WINEVENT_SKIPOWNPROCESS)); + hooks.Add(User32.SetWinEventHook(WinEvent.EVENT_OBJECT_LOCATIONCHANGE, WinEvent.EVENT_OBJECT_LOCATIONCHANGE, IntPtr.Zero, _winEventProc, 0, 0, WinEventHookFlags.WINEVENT_SKIPOWNPROCESS)); + hooks.Add(User32.SetWinEventHook(WinEvent.EVENT_SYSTEM_MENUSTART, WinEvent.EVENT_SYSTEM_MENUPOPUPEND, IntPtr.Zero, _winEventProc, processID, 0, WinEventHookFlags.WINEVENT_SKIPOWNPROCESS)); + } + + /// + /// Handle the WinEvent + /// + /// The Hook IntPtr + /// Event Type to handle, enum WinEvent + /// Window handle which caused the event + /// Object ID, enum EventObjects + /// Child ID of the window + /// Thread which generated the ID + /// + private static void WinEventProc(IntPtr hWinEventHook, WinEvent eventType, IntPtr hwnd, EventObjects idObject, int idChild, uint dwEventThread, uint dwmsEventTime) { + // Check if it's an event generated by a Window + if (hwnd == IntPtr.Zero || idObject != EventObjects.OBJID_WINDOW) { + // Other events do not interest us. + return; + } + String classname = null; + // Check if the event was generated by the OLE Event Thread, which causes a lot of create/destroy + if (oleEventThread != 0 && dwEventThread == oleEventThread) { + return; + } + + // Only get the classname when it's not a destroy (classname is not available) + if (eventType == WinEvent.EVENT_OBJECT_CREATE) { + classname = WindowDetails.GetClassName(hwnd); + // Make sure the OleMainThreadWndClass events are ignored. + if (oleEventThread == 0) { + if (classname == "OleMainThreadWndClass") { + oleEventThread = dwEventThread; + return; + } + } + } + + LOG.DebugFormat("eventType={0},hwnd={1},classname={4},idObject={2},idChild={3},dwEventThread={5}", eventType, hwnd, idObject, idChild, classname, dwEventThread); + } + } +} diff --git a/Greenshot/releases/innosetup/setup.iss b/Greenshot/releases/innosetup/setup.iss index 0931bea2e..5ca9e3d59 100644 --- a/Greenshot/releases/innosetup/setup.iss +++ b/Greenshot/releases/innosetup/setup.iss @@ -143,10 +143,10 @@ Root: HKCU; Subkey: Software\Microsoft\Windows\CurrentVersion\Run; ValueType: st ; HKEY_LOCAL_MACHINE - for all users Root: HKLM; Subkey: Software\Microsoft\Windows\CurrentVersion\Run; ValueType: string; ValueName: {#ExeName}; ValueData: {app}\{#ExeName}.exe; Permissions: users-modify; Flags: uninsdeletevalue; Tasks: startup; Check: IsAdminLoggedOn ; Register our own filetype -;Root: HKCR; Subkey: ".gsb"; ValueType: string; ValueName: ""; ValueData: "GreenshotFile"; Flags: uninsdeletevalue -;Root: HKCR; Subkey: "GreenshotFile"; ValueType: string; ValueName: ""; ValueData: "Greenshot File"; Flags: uninsdeletekey -;Root: HKCR; Subkey: "GreenshotFile\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\Greenshot.EXE,0" -;Root: HKCR; Subkey: "GreenshotFile\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\Greenshot.EXE"" --openfile ""%1""" +Root: HKCR; Subkey: ".greenshot"; ValueType: string; ValueName: ""; ValueData: "GreenshotFile"; Flags: uninsdeletevalue +Root: HKCR; Subkey: "GreenshotFile"; ValueType: string; ValueName: ""; ValueData: "Greenshot File"; Flags: uninsdeletekey +Root: HKCR; Subkey: "GreenshotFile\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\Greenshot.EXE,0" +Root: HKCR; Subkey: "GreenshotFile\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\Greenshot.EXE"" --openfile ""%1""" [Icons] Name: {group}\{#ExeName}; Filename: {app}\{#ExeName}.exe; WorkingDir: {app} Name: {group}\Uninstall {#ExeName}; Filename: {uninstallexe}; WorkingDir: {app}; AppUserModelID: "{#ExeName}.{#ExeName}" diff --git a/GreenshotPlugin/Controls/AnimatingForm.cs b/GreenshotPlugin/Controls/AnimatingForm.cs index cc689d0c6..77c2acfc8 100644 --- a/GreenshotPlugin/Controls/AnimatingForm.cs +++ b/GreenshotPlugin/Controls/AnimatingForm.cs @@ -28,8 +28,7 @@ namespace GreenshotPlugin.Controls { /// /// Extend this Form to have the possibility for animations on your form /// - public abstract class AnimatingForm : Form { - protected static CoreConfiguration coreConfiguration = IniConfig.GetIniSection(); + public class AnimatingForm : GreenshotForm { private int vRefresh = 0; private Timer timer = null; @@ -111,6 +110,8 @@ namespace GreenshotPlugin.Controls { /// /// This method will be called every frame, so implement your animation/redraw logic here. /// - protected abstract void Animate(); + protected virtual void Animate() { + throw new NotImplementedException(); + } } } diff --git a/GreenshotPlugin/Controls/GreenshotForm.cs b/GreenshotPlugin/Controls/GreenshotForm.cs index 886b6827f..12b6a91e2 100644 --- a/GreenshotPlugin/Controls/GreenshotForm.cs +++ b/GreenshotPlugin/Controls/GreenshotForm.cs @@ -20,7 +20,6 @@ */ using System; using System.Collections.Generic; -using System.Text; using System.Windows.Forms; using System.Reflection; using GreenshotPlugin.Core; @@ -30,8 +29,12 @@ using System.ComponentModel.Design; using System.IO; namespace GreenshotPlugin.Controls { - public abstract class GreenshotForm : AnimatingForm, IGreenshotLanguageBindable { + /// + /// This form is used for automatically binding the elements of the form to the language + /// + public class GreenshotForm : Form, IGreenshotLanguageBindable { private static log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(GreenshotForm)); + protected static CoreConfiguration coreConfiguration; private static IDictionary reflectionCache = new Dictionary(); private IComponentChangeService m_changeService; private bool isDesignModeLanguageSet = false; @@ -40,12 +43,31 @@ namespace GreenshotPlugin.Controls { private IDictionary designTimeControls; private IDictionary designTimeToolStripItems; + static GreenshotForm() { + if (!IsInDesignMode) { + coreConfiguration = IniConfig.GetIniSection(); + } + } + [Category("Greenshot"), DefaultValue(null), Description("Specifies key of the language file to use when displaying the text.")] public string LanguageKey { get; set; } + /// + /// Used to check the designmode during a constructor + /// + /// + protected static bool IsInDesignMode { + get { + if (Application.ExecutablePath.IndexOf("devenv.exe", StringComparison.OrdinalIgnoreCase) > -1) { + return true; + } + return false; + } + } + protected bool ManualLanguageApply { get { return applyLanguageManually; @@ -64,13 +86,6 @@ namespace GreenshotPlugin.Controls { } } - /// - /// Normally a Greenshot form doesn't animate - /// - protected override void Animate() { - throw new NotImplementedException(); - } - /// /// Code to initialize the language etc during design time ///