1212using System . Xml ;
1313using SIL . FieldWorks . Common . Framework . DetailControls ;
1414using SIL . FieldWorks . Common . FwUtils ;
15+ using SIL . FieldWorks . Common . RootSites ;
16+ using SIL . FieldWorks . Common . ViewsInterfaces ;
1517using SIL . LCModel ;
1618using XCore ;
1719
@@ -282,8 +284,10 @@ public Bitmap CaptureCompositeBitmap()
282284 if ( m_dataTree == null )
283285 throw new InvalidOperationException ( "Call PopulateSlices before capturing." ) ;
284286
287+ bool wasVisible = m_dataTree . Visible ;
285288 try
286289 {
290+ m_dataTree . Visible = true ;
287291 var bitmap = CompositeViewCapture . CaptureDataTree ( m_dataTree , m_captureWidth ) ;
288292 LastCapture = bitmap ;
289293 return bitmap ;
@@ -293,6 +297,11 @@ public Bitmap CaptureCompositeBitmap()
293297 Trace . TraceWarning ( $ "[DataTreeRenderHarness] Composite capture failed: { ex . Message } ") ;
294298 return null ;
295299 }
300+ finally
301+ {
302+ if ( m_dataTree != null )
303+ m_dataTree . Visible = wasVisible ;
304+ }
296305 }
297306
298307 /// <summary>
@@ -439,19 +448,30 @@ private void LoadTestInventories()
439448
440449 private void DisposeResources ( )
441450 {
442- if ( m_dataTree != null )
443- {
444- // DataTree gets disposed by form.Close since it's in Controls
445- m_dataTree = null ;
446- }
447-
448451 if ( m_hostForm != null )
449452 {
453+ if ( m_dataTree != null )
454+ {
455+ m_dataTree . Enabled = false ;
456+ m_dataTree . Visible = false ;
457+ m_hostForm . Visible = false ;
458+ SuppressHostedRootSiteDrawing ( m_dataTree ) ;
459+ DrainHostedRootBoxDrawingErrors ( m_dataTree ) ;
460+ QuiesceHostedRootSites ( m_dataTree ) ;
461+ m_dataTree . Reset ( ) ;
462+ }
463+
450464 m_hostForm . Close ( ) ;
451465 m_hostForm . Dispose ( ) ;
452466 m_hostForm = null ;
453467 }
454468
469+ if ( m_dataTree != null )
470+ {
471+ // DataTree gets disposed by form.Close since it's in Controls
472+ m_dataTree = null ;
473+ }
474+
455475 if ( m_propertyTable != null )
456476 {
457477 m_propertyTable . Dispose ( ) ;
@@ -465,6 +485,132 @@ private void DisposeResources()
465485 }
466486 }
467487
488+ private void QuiesceHostedRootSites ( DataTree dataTree )
489+ {
490+ var rootSites = new HashSet < SimpleRootSite > ( ) ;
491+ CollectHostedRootSites ( dataTree , rootSites ) ;
492+ foreach ( var rootSite in rootSites )
493+ QuiesceRootSite ( rootSite ) ;
494+ }
495+
496+ private void DrainHostedRootBoxDrawingErrors ( DataTree dataTree )
497+ {
498+ var rootSites = new HashSet < SimpleRootSite > ( ) ;
499+ CollectHostedRootSites ( dataTree , rootSites ) ;
500+ foreach ( var rootSite in rootSites )
501+ DrainRootBoxDrawingErrors ( rootSite ) ;
502+ }
503+
504+ private void SuppressHostedRootSiteDrawing ( DataTree dataTree )
505+ {
506+ var rootSites = new HashSet < SimpleRootSite > ( ) ;
507+ CollectHostedRootSites ( dataTree , rootSites ) ;
508+ foreach ( var rootSite in rootSites )
509+ SuppressRootSiteDrawing ( rootSite ) ;
510+ }
511+
512+ private void CollectHostedRootSites ( DataTree dataTree , ISet < SimpleRootSite > rootSites )
513+ {
514+ if ( dataTree . Slices != null )
515+ {
516+ foreach ( Slice slice in dataTree . Slices )
517+ {
518+ var viewSlice = slice as ViewSlice ;
519+ if ( viewSlice == null )
520+ continue ;
521+
522+ try
523+ {
524+ var rootSite = viewSlice . RootSite ;
525+ if ( rootSite != null )
526+ rootSites . Add ( rootSite ) ;
527+ }
528+ catch
529+ {
530+ // Shutdown path only: slices may already be partially disposed.
531+ }
532+ }
533+ }
534+
535+ CollectRootSites ( dataTree , rootSites ) ;
536+ }
537+
538+ private void CollectRootSites ( Control control , ISet < SimpleRootSite > rootSites )
539+ {
540+ if ( control == null )
541+ return ;
542+
543+ var rootSite = control as SimpleRootSite ;
544+ if ( rootSite != null )
545+ rootSites . Add ( rootSite ) ;
546+
547+ foreach ( Control child in control . Controls )
548+ CollectRootSites ( child , rootSites ) ;
549+ }
550+
551+ private void QuiesceRootSite ( SimpleRootSite rootSite )
552+ {
553+ try
554+ {
555+ SuppressRootSiteDrawing ( rootSite ) ;
556+ rootSite . AboutToDiscard ( ) ;
557+ rootSite . CloseRootBox ( ) ;
558+ }
559+ catch
560+ {
561+ // Shutdown path only: controls may already be partially disposed.
562+ }
563+ }
564+
565+ private void SuppressRootSiteDrawing ( SimpleRootSite rootSite )
566+ {
567+ try
568+ {
569+ rootSite . AllowPainting = false ;
570+ rootSite . AllowLayout = false ;
571+ rootSite . Visible = false ;
572+ }
573+ catch
574+ {
575+ // Shutdown path only: controls may already be partially disposed.
576+ }
577+ }
578+
579+ private void DrainRootBoxDrawingErrors ( SimpleRootSite rootSite )
580+ {
581+ IVwRootBox rootBox = null ;
582+ try
583+ {
584+ rootBox = rootSite . RootBox ;
585+ }
586+ catch
587+ {
588+ return ;
589+ }
590+
591+ if ( rootBox == null )
592+ return ;
593+
594+ IVwGraphics graphics = null ;
595+ try
596+ {
597+ Rect sourceRectangle ;
598+ Rect destinationRectangle ;
599+ rootSite . GetGraphics ( rootBox , out graphics , out sourceRectangle , out destinationRectangle ) ;
600+ rootBox . DrawingErrors ( graphics ) ;
601+ }
602+ catch ( Exception ex )
603+ {
604+ Trace . TraceWarning (
605+ $ "[DataTreeRenderHarness] Suppressed deferred drawing error for '{ rootSite . Name } ': { ex . Message } ") ;
606+ }
607+ finally
608+ {
609+ if ( graphics != null )
610+ rootSite . ReleaseGraphics ( rootBox , graphics ) ;
611+ }
612+ }
613+
468614 /// <summary>Releases all resources used by the harness.</summary>
469615 public void Dispose ( )
470616 {
0 commit comments