Skip to content

Commit c262ac1

Browse files
committed
Code cleanup; fixed issue with detached panels of Octane Render Standalone
1 parent b6af76a commit c262ac1

4 files changed

Lines changed: 91 additions & 45 deletions

File tree

Src/ScreenGrid/Models/AppsInterop/NativeWindow.cs

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,20 @@ public string ClassName
4747
get
4848
{
4949
var lpClassName = new StringBuilder(1000);
50-
WinApiInterop.NativeMethods.GetClassName(hWnd, lpClassName, 1000);
50+
WinApiInterop.NativeMethods.GetClassName(this.hWnd, lpClassName, 1000);
5151

5252
return lpClassName.ToString();
5353
}
5454
}
5555

56+
public string Title
57+
{
58+
get
59+
{
60+
return WinApiInterop.NativeMethods.GetWindowText(this.hWnd);
61+
}
62+
}
63+
5664
public Point Location
5765
{
5866
get
@@ -90,7 +98,7 @@ public Bitmap GetShot()
9098
return WinApiInterop.NativeMethods.GetWindowImage(this.hWnd, 0, 0, (rect.Right - rect.Left) + 1, (rect.Bottom - rect.Top) + 1); // TODO: +1 ?
9199
}
92100

93-
public static NativeWindow GetTopMostWindow()
101+
public static IList<NativeWindow> GetWindowsInTopMostOrder()
94102
{
95103
// Is there are win32 function to get a list off all top level windows
96104
// with a given class name?
@@ -106,6 +114,7 @@ public static NativeWindow GetTopMostWindow()
106114
var ClassNamesPartialBlackList = new[] { "ScreenGrid", "HwndWrapper", };
107115

108116
var results = new List<NativeWindow>();
117+
109118
WinApiInterop.NativeMethods.EnumWindows((hWnd, lParam) =>
110119
{
111120
var window = new NativeWindow(hWnd);
@@ -135,14 +144,7 @@ public static NativeWindow GetTopMostWindow()
135144
return true;
136145
}, IntPtr.Zero);
137146

138-
if (results.Count > 0)
139-
{
140-
return results[0];
141-
}
142-
else
143-
{
144-
return null;
145-
}
147+
return results;
146148
}
147149

148150
public override string ToString()

Src/ScreenGrid/Models/AppsInterop/OctaneRenderWindow.cs

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,23 +20,19 @@ public OctaneRenderWindow(IntPtr hWnd)
2020

2121
public static OctaneRenderWindow GetFromFirstProcess()
2222
{
23-
var proc = System.Diagnostics.Process.GetProcesses().Where(p => String.Compare(p.ProcessName, ProcessName, StringComparison.OrdinalIgnoreCase) == 0).FirstOrDefault();
23+
var process = System.Diagnostics.Process.GetProcesses()
24+
.Where(p => String.Compare(p.ProcessName, ProcessName, StringComparison.OrdinalIgnoreCase) == 0)
25+
.FirstOrDefault();
2426

25-
if (proc != null)
26-
{
27-
return new OctaneRenderWindow(proc.MainWindowHandle);
28-
}
29-
else
30-
{
31-
return null;
32-
}
27+
return (process != null) ? new OctaneRenderWindow(process.MainWindowHandle) : null;
3328
}
3429

3530
public static IList<OctaneRenderWindow> GetFromAllProcesses()
3631
{
37-
var processes = System.Diagnostics.Process.GetProcesses().Where(p => String.Compare(p.ProcessName, ProcessName, StringComparison.OrdinalIgnoreCase) == 0).ToList();
38-
39-
return (processes.Select(w => new OctaneRenderWindow(w.MainWindowHandle)).ToList());
32+
return System.Diagnostics.Process.GetProcesses()
33+
.Where(p => String.Compare(p.ProcessName, ProcessName, StringComparison.OrdinalIgnoreCase) == 0)
34+
.Select(w => new OctaneRenderWindow(w.MainWindowHandle))
35+
.ToList();
4036
}
4137

