none
WebBrowser in WPF

    Question

  • Hi all, as I've mentioned in my past thread (http://social.msdn.microsoft.com/Forums/en/wpf/thread/fadc80f1-dd80-43bf-b2e6-c673b4c13ba7), I've embedded a WebBrowser object in my application to be able to play videos with WMDRM and PlayReady...

    <WebBrowser Margin="460,0,460,330" x:Name="myBrowser" x:Uid="myBrowser" Width="1000" Height="750"/>
    

    but now I have a problem.... I want to put another WPF object over the WebBrowser. So i use the SetWindowPos function

        [DllImport("user32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int x, int y, int cx, int cy, uint uFlags);
    
        static readonly IntPtr HWND_TOPMOST = new IntPtr(-1);
        static readonly IntPtr HWND_NOTOPMOST = new IntPtr(-2);
        static readonly IntPtr HWND_TOP = new IntPtr(0);
        static readonly IntPtr HWND_BOTTOM = new IntPtr(1);
    
        public const int SWP_ASYNCWINDOWPOS = 0x4000;
        public const int SWP_DEFERERASE = 0x2000;
        public const int SWP_DRAWFRAME = 0x0020;
        public const int SWP_FRAMECHANGED = 0x0020;
        public const int SWP_HIDEWINDOW = 0x0080;
        public const int SWP_NOACTIVATE = 0x0010;
        public const int SWP_NOCOPYBITS = 0x0100;
        public const int SWP_NOMOVE = 0x0002;
        public const int SWP_NOOWNERZORDER = 0x0200;
        public const int SWP_NOREDRAW = 0x0008;
        public const int SWP_NOREPOSITION = 0x0200;
        public const int SWP_NOSENDCHANGING = 0x0400;
        public const int SWP_NOSIZE = 0x0001;
        public const int SWP_NOZORDER = 0x0004;
        public const int SWP_SHOWWINDOW = 0x0040;
    
    //////////////////
    SetWindowPos(this.myBrowser.Handle, HWND_BOTTOM, 0, 0, 0, 0, 0);
    

    but nothing happens... my object (a custom object) stays behind the webbrowser... the SetWindowPos function returns true. What could it be?

    Thanks!

    Wednesday, March 09, 2011 12:59 PM

Answers

  • Hi Davide,

       This is a known limitation for WPF apps hosting other types of Hwnds.  The WPF layout system cannot composite over top of hosted Hwnds, so you get the behavior you are observing.    SetWindowPos is not going to help here.

       Depending on what your "custom object" is, you may be able to simulate the effect you want though using the WPF Popup control or a separate WPF Window.  Both of these controls, by virtue of being top-level Hwnds, will be able to render over top of your WebBrowser control.  It's also possible future releases of .NET will address this limitation.

    Hope this helps,

    Matt


    SDET : Deployment/Hosting
    Wednesday, March 09, 2011 9:32 PM
    Moderator

All replies

  • I don't understand why do you want to use Windows API to move WPF control? What is problem to use native WPF properties? WPF control is not a window, and I am not sure is that correct to use SetWindowPos here. Why don't use Margin property?
    Wednesday, March 09, 2011 1:07 PM
  • I don't want to move the control, but I want to place the custom object over the WebBrowser one. The ZIndex property does not work with WebBrowser
    Wednesday, March 09, 2011 1:11 PM
  • Ok, I see. And what if create ElementHost control and make it a child of WebBrowser; and place WPF object inside of this ElementHost?

    The problem is that WPF controls are not windows, so if you'll send WebBrowser to back of main window, it will not place it behind WPF controls that are actually images drawn in WPF window; WPF window is located behind web browser window, because web browser is its child. So you have to create a child window (child of you WPF window) and place web browser behind this window. One idea is to use ElementHost: you create WindowsFormsHost, and place ElementHost to this WindowsFormsHost; and in this ElementHost you place your WPF control. It is just idea.

    Wednesday, March 09, 2011 1:29 PM
  • My Custom object inside the ElementHost? Do you know where I can find an example? I've never seen these classes :)
    Wednesday, March 09, 2011 1:37 PM
  • Well, I don't know examples; however, it definitely may be solution, now I see how.

    1. You create user control (Windows Forms).

    2. You add web browser (Windows Forms) and ElementHost to this Windows Forms user control.

    3. You add your custom WPF control as child for ElementHost.

    4. You add this Windows Forms custom control (which has web browser and WPF element in front of it) to your WPF window with WindowsFormsHost.

    Details on WindowsFormsHost and ElementHost are available here: http://msdn.microsoft.com/en-us/library/ms751797.aspx

    Wednesday, March 09, 2011 2:22 PM
  • Sorry, but why should I use A windows form in my wpf project?
    Wednesday, March 09, 2011 2:36 PM
  • Well, possibly guys from Microsoft will advice anything better, I am not Microsoft guy I just .NET programmer.

    However, I think:

    1. WebBrowser is not native WPF control; WebBrowser WPF control is just "wrapper to wrapper": Windows Forms WebBrowser control is actually wrapper to ActiveX WebBrowser control, and WPF WebBrowser control is wrapper for WinForms WebBrowser control.

    2. So, even when you use WebBroser in WPF program and create it in XAML, you actually use implicit WindowsFormsHost, and this WindowsFormsHost uses Windows Forms version of WebBrowser. It is root of your problem that web browser actually ignores any WPF rules. It ignores ZIndex, as well as any WPF transforms, effects, etc.

    3. It is evident that there are no any native WPF way to show WPF control on top of WebBrowser; so, you have to use WPF and Windows Forms Interoperation.

    Wednesday, March 09, 2011 2:46 PM
  • Hi Davide,

       This is a known limitation for WPF apps hosting other types of Hwnds.  The WPF layout system cannot composite over top of hosted Hwnds, so you get the behavior you are observing.    SetWindowPos is not going to help here.

       Depending on what your "custom object" is, you may be able to simulate the effect you want though using the WPF Popup control or a separate WPF Window.  Both of these controls, by virtue of being top-level Hwnds, will be able to render over top of your WebBrowser control.  It's also possible future releases of .NET will address this limitation.

    Hope this helps,

    Matt


    SDET : Deployment/Hosting
    Wednesday, March 09, 2011 9:32 PM
    Moderator
  • My custom object is a canvas, I'll try starting from a Window...
    Thursday, March 10, 2011 7:56 AM
  • I  tried to add a PopUp class, then setting IsOpen to true (the popup contains my custom object), but the popup doesn't appears; debugging the code, the property "IsOpen" is false
    Thursday, March 10, 2011 8:42 AM
  • Hi Davide81,

    Have you tried StaysOpen property?

    If your issue persists, could you share more information about your popup?

    On the other hand, this thread topic is:

    -->          WebBrowser in WPF

    and if you want to get the answer of popup, I think you could try to start a new topic(thread), then more people could jumping in and discuss the "Popup doesn't appears" issue with you.

    I think you could get better and quicker responses.

     

    Best regards,


    Sheldon _Xiao[MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Friday, March 11, 2011 6:05 AM
    Moderator
  • Sheldon is correct, you shouldn't need more than IsOpen and StaysOpen to show and keep the popup.  Not sure what you're hitting there.
    SDET : Deployment/Hosting
    Monday, March 14, 2011 5:18 PM
    Moderator