SEBWIN-312: Implemented icon change event for application windows and finally moved IconResource from core to application namespace.

This commit is contained in:
dbuechel 2019-12-03 15:43:48 +01:00
parent d8a27e9298
commit 018e596905
52 changed files with 265 additions and 174 deletions

View file

@ -6,7 +6,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
using SafeExamBrowser.Core.Contracts;
using SafeExamBrowser.Applications.Contracts.Resources.Icons;
namespace SafeExamBrowser.Applications.Contracts.Events
{

View file

@ -9,7 +9,7 @@
using System;
using System.Collections.Generic;
using SafeExamBrowser.Applications.Contracts.Events;
using SafeExamBrowser.Core.Contracts;
using SafeExamBrowser.Applications.Contracts.Resources.Icons;
namespace SafeExamBrowser.Applications.Contracts
{

View file

@ -7,7 +7,7 @@
*/
using SafeExamBrowser.Applications.Contracts.Events;
using SafeExamBrowser.Core.Contracts;
using SafeExamBrowser.Applications.Contracts.Resources.Icons;
namespace SafeExamBrowser.Applications.Contracts
{

View file

@ -8,20 +8,15 @@
using System;
namespace SafeExamBrowser.Core.Contracts
namespace SafeExamBrowser.Applications.Contracts.Resources.Icons
{
/// <summary>
/// Defines an icon resource, i.e. the path to and type of an icon.
/// Defines an icon resource which is a bitmap image (i.e. raster graphics).
/// </summary>
public class IconResource
public class BitmapIconResource : IconResource
{
/// <summary>
/// Defines the data type of the resource.
/// </summary>
public IconResourceType Type { get; set; }
/// <summary>
/// The <see cref="System.Uri"/> pointing to the icon data.
/// The <see cref="System.Uri"/> pointing to the image file.
/// </summary>
public Uri Uri { get; set; }
}

View file

@ -0,0 +1,21 @@
/*
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
namespace SafeExamBrowser.Applications.Contracts.Resources.Icons
{
/// <summary>
/// Defines an icon resource which is a file with embedded icon data (e.g. an executable).
/// </summary>
public class EmbeddedIconResource : IconResource
{
/// <summary>
/// The full path of the file.
/// </summary>
public string FilePath { get; set; }
}
}

View file

@ -0,0 +1,17 @@
/*
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
namespace SafeExamBrowser.Applications.Contracts.Resources.Icons
{
/// <summary>
/// Defines an icon resource.
/// </summary>
public abstract class IconResource
{
}
}

View file

@ -0,0 +1,23 @@
/*
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
using System;
namespace SafeExamBrowser.Applications.Contracts.Resources.Icons
{
/// <summary>
/// Defines an icon resource which is managed by the operating system.
/// </summary>
public class NativeIconResource : IconResource
{
/// <summary>
/// The handle of the icon.
/// </summary>
public IntPtr Handle { get; set; }
}
}

View file

@ -0,0 +1,23 @@
/*
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
using System;
namespace SafeExamBrowser.Applications.Contracts.Resources.Icons
{
/// <summary>
/// Defines an icon resource which consists of XAML markup (i.e. vector graphics).
/// </summary>
public class XamlIconResource : IconResource
{
/// <summary>
/// The <see cref="System.Uri"/> pointing to the XAML file.
/// </summary>
public Uri Uri { get; set; }
}
}

View file

@ -61,13 +61,14 @@
<Compile Include="IApplication.cs" />
<Compile Include="IApplicationFactory.cs" />
<Compile Include="IApplicationWindow.cs" />
<Compile Include="Resources\Icons\BitmapIconResource.cs" />
<Compile Include="Resources\Icons\EmbeddedIconResource.cs" />
<Compile Include="Resources\Icons\IconResource.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Resources\Icons\NativeIconResource.cs" />
<Compile Include="Resources\Icons\XamlIconResource.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\SafeExamBrowser.Core.Contracts\SafeExamBrowser.Core.Contracts.csproj">
<Project>{fe0e1224-b447-4b14-81e7-ed7d84822aa0}</Project>
<Name>SafeExamBrowser.Core.Contracts</Name>
</ProjectReference>
<ProjectReference Include="..\SafeExamBrowser.Settings\SafeExamBrowser.Settings.csproj">
<Project>{30b2d907-5861-4f39-abad-c4abf1b3470e}</Project>
<Name>SafeExamBrowser.Settings</Name>

View file

@ -11,7 +11,7 @@ using System.Collections.Generic;
using System.Linq;
using SafeExamBrowser.Applications.Contracts;
using SafeExamBrowser.Applications.Contracts.Events;
using SafeExamBrowser.Core.Contracts;
using SafeExamBrowser.Applications.Contracts.Resources.Icons;
using SafeExamBrowser.Logging.Contracts;
using SafeExamBrowser.Monitoring.Contracts.Applications;
using SafeExamBrowser.Settings.Applications;
@ -67,7 +67,7 @@ namespace SafeExamBrowser.Applications
public void Initialize()
{
AutoStart = settings.AutoStart;
Icon = new IconResource { Type = IconResourceType.Embedded, Uri = new Uri(executablePath) };
Icon = new EmbeddedIconResource { FilePath = executablePath };
Id = settings.Id;
Name = settings.DisplayName;
Tooltip = settings.Description ?? settings.DisplayName;

View file

@ -12,8 +12,8 @@ using System.Linq;
using System.Timers;
using SafeExamBrowser.Applications.Contracts;
using SafeExamBrowser.Applications.Contracts.Events;
using SafeExamBrowser.Applications.Contracts.Resources.Icons;
using SafeExamBrowser.Applications.Events;
using SafeExamBrowser.Core.Contracts;
using SafeExamBrowser.Logging.Contracts;
using SafeExamBrowser.WindowsApi.Contracts;

View file

@ -9,7 +9,7 @@
using System;
using SafeExamBrowser.Applications.Contracts;
using SafeExamBrowser.Applications.Contracts.Events;
using SafeExamBrowser.Core.Contracts;
using SafeExamBrowser.Applications.Contracts.Resources.Icons;
using SafeExamBrowser.WindowsApi.Contracts;
namespace SafeExamBrowser.Applications
@ -19,10 +19,10 @@ namespace SafeExamBrowser.Applications
private INativeMethods nativeMethods;
internal IntPtr Handle { get; }
public IconResource Icon { get; }
public IconResource Icon { get; private set; }
public string Title { get; private set; }
public event IconChangedEventHandler IconChanged { add { } remove { } }
public event IconChangedEventHandler IconChanged;
public event TitleChangedEventHandler TitleChanged;
internal ExternalApplicationWindow(IconResource icon, INativeMethods nativeMethods, IntPtr handle)
@ -39,10 +39,18 @@ namespace SafeExamBrowser.Applications
internal void Update()
{
var icon = nativeMethods.GetWindowIcon(Handle);
var iconChanged = icon != IntPtr.Zero && (!(Icon is NativeIconResource) || Icon is NativeIconResource r && r.Handle != icon);
var title = nativeMethods.GetWindowTitle(Handle);
var hasChanged = Title?.Equals(title, StringComparison.Ordinal) != true;
var titleChanged = Title?.Equals(title, StringComparison.Ordinal) != true;
if (hasChanged)
if (iconChanged)
{
Icon = new NativeIconResource { Handle = icon };
IconChanged?.Invoke(Icon);
}
if (titleChanged)
{
Title = title;
TitleChanged?.Invoke(title);

View file

@ -66,10 +66,6 @@
<Project>{ac77745d-3b41-43e2-8e84-d40e5a4ee77f}</Project>
<Name>SafeExamBrowser.Applications.Contracts</Name>
</ProjectReference>
<ProjectReference Include="..\SafeExamBrowser.Core.Contracts\SafeExamBrowser.Core.Contracts.csproj">
<Project>{fe0e1224-b447-4b14-81e7-ed7d84822aa0}</Project>
<Name>SafeExamBrowser.Core.Contracts</Name>
</ProjectReference>
<ProjectReference Include="..\SafeExamBrowser.Logging.Contracts\SafeExamBrowser.Logging.Contracts.csproj">
<Project>{64ea30fb-11d4-436a-9c2b-88566285363e}</Project>
<Name>SafeExamBrowser.Logging.Contracts</Name>

View file

@ -13,11 +13,11 @@ using CefSharp;
using CefSharp.WinForms;
using SafeExamBrowser.Applications.Contracts;
using SafeExamBrowser.Applications.Contracts.Events;
using SafeExamBrowser.Applications.Contracts.Resources.Icons;
using SafeExamBrowser.Browser.Contracts;
using SafeExamBrowser.Browser.Contracts.Events;
using SafeExamBrowser.Browser.Events;
using SafeExamBrowser.Configuration.Contracts;
using SafeExamBrowser.Core.Contracts;
using SafeExamBrowser.I18n.Contracts;
using SafeExamBrowser.Logging.Contracts;
using SafeExamBrowser.Settings.Logging;

View file

@ -11,13 +11,13 @@ using System.Net.Http;
using System.Threading.Tasks;
using SafeExamBrowser.Applications.Contracts;
using SafeExamBrowser.Applications.Contracts.Events;
using SafeExamBrowser.Applications.Contracts.Resources.Icons;
using SafeExamBrowser.Browser.Contracts.Events;
using SafeExamBrowser.Browser.Contracts.Filters;
using SafeExamBrowser.Browser.Events;
using SafeExamBrowser.Browser.Filters;
using SafeExamBrowser.Browser.Handlers;
using SafeExamBrowser.Configuration.Contracts;
using SafeExamBrowser.Core.Contracts;
using SafeExamBrowser.I18n.Contracts;
using SafeExamBrowser.Logging.Contracts;
using SafeExamBrowser.Settings.Browser;

View file

@ -7,15 +7,14 @@
*/
using System;
using SafeExamBrowser.Core.Contracts;
using SafeExamBrowser.Applications.Contracts.Resources.Icons;
namespace SafeExamBrowser.Browser
{
public class BrowserIconResource : IconResource
public class BrowserIconResource : BitmapIconResource
{
public BrowserIconResource(string uri = null)
{
Type = IconResourceType.Bitmap;
Uri = new Uri(uri ?? "pack://application:,,,/SafeExamBrowser.UserInterface.Desktop;component/Images/SafeExamBrowser.ico");
}
}

View file

@ -99,10 +99,6 @@
<Project>{7d74555e-63e1-4c46-bd0a-8580552368c8}</Project>
<Name>SafeExamBrowser.Configuration.Contracts</Name>
</ProjectReference>
<ProjectReference Include="..\SafeExamBrowser.Core.Contracts\SafeExamBrowser.Core.Contracts.csproj">
<Project>{fe0e1224-b447-4b14-81e7-ed7d84822aa0}</Project>
<Name>SafeExamBrowser.Core.Contracts</Name>
</ProjectReference>
<ProjectReference Include="..\SafeExamBrowser.I18n.Contracts\SafeExamBrowser.I18n.Contracts.csproj">
<Project>{1858ddf3-bc2a-4bff-b663-4ce2ffeb8b7d}</Project>
<Name>SafeExamBrowser.I18n.Contracts</Name>

View file

@ -6,7 +6,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
using SafeExamBrowser.Core.Contracts;
using SafeExamBrowser.Applications.Contracts.Resources.Icons;
namespace SafeExamBrowser.Client.Contracts
{

View file

@ -60,6 +60,10 @@
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\SafeExamBrowser.Applications.Contracts\SafeExamBrowser.Applications.Contracts.csproj">
<Project>{ac77745d-3b41-43e2-8e84-d40e5a4ee77f}</Project>
<Name>SafeExamBrowser.Applications.Contracts</Name>
</ProjectReference>
<ProjectReference Include="..\SafeExamBrowser.Core.Contracts\SafeExamBrowser.Core.Contracts.csproj">
<Project>{fe0e1224-b447-4b14-81e7-ed7d84822aa0}</Project>
<Name>SafeExamBrowser.Core.Contracts</Name>

View file

@ -7,8 +7,8 @@
*/
using System;
using SafeExamBrowser.Applications.Contracts.Resources.Icons;
using SafeExamBrowser.Client.Contracts;
using SafeExamBrowser.Core.Contracts;
using SafeExamBrowser.I18n.Contracts;
namespace SafeExamBrowser.Client.Notifications
@ -20,11 +20,7 @@ namespace SafeExamBrowser.Client.Notifications
public AboutNotificationInfo(IText text)
{
IconResource = new IconResource
{
Type = IconResourceType.Xaml,
Uri = new Uri("pack://application:,,,/SafeExamBrowser.UserInterface.Desktop;component/Images/AboutNotification.xaml")
};
IconResource = new XamlIconResource { Uri = new Uri("pack://application:,,,/SafeExamBrowser.UserInterface.Desktop;component/Images/AboutNotification.xaml") };
Tooltip = text.Get(TextKey.Notification_AboutTooltip);
}
}

View file

@ -7,8 +7,8 @@
*/
using System;
using SafeExamBrowser.Applications.Contracts.Resources.Icons;
using SafeExamBrowser.Client.Contracts;
using SafeExamBrowser.Core.Contracts;
using SafeExamBrowser.I18n.Contracts;
namespace SafeExamBrowser.Client.Notifications
@ -20,11 +20,7 @@ namespace SafeExamBrowser.Client.Notifications
public LogNotificationInfo(IText text)
{
IconResource = new IconResource
{
Type = IconResourceType.Bitmap,
Uri = new Uri("pack://application:,,,/SafeExamBrowser.UserInterface.Desktop;component/Images/LogNotification.ico")
};
IconResource = new BitmapIconResource { Uri = new Uri("pack://application:,,,/SafeExamBrowser.UserInterface.Desktop;component/Images/LogNotification.ico") };
Tooltip = text.Get(TextKey.Notification_LogTooltip);
}
}

View file

@ -1,31 +0,0 @@
/*
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
namespace SafeExamBrowser.Core.Contracts
{
/// <summary>
/// Defines the data format of an icon resource.
/// </summary>
public enum IconResourceType
{
/// <summary>
/// The icon resource is a bitmap image (i.e. raster graphics).
/// </summary>
Bitmap,
/// <summary>
/// The icon resource is a file with embedded icon data (e.g. an executable).
/// </summary>
Embedded,
/// <summary>
/// The icon resource consists of XAML markup (i.e. vector graphics).
/// </summary>
Xaml
}
}

View file

@ -54,8 +54,6 @@
<Reference Include="Microsoft.CSharp" />
</ItemGroup>
<ItemGroup>
<Compile Include="IconResource.cs" />
<Compile Include="IconResourceType.cs" />
<Compile Include="OperationModel\Events\ActionRequiredEventArgs.cs" />
<Compile Include="OperationModel\Events\ActionRequiredEventHandler.cs" />
<Compile Include="OperationModel\Events\ProgressChangedEventArgs.cs" />

View file

@ -6,7 +6,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
using SafeExamBrowser.Core.Contracts;
using SafeExamBrowser.Applications.Contracts.Resources.Icons;
using SafeExamBrowser.UserInterface.Contracts.Browser.Events;
using SafeExamBrowser.UserInterface.Contracts.Windows;

View file

@ -103,10 +103,6 @@
<Project>{7d74555e-63e1-4c46-bd0a-8580552368c8}</Project>
<Name>SafeExamBrowser.Configuration.Contracts</Name>
</ProjectReference>
<ProjectReference Include="..\SafeExamBrowser.Core.Contracts\SafeExamBrowser.Core.Contracts.csproj">
<Project>{fe0e1224-b447-4b14-81e7-ed7d84822aa0}</Project>
<Name>SafeExamBrowser.Core.Contracts</Name>
</ProjectReference>
<ProjectReference Include="..\SafeExamBrowser.I18n.Contracts\SafeExamBrowser.I18n.Contracts.csproj">
<Project>{1858ddf3-bc2a-4bff-b663-4ce2ffeb8b7d}</Project>
<Name>SafeExamBrowser.I18n.Contracts</Name>

View file

@ -14,9 +14,9 @@ using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using SafeExamBrowser.Settings.Browser;
using SafeExamBrowser.Core.Contracts;
using SafeExamBrowser.Applications.Contracts.Resources.Icons;
using SafeExamBrowser.I18n.Contracts;
using SafeExamBrowser.Settings.Browser;
using SafeExamBrowser.UserInterface.Contracts;
using SafeExamBrowser.UserInterface.Contracts.Browser;
using SafeExamBrowser.UserInterface.Contracts.Browser.Events;
@ -106,7 +106,13 @@ namespace SafeExamBrowser.UserInterface.Desktop
public void UpdateIcon(IconResource icon)
{
Dispatcher.InvokeAsync(() => Icon = new BitmapImage(icon.Uri));
Dispatcher.InvokeAsync(() =>
{
if (icon is BitmapIconResource bitmap)
{
Icon = new BitmapImage(bitmap.Uri);
}
});
}
public void UpdateLoadingState(bool isLoading)
@ -278,14 +284,10 @@ namespace SafeExamBrowser.UserInterface.Desktop
private void LoadIcons()
{
var backUri = new Uri("pack://application:,,,/SafeExamBrowser.UserInterface.Desktop;component/Images/NavigateBack.xaml");
var forwardUri = new Uri("pack://application:,,,/SafeExamBrowser.UserInterface.Desktop;component/Images/NavigateForward.xaml");
var menuUri = new Uri("pack://application:,,,/SafeExamBrowser.UserInterface.Desktop;component/Images/Menu.xaml");
var reloadUri = new Uri("pack://application:,,,/SafeExamBrowser.UserInterface.Desktop;component/Images/Reload.xaml");
var backward = new IconResource { Type = IconResourceType.Xaml, Uri = backUri };
var forward = new IconResource { Type = IconResourceType.Xaml, Uri = forwardUri };
var menu = new IconResource { Type = IconResourceType.Xaml, Uri = menuUri };
var reload = new IconResource { Type = IconResourceType.Xaml, Uri = reloadUri };
var backward = new XamlIconResource { Uri = new Uri("pack://application:,,,/SafeExamBrowser.UserInterface.Desktop;component/Images/NavigateBack.xaml") };
var forward = new XamlIconResource { Uri = new Uri("pack://application:,,,/SafeExamBrowser.UserInterface.Desktop;component/Images/NavigateForward.xaml") };
var menu = new XamlIconResource { Uri = new Uri("pack://application:,,,/SafeExamBrowser.UserInterface.Desktop;component/Images/Menu.xaml") };
var reload = new XamlIconResource { Uri = new Uri("pack://application:,,,/SafeExamBrowser.UserInterface.Desktop;component/Images/Reload.xaml") };
BackwardButton.Content = IconResourceLoader.Load(backward);
ForwardButton.Content = IconResourceLoader.Load(forward);

View file

@ -9,7 +9,7 @@
using System;
using System.Windows.Controls;
using SafeExamBrowser.Applications.Contracts;
using SafeExamBrowser.Core.Contracts;
using SafeExamBrowser.Applications.Contracts.Resources.Icons;
using SafeExamBrowser.UserInterface.Shared.Utilities;
namespace SafeExamBrowser.UserInterface.Desktop.Controls
@ -32,7 +32,7 @@ namespace SafeExamBrowser.UserInterface.Desktop.Controls
private void InitializeApplicationInstanceButton()
{
Icon.Content = IconResourceLoader.Load(application.Icon);
Icon.Content = IconResourceLoader.Load(window?.Icon ?? application.Icon);
Text.Text = window?.Title ?? application.Name;
Button.Click += (o, args) => Clicked?.Invoke(this, EventArgs.Empty);
Button.ToolTip = window?.Title ?? application.Tooltip;

View file

@ -13,7 +13,7 @@ using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Media;
using System.Windows.Threading;
using SafeExamBrowser.Core.Contracts;
using SafeExamBrowser.Applications.Contracts.Resources.Icons;
using SafeExamBrowser.I18n.Contracts;
using SafeExamBrowser.SystemComponents.Contracts.Audio;
using SafeExamBrowser.UserInterface.Contracts.Shell;
@ -51,8 +51,8 @@ namespace SafeExamBrowser.UserInterface.Desktop.Controls
Button.Click += (o, args) => Popup.IsOpen = !Popup.IsOpen;
Button.MouseLeave += (o, args) => Task.Delay(250).ContinueWith(_ => Dispatcher.Invoke(() => Popup.IsOpen = Popup.IsMouseOver));
MuteButton.Click += MuteButton_Click;
MutedIcon = new IconResource { Type = IconResourceType.Xaml, Uri = new Uri("pack://application:,,,/SafeExamBrowser.UserInterface.Desktop;component/Images/Audio_Muted.xaml") };
NoDeviceIcon = new IconResource { Type = IconResourceType.Xaml, Uri = new Uri("pack://application:,,,/SafeExamBrowser.UserInterface.Desktop;component/Images/Audio_Light_NoDevice.xaml") };
MutedIcon = new XamlIconResource { Uri = new Uri("pack://application:,,,/SafeExamBrowser.UserInterface.Desktop;component/Images/Audio_Muted.xaml") };
NoDeviceIcon = new XamlIconResource { Uri = new Uri("pack://application:,,,/SafeExamBrowser.UserInterface.Desktop;component/Images/Audio_Light_NoDevice.xaml") };
Popup.MouseLeave += (o, args) => Task.Delay(250).ContinueWith(_ => Dispatcher.Invoke(() => Popup.IsOpen = IsMouseOver));
Popup.Opened += (o, args) => Grid.Background = Brushes.Gray;
Popup.Closed += (o, args) => Grid.Background = originalBrush;
@ -147,7 +147,7 @@ namespace SafeExamBrowser.UserInterface.Desktop.Controls
{
var icon = volume > 0.66 ? "100" : (volume > 0.33 ? "66" : "33");
var uri = new Uri($"pack://application:,,,/SafeExamBrowser.UserInterface.Desktop;component/Images/Audio_Light_{icon}.xaml");
var resource = new IconResource { Type = IconResourceType.Xaml, Uri = uri};
var resource = new XamlIconResource { Uri = uri};
return IconResourceLoader.Load(resource);
}

View file

@ -9,7 +9,7 @@
using System;
using System.ComponentModel;
using System.Windows.Controls;
using SafeExamBrowser.Core.Contracts;
using SafeExamBrowser.Applications.Contracts.Resources.Icons;
using SafeExamBrowser.UserInterface.Contracts.Shell.Events;
using SafeExamBrowser.UserInterface.Shared.Utilities;
@ -28,7 +28,7 @@ namespace SafeExamBrowser.UserInterface.Desktop.Controls
private void InitializeControl()
{
var uri = new Uri("pack://application:,,,/SafeExamBrowser.UserInterface.Desktop;component/Images/ShutDown.xaml");
var resource = new IconResource { Type = IconResourceType.Xaml, Uri = uri };
var resource = new XamlIconResource { Uri = uri };
Icon.Content = IconResourceLoader.Load(resource);
Button.Click += (o, args) => Clicked?.Invoke(new CancelEventArgs());

View file

@ -12,7 +12,7 @@ using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using FontAwesome.WPF;
using SafeExamBrowser.Core.Contracts;
using SafeExamBrowser.Applications.Contracts.Resources.Icons;
using SafeExamBrowser.I18n.Contracts;
using SafeExamBrowser.SystemComponents.Contracts.WirelessNetwork;
using SafeExamBrowser.UserInterface.Contracts.Shell;
@ -134,7 +134,7 @@ namespace SafeExamBrowser.UserInterface.Desktop.Controls
{
var icon = signalStrength > 66 ? "100" : (signalStrength > 33 ? "66" : (signalStrength > 0 ? "33" : "0"));
var uri = new Uri($"pack://application:,,,/SafeExamBrowser.UserInterface.Desktop;component/Images/WiFi_Light_{icon}.xaml");
var resource = new IconResource { Type = IconResourceType.Xaml, Uri = uri };
var resource = new XamlIconResource { Uri = uri };
return IconResourceLoader.Load(resource);
}

View file

@ -9,7 +9,7 @@
using System.Windows;
using System.Windows.Controls;
using SafeExamBrowser.Applications.Contracts;
using SafeExamBrowser.Core.Contracts;
using SafeExamBrowser.Applications.Contracts.Resources.Icons;
using SafeExamBrowser.UserInterface.Shared.Utilities;
namespace SafeExamBrowser.UserInterface.Desktop.Controls

View file

@ -9,7 +9,7 @@
using System.Windows;
using System.Windows.Controls;
using SafeExamBrowser.Applications.Contracts;
using SafeExamBrowser.Core.Contracts;
using SafeExamBrowser.Applications.Contracts.Resources.Icons;
using SafeExamBrowser.UserInterface.Shared.Utilities;
namespace SafeExamBrowser.UserInterface.Desktop.Controls

View file

@ -12,7 +12,7 @@ using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Media;
using SafeExamBrowser.Core.Contracts;
using SafeExamBrowser.Applications.Contracts.Resources.Icons;
using SafeExamBrowser.I18n.Contracts;
using SafeExamBrowser.SystemComponents.Contracts.Audio;
using SafeExamBrowser.UserInterface.Contracts.Shell;
@ -50,8 +50,8 @@ namespace SafeExamBrowser.UserInterface.Desktop.Controls
Button.Click += (o, args) => Popup.IsOpen = !Popup.IsOpen;
Button.MouseLeave += (o, args) => Task.Delay(250).ContinueWith(_ => Dispatcher.Invoke(() => Popup.IsOpen = Popup.IsMouseOver));
MuteButton.Click += MuteButton_Click;
MutedIcon = new IconResource { Type = IconResourceType.Xaml, Uri = new Uri("pack://application:,,,/SafeExamBrowser.UserInterface.Desktop;component/Images/Audio_Muted.xaml") };
NoDeviceIcon = new IconResource { Type = IconResourceType.Xaml, Uri = new Uri("pack://application:,,,/SafeExamBrowser.UserInterface.Desktop;component/Images/Audio_NoDevice.xaml") };
MutedIcon = new XamlIconResource { Uri = new Uri("pack://application:,,,/SafeExamBrowser.UserInterface.Desktop;component/Images/Audio_Muted.xaml") };
NoDeviceIcon = new XamlIconResource { Uri = new Uri("pack://application:,,,/SafeExamBrowser.UserInterface.Desktop;component/Images/Audio_NoDevice.xaml") };
Popup.MouseLeave += (o, args) => Task.Delay(250).ContinueWith(_ => Dispatcher.Invoke(() => Popup.IsOpen = IsMouseOver));
Volume.ValueChanged += Volume_ValueChanged;
@ -154,7 +154,7 @@ namespace SafeExamBrowser.UserInterface.Desktop.Controls
{
var icon = volume > 0.66 ? "100" : (volume > 0.33 ? "66" : "33");
var uri = new Uri($"pack://application:,,,/SafeExamBrowser.UserInterface.Desktop;component/Images/Audio_{icon}.xaml");
var resource = new IconResource { Type = IconResourceType.Xaml, Uri = uri };
var resource = new XamlIconResource { Uri = uri };
return IconResourceLoader.Load(resource);
}

View file

@ -10,7 +10,7 @@ using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using SafeExamBrowser.Core.Contracts;
using SafeExamBrowser.Applications.Contracts.Resources.Icons;
using SafeExamBrowser.UserInterface.Contracts.Shell.Events;
using SafeExamBrowser.UserInterface.Shared.Utilities;
@ -34,7 +34,7 @@ namespace SafeExamBrowser.UserInterface.Desktop.Controls
private void LoadIcon()
{
var uri = new Uri("pack://application:,,,/SafeExamBrowser.UserInterface.Desktop;component/Images/ShutDown.xaml");
var resource = new IconResource { Type = IconResourceType.Xaml, Uri = uri };
var resource = new XamlIconResource { Uri = uri };
Button.Content = IconResourceLoader.Load(resource);
}

View file

@ -12,7 +12,7 @@ using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using FontAwesome.WPF;
using SafeExamBrowser.Core.Contracts;
using SafeExamBrowser.Applications.Contracts.Resources.Icons;
using SafeExamBrowser.I18n.Contracts;
using SafeExamBrowser.SystemComponents.Contracts.WirelessNetwork;
using SafeExamBrowser.UserInterface.Contracts.Shell;
@ -143,7 +143,7 @@ namespace SafeExamBrowser.UserInterface.Desktop.Controls
{
var icon = signalStrength > 66 ? "100" : (signalStrength > 33 ? "66" : (signalStrength > 0 ? "33" : "0"));
var uri = new Uri($"pack://application:,,,/SafeExamBrowser.UserInterface.Desktop;component/Images/WiFi_{icon}.xaml");
var resource = new IconResource { Type = IconResourceType.Xaml, Uri = uri };
var resource = new XamlIconResource { Uri = uri };
return IconResourceLoader.Load(resource);
}

View file

@ -451,10 +451,6 @@
<Project>{7d74555e-63e1-4c46-bd0a-8580552368c8}</Project>
<Name>SafeExamBrowser.Configuration.Contracts</Name>
</ProjectReference>
<ProjectReference Include="..\SafeExamBrowser.Core.Contracts\SafeExamBrowser.Core.Contracts.csproj">
<Project>{fe0e1224-b447-4b14-81e7-ed7d84822aa0}</Project>
<Name>SafeExamBrowser.Core.Contracts</Name>
</ProjectReference>
<ProjectReference Include="..\SafeExamBrowser.I18n.Contracts\SafeExamBrowser.I18n.Contracts.csproj">
<Project>{1858ddf3-bc2a-4bff-b663-4ce2ffeb8b7d}</Project>
<Name>SafeExamBrowser.I18n.Contracts</Name>

View file

@ -14,9 +14,9 @@ using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using SafeExamBrowser.Settings.Browser;
using SafeExamBrowser.Core.Contracts;
using SafeExamBrowser.Applications.Contracts.Resources.Icons;
using SafeExamBrowser.I18n.Contracts;
using SafeExamBrowser.Settings.Browser;
using SafeExamBrowser.UserInterface.Contracts;
using SafeExamBrowser.UserInterface.Contracts.Browser;
using SafeExamBrowser.UserInterface.Contracts.Browser.Events;
@ -106,7 +106,13 @@ namespace SafeExamBrowser.UserInterface.Mobile
public void UpdateIcon(IconResource icon)
{
Dispatcher.InvokeAsync(() => Icon = new BitmapImage(icon.Uri));
Dispatcher.InvokeAsync(() =>
{
if (icon is BitmapIconResource bitmap)
{
Icon = new BitmapImage(bitmap.Uri);
}
});
}
public void UpdateLoadingState(bool isLoading)
@ -287,14 +293,10 @@ namespace SafeExamBrowser.UserInterface.Mobile
private void LoadIcons()
{
var backUri = new Uri("pack://application:,,,/SafeExamBrowser.UserInterface.Desktop;component/Images/NavigateBack.xaml");
var forwardUri = new Uri("pack://application:,,,/SafeExamBrowser.UserInterface.Desktop;component/Images/NavigateForward.xaml");
var menuUri = new Uri("pack://application:,,,/SafeExamBrowser.UserInterface.Desktop;component/Images/Menu.xaml");
var reloadUri = new Uri("pack://application:,,,/SafeExamBrowser.UserInterface.Desktop;component/Images/Reload.xaml");
var backward = new IconResource { Type = IconResourceType.Xaml, Uri = backUri };
var forward = new IconResource { Type = IconResourceType.Xaml, Uri = forwardUri };
var menu = new IconResource { Type = IconResourceType.Xaml, Uri = menuUri };
var reload = new IconResource { Type = IconResourceType.Xaml, Uri = reloadUri };
var backward = new XamlIconResource { Uri = new Uri("pack://application:,,,/SafeExamBrowser.UserInterface.Desktop;component/Images/NavigateBack.xaml") };
var forward = new XamlIconResource { Uri = new Uri("pack://application:,,,/SafeExamBrowser.UserInterface.Desktop;component/Images/NavigateForward.xaml") };
var menu = new XamlIconResource { Uri = new Uri("pack://application:,,,/SafeExamBrowser.UserInterface.Desktop;component/Images/Menu.xaml") };
var reload = new XamlIconResource { Uri = new Uri("pack://application:,,,/SafeExamBrowser.UserInterface.Desktop;component/Images/Reload.xaml") };
BackwardButton.Content = IconResourceLoader.Load(backward);
ForwardButton.Content = IconResourceLoader.Load(forward);

View file

@ -9,7 +9,7 @@
using System;
using System.Windows.Controls;
using SafeExamBrowser.Applications.Contracts;
using SafeExamBrowser.Core.Contracts;
using SafeExamBrowser.Applications.Contracts.Resources.Icons;
using SafeExamBrowser.UserInterface.Shared.Utilities;
namespace SafeExamBrowser.UserInterface.Mobile.Controls
@ -32,7 +32,7 @@ namespace SafeExamBrowser.UserInterface.Mobile.Controls
private void InitializeApplicationInstanceButton()
{
Icon.Content = IconResourceLoader.Load(application.Icon);
Icon.Content = IconResourceLoader.Load(window?.Icon ?? application.Icon);
Text.Text = window?.Title ?? application.Name;
Button.Click += (o, args) => Clicked?.Invoke(this, EventArgs.Empty);
Button.ToolTip = window?.Title ?? application.Tooltip;

View file

@ -13,7 +13,7 @@ using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Media;
using System.Windows.Threading;
using SafeExamBrowser.Core.Contracts;
using SafeExamBrowser.Applications.Contracts.Resources.Icons;
using SafeExamBrowser.I18n.Contracts;
using SafeExamBrowser.SystemComponents.Contracts.Audio;
using SafeExamBrowser.UserInterface.Contracts.Shell;
@ -51,8 +51,8 @@ namespace SafeExamBrowser.UserInterface.Mobile.Controls
Button.Click += (o, args) => Popup.IsOpen = !Popup.IsOpen;
Button.MouseLeave += (o, args) => Task.Delay(250).ContinueWith(_ => Dispatcher.Invoke(() => Popup.IsOpen = Popup.IsMouseOver));
MuteButton.Click += MuteButton_Click;
MutedIcon = new IconResource { Type = IconResourceType.Xaml, Uri = new Uri("pack://application:,,,/SafeExamBrowser.UserInterface.Mobile;component/Images/Audio_Muted.xaml") };
NoDeviceIcon = new IconResource { Type = IconResourceType.Xaml, Uri = new Uri("pack://application:,,,/SafeExamBrowser.UserInterface.Mobile;component/Images/Audio_Light_NoDevice.xaml") };
MutedIcon = new XamlIconResource { Uri = new Uri("pack://application:,,,/SafeExamBrowser.UserInterface.Mobile;component/Images/Audio_Muted.xaml") };
NoDeviceIcon = new XamlIconResource { Uri = new Uri("pack://application:,,,/SafeExamBrowser.UserInterface.Mobile;component/Images/Audio_Light_NoDevice.xaml") };
Popup.MouseLeave += (o, args) => Task.Delay(250).ContinueWith(_ => Dispatcher.Invoke(() => Popup.IsOpen = IsMouseOver));
Popup.Opened += (o, args) => Grid.Background = Brushes.Gray;
Popup.Closed += (o, args) => Grid.Background = originalBrush;
@ -146,7 +146,7 @@ namespace SafeExamBrowser.UserInterface.Mobile.Controls
{
var icon = volume > 0.66 ? "100" : (volume > 0.33 ? "66" : "33");
var uri = new Uri($"pack://application:,,,/SafeExamBrowser.UserInterface.Mobile;component/Images/Audio_Light_{icon}.xaml");
var resource = new IconResource { Type = IconResourceType.Xaml, Uri = uri };
var resource = new XamlIconResource { Uri = uri };
return IconResourceLoader.Load(resource);
}

View file

@ -9,7 +9,7 @@
using System;
using System.ComponentModel;
using System.Windows.Controls;
using SafeExamBrowser.Core.Contracts;
using SafeExamBrowser.Applications.Contracts.Resources.Icons;
using SafeExamBrowser.UserInterface.Contracts.Shell.Events;
using SafeExamBrowser.UserInterface.Shared.Utilities;
@ -28,7 +28,7 @@ namespace SafeExamBrowser.UserInterface.Mobile.Controls
private void InitializeControl()
{
var uri = new Uri("pack://application:,,,/SafeExamBrowser.UserInterface.Desktop;component/Images/ShutDown.xaml");
var resource = new IconResource { Type = IconResourceType.Xaml, Uri = uri };
var resource = new XamlIconResource { Uri = uri };
Icon.Content = IconResourceLoader.Load(resource);
Button.Click += (o, args) => Clicked?.Invoke(new CancelEventArgs());

View file

@ -12,7 +12,7 @@ using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using FontAwesome.WPF;
using SafeExamBrowser.Core.Contracts;
using SafeExamBrowser.Applications.Contracts.Resources.Icons;
using SafeExamBrowser.I18n.Contracts;
using SafeExamBrowser.SystemComponents.Contracts.WirelessNetwork;
using SafeExamBrowser.UserInterface.Contracts.Shell;
@ -134,7 +134,7 @@ namespace SafeExamBrowser.UserInterface.Mobile.Controls
{
var icon = signalStrength > 66 ? "100" : (signalStrength > 33 ? "66" : (signalStrength > 0 ? "33" : "0"));
var uri = new Uri($"pack://application:,,,/SafeExamBrowser.UserInterface.Mobile;component/Images/WiFi_Light_{icon}.xaml");
var resource = new IconResource { Type = IconResourceType.Xaml, Uri = uri };
var resource = new XamlIconResource { Uri = uri };
return IconResourceLoader.Load(resource);
}

View file

@ -9,7 +9,7 @@
using System.Windows;
using System.Windows.Controls;
using SafeExamBrowser.Applications.Contracts;
using SafeExamBrowser.Core.Contracts;
using SafeExamBrowser.Applications.Contracts.Resources.Icons;
using SafeExamBrowser.UserInterface.Shared.Utilities;
namespace SafeExamBrowser.UserInterface.Mobile.Controls

View file

@ -9,7 +9,7 @@
using System.Windows;
using System.Windows.Controls;
using SafeExamBrowser.Applications.Contracts;
using SafeExamBrowser.Core.Contracts;
using SafeExamBrowser.Applications.Contracts.Resources.Icons;
using SafeExamBrowser.UserInterface.Shared.Utilities;
namespace SafeExamBrowser.UserInterface.Mobile.Controls

View file

@ -12,7 +12,7 @@ using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Media;
using SafeExamBrowser.Core.Contracts;
using SafeExamBrowser.Applications.Contracts.Resources.Icons;
using SafeExamBrowser.I18n.Contracts;
using SafeExamBrowser.SystemComponents.Contracts.Audio;
using SafeExamBrowser.UserInterface.Contracts.Shell;
@ -50,8 +50,8 @@ namespace SafeExamBrowser.UserInterface.Mobile.Controls
Button.Click += (o, args) => Popup.IsOpen = !Popup.IsOpen;
Button.MouseLeave += (o, args) => Task.Delay(250).ContinueWith(_ => Dispatcher.Invoke(() => Popup.IsOpen = Popup.IsMouseOver));
MuteButton.Click += MuteButton_Click;
MutedIcon = new IconResource { Type = IconResourceType.Xaml, Uri = new Uri("pack://application:,,,/SafeExamBrowser.UserInterface.Mobile;component/Images/Audio_Muted.xaml") };
NoDeviceIcon = new IconResource { Type = IconResourceType.Xaml, Uri = new Uri("pack://application:,,,/SafeExamBrowser.UserInterface.Mobile;component/Images/Audio_NoDevice.xaml") };
MutedIcon = new XamlIconResource { Uri = new Uri("pack://application:,,,/SafeExamBrowser.UserInterface.Mobile;component/Images/Audio_Muted.xaml") };
NoDeviceIcon = new XamlIconResource { Uri = new Uri("pack://application:,,,/SafeExamBrowser.UserInterface.Mobile;component/Images/Audio_NoDevice.xaml") };
Popup.MouseLeave += (o, args) => Task.Delay(250).ContinueWith(_ => Dispatcher.Invoke(() => Popup.IsOpen = IsMouseOver));
Volume.ValueChanged += Volume_ValueChanged;
@ -154,7 +154,7 @@ namespace SafeExamBrowser.UserInterface.Mobile.Controls
{
var icon = volume > 0.66 ? "100" : (volume > 0.33 ? "66" : "33");
var uri = new Uri($"pack://application:,,,/SafeExamBrowser.UserInterface.Mobile;component/Images/Audio_{icon}.xaml");
var resource = new IconResource { Type = IconResourceType.Xaml, Uri = uri };
var resource = new XamlIconResource { Uri = uri };
return IconResourceLoader.Load(resource);
}

View file

@ -10,7 +10,7 @@ using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using SafeExamBrowser.Core.Contracts;
using SafeExamBrowser.Applications.Contracts.Resources.Icons;
using SafeExamBrowser.UserInterface.Contracts.Shell.Events;
using SafeExamBrowser.UserInterface.Shared.Utilities;
@ -34,7 +34,7 @@ namespace SafeExamBrowser.UserInterface.Mobile.Controls
private void LoadIcon()
{
var uri = new Uri("pack://application:,,,/SafeExamBrowser.UserInterface.Desktop;component/Images/ShutDown.xaml");
var resource = new IconResource { Type = IconResourceType.Xaml, Uri = uri };
var resource = new XamlIconResource { Uri = uri };
Button.Content = IconResourceLoader.Load(resource);
}

View file

@ -12,7 +12,7 @@ using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using FontAwesome.WPF;
using SafeExamBrowser.Core.Contracts;
using SafeExamBrowser.Applications.Contracts.Resources.Icons;
using SafeExamBrowser.I18n.Contracts;
using SafeExamBrowser.SystemComponents.Contracts.WirelessNetwork;
using SafeExamBrowser.UserInterface.Contracts.Shell;
@ -143,7 +143,7 @@ namespace SafeExamBrowser.UserInterface.Mobile.Controls
{
var icon = signalStrength > 66 ? "100" : (signalStrength > 33 ? "66" : (signalStrength > 0 ? "33" : "0"));
var uri = new Uri($"pack://application:,,,/SafeExamBrowser.UserInterface.Mobile;component/Images/WiFi_{icon}.xaml");
var resource = new IconResource { Type = IconResourceType.Xaml, Uri = uri };
var resource = new XamlIconResource { Uri = uri };
return IconResourceLoader.Load(resource);
}

View file

@ -193,10 +193,6 @@
<Project>{7d74555e-63e1-4c46-bd0a-8580552368c8}</Project>
<Name>SafeExamBrowser.Configuration.Contracts</Name>
</ProjectReference>
<ProjectReference Include="..\SafeExamBrowser.Core.Contracts\SafeExamBrowser.Core.Contracts.csproj">
<Project>{fe0e1224-b447-4b14-81e7-ed7d84822aa0}</Project>
<Name>SafeExamBrowser.Core.Contracts</Name>
</ProjectReference>
<ProjectReference Include="..\SafeExamBrowser.I18n.Contracts\SafeExamBrowser.I18n.Contracts.csproj">
<Project>{1858ddf3-bc2a-4bff-b663-4ce2ffeb8b7d}</Project>
<Name>SafeExamBrowser.I18n.Contracts</Name>

View file

@ -77,9 +77,9 @@
<Compile Include="Utilities\WindowUtility.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\SafeExamBrowser.Core.Contracts\SafeExamBrowser.Core.Contracts.csproj">
<Project>{fe0e1224-b447-4b14-81e7-ed7d84822aa0}</Project>
<Name>SafeExamBrowser.Core.Contracts</Name>
<ProjectReference Include="..\SafeExamBrowser.Applications.Contracts\SafeExamBrowser.Applications.Contracts.csproj">
<Project>{ac77745d-3b41-43e2-8e84-d40e5a4ee77f}</Project>
<Name>SafeExamBrowser.Applications.Contracts</Name>
</ProjectReference>
<ProjectReference Include="..\SafeExamBrowser.Logging.Contracts\SafeExamBrowser.Logging.Contracts.csproj">
<Project>{64ea30fb-11d4-436a-9c2b-88566285363e}</Project>

View file

@ -13,9 +13,10 @@ using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Interop;
using System.Windows.Markup;
using System.Windows.Media.Imaging;
using SafeExamBrowser.Core.Contracts;
using SafeExamBrowser.Applications.Contracts.Resources.Icons;
using Brushes = System.Windows.Media.Brushes;
using Image = System.Windows.Controls.Image;
@ -27,16 +28,18 @@ namespace SafeExamBrowser.UserInterface.Shared.Utilities
{
try
{
switch (resource.Type)
switch (resource)
{
case IconResourceType.Bitmap:
return LoadBitmapResource(resource);
case IconResourceType.Embedded:
return LoadEmbeddedResource(resource);
case IconResourceType.Xaml:
return LoadXamlResource(resource);
case BitmapIconResource bitmap:
return LoadBitmapResource(bitmap);
case EmbeddedIconResource embedded:
return LoadEmbeddedResource(embedded);
case NativeIconResource native:
return LoadNativeResource(native);
case XamlIconResource xaml:
return LoadXamlResource(xaml);
default:
throw new NotSupportedException($"Application icon resource of type '{resource.Type}' is not supported!");
throw new NotSupportedException($"Application icon resource of type '{resource.GetType()}' is not supported!");
}
}
catch (Exception)
@ -45,7 +48,7 @@ namespace SafeExamBrowser.UserInterface.Shared.Utilities
}
}
private static UIElement LoadBitmapResource(IconResource resource)
private static UIElement LoadBitmapResource(BitmapIconResource resource)
{
return new Image
{
@ -53,13 +56,13 @@ namespace SafeExamBrowser.UserInterface.Shared.Utilities
};
}
private static UIElement LoadEmbeddedResource(IconResource resource)
private static UIElement LoadEmbeddedResource(EmbeddedIconResource resource)
{
using (var stream = new MemoryStream())
{
var bitmap = new BitmapImage();
Icon.ExtractAssociatedIcon(resource.Uri.LocalPath).ToBitmap().Save(stream, ImageFormat.Png);
Icon.ExtractAssociatedIcon(resource.FilePath).ToBitmap().Save(stream, ImageFormat.Png);
bitmap.BeginInit();
bitmap.StreamSource = stream;
@ -74,7 +77,15 @@ namespace SafeExamBrowser.UserInterface.Shared.Utilities
}
}
private static UIElement LoadXamlResource(IconResource resource)
private static UIElement LoadNativeResource(NativeIconResource resource)
{
return new Image
{
Source = Imaging.CreateBitmapSourceFromHIcon(resource.Handle, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions())
};
}
private static UIElement LoadXamlResource(XamlIconResource resource)
{
using (var stream = Application.GetResourceStream(resource.Uri)?.Stream)
{

View file

@ -90,6 +90,11 @@ namespace SafeExamBrowser.WindowsApi.Contracts
/// </exception>
string GetWallpaperPath();
/// <summary>
/// Attempts to retrieve the icon of the given window. Returns a handle to the icon, or <see cref="IntPtr.Zero"/> if the icon could not be retrieved.
/// </summary>
IntPtr GetWindowIcon(IntPtr window);
/// <summary>
/// Retrieves the title of the window with the given handle, or an empty string if the given window does not have a title.
/// </summary>

View file

@ -27,6 +27,22 @@ namespace SafeExamBrowser.WindowsApi.Constants
/// </summary>
internal const uint EVENT_SYSTEM_FOREGROUND = 0x3;
/// <summary>
/// The large icon of a window. See https://docs.microsoft.com/en-us/windows/win32/winmsg/wm-geticon#parameters.
/// </summary>
internal const int ICON_BIG = 1;
/// <summary>
/// The small icon of a window. See https://docs.microsoft.com/en-us/windows/win32/winmsg/wm-geticon#parameters.
/// </summary>
internal const int ICON_SMALL = 0;
/// <summary>
/// The small icon of an application. If an application does not provide one, the system uses a system-generated icon for a window.
/// See https://docs.microsoft.com/en-us/windows/win32/winmsg/wm-geticon#parameters.
/// </summary>
internal const int ICON_SMALL2 = 2;
/// <summary>
/// Minimize all open windows.
/// </summary>
@ -84,6 +100,14 @@ namespace SafeExamBrowser.WindowsApi.Constants
/// </summary>
internal const int WM_COMMAND = 0x111;
/// <summary>
/// Sent to a window to retrieve a handle to the large or small icon associated with a window. The system displays the large icon
/// in the ALT+TAB dialog, and the small icon in the window caption.
///
/// See https://docs.microsoft.com/en-us/windows/win32/winmsg/wm-geticon.
/// </summary>
internal const int WM_GETICON = 0x7F;
/// <summary>
/// Posted to the window with the keyboard focus when a nonsystem key is pressed. A nonsystem key is a key that is pressed when
/// the ALT key is not pressed.

View file

@ -199,6 +199,23 @@ namespace SafeExamBrowser.WindowsApi
return path;
}
public IntPtr GetWindowIcon(IntPtr window)
{
var icon = User32.SendMessage(window, Constant.WM_GETICON, new IntPtr(Constant.ICON_BIG), IntPtr.Zero);
if (icon == IntPtr.Zero)
{
icon = User32.SendMessage(window, Constant.WM_GETICON, new IntPtr(Constant.ICON_SMALL), IntPtr.Zero);
}
if (icon == IntPtr.Zero)
{
icon = User32.SendMessage(window, Constant.WM_GETICON, new IntPtr(Constant.ICON_SMALL2), IntPtr.Zero);
}
return icon;
}
public string GetWindowTitle(IntPtr window)
{
var length = User32.GetWindowTextLength(window);