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/. * 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 namespace SafeExamBrowser.Applications.Contracts.Events
{ {

View file

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

View file

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

View file

@ -8,20 +8,15 @@
using System; using System;
namespace SafeExamBrowser.Core.Contracts namespace SafeExamBrowser.Applications.Contracts.Resources.Icons
{ {
/// <summary> /// <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> /// </summary>
public class IconResource public class BitmapIconResource : IconResource
{ {
/// <summary> /// <summary>
/// Defines the data type of the resource. /// The <see cref="System.Uri"/> pointing to the image file.
/// </summary>
public IconResourceType Type { get; set; }
/// <summary>
/// The <see cref="System.Uri"/> pointing to the icon data.
/// </summary> /// </summary>
public Uri Uri { get; set; } 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="IApplication.cs" />
<Compile Include="IApplicationFactory.cs" /> <Compile Include="IApplicationFactory.cs" />
<Compile Include="IApplicationWindow.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="Properties\AssemblyInfo.cs" />
<Compile Include="Resources\Icons\NativeIconResource.cs" />
<Compile Include="Resources\Icons\XamlIconResource.cs" />
</ItemGroup> </ItemGroup>
<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"> <ProjectReference Include="..\SafeExamBrowser.Settings\SafeExamBrowser.Settings.csproj">
<Project>{30b2d907-5861-4f39-abad-c4abf1b3470e}</Project> <Project>{30b2d907-5861-4f39-abad-c4abf1b3470e}</Project>
<Name>SafeExamBrowser.Settings</Name> <Name>SafeExamBrowser.Settings</Name>

View file

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

View file

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

View file

@ -9,7 +9,7 @@
using System; using System;
using SafeExamBrowser.Applications.Contracts; using SafeExamBrowser.Applications.Contracts;
using SafeExamBrowser.Applications.Contracts.Events; using SafeExamBrowser.Applications.Contracts.Events;
using SafeExamBrowser.Core.Contracts; using SafeExamBrowser.Applications.Contracts.Resources.Icons;
using SafeExamBrowser.WindowsApi.Contracts; using SafeExamBrowser.WindowsApi.Contracts;
namespace SafeExamBrowser.Applications namespace SafeExamBrowser.Applications
@ -19,10 +19,10 @@ namespace SafeExamBrowser.Applications
private INativeMethods nativeMethods; private INativeMethods nativeMethods;
internal IntPtr Handle { get; } internal IntPtr Handle { get; }
public IconResource Icon { get; } public IconResource Icon { get; private set; }
public string Title { get; private set; } public string Title { get; private set; }
public event IconChangedEventHandler IconChanged { add { } remove { } } public event IconChangedEventHandler IconChanged;
public event TitleChangedEventHandler TitleChanged; public event TitleChangedEventHandler TitleChanged;
internal ExternalApplicationWindow(IconResource icon, INativeMethods nativeMethods, IntPtr handle) internal ExternalApplicationWindow(IconResource icon, INativeMethods nativeMethods, IntPtr handle)
@ -39,10 +39,18 @@ namespace SafeExamBrowser.Applications
internal void Update() 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 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; Title = title;
TitleChanged?.Invoke(title); TitleChanged?.Invoke(title);

View file

@ -66,10 +66,6 @@
<Project>{ac77745d-3b41-43e2-8e84-d40e5a4ee77f}</Project> <Project>{ac77745d-3b41-43e2-8e84-d40e5a4ee77f}</Project>
<Name>SafeExamBrowser.Applications.Contracts</Name> <Name>SafeExamBrowser.Applications.Contracts</Name>
</ProjectReference> </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"> <ProjectReference Include="..\SafeExamBrowser.Logging.Contracts\SafeExamBrowser.Logging.Contracts.csproj">
<Project>{64ea30fb-11d4-436a-9c2b-88566285363e}</Project> <Project>{64ea30fb-11d4-436a-9c2b-88566285363e}</Project>
<Name>SafeExamBrowser.Logging.Contracts</Name> <Name>SafeExamBrowser.Logging.Contracts</Name>

View file

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

View file

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

View file

@ -7,15 +7,14 @@
*/ */
using System; using System;
using SafeExamBrowser.Core.Contracts; using SafeExamBrowser.Applications.Contracts.Resources.Icons;
namespace SafeExamBrowser.Browser namespace SafeExamBrowser.Browser
{ {
public class BrowserIconResource : IconResource public class BrowserIconResource : BitmapIconResource
{ {
public BrowserIconResource(string uri = null) public BrowserIconResource(string uri = null)
{ {
Type = IconResourceType.Bitmap;
Uri = new Uri(uri ?? "pack://application:,,,/SafeExamBrowser.UserInterface.Desktop;component/Images/SafeExamBrowser.ico"); 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> <Project>{7d74555e-63e1-4c46-bd0a-8580552368c8}</Project>
<Name>SafeExamBrowser.Configuration.Contracts</Name> <Name>SafeExamBrowser.Configuration.Contracts</Name>
</ProjectReference> </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"> <ProjectReference Include="..\SafeExamBrowser.I18n.Contracts\SafeExamBrowser.I18n.Contracts.csproj">
<Project>{1858ddf3-bc2a-4bff-b663-4ce2ffeb8b7d}</Project> <Project>{1858ddf3-bc2a-4bff-b663-4ce2ffeb8b7d}</Project>
<Name>SafeExamBrowser.I18n.Contracts</Name> <Name>SafeExamBrowser.I18n.Contracts</Name>

View file

@ -6,7 +6,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * 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 namespace SafeExamBrowser.Client.Contracts
{ {

View file

@ -60,6 +60,10 @@
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup> </ItemGroup>
<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"> <ProjectReference Include="..\SafeExamBrowser.Core.Contracts\SafeExamBrowser.Core.Contracts.csproj">
<Project>{fe0e1224-b447-4b14-81e7-ed7d84822aa0}</Project> <Project>{fe0e1224-b447-4b14-81e7-ed7d84822aa0}</Project>
<Name>SafeExamBrowser.Core.Contracts</Name> <Name>SafeExamBrowser.Core.Contracts</Name>

View file

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

View file

@ -7,8 +7,8 @@
*/ */
using System; using System;
using SafeExamBrowser.Applications.Contracts.Resources.Icons;
using SafeExamBrowser.Client.Contracts; using SafeExamBrowser.Client.Contracts;
using SafeExamBrowser.Core.Contracts;
using SafeExamBrowser.I18n.Contracts; using SafeExamBrowser.I18n.Contracts;
namespace SafeExamBrowser.Client.Notifications namespace SafeExamBrowser.Client.Notifications
@ -20,11 +20,7 @@ namespace SafeExamBrowser.Client.Notifications
public LogNotificationInfo(IText text) public LogNotificationInfo(IText text)
{ {
IconResource = new IconResource IconResource = new BitmapIconResource { Uri = new Uri("pack://application:,,,/SafeExamBrowser.UserInterface.Desktop;component/Images/LogNotification.ico") };
{
Type = IconResourceType.Bitmap,
Uri = new Uri("pack://application:,,,/SafeExamBrowser.UserInterface.Desktop;component/Images/LogNotification.ico")
};
Tooltip = text.Get(TextKey.Notification_LogTooltip); 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" /> <Reference Include="Microsoft.CSharp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="IconResource.cs" />
<Compile Include="IconResourceType.cs" />
<Compile Include="OperationModel\Events\ActionRequiredEventArgs.cs" /> <Compile Include="OperationModel\Events\ActionRequiredEventArgs.cs" />
<Compile Include="OperationModel\Events\ActionRequiredEventHandler.cs" /> <Compile Include="OperationModel\Events\ActionRequiredEventHandler.cs" />
<Compile Include="OperationModel\Events\ProgressChangedEventArgs.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/. * 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.Browser.Events;
using SafeExamBrowser.UserInterface.Contracts.Windows; using SafeExamBrowser.UserInterface.Contracts.Windows;

View file

@ -103,10 +103,6 @@
<Project>{7d74555e-63e1-4c46-bd0a-8580552368c8}</Project> <Project>{7d74555e-63e1-4c46-bd0a-8580552368c8}</Project>
<Name>SafeExamBrowser.Configuration.Contracts</Name> <Name>SafeExamBrowser.Configuration.Contracts</Name>
</ProjectReference> </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"> <ProjectReference Include="..\SafeExamBrowser.I18n.Contracts\SafeExamBrowser.I18n.Contracts.csproj">
<Project>{1858ddf3-bc2a-4bff-b663-4ce2ffeb8b7d}</Project> <Project>{1858ddf3-bc2a-4bff-b663-4ce2ffeb8b7d}</Project>
<Name>SafeExamBrowser.I18n.Contracts</Name> <Name>SafeExamBrowser.I18n.Contracts</Name>

View file

@ -14,9 +14,9 @@ using System.Windows.Controls.Primitives;
using System.Windows.Input; using System.Windows.Input;
using System.Windows.Media; using System.Windows.Media;
using System.Windows.Media.Imaging; using System.Windows.Media.Imaging;
using SafeExamBrowser.Settings.Browser; using SafeExamBrowser.Applications.Contracts.Resources.Icons;
using SafeExamBrowser.Core.Contracts;
using SafeExamBrowser.I18n.Contracts; using SafeExamBrowser.I18n.Contracts;
using SafeExamBrowser.Settings.Browser;
using SafeExamBrowser.UserInterface.Contracts; using SafeExamBrowser.UserInterface.Contracts;
using SafeExamBrowser.UserInterface.Contracts.Browser; using SafeExamBrowser.UserInterface.Contracts.Browser;
using SafeExamBrowser.UserInterface.Contracts.Browser.Events; using SafeExamBrowser.UserInterface.Contracts.Browser.Events;
@ -106,7 +106,13 @@ namespace SafeExamBrowser.UserInterface.Desktop
public void UpdateIcon(IconResource icon) 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) public void UpdateLoadingState(bool isLoading)
@ -278,14 +284,10 @@ namespace SafeExamBrowser.UserInterface.Desktop
private void LoadIcons() private void LoadIcons()
{ {
var backUri = new Uri("pack://application:,,,/SafeExamBrowser.UserInterface.Desktop;component/Images/NavigateBack.xaml"); var backward = new XamlIconResource { Uri = 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 forward = new XamlIconResource { Uri = 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 menu = new XamlIconResource { Uri = 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 reload = new XamlIconResource { Uri = 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 };
BackwardButton.Content = IconResourceLoader.Load(backward); BackwardButton.Content = IconResourceLoader.Load(backward);
ForwardButton.Content = IconResourceLoader.Load(forward); ForwardButton.Content = IconResourceLoader.Load(forward);

View file

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

View file

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

View file

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

View file

@ -12,7 +12,7 @@ using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Media; using System.Windows.Media;
using FontAwesome.WPF; using FontAwesome.WPF;
using SafeExamBrowser.Core.Contracts; using SafeExamBrowser.Applications.Contracts.Resources.Icons;
using SafeExamBrowser.I18n.Contracts; using SafeExamBrowser.I18n.Contracts;
using SafeExamBrowser.SystemComponents.Contracts.WirelessNetwork; using SafeExamBrowser.SystemComponents.Contracts.WirelessNetwork;
using SafeExamBrowser.UserInterface.Contracts.Shell; 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 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 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); return IconResourceLoader.Load(resource);
} }

View file

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

View file

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

View file

@ -12,7 +12,7 @@ using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Controls.Primitives; using System.Windows.Controls.Primitives;
using System.Windows.Media; using System.Windows.Media;
using SafeExamBrowser.Core.Contracts; using SafeExamBrowser.Applications.Contracts.Resources.Icons;
using SafeExamBrowser.I18n.Contracts; using SafeExamBrowser.I18n.Contracts;
using SafeExamBrowser.SystemComponents.Contracts.Audio; using SafeExamBrowser.SystemComponents.Contracts.Audio;
using SafeExamBrowser.UserInterface.Contracts.Shell; using SafeExamBrowser.UserInterface.Contracts.Shell;
@ -50,8 +50,8 @@ namespace SafeExamBrowser.UserInterface.Desktop.Controls
Button.Click += (o, args) => Popup.IsOpen = !Popup.IsOpen; Button.Click += (o, args) => Popup.IsOpen = !Popup.IsOpen;
Button.MouseLeave += (o, args) => Task.Delay(250).ContinueWith(_ => Dispatcher.Invoke(() => Popup.IsOpen = Popup.IsMouseOver)); Button.MouseLeave += (o, args) => Task.Delay(250).ContinueWith(_ => Dispatcher.Invoke(() => Popup.IsOpen = Popup.IsMouseOver));
MuteButton.Click += MuteButton_Click; MuteButton.Click += MuteButton_Click;
MutedIcon = new IconResource { Type = IconResourceType.Xaml, Uri = new Uri("pack://application:,,,/SafeExamBrowser.UserInterface.Desktop;component/Images/Audio_Muted.xaml") }; MutedIcon = new XamlIconResource { 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") }; 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)); Popup.MouseLeave += (o, args) => Task.Delay(250).ContinueWith(_ => Dispatcher.Invoke(() => Popup.IsOpen = IsMouseOver));
Volume.ValueChanged += Volume_ValueChanged; 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 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 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); return IconResourceLoader.Load(resource);
} }

View file

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

View file

@ -12,7 +12,7 @@ using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Media; using System.Windows.Media;
using FontAwesome.WPF; using FontAwesome.WPF;
using SafeExamBrowser.Core.Contracts; using SafeExamBrowser.Applications.Contracts.Resources.Icons;
using SafeExamBrowser.I18n.Contracts; using SafeExamBrowser.I18n.Contracts;
using SafeExamBrowser.SystemComponents.Contracts.WirelessNetwork; using SafeExamBrowser.SystemComponents.Contracts.WirelessNetwork;
using SafeExamBrowser.UserInterface.Contracts.Shell; 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 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 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); return IconResourceLoader.Load(resource);
} }

View file

@ -451,10 +451,6 @@
<Project>{7d74555e-63e1-4c46-bd0a-8580552368c8}</Project> <Project>{7d74555e-63e1-4c46-bd0a-8580552368c8}</Project>
<Name>SafeExamBrowser.Configuration.Contracts</Name> <Name>SafeExamBrowser.Configuration.Contracts</Name>
</ProjectReference> </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"> <ProjectReference Include="..\SafeExamBrowser.I18n.Contracts\SafeExamBrowser.I18n.Contracts.csproj">
<Project>{1858ddf3-bc2a-4bff-b663-4ce2ffeb8b7d}</Project> <Project>{1858ddf3-bc2a-4bff-b663-4ce2ffeb8b7d}</Project>
<Name>SafeExamBrowser.I18n.Contracts</Name> <Name>SafeExamBrowser.I18n.Contracts</Name>

View file

@ -14,9 +14,9 @@ using System.Windows.Controls.Primitives;
using System.Windows.Input; using System.Windows.Input;
using System.Windows.Media; using System.Windows.Media;
using System.Windows.Media.Imaging; using System.Windows.Media.Imaging;
using SafeExamBrowser.Settings.Browser; using SafeExamBrowser.Applications.Contracts.Resources.Icons;
using SafeExamBrowser.Core.Contracts;
using SafeExamBrowser.I18n.Contracts; using SafeExamBrowser.I18n.Contracts;
using SafeExamBrowser.Settings.Browser;
using SafeExamBrowser.UserInterface.Contracts; using SafeExamBrowser.UserInterface.Contracts;
using SafeExamBrowser.UserInterface.Contracts.Browser; using SafeExamBrowser.UserInterface.Contracts.Browser;
using SafeExamBrowser.UserInterface.Contracts.Browser.Events; using SafeExamBrowser.UserInterface.Contracts.Browser.Events;
@ -106,7 +106,13 @@ namespace SafeExamBrowser.UserInterface.Mobile
public void UpdateIcon(IconResource icon) 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) public void UpdateLoadingState(bool isLoading)
@ -287,14 +293,10 @@ namespace SafeExamBrowser.UserInterface.Mobile
private void LoadIcons() private void LoadIcons()
{ {
var backUri = new Uri("pack://application:,,,/SafeExamBrowser.UserInterface.Desktop;component/Images/NavigateBack.xaml"); var backward = new XamlIconResource { Uri = 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 forward = new XamlIconResource { Uri = 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 menu = new XamlIconResource { Uri = 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 reload = new XamlIconResource { Uri = 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 };
BackwardButton.Content = IconResourceLoader.Load(backward); BackwardButton.Content = IconResourceLoader.Load(backward);
ForwardButton.Content = IconResourceLoader.Load(forward); ForwardButton.Content = IconResourceLoader.Load(forward);

View file

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

View file

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

View file

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

View file

@ -12,7 +12,7 @@ using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Media; using System.Windows.Media;
using FontAwesome.WPF; using FontAwesome.WPF;
using SafeExamBrowser.Core.Contracts; using SafeExamBrowser.Applications.Contracts.Resources.Icons;
using SafeExamBrowser.I18n.Contracts; using SafeExamBrowser.I18n.Contracts;
using SafeExamBrowser.SystemComponents.Contracts.WirelessNetwork; using SafeExamBrowser.SystemComponents.Contracts.WirelessNetwork;
using SafeExamBrowser.UserInterface.Contracts.Shell; 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 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 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); return IconResourceLoader.Load(resource);
} }

View file

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

View file

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

View file

@ -12,7 +12,7 @@ using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Controls.Primitives; using System.Windows.Controls.Primitives;
using System.Windows.Media; using System.Windows.Media;
using SafeExamBrowser.Core.Contracts; using SafeExamBrowser.Applications.Contracts.Resources.Icons;
using SafeExamBrowser.I18n.Contracts; using SafeExamBrowser.I18n.Contracts;
using SafeExamBrowser.SystemComponents.Contracts.Audio; using SafeExamBrowser.SystemComponents.Contracts.Audio;
using SafeExamBrowser.UserInterface.Contracts.Shell; using SafeExamBrowser.UserInterface.Contracts.Shell;
@ -50,8 +50,8 @@ namespace SafeExamBrowser.UserInterface.Mobile.Controls
Button.Click += (o, args) => Popup.IsOpen = !Popup.IsOpen; Button.Click += (o, args) => Popup.IsOpen = !Popup.IsOpen;
Button.MouseLeave += (o, args) => Task.Delay(250).ContinueWith(_ => Dispatcher.Invoke(() => Popup.IsOpen = Popup.IsMouseOver)); Button.MouseLeave += (o, args) => Task.Delay(250).ContinueWith(_ => Dispatcher.Invoke(() => Popup.IsOpen = Popup.IsMouseOver));
MuteButton.Click += MuteButton_Click; MuteButton.Click += MuteButton_Click;
MutedIcon = new IconResource { Type = IconResourceType.Xaml, Uri = new Uri("pack://application:,,,/SafeExamBrowser.UserInterface.Mobile;component/Images/Audio_Muted.xaml") }; MutedIcon = new XamlIconResource { 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") }; 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)); Popup.MouseLeave += (o, args) => Task.Delay(250).ContinueWith(_ => Dispatcher.Invoke(() => Popup.IsOpen = IsMouseOver));
Volume.ValueChanged += Volume_ValueChanged; 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 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 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); return IconResourceLoader.Load(resource);
} }

View file

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

View file

@ -12,7 +12,7 @@ using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Media; using System.Windows.Media;
using FontAwesome.WPF; using FontAwesome.WPF;
using SafeExamBrowser.Core.Contracts; using SafeExamBrowser.Applications.Contracts.Resources.Icons;
using SafeExamBrowser.I18n.Contracts; using SafeExamBrowser.I18n.Contracts;
using SafeExamBrowser.SystemComponents.Contracts.WirelessNetwork; using SafeExamBrowser.SystemComponents.Contracts.WirelessNetwork;
using SafeExamBrowser.UserInterface.Contracts.Shell; 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 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 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); return IconResourceLoader.Load(resource);
} }

View file

@ -193,10 +193,6 @@
<Project>{7d74555e-63e1-4c46-bd0a-8580552368c8}</Project> <Project>{7d74555e-63e1-4c46-bd0a-8580552368c8}</Project>
<Name>SafeExamBrowser.Configuration.Contracts</Name> <Name>SafeExamBrowser.Configuration.Contracts</Name>
</ProjectReference> </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"> <ProjectReference Include="..\SafeExamBrowser.I18n.Contracts\SafeExamBrowser.I18n.Contracts.csproj">
<Project>{1858ddf3-bc2a-4bff-b663-4ce2ffeb8b7d}</Project> <Project>{1858ddf3-bc2a-4bff-b663-4ce2ffeb8b7d}</Project>
<Name>SafeExamBrowser.I18n.Contracts</Name> <Name>SafeExamBrowser.I18n.Contracts</Name>

View file

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

View file

@ -13,9 +13,10 @@ using System.IO;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Documents; using System.Windows.Documents;
using System.Windows.Interop;
using System.Windows.Markup; using System.Windows.Markup;
using System.Windows.Media.Imaging; using System.Windows.Media.Imaging;
using SafeExamBrowser.Core.Contracts; using SafeExamBrowser.Applications.Contracts.Resources.Icons;
using Brushes = System.Windows.Media.Brushes; using Brushes = System.Windows.Media.Brushes;
using Image = System.Windows.Controls.Image; using Image = System.Windows.Controls.Image;
@ -27,16 +28,18 @@ namespace SafeExamBrowser.UserInterface.Shared.Utilities
{ {
try try
{ {
switch (resource.Type) switch (resource)
{ {
case IconResourceType.Bitmap: case BitmapIconResource bitmap:
return LoadBitmapResource(resource); return LoadBitmapResource(bitmap);
case IconResourceType.Embedded: case EmbeddedIconResource embedded:
return LoadEmbeddedResource(resource); return LoadEmbeddedResource(embedded);
case IconResourceType.Xaml: case NativeIconResource native:
return LoadXamlResource(resource); return LoadNativeResource(native);
case XamlIconResource xaml:
return LoadXamlResource(xaml);
default: 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) 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 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()) using (var stream = new MemoryStream())
{ {
var bitmap = new BitmapImage(); 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.BeginInit();
bitmap.StreamSource = stream; 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) using (var stream = Application.GetResourceStream(resource.Uri)?.Stream)
{ {

View file

@ -90,6 +90,11 @@ namespace SafeExamBrowser.WindowsApi.Contracts
/// </exception> /// </exception>
string GetWallpaperPath(); 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> /// <summary>
/// Retrieves the title of the window with the given handle, or an empty string if the given window does not have a title. /// Retrieves the title of the window with the given handle, or an empty string if the given window does not have a title.
/// </summary> /// </summary>

View file

@ -27,6 +27,22 @@ namespace SafeExamBrowser.WindowsApi.Constants
/// </summary> /// </summary>
internal const uint EVENT_SYSTEM_FOREGROUND = 0x3; 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> /// <summary>
/// Minimize all open windows. /// Minimize all open windows.
/// </summary> /// </summary>
@ -84,6 +100,14 @@ namespace SafeExamBrowser.WindowsApi.Constants
/// </summary> /// </summary>
internal const int WM_COMMAND = 0x111; 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> /// <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 /// 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. /// the ALT key is not pressed.

View file

@ -199,6 +199,23 @@ namespace SafeExamBrowser.WindowsApi
return path; 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) public string GetWindowTitle(IntPtr window)
{ {
var length = User32.GetWindowTextLength(window); var length = User32.GetWindowTextLength(window);