Implemented basic clipboard operation and made loading of icons failsafe (i.e. a red "X" will be displayed if an icon cannot be loaded).

This commit is contained in:
Damian Büchel 2017-08-07 18:08:55 +02:00
parent 893febdf00
commit 7c4d443764
9 changed files with 115 additions and 10 deletions

View file

@ -23,6 +23,7 @@ namespace SafeExamBrowser.Contracts.I18n
MessageBox_StartupErrorTitle,
Notification_AboutTooltip,
Notification_LogTooltip,
SplashScreen_EmptyClipboard,
SplashScreen_InitializeBrowser,
SplashScreen_InitializeProcessMonitoring,
SplashScreen_InitializeTaskbar,

View file

@ -38,6 +38,14 @@ namespace SafeExamBrowser.Contracts.WindowsApi
/// </exception>
void DeregisterSystemEvent(IntPtr handle);
/// <summary>
/// Empties the clipboard.
/// </summary>
/// <exception cref="System.ComponentModel.Win32Exception">
/// If the emptying of the clipboard failed.
/// </exception>
void EmptyClipboard();
/// <summary>
/// Retrieves a collection of handles to all currently open (i.e. visible) windows.
/// </summary>

View file

@ -0,0 +1,48 @@
/*
* Copyright (c) 2017 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 SafeExamBrowser.Contracts.Behaviour;
using SafeExamBrowser.Contracts.I18n;
using SafeExamBrowser.Contracts.Logging;
using SafeExamBrowser.Contracts.UserInterface;
using SafeExamBrowser.Contracts.WindowsApi;
namespace SafeExamBrowser.Core.Behaviour.Operations
{
public class ClipboardOperation : IOperation
{
private ILogger logger;
private INativeMethods nativeMethods;
public ISplashScreen SplashScreen { private get; set; }
public ClipboardOperation(ILogger logger, INativeMethods nativeMethods)
{
this.logger = logger;
this.nativeMethods = nativeMethods;
}
public void Perform()
{
EmptyClipboard();
}
public void Revert()
{
EmptyClipboard();
}
private void EmptyClipboard()
{
logger.Info("Emptying clipboard...");
SplashScreen.UpdateText(TextKey.SplashScreen_EmptyClipboard);
nativeMethods.EmptyClipboard();
}
}
}

View file

@ -8,6 +8,7 @@
<MessageBox_StartupErrorTitle>Startup Error</MessageBox_StartupErrorTitle>
<Notification_AboutTooltip>About Safe Exam Browser</Notification_AboutTooltip>
<Notification_LogTooltip>Application Log</Notification_LogTooltip>
<SplashScreen_EmptyClipboard>Emptying clipboard</SplashScreen_EmptyClipboard>
<SplashScreen_InitializeBrowser>Initializing browser</SplashScreen_InitializeBrowser>
<SplashScreen_InitializeProcessMonitoring>Initializing process monitoring</SplashScreen_InitializeProcessMonitoring>
<SplashScreen_InitializeTaskbar>Initializing taskbar</SplashScreen_InitializeTaskbar>

View file

@ -58,6 +58,7 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Behaviour\Operations\ClipboardOperation.cs" />
<Compile Include="Behaviour\Operations\KeyboardInterceptorOperation.cs" />
<Compile Include="Behaviour\Operations\MouseInterceptorOperation.cs" />
<Compile Include="Behaviour\RuntimeController.cs" />

View file

@ -9,7 +9,9 @@
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Markup;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using SafeExamBrowser.Contracts.Configuration;
@ -19,22 +21,39 @@ namespace SafeExamBrowser.UserInterface.Utilities
{
internal static UIElement Load(IIconResource resource)
{
if (resource.IsBitmapResource)
try
{
return new Image
if (resource.IsBitmapResource)
{
Source = new BitmapImage(resource.Uri)
};
}
else if (resource.IsXamlResource)
{
using (var stream = Application.GetResourceStream(resource.Uri)?.Stream)
{
return XamlReader.Load(stream) as UIElement;
return LoadBitmapResource(resource);
}
else if (resource.IsXamlResource)
{
return LoadXamlResource(resource);
}
}
catch (Exception)
{
return new TextBlock(new Run("X") { Foreground = Brushes.Red, FontWeight = FontWeights.Bold });
}
throw new NotSupportedException($"Application icon resource of type '{resource.GetType()}' is not supported!");
}
private static UIElement LoadBitmapResource(IIconResource resource)
{
return new Image
{
Source = new BitmapImage(resource.Uri)
};
}
private static UIElement LoadXamlResource(IIconResource resource)
{
using (var stream = Application.GetResourceStream(resource.Uri)?.Stream)
{
return XamlReader.Load(stream) as UIElement;
}
}
}
}

View file

@ -94,6 +94,20 @@ namespace SafeExamBrowser.WindowsApi
EventDelegates.TryRemove(handle, out EventProc d);
}
public void EmptyClipboard()
{
var success = true;
success &= User32.OpenClipboard(IntPtr.Zero);
success &= User32.EmptyClipboard();
success &= User32.CloseClipboard();
if (!success)
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
}
public IEnumerable<IntPtr> GetOpenWindows()
{
var windows = new List<IntPtr>();

View file

@ -26,6 +26,14 @@ namespace SafeExamBrowser.WindowsApi
[DllImport("user32.dll", SetLastError = true)]
internal static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool CloseClipboard();
[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool EmptyClipboard();
[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool EnumWindows(EnumWindowsDelegate enumProc, IntPtr lParam);
@ -46,6 +54,10 @@ namespace SafeExamBrowser.WindowsApi
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool IsWindowVisible(IntPtr hWnd);
[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool OpenClipboard(IntPtr hWndNewOwner);
[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool PostMessage(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);

View file

@ -86,6 +86,7 @@ namespace SafeExamBrowser
StartupOperations.Enqueue(new TaskbarOperation(logger, logFormatter, settings, Taskbar, text, uiFactory));
StartupOperations.Enqueue(new BrowserOperation(browserController, browserInfo, logger, Taskbar, uiFactory));
StartupOperations.Enqueue(new RuntimeControllerOperation(runtimeController, logger));
StartupOperations.Enqueue(new ClipboardOperation(logger, nativeMethods));
StartupOperations.Enqueue(new MouseInterceptorOperation(logger, mouseInterceptor, nativeMethods));
}
}