mirror of
https://github.com/kangyu-california/PersistentWindows.git
synced 2025-05-11 21:15:38 +02:00
1. Modifying the UI to scroll the diagnositcs to the bottom
2. Updating logic to be a little smarter in regards to when to update the stored locations
This commit is contained in:
parent
7e49f459b4
commit
e26c464a95
6 changed files with 107 additions and 38 deletions
|
@ -7,6 +7,6 @@
|
|||
mc:Ignorable="d"
|
||||
d:DesignHeight="300" d:DesignWidth="300">
|
||||
<Grid>
|
||||
<ListBox Name="eventLogList" ItemsSource="{Binding EventLog}" />
|
||||
<ListBox Name="eventLogList" ItemsSource="{Binding EventLog}" />
|
||||
</Grid>
|
||||
</UserControl>
|
||||
|
|
|
@ -28,6 +28,7 @@ namespace Ninjacrab.PersistentWindows.WpfShell
|
|||
{
|
||||
viewModel.EventLog.RemoveAt(0);
|
||||
}
|
||||
eventLogList.ScrollIntoView(viewModel.EventLog[viewModel.EventLog.Count - 1]);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
|
@ -25,13 +25,14 @@
|
|||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="ManagedWinapi">
|
||||
|
@ -63,6 +64,7 @@
|
|||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Core" />
|
||||
|
@ -143,6 +145,12 @@
|
|||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="..\packages\ManagedWinapi.0.3\ManagedWinapiNativeHelper.dll">
|
||||
<Link>ManagedWinapiNativeHelper.dll</Link>
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
|
|
|
@ -16,13 +16,15 @@ namespace Ninjacrab.PersistentWindows.WpfShell
|
|||
{
|
||||
public class PersistentWindowProcessor : IDisposable
|
||||
{
|
||||
// read and update this from a config file eventually
|
||||
private int AppsMovedThreshold = 4;
|
||||
private DesktopDisplayMetrics lastMetrics = null;
|
||||
private Hook windowProcHook;
|
||||
|
||||
public void Start()
|
||||
{
|
||||
lastMetrics = DesktopDisplayMetrics.AcquireMetrics();
|
||||
CaptureApplicationsOnCurrentDisplays();
|
||||
CaptureApplicationsOnCurrentDisplays(initialCapture: true);
|
||||
|
||||
var thread = new Thread(InternalRun);
|
||||
thread.IsBackground = true;
|
||||
|
@ -50,10 +52,10 @@ namespace Ninjacrab.PersistentWindows.WpfShell
|
|||
}
|
||||
};
|
||||
|
||||
windowProcHook = new Hook();
|
||||
windowProcHook.Type = HookType.WH_CALLWNDPROC;
|
||||
windowProcHook.Callback += GlobalWindowProcCallback;
|
||||
windowProcHook.StartHook();
|
||||
//windowProcHook = new Hook();
|
||||
//windowProcHook.Type = HookType.WH_CALLWNDPROC;
|
||||
//windowProcHook.Callback += GlobalWindowProcCallback;
|
||||
//windowProcHook.StartHook();
|
||||
}
|
||||
|
||||
int GlobalWindowProcCallback(int code, IntPtr wParam, IntPtr lParam, ref bool callNext)
|
||||
|
@ -113,6 +115,10 @@ namespace Ninjacrab.PersistentWindows.WpfShell
|
|||
return 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// OMG this method is awful!!! but yagni
|
||||
/// </summary>
|
||||
/// <param name="callbackParam"></param>
|
||||
private void WindowPositionChangedHandler(CallWindowProcedureParam callbackParam)
|
||||
{
|
||||
ApplicationDisplayMetrics appMetrics = null;
|
||||
|
@ -127,6 +133,25 @@ namespace Ninjacrab.PersistentWindows.WpfShell
|
|||
.FirstOrDefault(row => row.Value.HWnd == callbackParam.hwnd)
|
||||
.Value;
|
||||
|
||||
if (appMetrics == null)
|
||||
{
|
||||
var newAppWindow = SystemWindow.AllToplevelWindows
|
||||
.FirstOrDefault(row => row.Parent.HWnd.ToInt64() == 0
|
||||
&& !string.IsNullOrEmpty(row.Title)
|
||||
&& !row.Title.Equals("Program Manager")
|
||||
&& row.Visible
|
||||
&& row.HWnd == callbackParam.hwnd);
|
||||
|
||||
if (newAppWindow == null)
|
||||
{
|
||||
Log.Error("Can't find hwnd {0}", callbackParam.hwnd.ToInt64());
|
||||
return;
|
||||
}
|
||||
ApplicationDisplayMetrics applicationDisplayMetric = null;
|
||||
AddOrUpdateWindow(lastMetrics.Key, newAppWindow, out applicationDisplayMetric);
|
||||
return;
|
||||
}
|
||||
|
||||
WindowPlacement windowPlacement = appMetrics.WindowPlacement;
|
||||
WindowsPosition newPosition = (WindowsPosition)Marshal.PtrToStructure(callbackParam.lparam, typeof(WindowsPosition));
|
||||
windowPlacement.NormalPosition.Left = newPosition.Left;
|
||||
|
@ -145,7 +170,7 @@ namespace Ninjacrab.PersistentWindows.WpfShell
|
|||
return;
|
||||
}
|
||||
|
||||
Log.Info("Capturing {0} at [{1}x{2}] size [{3}x{4}]",
|
||||
Log.Info("WPCH - Capturing {0} at [{1}x{2}] size [{3}x{4}]",
|
||||
appMetrics,
|
||||
appMetrics.WindowPlacement.NormalPosition.Left,
|
||||
appMetrics.WindowPlacement.NormalPosition.Top,
|
||||
|
@ -161,7 +186,7 @@ namespace Ninjacrab.PersistentWindows.WpfShell
|
|||
{
|
||||
while(true)
|
||||
{
|
||||
//CaptureApplicationsOnCurrentDisplays();
|
||||
CaptureApplicationsOnCurrentDisplays();
|
||||
Thread.Sleep(1000);
|
||||
}
|
||||
}
|
||||
|
@ -174,7 +199,7 @@ namespace Ninjacrab.PersistentWindows.WpfShell
|
|||
thread.Start();
|
||||
}
|
||||
|
||||
private void CaptureApplicationsOnCurrentDisplays(string displayKey = null)
|
||||
private void CaptureApplicationsOnCurrentDisplays(string displayKey = null, bool initialCapture = false)
|
||||
{
|
||||
lock(displayChangeLock)
|
||||
{
|
||||
|
@ -197,44 +222,51 @@ namespace Ninjacrab.PersistentWindows.WpfShell
|
|||
}
|
||||
|
||||
List<string> changeLog = new List<string>();
|
||||
var windows = SystemWindow.AllToplevelWindows.Where(row => row.VisibilityFlag == true);
|
||||
foreach (var window in windows)
|
||||
var appWindows = SystemWindow.AllToplevelWindows
|
||||
.Where(row => row.Parent.HWnd.ToInt64() == 0
|
||||
&& !string.IsNullOrEmpty(row.Title)
|
||||
&& !row.Title.Equals("Program Manager")
|
||||
&& row.Visible);
|
||||
|
||||
List<ApplicationDisplayMetrics> apps = new List<ApplicationDisplayMetrics>();
|
||||
foreach (var window in appWindows)
|
||||
{
|
||||
WindowPlacement windowPlacement = new WindowPlacement();
|
||||
User32.GetWindowPlacement(window.HWnd, ref windowPlacement);
|
||||
|
||||
var applicationDisplayMetric = new ApplicationDisplayMetrics
|
||||
{
|
||||
HWnd = window.HWnd,
|
||||
ApplicationName = window.Process.ProcessName,
|
||||
ProcessId = window.Process.Id,
|
||||
WindowPlacement = windowPlacement
|
||||
};
|
||||
|
||||
bool addToChangeLog = false;
|
||||
if (!monitorApplications[displayKey].ContainsKey(applicationDisplayMetric.Key))
|
||||
{
|
||||
monitorApplications[displayKey].Add(applicationDisplayMetric.Key, applicationDisplayMetric);
|
||||
addToChangeLog = true;
|
||||
}
|
||||
else if (!monitorApplications[displayKey][applicationDisplayMetric.Key].EqualPlacement(applicationDisplayMetric))
|
||||
{
|
||||
monitorApplications[displayKey][applicationDisplayMetric.Key].WindowPlacement = applicationDisplayMetric.WindowPlacement;
|
||||
addToChangeLog = true;
|
||||
}
|
||||
ApplicationDisplayMetrics applicationDisplayMetric = null;
|
||||
bool addToChangeLog = AddOrUpdateWindow(displayKey, window, out applicationDisplayMetric);
|
||||
|
||||
if (addToChangeLog)
|
||||
{
|
||||
changeLog.Add(string.Format("Capturing {0} at [{1}x{2}] size [{3}x{4}]",
|
||||
apps.Add(applicationDisplayMetric);
|
||||
changeLog.Add(string.Format("CAOCD - Capturing {0,-45} at [{1,4}x{2,4}] size [{3,4}x{4,4}] V:{5} {6} ",
|
||||
applicationDisplayMetric,
|
||||
applicationDisplayMetric.WindowPlacement.NormalPosition.Left,
|
||||
applicationDisplayMetric.WindowPlacement.NormalPosition.Top,
|
||||
applicationDisplayMetric.WindowPlacement.NormalPosition.Width,
|
||||
applicationDisplayMetric.WindowPlacement.NormalPosition.Height
|
||||
applicationDisplayMetric.WindowPlacement.NormalPosition.Height,
|
||||
window.Visible,
|
||||
window.Title
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
// only save the updated if it didn't seem like something moved everything
|
||||
if ((apps.Count > 0
|
||||
&& apps.Count < AppsMovedThreshold)
|
||||
|| initialCapture)
|
||||
{
|
||||
foreach(var app in apps)
|
||||
{
|
||||
if (!monitorApplications[displayKey].ContainsKey(app.Key))
|
||||
{
|
||||
monitorApplications[displayKey].Add(app.Key, app);
|
||||
}
|
||||
else if (!monitorApplications[displayKey][app.Key].EqualPlacement(app))
|
||||
{
|
||||
monitorApplications[displayKey][app.Key].WindowPlacement = app.WindowPlacement;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (changeLog.Count > 0)
|
||||
{
|
||||
changeLog.Sort();
|
||||
|
@ -244,6 +276,33 @@ namespace Ninjacrab.PersistentWindows.WpfShell
|
|||
}
|
||||
}
|
||||
|
||||
private bool AddOrUpdateWindow(string displayKey, SystemWindow window, out ApplicationDisplayMetrics applicationDisplayMetric)
|
||||
{
|
||||
WindowPlacement windowPlacement = new WindowPlacement();
|
||||
User32.GetWindowPlacement(window.HWnd, ref windowPlacement);
|
||||
|
||||
applicationDisplayMetric = new ApplicationDisplayMetrics
|
||||
{
|
||||
HWnd = window.HWnd,
|
||||
ApplicationName = window.Process.ProcessName,
|
||||
ProcessId = window.Process.Id,
|
||||
WindowPlacement = windowPlacement
|
||||
};
|
||||
|
||||
bool updated = false;
|
||||
if (!monitorApplications[displayKey].ContainsKey(applicationDisplayMetric.Key))
|
||||
{
|
||||
monitorApplications[displayKey].Add(applicationDisplayMetric.Key, applicationDisplayMetric);
|
||||
updated = true;
|
||||
}
|
||||
else if (!monitorApplications[displayKey][applicationDisplayMetric.Key].EqualPlacement(applicationDisplayMetric))
|
||||
{
|
||||
monitorApplications[displayKey][applicationDisplayMetric.Key].WindowPlacement = applicationDisplayMetric.WindowPlacement;
|
||||
updated = true;
|
||||
}
|
||||
return updated;
|
||||
}
|
||||
|
||||
private void BeginRestoreApplicationsOnCurrentDisplays()
|
||||
{
|
||||
var thread = new Thread(() => RestoreApplicationsOnCurrentDisplays());
|
||||
|
@ -267,6 +326,7 @@ namespace Ninjacrab.PersistentWindows.WpfShell
|
|||
{
|
||||
// no old profile, we're done
|
||||
Log.Info("No old profile found for {0}", displayKey);
|
||||
CaptureApplicationsOnCurrentDisplays(initialCapture: true);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -49,5 +49,5 @@ using System.Windows;
|
|||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.3.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.3.0")]
|
||||
[assembly: AssemblyVersion("1.0.5.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.5.0")]
|
||||
|
|
BIN
Ninjacrab.PersistentWindows.Solution/packages/ManagedWinapi.0.3/ManagedWinapiNativeHelper.dll
vendored
Normal file
BIN
Ninjacrab.PersistentWindows.Solution/packages/ManagedWinapi.0.3/ManagedWinapiNativeHelper.dll
vendored
Normal file
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue