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:
		
							parent
							
								
									893febdf00
								
							
						
					
					
						commit
						7c4d443764
					
				
					 9 changed files with 115 additions and 10 deletions
				
			
		|  | @ -23,6 +23,7 @@ namespace SafeExamBrowser.Contracts.I18n | ||||||
| 		MessageBox_StartupErrorTitle, | 		MessageBox_StartupErrorTitle, | ||||||
| 		Notification_AboutTooltip, | 		Notification_AboutTooltip, | ||||||
| 		Notification_LogTooltip, | 		Notification_LogTooltip, | ||||||
|  | 		SplashScreen_EmptyClipboard, | ||||||
| 		SplashScreen_InitializeBrowser, | 		SplashScreen_InitializeBrowser, | ||||||
| 		SplashScreen_InitializeProcessMonitoring, | 		SplashScreen_InitializeProcessMonitoring, | ||||||
| 		SplashScreen_InitializeTaskbar, | 		SplashScreen_InitializeTaskbar, | ||||||
|  |  | ||||||
|  | @ -38,6 +38,14 @@ namespace SafeExamBrowser.Contracts.WindowsApi | ||||||
| 		/// </exception> | 		/// </exception> | ||||||
| 		void DeregisterSystemEvent(IntPtr handle); | 		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> | 		/// <summary> | ||||||
| 		/// Retrieves a collection of handles to all currently open (i.e. visible) windows. | 		/// Retrieves a collection of handles to all currently open (i.e. visible) windows. | ||||||
| 		/// </summary> | 		/// </summary> | ||||||
|  |  | ||||||
|  | @ -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(); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | @ -8,6 +8,7 @@ | ||||||
|   <MessageBox_StartupErrorTitle>Startup Error</MessageBox_StartupErrorTitle> |   <MessageBox_StartupErrorTitle>Startup Error</MessageBox_StartupErrorTitle> | ||||||
|   <Notification_AboutTooltip>About Safe Exam Browser</Notification_AboutTooltip> |   <Notification_AboutTooltip>About Safe Exam Browser</Notification_AboutTooltip> | ||||||
|   <Notification_LogTooltip>Application Log</Notification_LogTooltip> |   <Notification_LogTooltip>Application Log</Notification_LogTooltip> | ||||||
|  |   <SplashScreen_EmptyClipboard>Emptying clipboard</SplashScreen_EmptyClipboard> | ||||||
|   <SplashScreen_InitializeBrowser>Initializing browser</SplashScreen_InitializeBrowser> |   <SplashScreen_InitializeBrowser>Initializing browser</SplashScreen_InitializeBrowser> | ||||||
|   <SplashScreen_InitializeProcessMonitoring>Initializing process monitoring</SplashScreen_InitializeProcessMonitoring> |   <SplashScreen_InitializeProcessMonitoring>Initializing process monitoring</SplashScreen_InitializeProcessMonitoring> | ||||||
|   <SplashScreen_InitializeTaskbar>Initializing taskbar</SplashScreen_InitializeTaskbar> |   <SplashScreen_InitializeTaskbar>Initializing taskbar</SplashScreen_InitializeTaskbar> | ||||||
|  |  | ||||||
|  | @ -58,6 +58,7 @@ | ||||||
|     <Reference Include="System.Xml" /> |     <Reference Include="System.Xml" /> | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|  |     <Compile Include="Behaviour\Operations\ClipboardOperation.cs" /> | ||||||
|     <Compile Include="Behaviour\Operations\KeyboardInterceptorOperation.cs" /> |     <Compile Include="Behaviour\Operations\KeyboardInterceptorOperation.cs" /> | ||||||
|     <Compile Include="Behaviour\Operations\MouseInterceptorOperation.cs" /> |     <Compile Include="Behaviour\Operations\MouseInterceptorOperation.cs" /> | ||||||
|     <Compile Include="Behaviour\RuntimeController.cs" /> |     <Compile Include="Behaviour\RuntimeController.cs" /> | ||||||
|  |  | ||||||
|  | @ -9,7 +9,9 @@ | ||||||
| using System; | using System; | ||||||
| using System.Windows; | using System.Windows; | ||||||
| using System.Windows.Controls; | using System.Windows.Controls; | ||||||
|  | using System.Windows.Documents; | ||||||
| using System.Windows.Markup; | using System.Windows.Markup; | ||||||
|  | using System.Windows.Media; | ||||||
| using System.Windows.Media.Imaging; | using System.Windows.Media.Imaging; | ||||||
| using SafeExamBrowser.Contracts.Configuration; | using SafeExamBrowser.Contracts.Configuration; | ||||||
| 
 | 
 | ||||||
