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, | ||||
| 		Notification_AboutTooltip, | ||||
| 		Notification_LogTooltip, | ||||
| 		SplashScreen_EmptyClipboard, | ||||
| 		SplashScreen_InitializeBrowser, | ||||
| 		SplashScreen_InitializeProcessMonitoring, | ||||
| 		SplashScreen_InitializeTaskbar, | ||||
|  |  | |||
|  | @ -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> | ||||
|  |  | |||
|  | @ -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> | ||||
|   <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> | ||||
|  |  | |||
|  | @ -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" /> | ||||
|  |  | |||
|  | @ -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; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  |  | |||
|  | @ -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>(); | ||||
|  |  | |||
|  | @ -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); | ||||
|  |  | |||
|  | @ -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)); | ||||
| 		} | ||||
| 	} | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 Damian Büchel
						Damian Büchel