1
0
Fork 0
mirror of https://github.com/hawkeye-stan/msfs-popout-panel-manager.git synced 2024-10-16 06:00:45 +00:00

Version 3.2 Release

This commit is contained in:
hawkeye 2022-02-06 22:05:05 -05:00
parent 39d4d98be6
commit 973ebd3dd7
18 changed files with 164 additions and 72 deletions

View file

@ -16,6 +16,8 @@ EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{15FC98CD-0A69-437B-A5E5-67D025DB5CDC}"
ProjectSection(SolutionItems) = preProject
.gitignore = .gitignore
autoupdate.xml = autoupdate.xml
latestreleasenotes.txt = latestreleasenotes.txt
LICENSE = LICENSE
README.md = README.md
VERSION.md = VERSION.md

View file

@ -141,7 +141,7 @@ namespace MSFSPopoutPanelManager.Model
{
public AutoPopOutPanelsWaitDelay()
{
ReadyToFlyButton = 2;
ReadyToFlyButton = 4;
InitialCockpitView = 2;
InstrumentationPowerOn = 2;
}

View file

@ -1,4 +1,5 @@
using System;
using MSFSPopoutPanelManager.Shared;
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Threading;
@ -9,6 +10,9 @@ namespace MSFSPopoutPanelManager.Provider
{
public static Bitmap TakeScreenShot(IntPtr windowHandle)
{
if (!PInvoke.IsWindow(windowHandle))
throw new PopoutManagerException("Pop out windows were closed unexpectedly.");
// Set window to foreground so nothing can hide the window
PInvoke.SetForegroundWindow(windowHandle);
Thread.Sleep(300);
@ -16,19 +20,30 @@ namespace MSFSPopoutPanelManager.Provider
Rectangle rectangle;
PInvoke.GetWindowRect(windowHandle, out rectangle);
var left = rectangle.Left;
var top = rectangle.Top;
var width = rectangle.Right - rectangle.Left;
var height = rectangle.Bottom - rectangle.Top;
Rectangle clientRectangle;
PInvoke.GetClientRect(windowHandle, out clientRectangle);
var bmp = new Bitmap(width, height, PixelFormat.Format24bppRgb);
// Take a screen shot by removing the titlebar of the window
var left = rectangle.Left;
var top = rectangle.Top + (rectangle.Height - clientRectangle.Height) - 8; // 8 pixels adjustments
var bmp = new Bitmap(clientRectangle.Width, clientRectangle.Height, PixelFormat.Format24bppRgb);
using (Graphics g = Graphics.FromImage(bmp))
{
g.CopyFromScreen(new Point(left, top), Point.Empty, rectangle.Size);
}
return bmp;
// Place the above image in the same canvas size as before
Bitmap backingImage = new Bitmap(rectangle.Width, rectangle.Height);
using (Graphics gfx = Graphics.FromImage(backingImage))
using (SolidBrush brush = new SolidBrush(Color.FromArgb(255, 0, 0)))
{
gfx.FillRectangle(brush, 0, 0, rectangle.Width, rectangle.Height);
gfx.DrawImage(bmp, new Point(0, top));
}
return backingImage;
}
}
}

View file

