-
Notifications
You must be signed in to change notification settings - Fork 202
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
160 changed files
with
8,991 additions
and
4,312 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
using System; | ||
using System.Diagnostics; | ||
using System.IO; | ||
using static ModernFlyouts.Core.Interop.NativeMethods; | ||
|
||
namespace ModernFlyouts.Core.AppInformation | ||
{ | ||
public abstract class SourceAppInfo : IDisposable | ||
{ | ||
private bool disposedValue; | ||
|
||
#region Properties | ||
|
||
public Stream LogoStream { get; protected set; } | ||
|
||
public string DisplayName { get; protected set; } = string.Empty; | ||
|
||
protected SourceAppInfoData Data { get; set; } | ||
|
||
#endregion | ||
|
||
public abstract event EventHandler InfoFetched; | ||
|
||
public static SourceAppInfo FromData(SourceAppInfoData data) | ||
{ | ||
if (data.DataType == SourceAppInfoDataType.FromAppUserModelId) | ||
{ | ||
if (string.IsNullOrEmpty(data.AppUserModelId) | ||
|| string.IsNullOrWhiteSpace(data.AppUserModelId)) | ||
return null; | ||
|
||
if (IsAppUnpackaged(data)) | ||
{ | ||
return new SourceDesktopAppInfo(data); | ||
} | ||
else | ||
{ | ||
return new SourceModernAppInfo(data); | ||
} | ||
} | ||
else if (data.DataType == SourceAppInfoDataType.FromProcessId) | ||
{ | ||
if (data.ProcessId == 0) | ||
return null; | ||
|
||
if (IsAppPackaged(data)) | ||
{ | ||
return new SourceModernAppInfo(data); | ||
} | ||
else | ||
{ | ||
return new SourceDesktopAppInfo(data); | ||
} | ||
} | ||
|
||
return null; | ||
} | ||
|
||
public static SourceAppInfo FromAppUserModelId(string appUserModelId) | ||
{ | ||
SourceAppInfoData data = new() | ||
{ | ||
AppUserModelId = appUserModelId, | ||
DataType = SourceAppInfoDataType.FromAppUserModelId | ||
}; | ||
|
||
return FromData(data); | ||
} | ||
|
||
public static SourceAppInfo FromProcessId(uint processId, IntPtr hWnd = default) | ||
{ | ||
SourceAppInfoData data = new() | ||
{ | ||
ProcessId = processId, | ||
MainWindowHandle = hWnd, | ||
DataType = SourceAppInfoDataType.FromProcessId | ||
}; | ||
|
||
return FromData(data); | ||
} | ||
|
||
public abstract void Activate(); | ||
|
||
public abstract void FetchInfosAsync(); | ||
|
||
protected virtual void Disconnect() | ||
{ | ||
} | ||
|
||
internal static bool IsAppUnpackaged(SourceAppInfoData data) | ||
{ | ||
return data.AppUserModelId.EndsWith(".exe", StringComparison.OrdinalIgnoreCase); | ||
} | ||
|
||
internal static bool IsAppPackaged(SourceAppInfoData data) | ||
{ | ||
using var process = Process.GetProcessById((int)data.ProcessId); | ||
return IsImmersiveProcess(process.Handle); | ||
} | ||
|
||
public void Dispose() | ||
{ | ||
if (!disposedValue) | ||
{ | ||
Disconnect(); | ||
LogoStream.Dispose(); | ||
LogoStream = null; | ||
disposedValue = true; | ||
} | ||
GC.SuppressFinalize(this); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
using System; | ||
|
||
namespace ModernFlyouts.Core.AppInformation | ||
{ | ||
public enum SourceAppInfoDataType | ||
{ | ||
FromProcessId, | ||
FromAppUserModelId | ||
} | ||
|
||
public class SourceAppInfoData | ||
{ | ||
public string AppUserModelId { get; init; } | ||
|
||
public IntPtr MainWindowHandle { get; init; } | ||
|
||
public uint ProcessId { get; init; } | ||
|
||
public SourceAppInfoDataType DataType { get; init; } | ||
} | ||
} |
138 changes: 138 additions & 0 deletions
138
ModernFlyouts.Core/AppInformation/SourceDesktopAppInfo.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
using ModernFlyouts.Core.Interop; | ||
using ModernFlyouts.Core.Utilities; | ||
using System; | ||
using System.Diagnostics; | ||
using System.Drawing; | ||
using System.Drawing.Imaging; | ||
using System.IO; | ||
using System.Threading.Tasks; | ||
using static ModernFlyouts.Core.Interop.NativeMethods; | ||
|
||
namespace ModernFlyouts.Core.AppInformation | ||
{ | ||
internal class SourceDesktopAppInfo : SourceAppInfo | ||
{ | ||
public SourceDesktopAppInfo(SourceAppInfoData data) | ||
{ | ||
Data = data; | ||
} | ||
|
||
public override event EventHandler InfoFetched; | ||
|
||
private Process sourceProcess; | ||
|
||
public override void Activate() | ||
{ | ||
if (sourceProcess == null) | ||
return; | ||
|
||
IntPtr hWnd = IsWindow(Data.MainWindowHandle) | ||
? Data.MainWindowHandle : sourceProcess.MainWindowHandle; | ||
|
||
ActivateWindow(hWnd); | ||
} | ||
|
||
public override async void FetchInfosAsync() | ||
{ | ||
Bitmap bitmap = new(16, 16); | ||
|
||
await Task.Run(() => | ||
{ | ||
try | ||
{ | ||
if (Data.DataType == SourceAppInfoDataType.FromAppUserModelId) | ||
{ | ||
var processName = Data.AppUserModelId[..^4]; | ||
var processes = Process.GetProcessesByName(processName); | ||
|
||
if (processes?.Length > 0) | ||
{ | ||
sourceProcess = processes[0]; | ||
} | ||
} | ||
else if (Data.DataType == SourceAppInfoDataType.FromProcessId) | ||
{ | ||
sourceProcess = Process.GetProcessById((int)Data.ProcessId); | ||
} | ||
} | ||
catch { } | ||
|
||
if (sourceProcess == null) | ||
return; | ||
|
||
try | ||
{ | ||
DisplayName = sourceProcess.MainModule.FileVersionInfo.FileDescription; | ||
} | ||
catch { } | ||
|
||
try | ||
{ | ||
var path = sourceProcess.MainModule.FileName; | ||
var ie = new IconExtractor(path); | ||
var icon = ie.GetIcon(0); | ||
bitmap = icon.ToBitmap(); | ||
} | ||
catch { } | ||
|
||
if (bitmap != null) | ||
{ | ||
MemoryStream memoryStream = new(); | ||
bitmap.Save(memoryStream, ImageFormat.Png); | ||
memoryStream.Seek(0, SeekOrigin.Begin); | ||
|
||
LogoStream = memoryStream; | ||
} | ||
}); | ||
|
||
InfoFetched?.Invoke(this, null); | ||
} | ||
|
||
protected override void Disconnect() | ||
{ | ||
base.Disconnect(); | ||
|
||
sourceProcess.Dispose(); | ||
sourceProcess = null; | ||
} | ||
|
||
#region Window activation things | ||
|
||
internal static void ActivateWindow(IntPtr hWnd) | ||
{ | ||
if (hWnd != IntPtr.Zero) | ||
{ | ||
if (GetWindowSizeState(hWnd) == WindowSizeState.Minimized) | ||
{ | ||
ShowWindowAsync(hWnd, ShowWindowCommands.Restore); | ||
} | ||
|
||
SetForegroundWindow(hWnd); | ||
FlashWindow(hWnd, true); | ||
} | ||
} | ||
|
||
private static WindowSizeState GetWindowSizeState(IntPtr hWnd) | ||
{ | ||
GetWindowPlacement(hWnd, out WINDOWPLACEMENT placement); | ||
|
||
return placement.ShowCmd switch | ||
{ | ||
ShowWindowCommands.Normal => WindowSizeState.Normal, | ||
ShowWindowCommands.Minimize or ShowWindowCommands.ShowMinimized => WindowSizeState.Minimized, | ||
ShowWindowCommands.Maximize => WindowSizeState.Maximized, | ||
_ => WindowSizeState.Unknown, | ||
}; | ||
} | ||
|
||
private enum WindowSizeState | ||
{ | ||
Normal, | ||
Minimized, | ||
Maximized, | ||
Unknown, | ||
} | ||
|
||
#endregion | ||
} | ||
} |
Oops, something went wrong.