Using background thread to retrieve the window details, this should speed up the time until the CaptureForm is shown.

git-svn-id: http://svn.code.sf.net/p/greenshot/code/trunk@1610 7dccd23d-a4a3-4e1f-8c07-b4c1b4018ab4
This commit is contained in:
RKrom 2012-01-24 21:53:09 +00:00
parent 73cfc30d49
commit 6ecba18fae
2 changed files with 64 additions and 52 deletions

View file

@ -230,15 +230,17 @@ namespace Greenshot.Forms {
// Iterate over the found windows and check if the current location is inside a window // Iterate over the found windows and check if the current location is inside a window
Point cursorPosition = Cursor.Position; Point cursorPosition = Cursor.Position;
selectedCaptureWindow = null; selectedCaptureWindow = null;
foreach (WindowDetails window in windows) { lock (windows) {
if (window.Contains(cursorPosition)) { foreach (WindowDetails window in windows) {
// Only go over the children if we are in window mode if (window.Contains(cursorPosition)) {
if (CaptureMode.Window == captureMode) { // Only go over the children if we are in window mode
selectedCaptureWindow = window.FindChildUnderPoint(cursorPosition); if (CaptureMode.Window == captureMode) {
} else { selectedCaptureWindow = window.FindChildUnderPoint(cursorPosition);
selectedCaptureWindow = window; } else {
selectedCaptureWindow = window;
}
break;
} }
break;
} }
} }
if (selectedCaptureWindow != null && !selectedCaptureWindow.Equals(lastWindow)) { if (selectedCaptureWindow != null && !selectedCaptureWindow.Equals(lastWindow)) {

View file

@ -25,15 +25,16 @@ using System.Drawing;
using System.Drawing.Drawing2D; using System.Drawing.Drawing2D;
using System.Drawing.Printing; using System.Drawing.Printing;
using System.IO; using System.IO;
using System.Threading;
using System.Windows.Forms; using System.Windows.Forms;
using Greenshot.Configuration; using Greenshot.Configuration;
using Greenshot.Drawing; using Greenshot.Drawing;
using Greenshot.Helpers;
using Greenshot.Forms; using Greenshot.Forms;
using Greenshot.Helpers;
using Greenshot.Plugin; using Greenshot.Plugin;
using GreenshotPlugin.UnmanagedHelpers;
using GreenshotPlugin.Core; using GreenshotPlugin.Core;
using GreenshotPlugin.UnmanagedHelpers;
using IniFile; using IniFile;
namespace Greenshot.Helpers { namespace Greenshot.Helpers {
@ -133,7 +134,6 @@ namespace Greenshot.Helpers {
/// Make Capture with specified destinations /// Make Capture with specified destinations
/// </summary> /// </summary>
private void MakeCapture() { private void MakeCapture() {
// Experimental code // Experimental code
if (screenCapture != null) { if (screenCapture != null) {
screenCapture.Stop(); screenCapture.Stop();
@ -141,14 +141,16 @@ namespace Greenshot.Helpers {
return; return;
} }
LOG.Debug(String.Format("Capturing with mode {0} and using Cursor {1})", captureMode, captureMouseCursor)); LOG.Debug(String.Format("Capturing with mode {0} and using Cursor {1}", captureMode, captureMouseCursor));
capture.CaptureDetails.CaptureMode = captureMode; capture.CaptureDetails.CaptureMode = captureMode;
// Get the windows details in a seperate thread
PrepareForCaptureWithFeedback();
// Add destinations if no-one passed a handler // Add destinations if no-one passed a handler
if (capture.CaptureDetails.CaptureDestinations == null || capture.CaptureDetails.CaptureDestinations.Count == 0) { if (capture.CaptureDetails.CaptureDestinations == null || capture.CaptureDetails.CaptureDestinations.Count == 0) {
AddConfiguredDestination(); AddConfiguredDestination();
} }
PrepareForCaptureWithFeedback();
// Workaround for proble with DPI retrieval, the FromHwnd activates the window... // Workaround for proble with DPI retrieval, the FromHwnd activates the window...
WindowDetails previouslyActiveWindow = WindowDetails.GetActiveWindow(); WindowDetails previouslyActiveWindow = WindowDetails.GetActiveWindow();
@ -302,47 +304,55 @@ namespace Greenshot.Helpers {
/// </summary> /// </summary>
private void PrepareForCaptureWithFeedback() { private void PrepareForCaptureWithFeedback() {
windows = new List<WindowDetails>(); windows = new List<WindowDetails>();
// Start Enumeration of "active" windows
foreach (WindowDetails window in WindowDetails.GetAllWindows()) { Thread getWindowDetailsThread= new Thread (delegate() {
// Window should be visible and not ourselves // Start Enumeration of "active" windows
if (!window.Visible) { foreach (WindowDetails window in WindowDetails.GetAllWindows()) {
continue; // Window should be visible and not ourselves
if (!window.Visible) {
continue;
}
// Skip empty
Rectangle windowRectangle = window.WindowRectangle;
Size windowSize = windowRectangle.Size;
if (windowSize.Width == 0 || windowSize.Height == 0) {
continue;
}
// Make sure the details are retrieved once
window.FreezeDetails();
// Force children retrieval, sometimes windows close on losing focus and this is solved by caching
int goLevelDeep = 3;
if (conf.WindowCaptureAllChildLocations) {
goLevelDeep = 20;
}
window.GetChildren(goLevelDeep);
lock (windows) {
windows.Add(window);
}
// Get window rectangle as capture Element
CaptureElement windowCaptureElement = new CaptureElement(windowRectangle);
capture.Elements.Add(windowCaptureElement);
if (!window.HasParent) {
// Get window client rectangle as capture Element, place all the other "children" in there
Rectangle clientRectangle = window.ClientRectangle;
CaptureElement windowClientCaptureElement = new CaptureElement(clientRectangle);
windowCaptureElement.Children.Add(windowClientCaptureElement);
AddCaptureElementsForWindow(windowClientCaptureElement, window, goLevelDeep);
} else {
AddCaptureElementsForWindow(windowCaptureElement, window, goLevelDeep);
}
} }
lock (windows) {
// Skip empty windows = WindowDetails.SortByZOrder(IntPtr.Zero, windows);
Rectangle windowRectangle = window.WindowRectangle;
Size windowSize = windowRectangle.Size;
if (windowSize.Width == 0 || windowSize.Height == 0) {
continue;
} }
});
// Make sure the details are retrieved once getWindowDetailsThread.IsBackground = true;
window.FreezeDetails(); getWindowDetailsThread.Start();
// Force children retrieval, sometimes windows close on losing focus and this is solved by caching
int goLevelDeep = 3;
if (conf.WindowCaptureAllChildLocations) {
goLevelDeep = 20;
}
window.GetChildren(goLevelDeep);
windows.Add(window);
// Get window rectangle as capture Element
CaptureElement windowCaptureElement = new CaptureElement(windowRectangle);
capture.Elements.Add(windowCaptureElement);
if (!window.HasParent) {
// Get window client rectangle as capture Element, place all the other "children" in there
Rectangle clientRectangle = window.ClientRectangle;
CaptureElement windowClientCaptureElement = new CaptureElement(clientRectangle);
windowCaptureElement.Children.Add(windowClientCaptureElement);
AddCaptureElementsForWindow(windowClientCaptureElement, window, goLevelDeep);
} else {
AddCaptureElementsForWindow(windowCaptureElement, window, goLevelDeep);
}
}
windows = WindowDetails.SortByZOrder(IntPtr.Zero, windows);
} }
private void AddCaptureElementsForWindow(ICaptureElement parentElement, WindowDetails parentWindow, int level) { private void AddCaptureElementsForWindow(ICaptureElement parentElement, WindowDetails parentWindow, int level) {