Beispiel #1
0
    def __init__(self, form, window, alert):
        self.pywebview_window = window
        self.web_browser = WebBrowserEx()
        self.web_browser.Dock = WinForms.DockStyle.Fill
        self.web_browser.ScriptErrorsSuppressed = not _debug
        self.web_browser.IsWebBrowserContextMenuEnabled = _debug
        self.web_browser.WebBrowserShortcutsEnabled = False
        self.web_browser.DpiAware = True
        MSHTML.alert = alert

        user_agent = _user_agent or settings.get('user_agent')
        if user_agent:
            self.web_browser.ChangeUserAgent(user_agent)

        self.web_browser.ScriptErrorsSuppressed = not _debug
        self.web_browser.IsWebBrowserContextMenuEnabled = _debug

        self.js_result_semaphore = Semaphore(0)
        self.js_bridge = MSHTML.JSBridge()
        self.js_bridge.window = window

        self.web_browser.ObjectForScripting = self.js_bridge

        # HACK. Hiding the WebBrowser is needed in order to show a non-default background color. Tweaking the Visible property
        # results in showing a non-responsive control, until it is loaded fully. To avoid this, we need to disable this behaviour
        # for the default background color.
        if window.background_color != '#FFFFFF':
            self.web_browser.Visible = False
            self.first_load = True
        else:
            self.first_load = False

        self.cancel_back = False
        self.web_browser.PreviewKeyDown += self.on_preview_keydown
        self.web_browser.Navigating += self.on_navigating
        self.web_browser.NewWindow3 += self.on_new_window
        self.web_browser.DownloadComplete += self.on_download_complete
        self.web_browser.DocumentCompleted += self.on_document_completed

        if window.real_url:
            self.web_browser.Navigate(window.real_url)
        elif window.html:
            self.web_browser.DocumentText = window.html
        else:
            self.web_browser.DocumentText = default_html

        self.form = form
        form.Controls.Add(self.web_browser)
Beispiel #2
0
        def _create_mshtml_browser(self, url, js_api, debug):
            self.web_browser = WebBrowserEx()
            self.web_browser.Dock = WinForms.DockStyle.Fill
            self.web_browser.ScriptErrorsSuppressed = not debug
            self.web_browser.IsWebBrowserContextMenuEnabled = debug
            self.web_browser.WebBrowserShortcutsEnabled = False
            self.web_browser.DpiAware = True

            self.web_browser.ScriptErrorsSuppressed = not debug
            self.web_browser.IsWebBrowserContextMenuEnabled = debug

            self.js_result_semaphore = Semaphore(0)
            self.js_bridge = BrowserView.JSBridge()

            if js_api:
                self.js_bridge.api = js_api
                self.js_bridge.parent_uid = self.uid

            self.web_browser.ObjectForScripting = self.js_bridge

            # HACK. Hiding the WebBrowser is needed in order to show a non-default background color. Tweaking the Visible property
            # results in showing a non-responsive control, until it is loaded fully. To avoid this, we need to disable this behaviour
            # for the default background color.
            if self.background_color != '#FFFFFF':
                self.web_browser.Visible = False
                self.first_load = True
            else:
                self.first_load = False

            self.cancel_back = False
            self.web_browser.PreviewKeyDown += self.on_preview_keydown
            self.web_browser.Navigating += self.on_navigating
            self.web_browser.NewWindow3 += self.on_new_window
            self.web_browser.DownloadComplete += self.on_download_complete
            self.web_browser.DocumentCompleted += self.on_document_completed

            if url:
                self.web_browser.Navigate(url)
            else:
                self.web_browser.DocumentText = default_html

            self.Controls.Add(self.web_browser)