|  | @ -19,22 +21,39 @@ namespace SafeExamBrowser.UserInterface.Utilities | ||||||
| 	{ | 	{ | ||||||
| 		internal static UIElement Load(IIconResource resource) | 		internal static UIElement Load(IIconResource resource) | ||||||
| 		{ | 		{ | ||||||
| 			if (resource.IsBitmapResource) | 			try | ||||||
| 			{ | 			{ | ||||||
| 				return new Image | 				if (resource.IsBitmapResource) | ||||||
| 				{ | 				{ | ||||||
| 					Source = new BitmapImage(resource.Uri) | 					return LoadBitmapResource(resource); | ||||||
| 				}; |  | ||||||
| 			} |  | ||||||
| 			else if (resource.IsXamlResource) |  | ||||||
| 			{ |  | ||||||
| 				using (var stream = Application.GetResourceStream(resource.Uri)?.Stream) |  | ||||||
| 				{ |  | ||||||
| 					return XamlReader.Load(stream) as UIElement; |  | ||||||
| 				} | 				} | ||||||
|  | 				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!"); | 			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; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -94,6 +94,20 @@ namespace SafeExamBrowser.WindowsApi | ||||||
| 			EventDelegates.TryRemove(handle, out EventProc d); | 			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() | 		public IEnumerable<IntPtr> GetOpenWindows() | ||||||
| 		{ | 		{ | ||||||
| 			var windows = new List<IntPtr>(); | 			var windows = new List<IntPtr>(); | ||||||
|  |  | ||||||
|  | @ -26,6 +26,14 @@ namespace SafeExamBrowser.WindowsApi | ||||||
| 		[DllImport("user32.dll", SetLastError = true)] | 		[DllImport("user32.dll", SetLastError = true)] | ||||||
| 		internal static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam); | 		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)] | 		[DllImport("user32.dll", SetLastError = true)] | ||||||
| 		[return: MarshalAs(UnmanagedType.Bool)] | 		[return: MarshalAs(UnmanagedType.Bool)] | ||||||
| 		internal static extern bool EnumWindows(EnumWindowsDelegate enumProc, IntPtr lParam); | 		internal static extern bool EnumWindows(EnumWindowsDelegate enumProc, IntPtr lParam); | ||||||
|  | @ -46,6 +54,10 @@ namespace SafeExamBrowser.WindowsApi | ||||||
| 		[return: MarshalAs(UnmanagedType.Bool)] | 		[return: MarshalAs(UnmanagedType.Bool)] | ||||||
| 		internal static extern bool IsWindowVisible(IntPtr hWnd); | 		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)] | 		[DllImport("user32.dll", SetLastError = true)] | ||||||
| 		[return: MarshalAs(UnmanagedType.Bool)] | 		[return: MarshalAs(UnmanagedType.Bool)] | ||||||
| 		internal static extern bool PostMessage(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam); | 		internal static extern bool PostMessage(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam); | ||||||
|  |  | ||||||
|  | @ -86,6 +86,7 @@ namespace SafeExamBrowser | ||||||
| 			StartupOperations.Enqueue(new TaskbarOperation(logger, logFormatter, settings, Taskbar, text, uiFactory)); | 			StartupOperations.Enqueue(new TaskbarOperation(logger, logFormatter, settings, Taskbar, text, uiFactory)); | ||||||
| 			StartupOperations.Enqueue(new BrowserOperation(browserController, browserInfo, logger, Taskbar, uiFactory)); | 			StartupOperations.Enqueue(new BrowserOperation(browserController, browserInfo, logger, Taskbar, uiFactory)); | ||||||
| 			StartupOperations.Enqueue(new RuntimeControllerOperation(runtimeController, logger)); | 			StartupOperations.Enqueue(new RuntimeControllerOperation(runtimeController, logger)); | ||||||
|  | 			StartupOperations.Enqueue(new ClipboardOperation(logger, nativeMethods)); | ||||||
| 			StartupOperations.Enqueue(new MouseInterceptorOperation(logger, mouseInterceptor, nativeMethods)); | 			StartupOperations.Enqueue(new MouseInterceptorOperation(logger, mouseInterceptor, nativeMethods)); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 Damian Büchel
						Damian Büchel