/// <summary> /// Initializes a new instance of the <see cref="Window"/> class. /// </summary> /// <param name="title">The title of the window.</param> /// <param name="url">The URL of the window.</param> /// <param name="width">The width of the window.</param> /// <param name="height">The height of the window.</param> /// <param name="resizable">Indicates if the window should be resizable.</param> public Window(string title, string url, int width, int height, bool resizable) { NativeMethods.Callback callback = Callback; gcCallback = GCHandle.Alloc(callback); ptr = NativeMethods.WebviewAlloc(title, url, width, height, resizable ? 1 : 0, 1, callback); this.title = title; JavaScript = new JavaScript(ptr); Document = new Document(JavaScript); }
void Work(string qmlText) { // The Qt Declarative parser ignores CR's. However, the Visual Studio editor does not. // To ensure that offsets are compatible, CR's are replaced with spaces. string qmlTextNormalized = qmlText.Replace('\r', ' '); var qmlTextData = Encoding.UTF8.GetBytes(qmlTextNormalized); qmlTextPtr = Marshal.AllocHGlobal(qmlTextData.Length); Marshal.Copy(qmlTextData, 0, qmlTextPtr, qmlTextData.Length); IntPtr tokensPtr = IntPtr.Zero; int tokensLength = 0; NativeMethods.GetTokens(qmlTextPtr, qmlTextData.Length, ref tokensPtr, ref tokensLength); if (tokensPtr != IntPtr.Zero) { var tokensData = new byte[tokensLength]; Marshal.Copy(tokensPtr, tokensData, 0, tokensLength); using (var rdr = new BinaryReader(new MemoryStream(tokensData))) { while (rdr.BaseStream.Position + (3 * sizeof(int)) <= tokensLength) { int kind = rdr.ReadInt32(); int offset = rdr.ReadInt32(); int length = rdr.ReadInt32(); tokens.Add(Token.Create((TokenKind)kind, offset, length)); } } NativeMethods.FreeTokens(tokensPtr); } bool parsedCorrectly = false; IntPtr diagnosticMessagesPtr = IntPtr.Zero; int diagnosticMessagesLength = 0; IntPtr commentsPtr = IntPtr.Zero; int commentsLength = 0; NativeMethods.Parse(qmlTextPtr, qmlTextData.Length, ref qmlParserPtr, ref parsedCorrectly, ref diagnosticMessagesPtr, ref diagnosticMessagesLength, ref commentsPtr, ref commentsLength); ParsedCorrectly = parsedCorrectly; if (diagnosticMessagesPtr != IntPtr.Zero) { var diagnosticMessagesData = new byte[diagnosticMessagesLength]; Marshal.Copy( diagnosticMessagesPtr, diagnosticMessagesData, 0, diagnosticMessagesLength); FirstErrorOffset = qmlTextNormalized.Length + 1; using (var rdr = new BinaryReader(new MemoryStream(diagnosticMessagesData))) { while (rdr.BaseStream.Position + (3 * sizeof(int)) <= diagnosticMessagesLength) { var kind = (DiagnosticMessageKind)rdr.ReadInt32(); int offset = rdr.ReadInt32(); int length = rdr.ReadInt32(); diagnosticMessages.Add(new DiagnosticMessage(kind, offset, length)); if (kind == DiagnosticMessageKind.Error && offset < FirstErrorOffset) { FirstErrorOffset = offset; } } } NativeMethods.FreeDiagnosticMessages(diagnosticMessagesPtr); } if (commentsPtr != IntPtr.Zero) { var commentsData = new byte[commentsLength]; Marshal.Copy(commentsPtr, commentsData, 0, commentsLength); using (var rdr = new BinaryReader(new MemoryStream(commentsData))) { while (rdr.BaseStream.Position + (2 * sizeof(int)) <= commentsLength) { int offset = rdr.ReadInt32(); int length = rdr.ReadInt32(); tokens.Add(Token.Create(TokenKind.T_COMMENT, offset, length)); } } NativeMethods.FreeComments(commentsPtr); } var astVisitor = NativeMethods.GetAstVisitor(); var callback = new NativeMethods.Callback(VisitorCallback); foreach (var callbackFilter in CallbackFilters) { NativeMethods.SetAstVisitorCallback(astVisitor, (int)callbackFilter, callback); } NativeMethods.AcceptAstVisitor(qmlParserPtr, IntPtr.Zero, astVisitor); while (pendingDereferences.Count > 0) { var deref = pendingDereferences.First(); NativeMethods.AcceptAstVisitor(qmlParserPtr, deref.Key, astVisitor); pendingDereferences.Remove(deref.Key); } GC.KeepAlive(callback); NativeMethods.FreeAstVisitor(astVisitor); }