Beispiel #3
0
class MSHTML:
    class JSBridge(IWebBrowserInterop):
        __namespace__ = 'MSHTML.JSBridge'
        window = None

        def call(self, func_name, param, value_id):
            return js_bridge_call(self.window, func_name, json.loads(param),
                                  value_id)

        def alert(self, message):
            BrowserView.alert(message)

        def console(self, message):
            print(message)

    def __init__(self, form, window):
        self.pywebview_window = window
        self.web_browser = WebBrowserEx()
        self.web_browser.Dock = WinForms.DockStyle.Fill
        self.web_browser.ScriptErrorsSuppressed = not _debug
        self.web_browser.IsWebBrowserContextMenuEnabled = _debug
        self.web_browser.WebBrowserShortcutsEnabled = False
        self.web_browser.DpiAware = True

        user_agent = _user_agent or settings.get('user_agent')
        if user_agent:
            self.web_browser.ChangeUserAgent(user_agent)

        self.web_browser.ScriptErrorsSuppressed = not _debug
        self.web_browser.IsWebBrowserContextMenuEnabled = _debug

        self.js_result_semaphore = Semaphore(0)
        self.js_bridge = MSHTML.JSBridge()
        self.js_bridge.window = window

        self.web_browser.ObjectForScripting = self.js_bridge

        # HACK. Hiding the WebBrowser is needed in order to show a non-default background color. Tweaking the Visible property
        # results in showing a non-responsive control, until it is loaded fully. To avoid this, we need to disable this behaviour
        # for the default background color.
        if window.background_color != '#FFFFFF':
            self.web_browser.Visible = False
            self.first_load = True
        else:
            self.first_load = False

        self.cancel_back = False
        self.web_browser.PreviewKeyDown += self.on_preview_keydown
        self.web_browser.Navigating += self.on_navigating
        self.web_browser.NewWindow3 += self.on_new_window
        self.web_browser.DownloadComplete += self.on_download_complete
        self.web_browser.DocumentCompleted += self.on_document_completed

        if window.real_url:
            self.web_browser.Navigate(window.real_url)
        elif window.html:
            self.web_browser.DocumentText = window.html
        else:
            self.web_browser.DocumentText = default_html

        self.form = form
        form.Controls.Add(self.web_browser)

    def evaluate_js(self, script):
        result = self.web_browser.Document.InvokeScript('eval', (script, ))
        #self.js_result = None if result is None or result is 'null' else json.loads(result)
        self.js_result = None if result is None or result == 'null' else json.loads(
            result)  ##
        self.js_result_semaphore.release()

    def load_html(self, content, base_uri):
        self.web_browser.DocumentText = inject_base_uri(content, base_uri)
        self.pywebview_window.loaded.clear()

    def load_url(self, url):
        self.web_browser.Navigate(url)

    def on_preview_keydown(self, sender, args):
        if args.KeyCode == WinForms.Keys.Back:
            self.cancel_back = True
        elif args.KeyCode == WinForms.Keys.Delete:
            self.web_browser.Document.ExecCommand('Delete', False, None)
        elif args.Modifiers == WinForms.Keys.Control and args.KeyCode == WinForms.Keys.C:
            self.web_browser.Document.ExecCommand('Copy', False, None)
        elif args.Modifiers == WinForms.Keys.Control and args.KeyCode == WinForms.Keys.X:
            self.web_browser.Document.ExecCommand('Cut', False, None)
        elif args.Modifiers == WinForms.Keys.Control and args.KeyCode == WinForms.Keys.V:
            self.web_browser.Document.ExecCommand('Paste', False, None)
        elif args.Modifiers == WinForms.Keys.Control and args.KeyCode == WinForms.Keys.Z:
            self.web_browser.Document.ExecCommand('Undo', False, None)
        elif args.Modifiers == WinForms.Keys.Control and args.KeyCode == WinForms.Keys.A:
            self.web_browser.Document.ExecCommand('selectAll', False, None)

    def on_new_window(self, sender, args):
        args.Cancel = True
        webbrowser.open(args.Url)

    def on_download_complete(self, sender, args):
        pass

    def on_navigating(self, sender, args):
        if self.cancel_back:
            args.Cancel = True
            self.cancel_back = False

    def on_document_completed(self, sender, args):
        document = self.web_browser.Document
        document.InvokeScript('eval', (alert.src, ))

        if _debug:
            document.InvokeScript('eval', (
                'window.console = { log: function(msg) { window.external.console(JSON.stringify(msg)) }}',
            ))

        if self.first_load:
            self.web_browser.Visible = True
            self.first_load = False

        self.url = None if args.Url.AbsoluteUri == 'about:blank' else str(
            args.Url.AbsoluteUri)

        document.InvokeScript(
            'eval', (parse_api_js(self.pywebview_window, 'mshtml'), ))

        if not self.pywebview_window.text_select:
            document.InvokeScript('eval', (disable_text_select, ))
        self.pywebview_window.loaded.set()

        if self.pywebview_window.easy_drag:
            document.MouseMove += self.on_mouse_move

    def on_mouse_move(self, sender, e):
        if e.MouseButtonsPressed == WinForms.MouseButtons.Left:
            WebBrowserEx.ReleaseCapture()
            windll.user32.SendMessageW(self.form.Handle.ToInt32(),
                                       WebBrowserEx.WM_NCLBUTTONDOWN,
                                       WebBrowserEx.HT_CAPTION, 6)
