dgwin::ie

NAME

Internet Explorer as a Tk widget.

DESCRIPTION

DDG 2020-03-20: This is a WIP to wrap the Internet Explorer on Windows using the twapi package as a Tk widget. So it can be used to display websites inside Tk applications using the COM interface of Internet Explorer. The code below is based on the wiki page Reparenting native applications on Windows.

TODO

I was not able to remove the thick title bar. I workaround the issue by moving the window 25px on top, so that the title bar is almost not visible. May be some guys understanding the Windows style documentation can fix this for me. I tried a few things but it did not work. Any suggestions? I found a workaround with Windows styles. The control has a property TheaterMode which gets rid of the title bar.

package require snit
package require Tk 
package require twapi 

namespace eval dgwin { }

snit::widget dgwin::ie {
    option -url https://wiki.tcl-lang.org
    variable ie
    variable ie_events
    constructor {args} {
        $self configurelist $args
        set ie [ twapi::comobj InternetExplorer.Application ] 
        
        set w [ $ie HWND ] 
        set wIE [ list $w HWND ] 
        #https://docs.microsoft.com/en-us/windows/win32/winmsg/window-styles
        set WS_CHILD 0x40000000 
        set WS_BORDER 0x00800000 
        set WS_DLGFRAME 0x00400000
        # did not work ; I like to have only a thin border around 
        # and not a thick title frame border 
        # any suggestion?
        
        set szStyleLst [ twapi::get_window_style $wIE ] 
        set szStyle [ lindex $szStyleLst 0 ] 
        set szExStyle [ lindex $szStyleLst 1 ] 
        #puts "szStyle: $szStyle szExStyle: $szExStyle"
  
        set szStyle [ expr {$szStyle | $WS_CHILD} ] 
        #puts "szStyle: $szStyle szExStyle: $szExStyle"
        twapi::set_window_style $wIE $szStyle $szExStyle 
        #twapi::set_window_style $wIE $szStyle [expr $WS_BORDER] ;# did not change anything
        twapi::configure_window_titlebar $wIE -visible 0 
        $ie Visible 0 
        set szUrl $options(-url)
        $ie Navigate $szUrl 
  
        twapi::resize_window $wIE 400 400 
        set frame [frame $win.tf -container true]
        set wParent [ twapi::tkpath_to_hwnd $frame ] 
  
        twapi::SetParent $wIE $wParent 
  
        $ie Resizable 1 
        $ie MenuBar 0 
        $ie AddressBar 0   
        $ie RegisterAsBrowser 1 
        $ie Visible 1 
        # fix for title frame
        $ie TheaterMode 1
        
        set ie_events [ $ie -bind [mymethod ie_bind_events ]] 

        #twapi::set_window_text $wIE "IE Child" 
        bind $frame <Configure> [mymethod moveWindow $wIE %w %h]
        #bind $frame <Destroy> [list onDestroy]
        #moveWindow $wIE [winfo width .] [winfo height .]
        $frame configure -width 400 -height 400
        pack $frame -side top -fill both -expand true
        update 
        $self moveWindow $wIE [winfo width $frame] [winfo height $frame]
    }
    onconfigure -url {value} { 
        set options(-url) $value
        $ie Navigate $value
    } 
 


    method ie_bind_events {args} {
        puts "events: $args"
        set nIndex 0 
        set nLength [ llength $args ] 
        while { $nIndex < $nLength } { 
            
            set arg [ lindex $args $nIndex ] 
            
            if { [ string compare $arg "OnQuit" ] == 0 } { 
                $ie -unbind $ie_events 
                $ie Quit 
                $ie -destroy 
                
                set ie_forever 1 
            } 
            if {$arg eq "NavigateComplete2"} {
                set url [lindex $args [expr {$nIndex + 2}]]
                # todo remove this title setting
                wm title . $url
                set options(-url) $url
            }
            incr nIndex 
        } 
    }
    method moveWindow {wId w h} {
        # fix to hide the title bar, not required anymore due to TheaterMode setting
        #incr h 25
        twapi::resize_window $wId $w $h
        twapi::move_window $wId 0 0
    }
    destructor {
        $ie -unbind $ie_events 
        # calling quit here gives an error message
        #$ie Quit 
        $ie -destroy 
    }
}

EXAMPLE

Below is an example on how to use the widget:

wm title . "IE Demo on Windows" 
set ie [dgwin::ie .ie] 
pack $ie -side left -fill both -expand true
$ie configure -url https://core.tcl.tk

Below an image of IE inside Tk:

dgwin-ie-image

DISCUSSION

Please discuss here ...