/// <summary> /// Show the browser (called after previous minimised) /// </summary> internal virtual void ShowInternal() { if (BrowserHwnd != IntPtr.Zero) { NativeMethodWrapper.SetWindowPosition(BrowserHwnd, 0, 0, Width, Height); } }
private void CreateBrowser() { browserCreated = true; if (((IWebBrowserInternal)this).HasParent == false) { //If we are Recreating our handle we will have re-parented our //browser to parkingControl. We'll assign the browser to our newly //created handle now. if ((RecreatingHandle || ParkControlOnHandleDestroyed) && IsBrowserInitialized && browser != null) { var host = this.GetBrowserHost(); var hwnd = host.GetWindowHandle(); NativeMethodWrapper.SetWindowParent(hwnd, Handle); parkingControl.Dispose(); parkingControl = null; } else { var windowInfo = CreateBrowserWindowInfo(Handle); initialAddressLoaded = !string.IsNullOrEmpty(Address); managedCefBrowserAdapter.CreateBrowser(windowInfo, browserSettings as BrowserSettings, requestContext as RequestContext, Address); } } }
internal void CreateBrowser(IntPtr parent) { if (((IWebBrowserInternal)this).HasParent == false) { if (IsBrowserInitialized == false || _browser == null) { _requestContext = Cef.GetGlobalRequestContext(); var windowInfo = CreateBrowserWindowInfo(parent); //We actually check if WS_EX_NOACTIVATE was set for instances //the user has override CreateBrowserWindowInfo and not called base.CreateBrowserWindowInfo _removeExNoActivateStyle = ((WS_EX)windowInfo.ExStyle & WS_EX.NOACTIVATE) == WS_EX.NOACTIVATE; _initialAddressLoaded = !string.IsNullOrEmpty(_config?.StartUrl); Address = _config?.StartUrl; _browserSettings.DefaultEncoding = "UTF-8"; _browserSettings.FileAccessFromFileUrls = CefState.Enabled; _browserSettings.UniversalAccessFromFileUrls = CefState.Enabled; _browserSettings.WebSecurity = CefState.Disabled; _managedCefBrowserAdapter.CreateBrowser(windowInfo, _browserSettings as BrowserSettings, _requestContext as RequestContext, Address); } else { // If the browser already exists we'll reparent it to the new Handle var browserHandle = _browser.GetHost().GetWindowHandle(); NativeMethodWrapper.SetWindowParent(browserHandle, parent); } Logger.Instance.Log.LogInformation("Cef browser successfully created."); } }
void IRenderHandler.OnPaint(bool isPopup, Rect dirtyRect, IntPtr buffer, int width, int height, Image image) { var writeableBitmap = image.Source as WriteableBitmap; if (writeableBitmap == null || writeableBitmap.PixelWidth != width || writeableBitmap.PixelHeight != height) { image.Source = writeableBitmap = new WriteableBitmap(width, height, dpiX, dpiY, AbstractRenderHandler.PixelFormat, null); } if (writeableBitmap != null) { writeableBitmap.Lock(); NativeMethodWrapper.MemoryCopy(writeableBitmap.BackBuffer, buffer, writeableBitmap.BackBufferStride * writeableBitmap.PixelHeight); if (invalidateDirtyRect) { writeableBitmap.AddDirtyRect(new Int32Rect(dirtyRect.X, dirtyRect.Y, dirtyRect.Width, dirtyRect.Height)); } else { writeableBitmap.AddDirtyRect(new Int32Rect(0, 0, writeableBitmap.PixelWidth, writeableBitmap.PixelHeight)); } writeableBitmap.Unlock(); } }
private void CreateBrowser() { browserCreated = true; if (((IWebBrowserInternal)this).HasParent == false) { if (IsBrowserInitialized == false || browser == null) { var windowInfo = new WindowInfo(); windowInfo.SetAsChild(Handle); managedCefBrowserAdapter.CreateBrowser(windowInfo, browserSettings, (RequestContext)RequestContext, Address); if (browserSettings != null) { browserSettings.Dispose(); browserSettings = null; } } else { //If the browser already exists we'll reparent it to the new Handle var browserHandle = browser.GetHost().GetWindowHandle(); NativeMethodWrapper.SetWindowParent(browserHandle, Handle); } } }
private void CreateBrowser() { browserCreated = true; if (((IWebBrowserInternal)this).HasParent == false) { //If we are Recreating our handle we will have re-parented our //browser to parkingControl. We'll assign the browser to our newly //created handle now. if ((RecreatingHandle || ParkControlOnHandleDestroyed) && IsBrowserInitialized && browser != null) { var host = this.GetBrowserHost(); var hwnd = host.GetWindowHandle(); NativeMethodWrapper.SetWindowParent(hwnd, Handle); parkingControl.Dispose(); parkingControl = null; } else { var windowInfo = CreateBrowserWindowInfo(Handle); //We actually check if WS_EX_NOACTIVATE was set for instances //the user has override CreateBrowserWindowInfo and not called base.CreateBrowserWindowInfo removeExNoActivateStyle = (windowInfo.ExStyle & WS_EX_NOACTIVATE) == WS_EX_NOACTIVATE; initialAddressLoaded = !string.IsNullOrEmpty(Address); managedCefBrowserAdapter.CreateBrowser(windowInfo, browserSettings as BrowserSettings, requestContext as RequestContext, Address); } } }
/// <summary> /// When minimized set the browser window size to 0x0 to reduce resource usage. /// https://github.com/chromiumembedded/cef/blob/c7701b8a6168f105f2c2d6b239ce3958da3e3f13/tests/cefclient/browser/browser_window_std_win.cc#L87 /// </summary> internal virtual void HideInternal() { if (BrowserHwnd != IntPtr.Zero) { NativeMethodWrapper.SetWindowPosition(BrowserHwnd, 0, 0, 0, 0); } }
/// <summary> /// Sets the loading state change. /// </summary> /// <param name="args">The <see cref="LoadingStateChangedEventArgs"/> instance containing the event data.</param> void IWebBrowserInternal.SetLoadingStateChange(LoadingStateChangedEventArgs args) { CanGoBack = args.CanGoBack; CanGoForward = args.CanGoForward; IsLoading = args.IsLoading; if (removeExNoActivateStyle && browser != null) { removeExNoActivateStyle = false; var host = this.GetBrowserHost(); var hwnd = host.GetWindowHandle(); //Remove the WS_EX_NOACTIVATE style so that future mouse clicks inside the //browser correctly activate and focus the browser. //https://github.com/chromiumembedded/cef/blob/9df4a54308a88fd80c5774d91c62da35afb5fd1b/tests/cefclient/browser/root_window_win.cc#L1088 NativeMethodWrapper.RemoveExNoActivateStyle(hwnd); } var handler = LoadingStateChanged; if (handler != null) { handler(this, args); } }
private void CreateOrUpdateBitmap(bool isPopup, IntPtr buffer, Rect dirtyRect, int width, int height, Image image, ref Size currentSize, ref MemoryMappedFile mappedFile, ref MemoryMappedViewAccessor viewAccessor) { bool createNewBitmap = false; if (image.Dispatcher.HasShutdownStarted) { return; } lock (lockObject) { int pixels = width * height; int numberOfBytes = pixels * BytesPerPixel; createNewBitmap = mappedFile == null || currentSize.Height != height || currentSize.Width != width; if (createNewBitmap) { ReleaseMemoryMappedView(ref mappedFile, ref viewAccessor); mappedFile = MemoryMappedFile.CreateNew(null, numberOfBytes, MemoryMappedFileAccess.ReadWrite); viewAccessor = mappedFile.CreateViewAccessor(); currentSize.Height = height; currentSize.Width = width; } NativeMethodWrapper.CopyMemoryUsingHandle(viewAccessor.SafeMemoryMappedViewHandle.DangerousGetHandle(), buffer, numberOfBytes); } image.Dispatcher.BeginInvoke((Action)(() => { lock (lockObject) { if (createNewBitmap) { if (image.Source != null) { image.Source = null; GC.Collect(1); } image.Source = new WriteableBitmap(width, height, DpiX, DpiY, PixelFormat, null); } var backBufferHandle = isPopup ? popupMemoryMappedFile.SafeMemoryMappedFileHandle : viewMemoryMappedFile.SafeMemoryMappedFileHandle; var stride = width * BytesPerPixel; var noOfBytes = stride * height; // Update the dirty region var sourceRect = new Int32Rect(dirtyRect.X, dirtyRect.Y, dirtyRect.Width, dirtyRect.Height); var bitmap = (WriteableBitmap)image.Source; bitmap.WritePixels(sourceRect, backBufferHandle.DangerousGetHandle(), noOfBytes, stride, dirtyRect.X, dirtyRect.Y); } }), DispatcherPriority.Render); }
private void ParentControlSizeChanged(object sender, EventArgs e) { var bounds = parentControl.Bounds; if (browserHandle != IntPtr.Zero) { NativeMethodWrapper.SetWindowPosition(browserHandle, bounds.X, bounds.Y, bounds.Width, bounds.Height); } }
private void OnHandleDestroyedInternal() { //When the Control is being Recreated then we'll park //the browser (set to a temp parent) and assign to //our new handle when it's ready. if (RecreatingHandle || ParkControlOnHandleDestroyed) { parkingControl = new Control(); parkingControl.CreateControl(); var host = this.GetBrowserHost(); var hwnd = host.GetWindowHandle(); NativeMethodWrapper.SetWindowParent(hwnd, parkingControl.Handle); } }
protected override void OnHandleDestroyed(EventArgs e) { //When the Control is being Recreated then we'll park //the browser (set to a temp parent) and assign to //our new handle when it's ready. if (RecreatingHandle) { parkingControl = new Control(); parkingControl.CreateControl(); var host = this.GetBrowserHost(); var hwnd = host.GetWindowHandle(); NativeMethodWrapper.SetWindowParent(hwnd, parkingControl.Handle); } base.OnHandleDestroyed(e); }
private void CreateBrowser() { browserCreated = true; if (((IWebBrowserInternal)this).HasParent == false) { if (IsBrowserInitialized == false || browser == null) { //TODO: Revert temp workaround for default url not loading managedCefBrowserAdapter.CreateBrowser(BrowserSettings, (RequestContext)RequestContext, Handle, null); } else { //If the browser already exists we'll reparent it to the new Handle var browserHandle = browser.GetHost().GetWindowHandle(); NativeMethodWrapper.SetWindowParent(browserHandle, Handle); } } }
public static bool TryLoadCursor(CursorType cursorType, out IntPtr cursor) { cursor = IntPtr.Zero; try { if (EmbeddedCursors.TryGetValue(cursorType, out int key)) { cursor = NativeMethodWrapper.LoadCursorFromLibCef(key); return(cursor != IntPtr.Zero); } } catch (Exception) { } return(false); }
internal void OnPaint(Rect dirtyRect, IntPtr sourceBuffer, int width, int height, Image image) { ImageSize = (width * height) * AbstractRenderHandler.BytesPerPixel; if (BufferSize < ImageSize) { Marshal.FreeHGlobal(Buffer); Buffer = Marshal.AllocHGlobal(ImageSize); BufferSize = ImageSize; } Width = width; Height = height; DirtyRect = dirtyRect; NativeMethodWrapper.MemoryCopy(Buffer, sourceBuffer, ImageSize); Image = image; IsDirty = true; }
internal void UpdateBuffer(Rect dirtyRect, IntPtr sourceBuffer, int width, int height, Image image) { imageSize = (width * height) * AbstractRenderHandler.BytesPerPixel; if (bufferSize < imageSize) { Marshal.FreeHGlobal(buffer); buffer = Marshal.AllocHGlobal(imageSize); bufferSize = imageSize; } this.width = width; this.height = height; this.dirtyRect = dirtyRect; NativeMethodWrapper.MemoryCopy(buffer, sourceBuffer, imageSize); this.image = image; IsDirty = true; }
private void OnHandleDestroyedInternal() { //When the Control is being Recreated then we'll park //the browser (set to a temp parent) and assign to //our new handle when it's ready. if (RecreatingHandle || ParkControlOnHandleDestroyed) { parkingControl = new Control(); parkingControl.CreateControl(); var host = this.GetBrowserHost(); // Possible host is null // https://github.com/cefsharp/CefSharp/issues/3931 if (host != null) { var hwnd = host.GetWindowHandle(); NativeMethodWrapper.SetWindowParent(hwnd, parkingControl.Handle); } } }
private void CreateBrowser() { browserCreated = true; if (((IWebBrowserInternal)this).HasParent == false) { if (IsBrowserInitialized == false || browser == null) { var windowInfo = CreateBrowserWindowInfo(Handle); initialAddressLoaded = !string.IsNullOrEmpty(Address); managedCefBrowserAdapter.CreateBrowser(windowInfo, browserSettings as BrowserSettings, requestContext as RequestContext, Address); browserSettings = null; } else { //If the browser already exists we'll reparent it to the new Handle var browserHandle = browser.GetHost().GetWindowHandle(); NativeMethodWrapper.SetWindowParent(browserHandle, Handle); } } }
protected override void CreateOrUpdateBitmap(bool isPopup, Rect dirtyRect, IntPtr buffer, int width, int height, Image image, ref Size currentSize, ref MemoryMappedFile mappedFile, ref MemoryMappedViewAccessor viewAccessor) { bool createNewBitmap = false; lock (lockObject) { int pixels = width * height; int numberOfBytes = pixels * BytesPerPixel; createNewBitmap = mappedFile == null || currentSize.Height != height || currentSize.Width != width; if (createNewBitmap) { //If the MemoryMappedFile is smaller than we need then create a larger one //If it's larger then we need then rather than going through the costly expense of //allocating a new one we'll just use the old one and only access the number of bytes we require. if (viewAccessor == null || viewAccessor.Capacity < numberOfBytes) { ReleaseMemoryMappedView(ref mappedFile, ref viewAccessor); mappedFile = MemoryMappedFile.CreateNew(null, numberOfBytes, MemoryMappedFileAccess.ReadWrite); viewAccessor = mappedFile.CreateViewAccessor(); } currentSize.Height = height; currentSize.Width = width; } NativeMethodWrapper.MemoryCopy(viewAccessor.SafeMemoryMappedViewHandle.DangerousGetHandle(), buffer, numberOfBytes); //Take a reference to the sourceBuffer that's used to update our WritableBitmap, //once we're on the UI thread we need to check if it's still valid var sourceBuffer = viewAccessor.SafeMemoryMappedViewHandle; image.Dispatcher.BeginInvoke((Action)(() => { lock (lockObject) { if (sourceBuffer.IsClosed || sourceBuffer.IsInvalid) { return; } if (createNewBitmap) { if (image.Source != null) { image.Source = null; GC.Collect(1); } image.Source = new WriteableBitmap(width, height, dpiX, dpiY, PixelFormat, null); } var stride = width * BytesPerPixel; var noOfBytes = stride * height; var bitmap = (WriteableBitmap)image.Source; //By default we'll only update the dirty rect, for those that run into a MILERR_WIN32ERROR Exception (#2035) //it's desirably to either upgrade to a newer .Net version (only client runtime needs to be installed, not compiled //against a newer version. Or invalidate the whole bitmap if (invalidateDirtyRect) { // Update the dirty region var sourceRect = new Int32Rect(dirtyRect.X, dirtyRect.Y, dirtyRect.Width, dirtyRect.Height); bitmap.Lock(); bitmap.WritePixels(sourceRect, sourceBuffer.DangerousGetHandle(), noOfBytes, stride, dirtyRect.X, dirtyRect.Y); bitmap.Unlock(); } else { // Update whole bitmap var sourceRect = new Int32Rect(0, 0, width, height); bitmap.Lock(); bitmap.WritePixels(sourceRect, sourceBuffer.DangerousGetHandle(), noOfBytes, stride); bitmap.Unlock(); } } }), dispatcherPriority); } }
protected override void CreateOrUpdateBitmap(bool isPopup, Rect dirtyRect, IntPtr buffer, int width, int height, Image image, ref Size currentSize, ref MemoryMappedFile mappedFile, ref MemoryMappedViewAccessor viewAccessor) { var createNewBitmap = false; lock (lockObject) { int pixels = width * height; int numberOfBytes = pixels * BytesPerPixel; createNewBitmap = mappedFile == null || currentSize.Height != height || currentSize.Width != width; if (createNewBitmap) { ReleaseMemoryMappedView(ref mappedFile, ref viewAccessor); mappedFile = MemoryMappedFile.CreateNew(null, numberOfBytes, MemoryMappedFileAccess.ReadWrite); viewAccessor = mappedFile.CreateViewAccessor(); currentSize.Height = height; currentSize.Width = width; } NativeMethodWrapper.MemoryCopy(viewAccessor.SafeMemoryMappedViewHandle.DangerousGetHandle(), buffer, numberOfBytes); //Take a reference to the backBufferHandle, once we're on the UI thread we need to check if it's still valid var backBufferHandle = mappedFile.SafeMemoryMappedFileHandle; //Invoke on the WPF UI Thread image.Dispatcher.BeginInvoke((Action)(() => { lock (lockObject) { if (backBufferHandle.IsClosed || backBufferHandle.IsInvalid) { return; } if (createNewBitmap) { if (image.Source != null) { image.Source = null; //TODO: Is this still required in newer versions of .Net? GC.Collect(1); } var stride = width * BytesPerPixel; var bitmap = (InteropBitmap)Imaging.CreateBitmapSourceFromMemorySection(backBufferHandle.DangerousGetHandle(), width, height, PixelFormat, stride, 0); image.Source = bitmap; } else if (image.Source != null) { var sourceRect = new Int32Rect(dirtyRect.X, dirtyRect.Y, dirtyRect.Width, dirtyRect.Height); var bitmap = (InteropBitmap)image.Source; bitmap.Invalidate(sourceRect); } } }), dispatcherPriority); } }
private void ResizeBrowserInternal(int width, int height) { NativeMethodWrapper.SetWindowPosition(BrowserHwnd, 0, 0, width, height); }
protected override void CreateOrUpdateBitmap(bool isPopup, Rect dirtyRect, IntPtr buffer, int width, int height, Image image, ref Size currentSize, ref MemoryMappedFile mappedFile, ref MemoryMappedViewAccessor viewAccessor) { bool createNewBitmap = false; lock (lockObject) { int pixels = width * height; int numberOfBytes = pixels * BytesPerPixel; createNewBitmap = mappedFile == null || currentSize.Height != height || currentSize.Width != width; if (createNewBitmap) { //If the MemoryMappedFile is smaller than we need then create a larger one //If it's larger then we need then rather than going through the costly expense of //allocating a new one we'll just use the old one and only access the number of bytes we require. if (viewAccessor == null || viewAccessor.Capacity < numberOfBytes) { ReleaseMemoryMappedView(ref mappedFile, ref viewAccessor); mappedFile = MemoryMappedFile.CreateNew(null, numberOfBytes, MemoryMappedFileAccess.ReadWrite); viewAccessor = mappedFile.CreateViewAccessor(); } currentSize.Height = height; currentSize.Width = width; } NativeMethodWrapper.MemoryCopy(viewAccessor.SafeMemoryMappedViewHandle.DangerousGetHandle(), buffer, numberOfBytes); //Take a reference to the sourceBuffer that's used to update our WritableBitmap, //once we're on the UI thread we need to check if it's still valid var sourceBuffer = viewAccessor.SafeMemoryMappedViewHandle; image.Dispatcher.BeginInvoke((Action)(() => { lock (lockObject) { if (sourceBuffer.IsClosed || sourceBuffer.IsInvalid) { return; } var size = isPopup ? popupSize : viewSize; //If OnPaint is called multiple times before //our BeginInvoke call we check the size matches our most recent //update, the buffer has already been overriden (frame is dropped effectively) //so we ignore this call //https://github.com/cefsharp/CefSharp/issues/3114 if (size.Width != width || size.Height != height) { return; } if (createNewBitmap) { if (image.Source != null) { image.Source = null; GC.Collect(1); } image.Source = new WriteableBitmap(width, height, dpiX, dpiY, PixelFormat, null); } var stride = width * BytesPerPixel; var noOfBytes = stride * height; var bitmap = (WriteableBitmap)image.Source; //When agressively resizing the ChromiumWebBrowser sometimes //we can end up with our buffer size not matching our bitmap size //Just ignore these frames as the rendering should eventually catch up //(CEF can generate multiple frames before WPF has performed a render cycle) //https://github.com/cefsharp/CefSharp/issues/3474 if (width > bitmap.PixelWidth || height > bitmap.PixelHeight) { return; } //By default we'll only update the dirty rect, for those that run into a MILERR_WIN32ERROR Exception (#2035) //it's desirably to either upgrade to a newer .Net version (only client runtime needs to be installed, not compiled //against a newer version. Or invalidate the whole bitmap if (invalidateDirtyRect) { // Update the dirty region var sourceRect = new Int32Rect(dirtyRect.X, dirtyRect.Y, dirtyRect.Width, dirtyRect.Height); bitmap.Lock(); bitmap.WritePixels(sourceRect, sourceBuffer.DangerousGetHandle(), noOfBytes, stride, dirtyRect.X, dirtyRect.Y); bitmap.Unlock(); } else { // Update whole bitmap var sourceRect = new Int32Rect(0, 0, width, height); bitmap.Lock(); bitmap.WritePixels(sourceRect, sourceBuffer.DangerousGetHandle(), noOfBytes, stride); bitmap.Unlock(); } } }), dispatcherPriority); } }