Beispiel #4
0
 def on_mouse_move(self, sender, e):
     if e.MouseButtonsPressed == WinForms.MouseButtons.Left:
         WebBrowserEx.ReleaseCapture()
         windll.user32.SendMessageW(self.form.Handle.ToInt32(),
                                    WebBrowserEx.WM_NCLBUTTONDOWN,
                                    WebBrowserEx.HT_CAPTION, 6)
Beispiel #5
0
        def __init__(self, uid, title, url, width, height, resizable,
                     fullscreen, min_size, confirm_quit, background_color,
                     debug, js_api, text_select, webview_ready):
            self.uid = uid
            self.Text = title
            self.ClientSize = Size(width, height)
            self.MinimumSize = Size(min_size[0], min_size[1])
            self.BackColor = ColorTranslator.FromHtml(background_color)

            self.AutoScaleDimensions = SizeF(96.0, 96.0)
            self.AutoScaleMode = WinForms.AutoScaleMode.Dpi

            if not resizable:
                self.FormBorderStyle = WinForms.FormBorderStyle.FixedSingle
                self.MaximizeBox = False

            # Application icon
            handle = windll.kernel32.GetModuleHandleW(None)
            icon_handle = windll.shell32.ExtractIconW(handle, sys.executable,
                                                      0)

            if icon_handle != 0:
                self.Icon = Icon.FromHandle(
                    IntPtr.op_Explicit(Int32(icon_handle))).Clone()

            windll.user32.DestroyIcon(icon_handle)

            self.webview_ready = webview_ready
            self.load_event = Event()

            self.web_browser = WebBrowserEx()
            self.web_browser.Dock = WinForms.DockStyle.Fill
            self.web_browser.ScriptErrorsSuppressed = not debug
            self.web_browser.IsWebBrowserContextMenuEnabled = debug
            self.web_browser.WebBrowserShortcutsEnabled = False
            self.web_browser.DpiAware = True

            self.web_browser.ScriptErrorsSuppressed = not debug
            self.web_browser.IsWebBrowserContextMenuEnabled = debug

            self.js_result_semaphore = Semaphore(0)
            self.js_bridge = BrowserView.JSBridge()
            self.js_bridge.parent_uid = uid
            self.web_browser.ObjectForScripting = self.js_bridge

            self.text_select = text_select

            if js_api:
                self.js_bridge.api = js_api

            # HACK. Hiding the WebBrowser is needed in order to show a non-default background color. Tweaking the Visible property
            # results in showing a non-responsive control, until it is loaded fully. To avoid this, we need to disable this behaviour
            # for the default background color.
            if background_color != '#FFFFFF':
                self.web_browser.Visible = False
                self.first_load = True
            else:
                self.first_load = False

            self.cancel_back = False
            self.web_browser.PreviewKeyDown += self.on_preview_keydown
            self.web_browser.Navigating += self.on_navigating
            self.web_browser.NewWindow3 += self.on_new_window
            self.web_browser.DownloadComplete += self.on_download_complete
            self.web_browser.DocumentCompleted += self.on_document_completed

            if url:
                self.web_browser.Navigate(url)
            else:
                self.web_browser.DocumentText = default_html

            self.url = url

            self.Controls.Add(self.web_browser)
            self.is_fullscreen = False
            self.Shown += self.on_shown
            self.FormClosed += self.on_close

            if confirm_quit:
                self.FormClosing += self.on_closing

            if fullscreen:
                self.toggle_fullscreen()