4238
private static Bitmap UpperLeftCorner
@@ -121,7 +117,6 @@ private static Point BottomRightCorner(FlatImage image)
121117
var bottomRightCornerY = 0;
122118
foreach (var bottomRightCornerFragment in bottomRightCornerFragments)
123119
{
124-
//for (var x = 0; x < image.Width - bottomRightCornerFragment.Width; x++)
125120
for (var x = image.Width - bottomRightCornerFragment.Width - 1; x > 0; x--)
126121
{
127122
for (var y = 0; y < image.Height - bottomRightCornerFragment.Height; y++)
@@ -157,7 +152,6 @@ private static Point TopLeftImage(FlatImage image, Point topLeftCorner, Point bo
157152
{
158153
for (var x = (int)topLeftCorner.X; x < (int)bottomRightCorner.X; x++)
159154
{
160-
//if (PointUtils.MidDiff(image.pixels[x, y], areaColor1) > 2)
161155
if (image.pixels[x, y] != canvasColor)
162156
{
163157
if (y > (int)topLeftCorner.Y)

Src/ScreenGrid/ViewModels/ScreenGridViewModel.cs

Lines changed: 56 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ public Grid ContentControl
176176
#region Window position and size
177177

178178
private const double OuterBorderWidth = 1.0;
179-
179+
180180
public const double HeaderHeight = 24.0;
181181

182182
private double windowWidth = 400.0 + 2 * OuterBorderWidth;
@@ -309,7 +309,7 @@ public string CaptionText
309309
{
310310
get
311311
{
312-
return String.Format(CultureInfo.InvariantCulture,
312+
return String.Format(CultureInfo.CurrentCulture,
313313
"{0}\u00D7{1}{2}",
314314
ImageSize.Item1,
315315
ImageSize.Item2,
@@ -320,31 +320,61 @@ public string CaptionText
320320
public void SnapToImageBounds()
321321
{
322322
// select foreground window from several processes of supported applications
323-
var nativeWindow = Models.AppsInterop.NativeWindow.GetTopMostWindow();
323+
var nativeWindows = Models.AppsInterop.NativeWindow.GetWindowsInTopMostOrder();
324324

325-
if (nativeWindow != null) // TODO: display error if no window was found
325+
if (nativeWindows.Count > 0) // TODO: display error if no window was found
326326
{
327-
if (nativeWindow.ClassName == Models.AppsInterop.PhotoViewerWindow.MainWindowClassName)
327+
if (String.Compare(nativeWindows[0].ClassName, Models.AppsInterop.PhotoViewerWindow.MainWindowClassName, StringComparison.Ordinal) == 0)
328328
{
329-
var photoViewerWindow = new Models.AppsInterop.PhotoViewerWindow(nativeWindow.Handle);
329+
var photoViewerWindow = new Models.AppsInterop.PhotoViewerWindow(nativeWindows[0].Handle);
330330

331331
var rectViewedImage = photoViewerWindow.PhotoCanvasRect();
332332
if (!rectViewedImage.IsEmpty)
333333
{
334-
this.PositionWindow(Models.Geometry.Point.Zero, rectViewedImage);
334+
var location = new GridTargetLocation { ImageBounds = rectViewedImage, Offset = Models.Geometry.Point.Zero, };
335+
this.PositionWindow(location);
335336
}
336337
}
337338
else
338339
{
339-
Task.Factory.StartNew<Tuple<Models.Geometry.Rectangle, Models.Geometry.Point>>(() =>
340+
var nativeWindow = nativeWindows[0];
341+
342+
// TODO: simplify Octane Render specific code
343+
// Fixing issue with detached panels of Octane Render Standalone
344+
if (Models.AppsInterop.OctaneRenderWindow.GetFromAllProcesses().Count > 0)
345+
{
346+
var octaneRenderWindows = nativeWindows
347+
.Where(w => w.ClassName == Models.AppsInterop.OctaneRenderWindow.GetFromAllProcesses()[0].ClassName)
348+
.OrderByDescending(w => w.Rect.Width)
349+
.First();
350+
351+
// Select window with max size from topmost list
352+
for (var i = 0; i < nativeWindows.Count; i++)
353+
{
354+
if (nativeWindows[i].ClassName != Models.AppsInterop.OctaneRenderWindow.GetFromAllProcesses()[0].ClassName)
355+
{
356+
break;
357+
}
358+
else
359+
{
360+
if (nativeWindows[i].Rect.Width == octaneRenderWindows.Rect.Width)
361+
{
362+
nativeWindow = nativeWindows[i];
363+
break;
364+
}
365+
}
366+
}
367+
}
368+
369+
var bitmap = nativeWindow.GetShot();
370+
371+
Task.Factory.StartNew<GridTargetLocation>(() =>
340372
{
341-
var bitmap = nativeWindow.GetShot();
342373
var flatImage = new Models.FlatImage(bitmap);
343374

344375
Models.Geometry.Rectangle imageBounds;
345376
if (Models.AppsInterop.OctaneRenderWindow.GetFromAllProcesses().Any(w => w.ClassName == nativeWindow.ClassName))
346377
{
347-
// TODO: remove this Octane Render specific code
348378
imageBounds = Models.AppsInterop.OctaneRenderWindow.FindRenderedImageBorders(flatImage);
349379
}
350380
else
@@ -353,16 +383,14 @@ public void SnapToImageBounds()
353383
}
354384

355385
var nativeWindowLocation = new Models.Geometry.Point(nativeWindow.Location.X, nativeWindow.Location.Y);
356-
return new Tuple<Models.Geometry.Rectangle, Models.Geometry.Point>(imageBounds, nativeWindowLocation);
386+
return new GridTargetLocation { ImageBounds = imageBounds, Offset = nativeWindowLocation, };
357387
}).ContinueWith((t) =>
358388
{
359-
var imageBounds = t.Result.Item1;
360-
var windowLocation = t.Result.Item2;
361-
if (!imageBounds.IsEmpty)
389+
if (!t.Result.ImageBounds.IsEmpty)
362390
{
363-
if ((imageBounds.Width > 150) && (imageBounds.Height > 50))
391+
if ((t.Result.ImageBounds.Width > 150) && (t.Result.ImageBounds.Height > 50))
364392
{
365-
this.PositionWindow(t.Result.Item2, t.Result.Item1);
393+
this.PositionWindow(t.Result);
366394
}
367395
}
368396
},
@@ -371,15 +399,22 @@ public void SnapToImageBounds()
371399
}
372400
}
373401

374-
private void PositionWindow(Models.Geometry.Point parentLocation, Models.Geometry.Rectangle rectRenderedImage)
402+
private void PositionWindow(GridTargetLocation location)
375403
{
376404
var diffX = 0.0;
377405
var diffY = HeaderHeight;
378406
// TODO: remove magiс numbers
379-
this.WindowLeft = rectRenderedImage.Left + parentLocation.X - diffX - 1;
380-
this.WindowTop = rectRenderedImage.Top + parentLocation.Y - diffY - 1;
381-
this.WindowWidth = (rectRenderedImage.Right - rectRenderedImage.Left) + diffX + 2;
382-
this.WindowHeight = (rectRenderedImage.Bottom - rectRenderedImage.Top) + diffY + 2;
407+
this.WindowLeft = location.ImageBounds.Left + location.Offset.X - diffX - 1;
408+
this.WindowTop = location.ImageBounds.Top + location.Offset.Y - diffY - 1;
409+
this.WindowWidth = (location.ImageBounds.Right - location.ImageBounds.Left) + diffX + 2;
410+
this.WindowHeight = (location.ImageBounds.Bottom - location.ImageBounds.Top) + diffY + 2;
383411
}
384412
}
413+
414+
class GridTargetLocation
415+
{
416+
public Models.Geometry.Point Offset { get; set; }
417+
418+
public Models.Geometry.Rectangle ImageBounds { get; set; }
419+
}
385420
}

Src/ScreenGrid/WinApiInterop/NativeMethods.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,12 @@ private static extern UInt64 BitBlt
5454
[DllImport("user32.dll")]
5555
public static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
5656

57+
[DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
58+
private static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
59+
60+
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
61+
private static extern int GetWindowTextLength(IntPtr hWnd);
62+
5763
[DllImport("user32.dll")]
5864
public static extern IntPtr GetTopWindow(IntPtr hWnd);
5965

@@ -70,6 +76,15 @@ private static extern UInt64 BitBlt
7076
[DllImport("user32.dll")]
7177
public static extern bool EnumWindows(EnumWindowsProc enumProc, IntPtr lParam);
7278

79+
public static string GetWindowText(IntPtr hWnd)
80+
{
81+
// Allocate correct string length first
82+
var length = GetWindowTextLength(hWnd);
83+
var sb = new StringBuilder(length + 1);
84+
GetWindowText(hWnd, sb, sb.Capacity);
85+
return sb.ToString();
86+
}
87+
7388
public static Bitmap GetWindowImage(IntPtr hWnd, int x, int y, int width, int height)
7489
{
7590
var image = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format24bppRgb);

0 commit comments

Comments
 (0)