@ -2,11 +2,14 @@
using System.Diagnostics;
using System.Drawing;
using System.Threading;
using WindowsInput.Events;
namespace MSFSPopoutPanelManager.Provider
{
public class InputEmulationManager
{
const uint MOUSEEVENTF_ABSOLUTE = 0x8000;
const uint MOUSEEVENTF_MOVE = 0x0001;
const uint MOUSEEVENTF_LEFTDOWN = 0x02;
const uint MOUSEEVENTF_LEFTUP = 0x04;
const uint KEYEVENTF_EXTENDEDKEY = 0x01;
@ -30,6 +33,9 @@ namespace MSFSPopoutPanelManager.Provider
public static void PopOutPanel(int x, int y)
{
LeftClick(x, y);
Thread.Sleep(300);
PInvoke.SetCursorPos(x, y);
Thread.Sleep(300);

View file

@ -38,7 +38,7 @@ namespace MSFSPopoutPanelManager.Provider
public static void EndHook()
{
if (_mouseHook == null)
if (_mouseHook != null)
{
_mouseHook.MouseDownExt -= HandleMouseHookMouseDownExt;
_mouseHook.Dispose();

View file

@ -39,10 +39,14 @@ namespace MSFSPopoutPanelManager.Provider
public class PInvoke
{
[DllImport("user32")]
public static extern int EnumWindows(CallBack x, int y);
public static extern int EnumWindows(CallBack callback, int lParam);
[DllImport("user32")]
private static extern bool EnumChildWindows(IntPtr window, CallBack callback, IntPtr lParam);
public static extern bool EnumChildWindows(IntPtr window, CallBack callback, IntPtr lParam);
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern int GetClassName(IntPtr hWnd, StringBuilder strPtrClassName, Int32 nMaxCount);
@ -81,6 +85,10 @@ namespace MSFSPopoutPanelManager.Provider
return sb.ToString();
}
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool IsWindow(IntPtr hWnd);
[DllImport("user32.dll")]
public static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, int dwExtraInfo);

View file

@ -61,10 +61,18 @@ namespace MSFSPopoutPanelManager.Provider
break;
case PanelConfigPropertyName.Left:
case PanelConfigPropertyName.Top:
// Do not allow changes to panel if title bar is hidden. This will cause the panel to resize incorrectly
if (panelConfig.HideTitlebar)
return;
PInvoke.MoveWindow(panelConfig.PanelHandle, panelConfig.Left, panelConfig.Top, panelConfig.Width, panelConfig.Height, true);
break;
case PanelConfigPropertyName.Width:
case PanelConfigPropertyName.Height:
// Do not allow changes to panel if title bar is hidden. This will cause the panel to resize incorrectly
if (panelConfig.HideTitlebar)
return;
int orignalLeft = panelConfig.Left;
PInvoke.MoveWindow(panelConfig.PanelHandle, panelConfig.Left, panelConfig.Top, panelConfig.Width, panelConfig.Height, true);
MSFSBugPanelShiftWorkaround(panelConfig.PanelHandle, orignalLeft, panelConfig.Top, panelConfig.Width, panelConfig.Height);
@ -92,6 +100,10 @@ namespace MSFSPopoutPanelManager.Provider
{
var panelConfig = UserProfile.PanelConfigs[index];
// Do not allow changes to panel if title bar is hidden. This will cause the panel to resize incorrectly
if (panelConfig.HideTitlebar)
return;
int orignalLeft = panelConfig.Left;
switch (panelConfigItem.PanelConfigProperty)

View file

@ -3,6 +3,7 @@ using MSFSPopoutPanelManager.Shared;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
@ -111,62 +112,40 @@ namespace MSFSPopoutPanelManager.Provider
_panels.Clear();
if(_simulatorHandle != IntPtr.Zero)
PInvoke.SetForegroundWindow(_simulatorHandle);
PInvoke.SetForegroundWindow(_simulatorHandle);
try
{
for (var i = 0; i < UserProfile.PanelSourceCoordinates.Count; i++)
// PanelIndex starts at 1
for (var i = 1; i <= UserProfile.PanelSourceCoordinates.Count; i++)
{
PopoutPanel(UserProfile.PanelSourceCoordinates[i].X, UserProfile.PanelSourceCoordinates[i].Y);
PopoutPanel(UserProfile.PanelSourceCoordinates[i - 1].X, UserProfile.PanelSourceCoordinates[i - 1].Y);
if (i == 0)
if (i > 1)
{
int retry = 0;
while (retry < RETRY_COUNT)
{
PInvoke.EnumWindows(new PInvoke.CallBack(EnumCustomPopoutCallBack), 0);
if (GetPopoutPanelCountByType(PanelType.CustomPopout) == 0)
retry += 1;
else
{
var panel = GetCustomPopoutPanelByIndex(i);
panel.PanelName = $"Panel{i + 1}";
PInvoke.SetWindowText(panel.PanelHandle, panel.PanelName + " (Custom)");
break;
}
}
if (GetPopoutPanelCountByType(PanelType.CustomPopout) != i + 1)
throw new PopoutManagerException("Unable to pop out the first panel. Please check the first panel's number circle is positioned inside the panel, check for panel obstruction, and check if panel can be popped out. Pop out process stopped.");
SeparatePanel(i - 1, _panels[0].PanelHandle); // The joined panel is always the first panel that got popped out
}
if (i >= 1) // only separate with 2 or more panels
{
int retry = 0;
while (retry < RETRY_COUNT)
{
SeparatePanel(i, _panels[0].PanelHandle); // The joined panel is always the first panel that got popped out
PInvoke.EnumWindows(new PInvoke.CallBack(EnumCustomPopoutCallBack), i);
if (GetPopoutPanelCountByType(PanelType.CustomPopout) != i + 1)
retry += 1;
else
{
// Panel has successfully popped out
var panel = GetCustomPopoutPanelByIndex(i);
var handle = PInvoke.FindWindow("AceApp", String.Empty);
PInvoke.MoveWindow(panel.PanelHandle, 0, 0, 800, 600, true);
panel.PanelName = $"Panel{i + 1}";
PInvoke.SetWindowText(panel.PanelHandle, panel.PanelName + " (Custom)");
break;
}
}
if(handle == IntPtr.Zero && i == 1)
throw new PopoutManagerException("Unable to pop out the first panel. Please check the first panel's number circle is positioned inside the panel, check for panel obstruction, and check if panel can be popped out. Pop out process stopped.");
else if(handle == IntPtr.Zero)
throw new PopoutManagerException($"Unable to pop out panel number {i}. Please check panel's number circle is positioned inside the panel, check for panel obstruction, and check if panel can be popped out. Pop out process stopped.");
if (GetPopoutPanelCountByType(PanelType.CustomPopout) != i + 1)
throw new PopoutManagerException($"Unable to pop out panel number {i + 1}. Please check panel's number circle is positioned inside the panel, check for panel obstruction, and check if panel can be popped out. Pop out process stopped.");
}
var panelInfo = GetPanelWindowInfo(handle);
panelInfo.PanelIndex = i;
panelInfo.PanelName = $"Panel{i}";
_panels.Add(panelInfo);
PInvoke.SetWindowText(panelInfo.PanelHandle, panelInfo.PanelName + " (Custom)");
if (i > 1)
PInvoke.MoveWindow(panelInfo.PanelHandle, 0, 0, 800, 600, true);
}
_currentPanelIndex = _panels.Count;
// Performance validation, make sure the number of pop out panels is equal to the number of selected panel
if (GetPopoutPanelCountByType(PanelType.CustomPopout) != UserProfile.PanelSourceCoordinates.Count)
throw new PopoutManagerException("Unable to pop out all panels. Please align all panel number circles with in-game panel locations.");
@ -293,8 +272,6 @@ namespace MSFSPopoutPanelManager.Provider
private void PopoutPanel(int x, int y)
{
InputEmulationManager.LeftClick(x, y);
Thread.Sleep(200);
InputEmulationManager.PopOutPanel(x, y);
}
@ -309,13 +286,10 @@ namespace MSFSPopoutPanelManager.Provider
// Find the magnifying glass coordinate
var point = AnalyzeMergedWindows(hwnd);
if (point.Y <= 39) // false positive
return;
InputEmulationManager.LeftClick(point.X, point.Y);
}
public bool EnumCustomPopoutCallBack(IntPtr hwnd, int index)
public bool EnumCustomPopoutCallBack(IntPtr hwnd, int lParam)
{
var panelInfo = GetPanelWindowInfo(hwnd);
@ -324,7 +298,7 @@ namespace MSFSPopoutPanelManager.Provider
if (!_panels.Exists(x => x.PanelHandle == hwnd))
{
Interlocked.Increment(ref _currentPanelIndex);
panelInfo.PanelIndex = _currentPanelIndex; // PanelIndex starts at 1
panelInfo.PanelIndex = _currentPanelIndex;
_panels.Add(panelInfo);
}
}
@ -332,7 +306,7 @@ namespace MSFSPopoutPanelManager.Provider
return true;
}
public bool EnumBuiltinPopoutCallBack(IntPtr hwnd, int index)
public bool EnumBuiltinPopoutCallBack(IntPtr hwnd, int lParam)
{
var panelInfo = GetPanelWindowInfo(hwnd);
@ -360,6 +334,9 @@ namespace MSFSPopoutPanelManager.Provider
Interlocked.Increment(ref _currentPanelIndex);
panelInfo.PanelIndex = _currentPanelIndex;
_panels.Add(panelInfo);
// Apply always on top to these panels
WindowManager.ApplyAlwaysOnTop(panelInfo.PanelHandle, true);
}
}
@ -374,9 +351,16 @@ namespace MSFSPopoutPanelManager.Provider
{
var caption = PInvoke.GetWindowText(hwnd);
Rectangle rectangle;
PInvoke.GetWindowRect(hwnd, out rectangle);
var panelInfo = new PanelConfig();
panelInfo.PanelHandle = hwnd;
panelInfo.PanelName = caption;
panelInfo.Top = rectangle.Top;
panelInfo.Left = rectangle.Left;
panelInfo.Width = rectangle.Width;
panelInfo.Height = rectangle.Height;
if (String.IsNullOrEmpty(caption) || caption.IndexOf("Custom") > -1)
panelInfo.PanelType = PanelType.CustomPopout;
@ -411,6 +395,9 @@ namespace MSFSPopoutPanelManager.Provider
{
var sourceImage = ImageOperation.TakeScreenShot(hwnd);
if (sourceImage == null)
return new Point(0, 0);
Rectangle rectangle;
PInvoke.GetClientRect(hwnd, out rectangle);

View file

@ -36,6 +36,7 @@
<ItemGroup>
<PackageReference Include="MouseKeyHook" Version="5.6.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="WindowsInput" Version="6.4.0" />
</ItemGroup>
<ItemGroup>

View file

@ -137,6 +137,8 @@ The user plane profile data and application settings data are stored as JSON fil
## Current Known Issue
* Automatic power on for Auto Pop Out Panel feature will not work if you're using any flight control hardware (such as Honeycomb Alpha or Bravo) that permanently binds the master battery switch or master avionics switch. If the hardware control switch is in the off position, pop out manager won't be able to temporary turn on the instrumentation panels to pop them out. This seems to be a bug on Asobo side and only affects the G1000 instrumentation at the moment.
* Sometimes when using the auto-panning feature, the keyboard combination of Ctrl-Alt-0 and Alt-0 do not work to save and load panel panning coordinates. First try to restart the flightsim and it usually fixes the problem. Otherwise, the only way to fix this is to redo the profile if you want the auto-panning feature since the camera angle is only being saved during the initial creation of the profile. The is another MSFS bug.
* Current application package size is bigger than previous version of the application because it is not a single EXE file package. With added feature of exception logging and stack trace to support user feedback and troubleshooting, a Single EXE package in .NET 5.0 as well as .NET 6.0 has a bug that stack trace information is not complete. Hopefully, Microsoft will be fixing this problem.
@ -180,3 +182,5 @@ Thank you for your super kind support of this app!
[WPF CalcBinding](https://github.com/Alex141/CalcBinding) by Alexander Zinchenko
[AutoUpdater.NET](https://github.com/ravibpatel/AutoUpdater.NET) by Ravi Patel

View file

@ -2,7 +2,13 @@
<hr/>
## Version 3.2.0 (Release)
* Added application auto update support. By installing this version of the app, auto update functionality will be available for all future versions of the application.
* Disabled panel adjustments when Hide Title Bar is checked for a panel. This is to fix an issue where panel adjustments (X-Pos, Y-Pos, Width, and Height) will behave erratically when Hide Title Bar is checked.
* Increased default delay for auto-clicking "Ready to Fly" button from 2 seconds to 4 seconds in regard to Auto Pop Out Panels feature . [Fixed Issue #9](https://github.com/hawkeye-stan/msfs-popout-panel-manager/issues/9)
## Version 3.2.0 (Beta)
* Added new Auto Pop Out Panels when flight start feature. Now the app will match a profile to the plane you're flying and perform all the pop outs for you, even help you to click the "ready to fly" button when a flying session is about to start!
* Added per monitor DPI-awareness support. The application should run and display correctly when using combination of mixed monitor (with high-DPI and low-DPI) resolutions and scaling.
* Added system tray icon access. Application can start minimize or minimize to system tray. System tray icon features a context menu to allow quick access to application functions.
* Added user requested feature to provide keyboard shortcut (Ctrl-Alt-P) to start panel pop out with either an active profile or a default profile selected.

View file

@ -76,7 +76,6 @@ namespace MSFSPopoutPanelManager.WpfApp
var messageBoxMessage = "Application has encountered a critical error and will be closed.\nPlease see the file 'error.log' for information.";
var messageBoxButtons = MessageBoxButton.OK;
// Let the user decide if the app should die or not (if applicable).
if (MessageBox.Show(messageBoxMessage, messageBoxTitle, messageBoxButtons) == MessageBoxResult.OK)
{
Application.Current.Shutdown();

View file

@ -17,6 +17,17 @@
<Trigger Property="IsFocused" Value="true">
<Setter Property="Background" Value="#FF576573" />
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TextBox">
<Border Background="Transparent" BorderBrush="Transparent" BorderThickness="0">
<TextBlock Text="{TemplateBinding Text}" Padding="4" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
</ResourceDictionary>
@ -110,7 +121,7 @@
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox Name="Left" Width="100" BorderThickness="0" Text="{Binding Path=Left, Mode=TwoWay, NotifyOnSourceUpdated=True, UpdateSourceTrigger=LostFocus}"
SourceUpdated="GridData_SourceUpdated" Style="{StaticResource TextBoxColumnFocus}" IsReadOnly="{c:Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid, AncestorLevel=1}, Path='DataContext.DataStore.ActiveUserProfile.IsLocked or !DataContext.DataStore.AllowEdit'}" />
SourceUpdated="GridData_SourceUpdated" Style="{StaticResource TextBoxColumnFocus}" IsReadOnly="{c:Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid, AncestorLevel=1}, Path='DataContext.DataStore.ActiveUserProfile.IsLocked or !DataContext.DataStore.AllowEdit'}" IsEnabled="{c:Binding Path='!HideTitlebar', Mode=TwoWay}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
@ -118,7 +129,7 @@
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox Name="Top" Width="100" BorderThickness="0" Text="{Binding Path=Top, Mode=TwoWay, NotifyOnSourceUpdated=True, UpdateSourceTrigger=LostFocus}"
SourceUpdated="GridData_SourceUpdated" Style="{StaticResource TextBoxColumnFocus}" IsReadOnly="{c:Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid, AncestorLevel=1}, Path='DataContext.DataStore.ActiveUserProfile.IsLocked or !DataContext.DataStore.AllowEdit'}" />
SourceUpdated="GridData_SourceUpdated" Style="{StaticResource TextBoxColumnFocus}" IsReadOnly="{c:Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid, AncestorLevel=1}, Path='DataContext.DataStore.ActiveUserProfile.IsLocked or !DataContext.DataStore.AllowEdit'}" IsEnabled="{c:Binding Path='!HideTitlebar', Mode=TwoWay}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
@ -126,7 +137,7 @@
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox Name="Width" Width="100" BorderThickness="0" Text="{Binding Path=Width, Mode=TwoWay, NotifyOnSourceUpdated=True, UpdateSourceTrigger=LostFocus}"
SourceUpdated="GridData_SourceUpdated" Style="{StaticResource TextBoxColumnFocus}" IsReadOnly="{c:Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid, AncestorLevel=1}, Path='DataContext.DataStore.ActiveUserProfile.IsLocked or !DataContext.DataStore.AllowEdit'}" />
SourceUpdated="GridData_SourceUpdated" Style="{StaticResource TextBoxColumnFocus}" IsReadOnly="{c:Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid, AncestorLevel=1}, Path='DataContext.DataStore.ActiveUserProfile.IsLocked or !DataContext.DataStore.AllowEdit'}" IsEnabled="{c:Binding Path='!HideTitlebar', Mode=TwoWay}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
@ -134,7 +145,7 @@
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox Name="Height" Width="100" BorderThickness="0" Text="{Binding Path=Height, Mode=TwoWay, NotifyOnSourceUpdated=True, UpdateSourceTrigger=LostFocus}"
SourceUpdated="GridData_SourceUpdated" Style="{StaticResource TextBoxColumnFocus}" IsReadOnly="{c:Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid, AncestorLevel=1}, Path='DataContext.DataStore.ActiveUserProfile.IsLocked or !DataContext.DataStore.AllowEdit'}" />
SourceUpdated="GridData_SourceUpdated" Style="{StaticResource TextBoxColumnFocus}" IsReadOnly="{c:Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid, AncestorLevel=1}, Path='DataContext.DataStore.ActiveUserProfile.IsLocked or !DataContext.DataStore.AllowEdit'}" IsEnabled="{c:Binding Path='!HideTitlebar', Mode=TwoWay}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

View file

@ -1,10 +1,11 @@
using MSFSPopoutPanelManager.FsConnector;
using AutoUpdaterDotNET;
using MSFSPopoutPanelManager.Model;
using MSFSPopoutPanelManager.Provider;
using MSFSPopoutPanelManager.Shared;
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading;
using System.Windows;
@ -92,7 +93,6 @@ namespace MSFSPopoutPanelManager.WpfApp.ViewModel
PanelConfigurationViewModel = new PanelConfigurationViewModel(DataStore, _userProfileManager);
InputHookManager.OnStartPopout += (source, e) => { OnStartPopOut(null); };
InputHookManager.StartHook();
}
public void Initialize()
@ -110,6 +110,8 @@ namespace MSFSPopoutPanelManager.WpfApp.ViewModel
DeativateAutoPanelPopOut();
};
CheckForAutoUpdate();
// Set application version
ApplicationVersion = DiagnosticManager.GetApplicationVersion();
@ -128,6 +130,8 @@ namespace MSFSPopoutPanelManager.WpfApp.ViewModel
ShowPanelSelection(true);
IsMinimizedAllPanels = false;
InputHookManager.StartHook();
}
private void OnRestart(object commandParameter)
@ -274,5 +278,17 @@ namespace MSFSPopoutPanelManager.WpfApp.ViewModel
{
DataStore.IsEnteredFlight = false;
}
private void CheckForAutoUpdate()
{
string jsonPath = Path.Combine(Path.Combine(FileIo.GetUserDataFilePath(), "autoupdate.json"));
AutoUpdater.PersistenceProvider = new JsonFilePersistenceProvider(jsonPath);
AutoUpdater.Synchronous = true;
AutoUpdater.AppTitle = "MSFS Pop Out Panel Manager";
AutoUpdater.RunUpdateAsAdmin = false;
AutoUpdater.UpdateFormSize = new System.Drawing.Size(930, 675);
//AutoUpdater.Start("https://raw.githubusercontent.com/hawkeye-stan/msfs-popout-panel-manager/master/autoupdate.xml");
AutoUpdater.Start("https://raw.githubusercontent.com/hawkeye-stan/AutoUpdateTest/main/autoupdate.xml");
}
}
}

View file

@ -125,7 +125,7 @@ namespace MSFSPopoutPanelManager.WpfApp.ViewModel
return;
}
if (DataStore.ActiveUserProfile.PanelSourceCoordinates.Count > 0)
if (DataStore.ActiveUserProfile != null && DataStore.ActiveUserProfile.PanelSourceCoordinates.Count > 0)
{
Logger.LogStatus("Panels pop out in progress.....", StatusMessageType.Info);

View file

@ -4,7 +4,7 @@
<OutputType>WinExe</OutputType>
<TargetFramework>net5.0-windows</TargetFramework>
<UseWPF>true</UseWPF>
<Version>3.2.0</Version>
<Version>3.2.0.0</Version>
<PackageId>MSFS 2020 Popout Panel Manager</PackageId>
<Authors>Stanley Kwok</Authors>
<Product>MSFS 2020 Popout Panel Manager</Product>
@ -50,6 +50,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Autoupdater.NET.Official" Version="1.7.0" />
<PackageReference Include="CalcBinding" Version="2.5.2" />
<PackageReference Include="Fody" Version="6.6.0">
<PrivateAssets>all</PrivateAssets>

7
autoupdate.xml Normal file
View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<item>
<version>3.2.0.0</version>
<url>https://github.com/hawkeye-stan/msfs-popout-panel-manager/releases/download/v3.2b/msfs-popout-panel-manager.zip</url>
<changelog>https://raw.githubusercontent.com/hawkeye-stan/msfs-popout-panel-manager/master/latestreleasenotes.txt</changelog>
<mandatory>false</mandatory>
</item>

17
latestreleasenotes.txt Normal file
View file

@ -0,0 +1,17 @@
- Added per monitor DPI-awareness support. The application should run and display correctly when using combination of mixed monitor (with high-DPI and low-DPI) resolutions and scaling.
- Added system tray icon access. Application can start minimize or minimize to system tray. System tray icon features a context menu to allow quick access to application functions.
- Added user requested feature to provide keyboard shortcut (Ctrl-Alt-P) to start panel pop out with either an active profile or a default profile selected.
- New copy profile feature. You can reuse your defined panel settings for another plane or plane/livery combination.
- Added quick panel location selection adjustment feature. You can now adjust panel locations without redoing the entire profile.
- Added Save Auto Panning Camera Angle function if you need to adjust the in-game camera angle during panel selection.
- Added application auto update feature.
- New logo icon for the app.
- New dark theme for the entire UI.