Beispiel #6
0
    class BrowserForm(WinForms.Form):
        def __init__(self, uid, title, url, width, height, resizable,
                     fullscreen, min_size, confirm_quit, background_color,
                     debug, js_api, text_select, webview_ready):
            self.uid = uid
            self.Text = title
            self.ClientSize = Size(width, height)
            self.MinimumSize = Size(min_size[0], min_size[1])
            self.BackColor = ColorTranslator.FromHtml(background_color)

            self.AutoScaleDimensions = SizeF(96.0, 96.0)
            self.AutoScaleMode = WinForms.AutoScaleMode.Dpi

            if not resizable:
                self.FormBorderStyle = WinForms.FormBorderStyle.FixedSingle
                self.MaximizeBox = False

            # Application icon
            handle = windll.kernel32.GetModuleHandleW(None)
            icon_handle = windll.shell32.ExtractIconW(handle, sys.executable,
                                                      0)

            if icon_handle != 0:
                self.Icon = Icon.FromHandle(
                    IntPtr.op_Explicit(Int32(icon_handle))).Clone()

            windll.user32.DestroyIcon(icon_handle)

            self.webview_ready = webview_ready
            self.load_event = Event()

            self.web_browser = WebBrowserEx()
            self.web_browser.Dock = WinForms.DockStyle.Fill
            self.web_browser.ScriptErrorsSuppressed = not debug
            self.web_browser.IsWebBrowserContextMenuEnabled = debug
            self.web_browser.WebBrowserShortcutsEnabled = False
            self.web_browser.DpiAware = True

            self.web_browser.ScriptErrorsSuppressed = not debug
            self.web_browser.IsWebBrowserContextMenuEnabled = debug

            self.js_result_semaphore = Semaphore(0)
            self.js_bridge = BrowserView.JSBridge()
            self.js_bridge.parent_uid = uid
            self.web_browser.ObjectForScripting = self.js_bridge

            self.text_select = text_select

            if js_api:
                self.js_bridge.api = js_api

            # HACK. Hiding the WebBrowser is needed in order to show a non-default background color. Tweaking the Visible property
            # results in showing a non-responsive control, until it is loaded fully. To avoid this, we need to disable this behaviour
            # for the default background color.
            if background_color != '#FFFFFF':
                self.web_browser.Visible = False
                self.first_load = True
            else:
                self.first_load = False

            self.cancel_back = False
            self.web_browser.PreviewKeyDown += self.on_preview_keydown
            self.web_browser.Navigating += self.on_navigating
            self.web_browser.NewWindow3 += self.on_new_window
            self.web_browser.DownloadComplete += self.on_download_complete
            self.web_browser.DocumentCompleted += self.on_document_completed

            if url:
                self.web_browser.Navigate(url)
            else:
                self.web_browser.DocumentText = default_html

            self.url = url

            self.Controls.Add(self.web_browser)
            self.is_fullscreen = False
            self.Shown += self.on_shown
            self.FormClosed += self.on_close

            if confirm_quit:
                self.FormClosing += self.on_closing

            if fullscreen:
                self.toggle_fullscreen()

        def _initialize_js(self):
            self.web_browser.Document.InvokeScript('eval', (alert.src, ))

        def on_shown(self, sender, args):
            self.webview_ready.set()

        def on_close(self, sender, args):
            del BrowserView.instances[self.uid]

            if len(BrowserView.instances) == 0:
                WinForms.Application.Exit()

        def on_closing(self, sender, args):
            result = WinForms.MessageBox.Show(
                localization['global.quitConfirmation'], self.Text,
                WinForms.MessageBoxButtons.OKCancel,
                WinForms.MessageBoxIcon.Asterisk)

            if result == WinForms.DialogResult.Cancel:
                args.Cancel = True

        def on_preview_keydown(self, sender, args):
            if args.KeyCode == WinForms.Keys.Back:
                self.cancel_back = True
            elif args.KeyCode == WinForms.Keys.Delete:
                self.web_browser.Document.ExecCommand('Delete', False, None)
            elif args.Modifiers == WinForms.Keys.Control and args.KeyCode == WinForms.Keys.C:
                self.web_browser.Document.ExecCommand('Copy', False, None)
            elif args.Modifiers == WinForms.Keys.Control and args.KeyCode == WinForms.Keys.X:
                self.web_browser.Document.ExecCommand('Cut', False, None)
            elif args.Modifiers == WinForms.Keys.Control and args.KeyCode == WinForms.Keys.V:
                self.web_browser.Document.ExecCommand('Paste', False, None)
            elif args.Modifiers == WinForms.Keys.Control and args.KeyCode == WinForms.Keys.Z:
                self.web_browser.Document.ExecCommand('Undo', False, None)
            elif args.Modifiers == WinForms.Keys.Control and args.KeyCode == WinForms.Keys.A:
                self.web_browser.Document.ExecCommand('selectAll', False, None)

        def on_new_window(self, sender, args):
            args.Cancel = True
            webbrowser.open(args.Url)

        def on_download_complete(self, sender, args):
            document = self.web_browser.Document

            if self.js_bridge.api:
                document.InvokeScript('eval',
                                      (parse_api_js(self.js_bridge.api), ))

            if not self.text_select:
                document.InvokeScript('eval', (disable_text_select, ))

        def on_navigating(self, sender, args):
            if self.cancel_back:
                args.Cancel = True
                self.cancel_back = False

        def on_document_completed(self, sender, args):
            self._initialize_js()

            if self.first_load:
                self.web_browser.Visible = True
                self.first_load = False

            self.load_event.set()

        def toggle_fullscreen(self):
            screen = WinForms.Screen.FromControl(self)
            if not self.is_fullscreen:
                self.old_size = self.Size
                self.old_state = self.WindowState
                self.old_style = self.FormBorderStyle
                self.old_location = self.Location

                self.TopMost = True
                self.FormBorderStyle = 0  # FormBorderStyle.None
                self.Bounds = WinForms.Screen.PrimaryScreen.Bounds
                self.WindowState = WinForms.FormWindowState.Maximized
                self.is_fullscreen = True

                windll.user32.SetWindowPos(self.Handle.ToInt32(), None,
                                           screen.Bounds.X, screen.Bounds.Y,
                                           screen.Bounds.Width,
                                           screen.Bounds.Height, 64)
            else:
                self.TopMost = False
                self.Size = self.old_size
                self.WindowState = self.old_state
                self.FormBorderStyle = self.old_style
                self.Location = self.old_location
                self.is_fullscreen = False

        def set_window_size(self, width, height):
            windll.user32.SetWindowPos(self.Handle.ToInt32(), None,
                                       self.Location.X, self.Location.Y, width,
                                       height, 64)
Beispiel #7
0
 def on_mouse_move(self, sender, e):
     if e.MouseButtonsPressed == WinForms.MouseButtons.Left:
         WebBrowserEx.ReleaseCapture()
         WebBrowserEx.SendMessage(self.Handle,
                                  WebBrowserEx.WM_NCLBUTTONDOWN,
                                  WebBrowserEx.HT_CAPTION, 0)