Reparenting native applications on Windows

APN The code below is from a comp.lang.tcl posting by JMarkCase. It shows how to wrap a Windows native application window into a Tk window.


For my purposes, the behavior of the IE session within the Tk parent is exactly what I needed. If you remove the SetParent line of code, you can see the possibility of potential orphan browsers. Yes, I could have coded to prevent leaving stray browsers open when the "parent" Tk app closes, but this is much cleaner.

My application uses gridplus to manage the GUI, but this code demonstrates the same principle.

proc ie_bind_events { args } { 

  global ie 
  global ie_forever 
  global ie_events 
  
  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 
    } 
    
    incr nIndex 
  } 
} 

proc okbtn { } { 

  global ie 
  global ie_forever 
  global ie_events 

  .ok configure -state disabled 
  .exit configure -state disable 
  set ie_forever 0 
  
  set ie [ twapi::comobj InternetExplorer.Application ] 

  set w [ $ie HWND ] 
  set wIE [ list $w HWND ] 
  
  set WS_CHILD 0x40000000 
  
  set szStyleLst [ twapi::get_window_style $wIE ] 
  set szStyle [ lindex $szStyleLst 0 ] 
  set szExStyle [ lindex $szStyleLst 1 ] 
  
  set szStyle [ expr {$szStyle | $WS_CHILD} ] 
  
  twapi::set_window_style $wIE $szStyle $szExStyle 
  twapi::configure_window_titlebar $wIE -visible 0 
  set szStyleLst [ twapi::get_window_style $wIE ] 
  
  $ie Visible 0 
  
  set szUrl "www.google.com" 
  $ie Navigate $szUrl 
  
  twapi::resize_window $wIE 400 400 

  set wParent [ twapi::tkpath_to_hwnd . ] 
  
  twapi::SetParent $wIE $wParent 
  
  $ie Resizable 0 
  $ie MenuBar 0 
  $ie AddressBar 0   
  $ie RegisterAsBrowser 1 
  $ie Visible 1 
  
  set ie_events [ $ie -bind ie_bind_events ] 

  twapi::set_window_text $wIE "IE Child" 
  
  vwait ie_forever 
  
  .ok configure -state normal 
  .exit configure -state normal 
} 

#-- 
#-- IE as a child 
#-- 
package require Tk 
package require twapi 

set ie "" 
set ie_forever 0 
set ie_events "" 

frame .f -width 500 -height 500 
grid .f -columnspan 2 
button .ok -text Ok -command okbtn -width 30 
button .exit -text Exit -command {exit 0} -width 30 
grid .ok -row 1 -column 0 
grid .exit -row 1 -column 1 

wm title . "IE Is My Child" 

See also

  • dgwin::ie a snit wrapper of this code, IE as Tk widget