Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Core / CSharp / System / Windows / Media / HostVisual.cs / 1407647 / HostVisual.cs
//------------------------------------------------------------------------------
//
//
// Copyright (C) Microsoft Corporation. All rights reserved.
//
//
// Description:
// Host visual.
//
//-----------------------------------------------------------------------------
namespace System.Windows.Media
{
using System;
using System.Windows.Threading;
using System.Windows.Media;
using System.Windows.Media.Composition;
using System.Diagnostics;
using System.Collections;
using System.Collections.Generic;
using MS.Internal;
using System.Resources;
using System.Runtime.InteropServices;
using MS.Win32;
using System.Threading;
using SR=MS.Internal.PresentationCore.SR;
using SRID=MS.Internal.PresentationCore.SRID;
///
/// Host visual.
///
public class HostVisual : ContainerVisual
{
//---------------------------------------------------------------------
//
// Constructors
//
//---------------------------------------------------------------------
#region Constructors
///
///
///
public HostVisual()
{
}
#endregion Constructors
//----------------------------------------------------------------------
//
// Protected Methods
//
//---------------------------------------------------------------------
#region Protected Methods
///
/// HitTestCore
///
protected override HitTestResult HitTestCore(
PointHitTestParameters hitTestParameters)
{
//
// HostVisual never reports itself as being hit. To change this
// behavior clients should derive from HostVisual and override
// HitTestCore methods.
//
return null;
}
///
/// HitTestCore
///
protected override GeometryHitTestResult HitTestCore(
GeometryHitTestParameters hitTestParameters)
{
//
// HostVisual never reports itself as being hit. To change this
// behavior clients should derive from HostVisual and override
// HitTestCore methods.
//
return null;
}
#endregion Protected Methods
//----------------------------------------------------------------------
//
// Internal Methods
//
//----------------------------------------------------------------------
#region Internal Methods
///
///
///
internal override Rect GetContentBounds()
{
return Rect.Empty;
}
///
///
///
internal override void RenderContent(RenderContext ctx, bool isOnChannel)
{
//
// Make sure that the visual target is properly hosted.
//
EnsureHostedVisualConnected(ctx.Channel);
}
///
///
///
internal override void FreeContent(DUCE.Channel channel)
{
//
// Disconnect hosted visual from this channel.
//
using (CompositionEngineLock.Acquire())
{
DisconnectHostedVisual(
channel,
/* removeChannelFromCollection */ true);
}
base.FreeContent(channel);
}
///
///
///
internal void BeginHosting(VisualTarget target)
{
//
// This method is executed on the visual target thread.
//
Debug.Assert(target != null);
Debug.Assert(target.Dispatcher.Thread == Thread.CurrentThread);
using (CompositionEngineLock.Acquire())
{
//
// Check if another target is already hosted by this
// visual and throw exception if this is the case.
//
if (_target != null)
{
throw new InvalidOperationException(
SR.Get(SRID.VisualTarget_AnotherTargetAlreadyConnected)
);
}
_target = target;
//
// If HostVisual and VisualTarget on same thread, then call Invalidate
// directly. Otherwise post invalidate message to the host visual thread
// indicating that content update is required.
//
if (this.CheckAccess())
{
Invalidate();
}
else
{
Dispatcher.BeginInvoke(
DispatcherPriority.Normal,
(DispatcherOperationCallback)delegate(object args)
{
Invalidate();
return null;
},
null
);
}
}
}
///
///
///
internal void EndHosting()
{
//
// This method is executed on the visual target thread.
//
using (CompositionEngineLock.Acquire())
{
Debug.Assert(_target != null);
Debug.Assert(_target.Dispatcher.Thread == Thread.CurrentThread);
DisconnectHostedVisualOnAllChannels();
_target = null;
}
}
///
/// Should be called from the VisualTarget thread
/// when it is safe to access the composition node
/// and out of band channel from the VisualTarget thread
/// to allow for the handle duplication/channel commit
///
internal object DoHandleDuplication(object channel)
{
DUCE.ResourceHandle targetsHandle = DUCE.ResourceHandle.Null;
using (CompositionEngineLock.Acquire())
{
targetsHandle = _target._contentRoot.DuplicateHandle(_target.OutOfBandChannel, (DUCE.Channel)channel);
Debug.Assert(!targetsHandle.IsNull);
_target.OutOfBandChannel.CloseBatch();
_target.OutOfBandChannel.Commit();
}
return targetsHandle;
}
#endregion Internal Methods
//---------------------------------------------------------------------
//
// Private Methods
//
//----------------------------------------------------------------------
#region Private Methods
///
/// Connects the hosted visual on a channel if necessary.
///
private void EnsureHostedVisualConnected(DUCE.Channel channel)
{
//
// Conditions for connecting VisualTarget to Host Visual:-
// 1. The channel on which we are rendering should not be synchronous. This
// scenario is not supported currently.
// 2. VisualTarget should not be null.
// 3. They should not be already connected.
//
if (!(channel.IsSynchronous)
&& _target != null
&& !_connectedChannels.Contains(channel))
{
Debug.Assert(IsOnChannel(channel));
DUCE.ResourceHandle targetsHandle = DUCE.ResourceHandle.Null;
bool doDuplication = true;
//
// If HostVisual and VisualTarget are on same thread, then we just addref
// VisualTarget. Otherwise, if on different threads, then we duplicate
// VisualTarget onto Hostvisual's channel.
//
if (_target.CheckAccess())
{
Debug.Assert(_target._contentRoot.IsOnChannel(channel));
Debug.Assert(_target.OutOfBandChannel == MediaContext.CurrentMediaContext.OutOfBandChannel);
bool created = _target._contentRoot.CreateOrAddRefOnChannel(this, channel, VisualTarget.s_contentRootType);
Debug.Assert(!created);
targetsHandle = _target._contentRoot.GetHandle(channel);
}
else
{
//
// Duplicate the target's handle onto our channel.
//
// We must wait synchronously for the _targets Dispatcher to call
// back and do handle duplication. We can't do handle duplication
// on this thread because access to the _target CompositionNode
// is not synchronized. If we duplicated here, we could potentially
// corrupt the _target OutOfBandChannel or the CompositionNode
// MultiChannelResource. We have to wait synchronously because
// we need the resulting duplicated handle to hook up as a child
// to this HostVisual.
//
object returnValue = _target.Dispatcher.Invoke(
DispatcherPriority.Normal,
TimeSpan.FromMilliseconds(1000),
new DispatcherOperationCallback(DoHandleDuplication),
channel
);
//
// Duplication and flush is complete, we can resume processing
// Only if the Invoke succeeded will we have a handle returned.
//
if (returnValue != null)
{
targetsHandle = (DUCE.ResourceHandle)returnValue;
}
else
{
// The Invoke didn't complete
doDuplication = false;
}
}
if (doDuplication)
{
if (!targetsHandle.IsNull)
{
using (CompositionEngineLock.Acquire())
{
DUCE.CompositionNode.InsertChildAt(
_proxy.GetHandle(channel),
targetsHandle,
0,
channel);
}
_connectedChannels.Add(channel);
//
// Indicate that that content composition root has been
// connected, this needs to be taken into account to
// properly manage children of this visual.
//
SetFlags(channel, true, VisualProxyFlags.IsContentNodeConnected);
}
}
else
{
//
// We didn't get a handle, because _target belongs to a
// different thread, and the Invoke operation failed. We can't do
// anything except try again in the next render pass. We can't
// call Invalidate during the render pass because it pushes up
// flags that are being modified within the render pass, so get
// the local Dispatcher to do it for us later.
//
Dispatcher.BeginInvoke(
DispatcherPriority.Normal,
(DispatcherOperationCallback)delegate(object args)
{
Invalidate();
return null;
},
null
);
}
}
}
///
/// Disconnects the hosted visual on all channels we have
/// connected it to.
///
private void DisconnectHostedVisualOnAllChannels()
{
foreach (DUCE.Channel channel in _connectedChannels)
{
DisconnectHostedVisual(
channel,
/* removeChannelFromCollection */ false);
}
_connectedChannels.Clear();
}
///
/// Disconnects the hosted visual on a channel.
///
private void DisconnectHostedVisual(
DUCE.Channel channel,
bool removeChannelFromCollection)
{
if (_target != null && _connectedChannels.Contains(channel))
{
DUCE.CompositionNode.RemoveChild(
_proxy.GetHandle(channel),
_target._contentRoot.GetHandle(channel),
channel
);
//
// Release the targets handle. If we had duplicated the handle,
// then this removes the duplicated handle, otherwise just decrease
// the ref count for VisualTarget.
//
_target._contentRoot.ReleaseOnChannel(channel);
SetFlags(channel, false, VisualProxyFlags.IsContentNodeConnected);
if (removeChannelFromCollection)
{
_connectedChannels.Remove(channel);
}
}
}
///
/// Invalidate this visual.
///
private void Invalidate()
{
SetFlagsOnAllChannels(true, VisualProxyFlags.IsContentDirty);
PropagateChangedFlags();
}
#endregion Private Methods
//---------------------------------------------------------------------
//
// Private Fields
//
//---------------------------------------------------------------------
#region Private Fields
///
/// The hosted visual target.
///
///
/// This field is free-threaded and should be accessed from under a lock.
///
private VisualTarget _target;
///
/// The channels we have marshalled the visual target composition root.
///
///
/// This field is free-threaded and should be accessed from under a lock.
///
private List _connectedChannels = new List();
#endregion Private Fields
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- WindowsRebar.cs
- ImageAttributes.cs
- PointCollection.cs
- TogglePattern.cs
- ContentFilePart.cs
- RulePatternOps.cs
- Math.cs
- QueryableDataSourceView.cs
- XmlSchemaSimpleContentExtension.cs
- PreProcessInputEventArgs.cs
- metadatamappinghashervisitor.cs
- ExpressionConverter.cs
- RelationshipWrapper.cs
- XmlWrappingReader.cs
- LocatorBase.cs
- RelationshipFixer.cs
- DataTableMappingCollection.cs
- InfoCardHelper.cs
- BmpBitmapEncoder.cs
- SerialReceived.cs
- RichTextBox.cs
- SqlDataReader.cs
- RoleServiceManager.cs
- AuthenticationModuleElement.cs
- PrintPageEvent.cs
- ButtonColumn.cs
- EncryptedReference.cs
- URL.cs
- DiscoveryOperationContext.cs
- TypeNameConverter.cs
- TailCallAnalyzer.cs
- ObfuscationAttribute.cs
- DefaultEventAttribute.cs
- CellLabel.cs
- EpmTargetPathSegment.cs
- Triplet.cs
- SqlDataAdapter.cs
- FontEmbeddingManager.cs
- ToolStripDesignerAvailabilityAttribute.cs
- _RequestLifetimeSetter.cs
- Marshal.cs
- WaitHandle.cs
- SqlEnums.cs
- HttpRawResponse.cs
- ProcessInputEventArgs.cs
- FileDialogCustomPlacesCollection.cs
- dtdvalidator.cs
- Marshal.cs
- BindingBase.cs
- SecurityTokenAuthenticator.cs
- FileLoadException.cs
- ImageAnimator.cs
- PolyBezierSegment.cs
- CrossContextChannel.cs
- DelimitedListTraceListener.cs
- WebEvents.cs
- TextContainerChangeEventArgs.cs
- ComponentDispatcherThread.cs
- ItemChangedEventArgs.cs
- UserMapPath.cs
- base64Transforms.cs
- MailHeaderInfo.cs
- HeaderCollection.cs
- NamespaceEmitter.cs
- TickBar.cs
- OutputWindow.cs
- Repeater.cs
- webclient.cs
- LeaseManager.cs
- DynamicResourceExtensionConverter.cs
- TypeInfo.cs
- WmpBitmapDecoder.cs
- TextCompositionEventArgs.cs
- ArrayWithOffset.cs
- RequestStatusBarUpdateEventArgs.cs
- Int64AnimationBase.cs
- SizeF.cs
- HideDisabledControlAdapter.cs
- PtsCache.cs
- PaginationProgressEventArgs.cs
- WindowsImpersonationContext.cs
- OrCondition.cs
- SchemaConstraints.cs
- PageAdapter.cs
- RootDesignerSerializerAttribute.cs
- EpmContentDeSerializerBase.cs
- DbProviderConfigurationHandler.cs
- XPathDocumentNavigator.cs
- BasicExpandProvider.cs
- XmlAnyElementAttributes.cs
- PageHandlerFactory.cs
- ButtonFlatAdapter.cs
- DrawingContextWalker.cs
- NullableFloatAverageAggregationOperator.cs
- WebPartsSection.cs
- TemplatePagerField.cs
- SqlUserDefinedAggregateAttribute.cs
- cache.cs
- Point3DAnimationUsingKeyFrames.cs
- assemblycache.cs