diff --git a/ProofOfConcept/Monaco/monacoPreview/MainWindow.xaml.cs b/ProofOfConcept/Monaco/monacoPreview/MainWindow.xaml.cs index 221d015e7..90924c2a1 100644 --- a/ProofOfConcept/Monaco/monacoPreview/MainWindow.xaml.cs +++ b/ProofOfConcept/Monaco/monacoPreview/MainWindow.xaml.cs @@ -1,8 +1,6 @@ using System; using System.IO; -using System.Windows; using Microsoft.Web.WebView2.Core; -using Windows.UI.Xaml; using WK.Libraries.WTL; namespace monacoPreview @@ -11,7 +9,7 @@ namespace monacoPreview /// Interaction logic for MainWindow.xaml /// public partial class MainWindow : System.Windows.Window - { + { // This variable prevents users from navigating private bool WasNavigated = false; @@ -32,19 +30,20 @@ namespace monacoPreview string[] file = GetFile(args); - InitializeAsync(file[0], fileHandler.GetLanguage(file[1])); + InitializeAsync(settings.compatibility?file[0]:file[2], fileHandler.GetLanguage(file[1])); } - private string[] GetFile(string[] args) + public string[] GetFile(string[] args) { // This function gets a file - string[] returnValue = new string[2]; + string[] returnValue = new string[3]; // Get source code returnValue[0] = File.ReadAllText(args[1]); // Gets file extension (without .) returnValue[1] = Path.GetExtension(args[1]).Replace(".",""); + returnValue[2] = args[1]; return returnValue; } @@ -100,29 +99,43 @@ namespace monacoPreview webView.Width = this.ActualWidth; } - async void InitializeAsync(string code, string lang) + public async void InitializeAsync(string code, string lang) { // This function initializes the webview settings // Partely copied from https://weblog.west-wind.com/posts/2021/Jan/14/Taking-the-new-Chromium-WebView2-Control-for-a-Spin-in-NET-Part-1 // Sets the url - webView.Source = GetURL(code, lang); + webView.Source = settings.compatibility?GetURLwithCode(code, lang):GetURLwithFilePath(code, lang); // Initialize WebView - var env = await CoreWebView2Environment.CreateAsync(); + + var webViewOptions = new CoreWebView2EnvironmentOptions + { + // Enable CORS for local file access. + AdditionalBrowserArguments = "--disable-web-security" + }; + + var env = await CoreWebView2Environment.CreateAsync(null, null, webViewOptions); await webView.EnsureCoreWebView2Async(env); webView.NavigationCompleted += WebView2Init; webView.NavigationStarting += NavigationStarted; } - public Uri GetURL(string code, string lang) + public Uri GetURLwithFilePath(string file, string lang) + { + // This function returns a url you can use to access index.html + + return new Uri(settings.baseURL + "?file=" + file + "&lang=" + lang + "&theme=" + settings.GetTheme(ThemeListener.AppMode) + "&wrap=" + (this.settings.wrap?"1":"0")); + } + + public Uri GetURLwithCode(string code, string lang) { // This function returns a url you can use to access index.html // Converts code to base64 code = System.Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(code)).Replace("+", "%2B"); - return new Uri(settings.baseURL + "?code=" + code + "&lang=" + lang + "&theme=" + settings.GetTheme(ThemeListener.AppMode) + "&wrap=" + (this.settings.wrap?"1":"0")); + return new Uri(settings.baseURL + "?code=" + code + "&lang=" + lang + "&theme=" + settings.GetTheme(ThemeListener.AppMode) + "&wrap=" + (this.settings.wrap ? "1" : "0")); } } } diff --git a/ProofOfConcept/Monaco/monacoPreview/MonacoPreviewHandlerInterfaces.cs b/ProofOfConcept/Monaco/monacoPreview/MonacoPreviewHandlerInterfaces.cs new file mode 100644 index 000000000..298843edf --- /dev/null +++ b/ProofOfConcept/Monaco/monacoPreview/MonacoPreviewHandlerInterfaces.cs @@ -0,0 +1,91 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Runtime.InteropServices; +using System.Runtime.InteropServices.ComTypes; +using System.Text; + +namespace monacoPreview +{ + + public struct RECT + { + public int Left { get; set; } + + public int Top { get; set; } + + public int Right { get; set; } + + public int Bottom { get; set; } + + public Rectangle ToRectangle() + { + return Rectangle.FromLTRB(Left, Top, Right, Bottom); + } + } + + public struct MSG + { + public IntPtr Hwnd { get; set; } + + public int Message { get; set; } + + public IntPtr WParam { get; set; } + public IntPtr LParam { get; set; } + + public int Time { get; set; } + + public int PtX { get; set; } + + public int PtY { get; set; } + } + + [ComImport] + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + [Guid("cfac301a-fdd7-4e54-aa10-318ffa7f7bd2")] + public interface IPreviewHandler + { + void SetWindow(IntPtr hwnd, ref RECT rect); + + void SetRect(ref RECT rect); + + void DoPreview(); + + void Unload(); + + void SetFocus(); + + void QueryFocus(out IntPtr phwnd); + + [PreserveSig] + uint TranslateAccelerator(ref MSG pmsg); + } + + [ComImport] + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + [Guid("cfac301a-fdd7-4e54-aa10-318ffa7f7bd2")] + public interface IInitializeWithStream + { + void Initialize(IStream pstream, uint grfMode); + } + + [ComImport] + [Guid("cfac301a-fdd7-4e54-aa10-318ffa7f7bd2")] + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IOleWindow + { + void GetWindow(out IntPtr phwnd); + + void ContextSensitiveHelp([MarshalAs(UnmanagedType.Bool)] bool fEnterMode); + } + + [ComImport] + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + [Guid("fc4801a3-2ba9-11cf-a229-00aa003d7352")] + public interface IObjectWithSite + { + void SetSite([In, MarshalAs(UnmanagedType.IUnknown)] object pUnkSite); + + void GetSite(ref Guid riid, [MarshalAs(UnmanagedType.IUnknown)] out object ppvSite); + } +} diff --git a/ProofOfConcept/Monaco/monacoPreview/PreviewWindow.xaml b/ProofOfConcept/Monaco/monacoPreview/PreviewWindow.xaml new file mode 100644 index 000000000..12ee347c9 --- /dev/null +++ b/ProofOfConcept/Monaco/monacoPreview/PreviewWindow.xaml @@ -0,0 +1,21 @@ + + + + data:text/html;base64,PHA+TG9hZGluZy4uLjwvcD48YnI+PGltZyBzcmM9Imh0dHBzOi8vZG9jcy5taWNyb3NvZnQuY29tL2RlLWRlL3dpbmRvd3Mvd2ludWkvYXBpL21pY3Jvc29mdC51aS54YW1sLmNvbnRyb2xzL2ltYWdlcy9jb250cm9scy9wcm9ncmVzc3JpbmdfaW5kZXRlcm1pbmF0ZS5naWYiPg== + + + + + diff --git a/ProofOfConcept/Monaco/monacoPreview/PreviewWindow.xaml.cs b/ProofOfConcept/Monaco/monacoPreview/PreviewWindow.xaml.cs new file mode 100644 index 000000000..2f0aeb1d8 --- /dev/null +++ b/ProofOfConcept/Monaco/monacoPreview/PreviewWindow.xaml.cs @@ -0,0 +1,203 @@ +using System; +using System.IO; +using System.Windows; +using Microsoft.Web.WebView2.Core; +using Windows.UI.Xaml; +using WK.Libraries.WTL; +using System.Windows.Shell; +using Microsoft.Win32; +using System.ComponentModel; +using System.Drawing; +using System.Runtime.InteropServices; + +namespace monacoPreview +{ + /// + /// Interaction logic for MainWindow.xaml + /// + public partial class PreviewWindow : IPreviewHandler, IOleWindow, IObjectWithSite + { + // This variable prevents users from navigating + private bool WasNavigated = false; + + // Settings from Settings.cs + private readonly Settings settings = new Settings(); + + // Filehandler class from FileHandler.cs + private readonly FileHandler fileHandler = new FileHandler(); + + public PreviewWindow() + { + System.Diagnostics.Debug.WriteLine("Start"); + + // Get command line args + string[] args = Environment.GetCommandLineArgs(); + + InitializeComponent(); + + string[] file = GetFile(args); + + InitializeAsync(settings.compatibility?file[0]:file[2], fileHandler.GetLanguage(file[1])); + + + } + + public string[] GetFile(string[] args) + { + // This function gets a file + string[] returnValue = new string[3]; + // Get source code + returnValue[0] = File.ReadAllText(args[1]); + // Gets file extension (without .) + returnValue[1] = Path.GetExtension(args[1]).Replace(".",""); + returnValue[2] = args[1]; + return returnValue; + } + + private void WebView2Init(Object sender, CoreWebView2NavigationCompletedEventArgs e) + { + // This function sets the diiferent settings for the webview + + // Checks if already navigated + if (!WasNavigated) + { + CoreWebView2Settings settings = webView.CoreWebView2.Settings; + + // Disable contextmenu + //settings.AreDefaultContextMenusEnabled = false; + // Disable developer menu + //settings.AreDevToolsEnabled = false; + // Disable script dialogs (like alert()) + settings.AreDefaultScriptDialogsEnabled = false; + // Enables JavaScript + settings.IsScriptEnabled = true; + // Disable zoom woth ctrl and scroll + settings.IsZoomControlEnabled = false; + // Disable developer menu + settings.IsBuiltInErrorPageEnabled = false; + // Disable status bar + settings.IsStatusBarEnabled = false; + } + } + + private void NavigationStarted(Object sender, CoreWebView2NavigationStartingEventArgs e) + { + // Prevents navigation if already one done to index.html + if (WasNavigated) + { + e.Cancel = false; + } + + // If it has navigated to index.html it stops further navigations + if(e.Uri.StartsWith(settings.baseURL)) + { + WasNavigated = true; + } + } + + private void FormResize(object sender, EventArgs e) + { + // This function gets called whan the form gets resized + // It's fitting the webview in the size of the window + // TO-DO: Javascript resize + viewbox.Height = this.ActualHeight; + viewbox.Width = this.ActualWidth; + webView.Height = this.ActualHeight; + webView.Width = this.ActualWidth; + } + + public async void InitializeAsync(string code, string lang) + { + // This function initializes the webview settings + // Partely copied from https://weblog.west-wind.com/posts/2021/Jan/14/Taking-the-new-Chromium-WebView2-Control-for-a-Spin-in-NET-Part-1 + + // Sets the url + webView.Source = settings.compatibility?GetURLwithCode(code, lang):GetURLwithFilePath(code, lang); + + // Initialize WebView + + var webViewOptions = new CoreWebView2EnvironmentOptions + { + // Enable CORS for local file access. + AdditionalBrowserArguments = "--disable-web-security" + }; + + var env = await CoreWebView2Environment.CreateAsync(null, null, webViewOptions); + await webView.EnsureCoreWebView2Async(env); + webView.NavigationCompleted += WebView2Init; + webView.NavigationStarting += NavigationStarted; + } + + public Uri GetURLwithFilePath(string file, string lang) + { + // This function returns a url you can use to access index.html + + return new Uri(settings.baseURL + "?file=" + file + "&lang=" + lang + "&theme=" + settings.GetTheme(ThemeListener.AppMode) + "&wrap=" + (this.settings.wrap?"1":"0")); + } + + public Uri GetURLwithCode(string code, string lang) + { + // This function returns a url you can use to access index.html + + // Converts code to base64 + code = System.Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(code)).Replace("+", "%2B"); + + return new Uri(settings.baseURL + "?code=" + code + "&lang=" + lang + "&theme=" + settings.GetTheme(ThemeListener.AppMode) + "&wrap=" + (this.settings.wrap ? "1" : "0")); + } + + public void SetWindow(IntPtr hwnd, ref RECT rect) + { + + } + + public void SetRect(ref RECT rect) + { + + } + + public void DoPreview() + { + + } + + public void Unload() + { + + } + + public void SetFocus() + { + + } + + public void QueryFocus(out IntPtr phwnd) + { + phwnd = new IntPtr(); + } + + public uint TranslateAccelerator(ref MSG pmsg) + { + return 1; + } + + public void GetWindow(out IntPtr phwnd) + { + phwnd = this; + } + + public void ContextSensitiveHelp([MarshalAs(UnmanagedType.Bool)] bool fEnterMode) + { + throw new NotImplementedException(); + } + + public void SetSite([In, MarshalAs(UnmanagedType.IUnknown)] object pUnkSite) + { + throw new NotImplementedException(); + } + + public void GetSite(ref Guid riid, [MarshalAs(UnmanagedType.IUnknown)] out object ppvSite) + { + throw new NotImplementedException(); + } + } +} diff --git a/ProofOfConcept/Monaco/monacoPreview/Settings.cs b/ProofOfConcept/Monaco/monacoPreview/Settings.cs index ea005419d..595cad96c 100644 --- a/ProofOfConcept/Monaco/monacoPreview/Settings.cs +++ b/ProofOfConcept/Monaco/monacoPreview/Settings.cs @@ -18,6 +18,9 @@ namespace monacoPreview // URL to the page public string baseURL = "file://" + System.AppContext.BaseDirectory + "/index.html"; + + // Activate compatibility mode + public bool compatibility = true; public String GetTheme(ThemeListener.ThemeModes t) diff --git a/ProofOfConcept/Monaco/monacoPreview/addHandler.xaml b/ProofOfConcept/Monaco/monacoPreview/addHandler.xaml deleted file mode 100644 index 8cdb6cd4f..000000000 --- a/ProofOfConcept/Monaco/monacoPreview/addHandler.xaml +++ /dev/null @@ -1,15 +0,0 @@ - - - -