// Decompiled with JetBrains decompiler // Type: Microsoft.Iris.Render.Internal.RenderWindow // Assembly: UIX.RenderApi, Version=4.8.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 // MVID: D47658B8-A8EA-43D6-8837-ECE823BFFFC1 // Assembly location: C:\Program Files\Zune\UIX.RenderApi.dll using Microsoft.Iris.Input; using Microsoft.Iris.Render.Common; using Microsoft.Iris.Render.Graphics; using Microsoft.Iris.Render.Protocol; using Microsoft.Iris.Render.Protocols.Splash.Desktop; using Microsoft.Iris.Render.Protocols.Splash.Desktop.Nt; using Microsoft.Iris.Render.Protocols.Splash.Rendering; using System; using System.Collections; using System.Runtime.InteropServices; using System.Security; namespace Microsoft.Iris.Render.Internal { [SuppressUnmanagedCodeSecurity] internal sealed class RenderWindow : IRenderWindow, ITreeOwner, IFormWindowCallback, IRenderHandleOwner { private const uint ACT_INACTIVE = 0; private const uint ACT_ACTIVE = 1; private const uint ACT_POPUP = 2; private const uint ACT_SYSUI = 3; private const uint STCH_MODE = 1; private const uint STCH_ACTIVATION = 2; private const uint STCH_VISIBILITY = 4; private const uint STCH_LOCATION = 8; private const uint STCH_SIZE = 16; private const uint STCH_UNPLANNED = 256; private const uint WM_KEYFIRST = 256; private const uint WM_KEYLAST = 265; private const uint WM_MOUSEFIRST = 512; private const uint WM_MOUSELAST = 526; private static ushort[] s_ByteOrder_FormStateCallbackMsg; private RenderSession m_session; private DisplayManager m_displayManager; private GraphicsDevice m_device; private GraphicsDeviceType m_graphicsDeviceType; private VisualContainer m_rootVisual; private int m_nX; private int m_nY; private int m_nWidth; private int m_nHeight; private int m_nMinResizeWidth; private int m_nMaxResizeWidth; private Size m_szDefault; private string m_stText; private Display m_currentDisplay; private bool m_fSpanningMonitors; private bool m_fOnSecondaryMonitor; private bool m_fRightToLeft; private bool m_fActivation; private bool m_fFocused; private bool m_fVisible; private bool m_fExclusive; private bool m_fShownBefore; private bool m_fSessionHasDisplay; private bool m_fSessionLocked; private bool m_fExplicitlyLocked; private bool m_fClosing; private bool m_fLoadComplete; private bool m_fLoadEventFired; private WindowState m_nWindowState; private FormStyleInfo m_windowStyles; private ColorF m_clrBackground; private ColorF m_clrOutlineAllColor; private ColorF m_clrOutlineMarkedColor; private Cursor m_cursor; private Cursor m_cursorIdle; private Stack m_stkWaitCursors; private HWND m_hwnd; private RemoteFormWindow m_remoteWindow; private RenderWindow.RenderFlags m_renderFlags; private bool m_fPreProcessedInput; private int m_nMouseLockCount; private ArrayList m_partialDropData; private bool m_fEnableExternalDragDrop; private uint m_nDragDropResult; private uint m_nDragOverResult; private bool m_fIsDragInProgress; private FormPlacement m_finalPlacement; private SmartMap m_mapShutdownHooks; private ushort m_nextShutdownHookId; internal RenderWindow( RenderSession session, DisplayManager displayManager, GraphicsDeviceType graphicsDeviceType, GraphicsRenderingQuality renderingQuality) { Debug2.Validate(session != null, typeof(ArgumentNullException), "must pass a valid session"); session.AssertOwningThread(); Debug2.Validate(displayManager != null, typeof(ArgumentNullException), "must pass a valid DisplayManager"); this.m_session = session; this.m_displayManager = displayManager; this.CreateGraphicsDevice(session, graphicsDeviceType, renderingQuality); this.m_device.RegisterWindow(this); this.m_clrBackground = new ColorF(0.0f, 0.0f, 0.0f); this.m_remoteWindow = this.m_session.BuildRemoteFormWindow(this, this.m_displayManager); this.m_fPreProcessedInput = false; this.m_cursor = Cursor.Default; this.m_cursorIdle = Cursor.Default; this.m_nWindowState = WindowState.Normal; this.m_fRightToLeft = false; this.m_fSessionHasDisplay = true; this.m_fSessionLocked = false; this.m_szDefault = new Size(640, 480); this.m_clrOutlineAllColor = new ColorF(byte.MaxValue, 0, byte.MaxValue, 0); this.m_clrOutlineMarkedColor = new ColorF(byte.MaxValue, byte.MaxValue, 0, 0); this.m_mapShutdownHooks = new SmartMap(); this.m_nextShutdownHookId = 1; this.m_nMouseLockCount = 0; this.SetFullScreenExclusive(false); } public void Initialize() => this.BuildRootContainer(); private GraphicsDevice CreateGraphicsDevice( RenderSession session, GraphicsDeviceType graphicsDeviceType, GraphicsRenderingQuality renderingQuality) { GraphicsDevice graphicsDevice = null; EngineApi.IFC(FormApi.SpGdiplusInit()); this.m_graphicsDeviceType = graphicsDeviceType; switch (this.m_graphicsDeviceType) { case GraphicsDeviceType.Gdi: this.m_device = new GdiGraphicsDevice(session); break; case GraphicsDeviceType.Direct3D9: this.m_device = new NtGraphicsDevice(session, renderingQuality); break; } return graphicsDevice; } internal void Dispose() { this.Visible = false; this.m_remoteWindow.SendSetRoot(null); this.m_rootVisual.UnregisterUsage(this); this.StopRendering(); } internal void StopRendering() { if (this.m_device != null) { this.m_device.Dispose(); this.m_device = null; } if (this.m_remoteWindow != null) { this.m_remoteWindow.Dispose(); this.m_remoteWindow = null; } EngineApi.IFC(FormApi.SpGdiplusUninit()); } RENDERHANDLE IRenderHandleOwner.RenderHandle => this.m_remoteWindow.RenderHandle; void IRenderHandleOwner.OnDisconnect() => this.m_remoteWindow = null; internal RemoteFormWindow RemoteStub => this.m_remoteWindow; public int Left => this.m_nX; public int Top => this.m_nY; public int Right => this.m_nX + this.m_nWidth; public int Bottom => this.m_nY + this.m_nHeight; public int Width => this.m_nWidth; public int Height => this.m_nHeight; public HWND WindowHandle => this.m_hwnd; public Size ClientSize { get => new Size(this.m_nWidth, this.m_nHeight); set { if (this.m_nWidth == value.Width && this.m_nHeight == value.Height || !this.m_session.IsValid) return; this.m_remoteWindow.SendSetSize(value); } } public Size InitialClientSize { get => this.m_szDefault; set => this.m_szDefault = value; } public FormPlacement InitialPlacement { set { if (!this.m_session.IsValid || this.m_remoteWindow == null || !(this.m_hwnd == HWND.NULL)) return; this.m_remoteWindow.SendSetInitialPlacement(value.ShowState, value.NormalPosition, value.MaximizedLocation); } } public FormPlacement FinalPlacement => this.m_finalPlacement; public int MinResizeWidth { get => this.m_nMinResizeWidth; set { if (this.m_nMinResizeWidth == value) return; this.m_nMinResizeWidth = value; if (!this.m_session.IsValid) return; this.m_remoteWindow.SendSetMinResizeWidth(this.m_nMinResizeWidth); } } public int MaxResizeWidth { get => this.m_nMaxResizeWidth; set { if (this.m_nMaxResizeWidth == value) return; this.m_nMaxResizeWidth = value; if (!this.m_session.IsValid) return; this.m_remoteWindow.SendSetMaxResizeWidth(this.m_nMaxResizeWidth); } } public Point Position { get => new Point(this.m_nX, this.m_nY); set { if (this.m_nX == value.X && this.m_nY == value.Y || !this.m_session.IsValid) return; this.m_remoteWindow.SendSetPosition(value); } } public string Text { get => this.m_stText == null ? "" : this.m_stText; set { this.m_stText = value; this.UpdateText(true); } } public Cursor Cursor { get => this.m_cursor; set { if (this.m_cursor == value) return; this.m_cursor = value; this.UpdateCursors(); } } public Cursor IdleCursor { get => this.m_cursorIdle; set { if (this.m_cursorIdle == value) return; this.m_cursorIdle = value; this.UpdateCursors(); } } public bool Visible { get => this.m_fVisible; set { if (this.m_fVisible == value) return; this.m_fVisible = value; if (!this.m_session.IsValid) return; this.m_remoteWindow.SendSetVisible(this.m_fVisible); } } public bool IsLoaded => this.m_fLoadEventFired; public ColorF BackgroundColor { get => this.m_clrBackground; set => this.SetBackgroundColor(value); } IDisplay IRenderWindow.CurrentDisplay { get => this.m_currentDisplay == null ? this.m_displayManager.PrimaryDisplay : m_currentDisplay; set => this.SetCurrentDisplay(value); } private void SetCurrentDisplay(IDisplay inputIDisplay) { Debug2.Validate(inputIDisplay is Display, null, "CurrentDisplay.set param MUST be a valid Display object"); Display display = this.m_displayManager.DisplayFromUniqueId((inputIDisplay as Display).UniqueId); if (display == null) return; this.m_currentDisplay = display; } public bool FullScreenExclusive { get => this.m_fExclusive; set => this.SetFullScreenExclusive(value); } private void SetFullScreenExclusive(bool fNewValue) { switch (this.m_graphicsDeviceType) { case GraphicsDeviceType.Direct3D9: this.m_fExclusive = fNewValue; break; case GraphicsDeviceType.XeDirectX9: this.m_fExclusive = true; break; default: this.m_fExclusive = false; break; } } public bool ActivationState => this.m_fActivation; public WindowState WindowState { get => this.m_nWindowState; set { if (this.m_nWindowState == value) return; this.m_nWindowState = value; if (!this.m_session.IsValid) return; this.m_remoteWindow.SendSetMode((uint)this.m_nWindowState); } } public FormStyleInfo Styles { get => this.m_windowStyles; set { this.m_windowStyles = value; if (!this.m_session.IsValid) return; this.m_remoteWindow.SendSetStyles(value.uStyleRestored, value.uExStyleRestored, value.uStyleMinimized, value.uExStyleMinimized, value.uStyleMaximized, value.uExStyleMaximized, value.uStyleFullscreen, value.uExStyleFullscreen); } } HWND IRenderWindow.AppNotifyWindow { set => this.m_remoteWindow.INPROC_SendSetAppNotifyWindow(value); } IVisualContainer IRenderWindow.VisualRoot => m_rootVisual; TreeNode ITreeOwner.Root => m_rootVisual; internal bool IsClosing => this.m_fClosing; internal bool IsSessionActive => this.m_fSessionHasDisplay && !this.m_fSessionLocked; internal bool IsSessionRemote => false; internal bool IsSpanningMonitors => this.m_fSpanningMonitors; internal bool IsOnSecondaryMonitor => this.m_fOnSecondaryMonitor; internal ColorF OutlineAllColor { get => this.m_clrOutlineAllColor; set { if (!(this.m_clrOutlineAllColor != value)) return; this.m_clrOutlineAllColor = value; this.m_remoteWindow.SendSetOutlineAllColor(value); } } internal ColorF OutlineMarkedColor { get => this.m_clrOutlineMarkedColor; set { if (!(this.m_clrOutlineMarkedColor != value)) return; this.m_clrOutlineMarkedColor = value; this.m_remoteWindow.SendSetOutlineMarkedColor(value); } } internal GraphicsDevice GraphicsDevice => this.m_device; internal RenderSession Session => this.m_session; internal GraphicsDeviceType GraphicsDeviceType => this.m_graphicsDeviceType; internal bool IsRightToLeft => this.m_fRightToLeft; public event LocationChangedHandler LocationChangedEvent; public event SizeChangedHandler SizeChangedEvent; public event MonitorChangedHandler MonitorChangedEvent; public event WindowStateChangedHandler WindowStateChangedEvent; public event CloseHandler CloseEvent; public event CloseRequestHandler CloseRequestEvent; public event SysCommandHandler SysCommandEvent; public event MouseIdleHandler MouseIdleEvent; public event ShowHandler ShowEvent; public event ActivationChangeHandler ActivationChangeEvent; public event SessionActivateHandler SessionActivateEvent; public event SessionConnectHandler SessionConnectEvent; public event SetFocusHandler SetFocusEvent; public event LoadHandler LoadEvent; public event ForwardMessageHandler ForwardMessageEvent; public event RenderWindow.RendererSuspendedHandler RendererSuspendedEvent; internal event EventHandler WindowCreatedEvent; private void OnCreated() { if (this.WindowCreatedEvent == null) return; this.WindowCreatedEvent(this, EventArgs.Empty); } private void OnForwardWndMsg(uint msg, IntPtr wParam, IntPtr lParam) { if (this.ForwardMessageEvent == null) return; this.ForwardMessageEvent(msg, wParam, lParam); } private void FireLoadEvent() { if (this.m_fLoadEventFired || !this.m_fLoadComplete || this.m_nWidth == 0 && this.m_nHeight == 0) return; if (this.LoadEvent != null) this.LoadEvent(); this.m_fLoadEventFired = true; } private void OnLocationChanged() { if (this.LocationChangedEvent == null) return; this.LocationChangedEvent(this.Position); } internal void NotifyDisplayReconfigured() => this.OnSizeChanged(); private void OnSizeChanged() { this.FireLoadEvent(); if (this.SizeChangedEvent == null) return; this.SizeChangedEvent(); } private void OnMonitorChanged() { if (this.MonitorChangedEvent == null) return; this.MonitorChangedEvent(); } private void OnWindowStateChanged(bool fUnplanned) { if (this.WindowStateChangedEvent == null) return; this.WindowStateChangedEvent(fUnplanned); } private void OnDestroyed() { } private void OnSysCommand(IntPtr uParam1, IntPtr uParam2) { if (this.SysCommandEvent == null) return; this.SysCommandEvent(uParam1, uParam2); } private void OnMouseIdle(bool fIdle) { if (this.MouseIdleEvent == null) return; this.MouseIdleEvent(fIdle); } private void OnShow(bool fShow, bool fFirstShow) { if (this.ShowEvent == null) return; this.ShowEvent(fShow, fFirstShow); } private void OnActivationChange() { if (this.ActivationChangeEvent == null) return; this.ActivationChangeEvent(); } private void OnTermSessionChange(uint uParam) { bool flag = false; bool isSessionActive = this.IsSessionActive; switch (uParam) { case 1: case 3: this.m_fSessionHasDisplay = true; break; case 2: case 4: this.m_fSessionHasDisplay = false; break; case 7: this.m_fSessionLocked = true; this.m_fExplicitlyLocked = true; break; case 8: this.m_fSessionLocked = false; flag = flag || !this.m_fExplicitlyLocked; break; } if (this.IsSessionActive != isSessionActive || flag) this.FireSessionActivate(this.IsSessionActive); if (uParam != 2U && uParam != 1U && (uParam != 4U && uParam != 3U)) return; this.FireSessionConnect(uParam == 1U || uParam == 3U); } public void FireSessionActivate(bool fIsActive) => this.OnSessionActivate(fIsActive); private void OnSessionActivate(bool fIsActive) { if (fIsActive && this.Visible && this.m_fExclusive) { this.Focus(); this.m_remoteWindow.SendSetForeground(false); } if (this.SessionActivateEvent == null) return; this.SessionActivateEvent(fIsActive); } private void FireSessionConnect(bool fIsConnected) { if (this.SessionConnectEvent == null) return; this.SessionConnectEvent(fIsConnected); } private void OnNativeScreensave(bool fStart) { } private void OnDroppedFiles(IEnumerable files) { } public void EnableShellShutdownHook(string hookName, EventHandler handler) => this.GetShutdownHookInfo(hookName, true).Handler += handler; private RenderWindow.ShutdownHookInfo GetShutdownHookInfo( string hookName, bool fCanAdd) { RenderWindow.ShutdownHookInfo desired = new RenderWindow.ShutdownHookInfo(hookName); if (this.m_mapShutdownHooks.Lookup(desired, out uint _)) return desired; if (fCanAdd) { ushort uIdMsg = this.m_nextShutdownHookId++; this.m_mapShutdownHooks.SetValue(uIdMsg, desired); this.m_remoteWindow.SendEnableShellShutdownHook(hookName, uIdMsg); } else desired = null; return desired; } void IFormWindowCallback.OnTerminalSessionChange( RENDERHANDLE target, IntPtr wParam, IntPtr lParam) { this.OnTermSessionChange((uint)wParam.ToInt32()); } void IFormWindowCallback.OnPrivateSysCommand( RENDERHANDLE target, IntPtr wParam, IntPtr lParam) { this.OnSysCommand(wParam, lParam); } void IFormWindowCallback.OnMouseIdle(RENDERHANDLE target, bool fNewIdle) => this.OnMouseIdle(fNewIdle); void IFormWindowCallback.OnCloseRequested(RENDERHANDLE target) => this.EngineCloseRequest(); void IFormWindowCallback.OnLoad(RENDERHANDLE target) { this.m_fLoadComplete = true; if (this.m_fClosing) return; this.FireLoadEvent(); } void IFormWindowCallback.OnWindowDestroyed( RENDERHANDLE target, uint nFinalShowState, Rectangle rcFinalPosition, Point ptFinalMaximizedLocation) { this.m_finalPlacement.NormalPosition = rcFinalPosition; this.m_finalPlacement.MaximizedLocation = ptFinalMaximizedLocation; this.m_finalPlacement.ShowState = nFinalShowState; this.m_hwnd = HWND.NULL; this.m_fClosing = true; if (this.CloseEvent == null) return; this.CloseEvent(); } void IFormWindowCallback.OnWindowCreated(RENDERHANDLE target, HWND hWnd) { this.m_hwnd = hWnd; this.m_device.PostCreate(); this.UpdateText(false); this.OnCreated(); } unsafe void IFormWindowCallback.OnStateChange( RENDERHANDLE target, Message* pmsgRaw) { RenderWindow.FormStateCallbackMsg* stateCallbackMsgPtr = (RenderWindow.FormStateCallbackMsg*)pmsgRaw; if (this.m_session.IsForeignByteOrderOnWindowing) MarshalHelper.SwapByteOrder((byte*)stateCallbackMsgPtr, ref s_ByteOrder_FormStateCallbackMsg, typeof(RenderWindow.FormStateCallbackMsg), 0, 0); uint num = 0; if (this.m_currentDisplay != null) num = this.m_currentDisplay.UniqueId; bool flag1 = stateCallbackMsgPtr->fOnSecondaryMonitor != 0; bool flag2 = stateCallbackMsgPtr->cSpanningMonitors > 1U; bool flag3 = false; if (stateCallbackMsgPtr->idDisplay != uint.MaxValue) flag3 = (int)num != (int)stateCallbackMsgPtr->idDisplay || this.m_fOnSecondaryMonitor != flag1 || this.m_fSpanningMonitors != flag2; bool flag4 = this.m_nX != stateCallbackMsgPtr->rcWindowGlobal_left || this.m_nY != stateCallbackMsgPtr->rcWindowGlobal_top; bool flag5 = this.m_nWidth != stateCallbackMsgPtr->szClientDims_cx || this.m_nHeight != stateCallbackMsgPtr->szClientDims_cy; this.m_nX = stateCallbackMsgPtr->rcWindowGlobal_left; this.m_nY = stateCallbackMsgPtr->rcWindowGlobal_top; this.m_nWidth = stateCallbackMsgPtr->szClientDims_cx; this.m_nHeight = stateCallbackMsgPtr->szClientDims_cy; this.m_nWindowState = (WindowState)stateCallbackMsgPtr->uCurrentMode; this.m_fVisible = stateCallbackMsgPtr->fVisible != 0; this.m_fSpanningMonitors = flag2; this.m_fOnSecondaryMonitor = flag1; this.SetFullScreenExclusive(stateCallbackMsgPtr->fExclusive != 0); bool fActivation = this.m_fActivation; this.m_fActivation = stateCallbackMsgPtr->uActivation == 1U; if (flag3) this.m_currentDisplay = this.m_displayManager.DisplayFromUniqueId(stateCallbackMsgPtr->idDisplay); if (flag3) this.OnMonitorChanged(); if (flag4) this.OnLocationChanged(); if (flag5) { this.m_rootVisual.Size = new Vector2(m_nWidth, m_nHeight); this.OnSizeChanged(); } if (((int)stateCallbackMsgPtr->uRecentlyChanged & 1) != 0) this.OnWindowStateChanged(((int)stateCallbackMsgPtr->uRecentlyChanged & 256) != 0); if (((int)stateCallbackMsgPtr->uRecentlyChanged & 4) != 0) { bool fFirstShow = this.m_fVisible && !this.m_fShownBefore; if (this.m_fVisible) this.m_fShownBefore = true; this.OnShow(this.m_fVisible, fFirstShow); } if (((int)stateCallbackMsgPtr->uRecentlyChanged & 2) == 0 || this.m_fActivation == fActivation) return; this.OnActivationChange(); } void IFormWindowCallback.OnPartialDrop(RENDERHANDLE target, string file) { if (this.m_partialDropData == null) this.m_partialDropData = new ArrayList(); this.m_partialDropData.Add(file); } void IFormWindowCallback.OnDropComplete(RENDERHANDLE target) { if (this.m_partialDropData == null || this.m_partialDropData.Count <= 0) return; IEnumerable partialDropData = m_partialDropData; this.m_partialDropData = null; this.OnDroppedFiles(partialDropData); } void IFormWindowCallback.OnSetFocus( RENDERHANDLE target, bool focused, HWND hwndFocusChange) { this.m_fFocused = focused; int num = focused ? 1 : 0; if (this.SetFocusEvent == null) return; this.SetFocusEvent(focused); } void IFormWindowCallback.OnShellShutdownHook( RENDERHANDLE target, ushort hookId) { RenderWindow.ShutdownHookInfo shutdownHookInfo; if (!this.m_mapShutdownHooks.TryGetValue(hookId, out shutdownHookInfo)) return; shutdownHookInfo.OnHook(this, EventArgs.Empty); } void IFormWindowCallback.OnNativeScreensave( RENDERHANDLE target, bool fStartScreensave) { this.m_session.DeferredInvoke(new DeferredHandler(this.DoNativeScreensave), fStartScreensave, DeferredInvokePriority.Idle); } private void DoNativeScreensave(object objParam) => this.OnNativeScreensave((bool)objParam); private void DoPopAnimations(object objParam) { } void IFormWindowCallback.OnRendererSuspended( RENDERHANDLE target, bool fSuspended) { this.FireRendererSuspended(fSuspended); } private void FireRendererSuspended(bool fSuspended) { if (this.RendererSuspendedEvent == null) return; this.RendererSuspendedEvent(m_device, new RenderWindow.RendererSuspendedArgs(fSuspended)); } internal RenderWindow.RenderFlags GlobalRenderFlags { get => this.m_renderFlags; set => this.SetGlobalRenderFlags(value, RenderFlags.All); } internal bool SetGlobalRenderFlags( RenderWindow.RenderFlags flags, RenderWindow.RenderFlags mask) { bool flag = false; RenderWindow.RenderFlags renderFlags = this.m_renderFlags & ~mask | flags & mask; if (this.m_renderFlags != renderFlags) { this.m_renderFlags = renderFlags; flag = true; this.m_remoteWindow.SendChangeDataBits((uint)flags, (uint)mask); } return flag; } public void SetWindowOptions(WindowOptions optionMask, bool enable) { if (!this.m_session.IsValid) return; this.m_remoteWindow.SendSetOptions((uint)optionMask, enable ? (uint)optionMask : 0U); } public void SetMouseIdleOptions(Size mouseIdleTolerance, uint mouseIdleDelay) { if (!this.m_session.IsValid) return; this.m_remoteWindow.SendSetMouseIdleOptions(mouseIdleTolerance, mouseIdleDelay); } public void ForwardWindowMessage(ref Win32Api.MSG msg) { if (msg.message < 256U || msg.message > 265U) return; this.OnForwardWndMsg(msg.message, msg.wParam, msg.lParam); } private void BuildRootContainer() { this.m_remoteWindow.SendSetSize(this.m_szDefault); this.m_remoteWindow.SendCreateRootContainer(); this.m_remoteWindow.SendSetHitMasks(1U, 2U, 4U, 8U); RemoteVisual remoteVisual; this.m_rootVisual = new VisualContainer(true, this.m_session, this, null, out remoteVisual); this.m_rootVisual.RegisterUsage(this); this.m_remoteWindow.SendSetRoot(remoteVisual); this.m_rootVisual.Size = new Vector2(m_nWidth, m_nHeight); } void IRenderWindow.ClientToScreen(ref Point point) { Win32Api.POINT pt; pt.x = !this.m_fRightToLeft ? point.X : this.ClientSize.Width - point.X; pt.y = point.Y; Win32Api.ClientToScreen(this.m_hwnd, ref pt); point.X = pt.x; point.Y = pt.y; } void IRenderWindow.ScreenToClient(ref Point point) { Win32Api.POINT pt; pt.x = point.X; pt.y = point.Y; Win32Api.ScreenToClient(this.m_hwnd, ref pt); point.X = !this.m_fRightToLeft ? pt.x : this.ClientSize.Width - pt.x; point.Y = pt.y; } void IRenderWindow.TakeFocus() => this.Focus(); private void Focus() { if (!this.m_session.IsValid) return; this.m_remoteWindow.SendTakeFocus(); } void IRenderWindow.TakeForeground(bool fForce) { if (!this.m_session.IsValid) return; this.m_remoteWindow.SendSetForeground(fForce); } void IRenderWindow.BringToTop() { if (!this.m_session.IsValid) return; this.m_remoteWindow.SendBringToTop(); } void IRenderWindow.RefreshHitTarget() { if (!this.m_session.IsValid) return; this.m_remoteWindow.SendRefreshHitTarget(); } private void EngineCloseRequest() { if (this.CloseRequestEvent != null) this.CloseRequestEvent(); else this.Close(FormCloseReason.RendererRequest); } public void Close(FormCloseReason nReason) { if (this.m_fClosing) return; this.ForceCloseWorker(nReason); } private void ForceClose() => this.ForceCloseWorker(FormCloseReason.ForcedClose); private void ForceCloseWorker(FormCloseReason nReason) { if (this.m_fClosing) return; this.m_fClosing = true; if (!this.m_session.IsValid) return; this.m_remoteWindow.SendDestroy(); } public void PushWaitCursor(Cursor cursor) { if (this.m_stkWaitCursors == null) this.m_stkWaitCursors = new Stack(); this.m_stkWaitCursors.Push(cursor); this.UpdateCursors(); } public void PopWaitCursor() { this.m_stkWaitCursors.Pop(); this.UpdateCursors(); } public void ForceMouseIdle(bool fIdle) { if (!this.m_session.IsValid) return; this.m_remoteWindow.SendForceMouseIdle(fIdle); } public void SetCapture(IRawInputSite captureSite, bool state) { if (captureSite == null) return; this.m_remoteWindow.SendSetCapture((captureSite as Visual).RemoteStub, state); } public void SetBackgroundColor(ColorF color) { if (!(this.m_clrBackground != color)) return; this.m_clrBackground = color; if (!this.m_session.IsValid) return; this.m_remoteWindow.SendSetBackgroundColor(color); } public void SetIcon(string sModuleName, uint nResourceID, IconFlags nOptions) { if (!this.m_session.IsValid) return; this.m_remoteWindow.SendSetIcon(sModuleName, nResourceID, (uint)nOptions); } public void SetEdgeImages(bool fActiveEdges, ShadowEdgePart[] edges) { if (!this.m_session.IsValid) return; Debug2.Validate(edges != null, null, "Must pass non-null edges set"); Debug2.Validate(edges.Length == 4, null, "Must pass exactly 4 edges, LTRB"); for (int index = 0; index < 4; ++index) { Debug2.Validate(edges[index].ModuleName != null, null, "Must pass non-null ModuleName:" + index.ToString()); Debug2.Validate(edges[index].ResourceName != null, null, "Must pass non-null ResourceName:" + index.ToString()); } Debug2.Validate(string.Equals(edges[0].ModuleName, edges[1].ModuleName), null, "Module names differ - not supported"); Debug2.Validate(string.Equals(edges[0].ModuleName, edges[2].ModuleName), null, "Module names differ - not supported"); Debug2.Validate(string.Equals(edges[0].ModuleName, edges[3].ModuleName), null, "Module names differ - not supported"); Debug2.Validate(edges[0].SplitPoints == edges[2].SplitPoints, null, "L+R splits differ - not supported"); Debug2.Validate(edges[1].SplitPoints == edges[3].SplitPoints, null, "T+B splits differ - not supported"); Inset insetSplits = new Inset(edges[1].SplitPoints.Left, edges[0].SplitPoints.Top, edges[1].SplitPoints.Right, edges[0].SplitPoints.Bottom); this.m_remoteWindow.SendSetEdgeImageParts(fActiveEdges, edges[0].ModuleName, edges[0].ResourceName, edges[1].ResourceName, edges[2].ResourceName, edges[3].ResourceName, insetSplits); } public bool EnableExternalDragDrop { get => this.m_fEnableExternalDragDrop; set { if (this.m_fEnableExternalDragDrop == value) return; this.m_fEnableExternalDragDrop = value; if (!this.m_session.IsValid) return; this.m_remoteWindow.SendEnableExternalDragDrop(value); } } public void SetDragDropResult(uint nDragOverResult, uint nDragDropResult) { if ((int)this.m_nDragOverResult == (int)nDragOverResult && (int)this.m_nDragDropResult == (int)nDragDropResult) return; this.m_nDragDropResult = nDragDropResult; this.m_nDragOverResult = nDragOverResult; if (!this.m_session.IsValid) return; this.m_remoteWindow.SendSetDragDropResult(nDragOverResult, nDragDropResult); } public bool IsDragInProgress { get => this.m_fIsDragInProgress; set { if (this.m_fIsDragInProgress == value) return; this.m_fIsDragInProgress = value; if (!this.m_session.IsValid) return; if (this.m_fIsDragInProgress) this.m_remoteWindow.SendEnterInternalDrag(); else this.m_remoteWindow.SendExitInternalDrag(); } } public void Restore() { if (!this.m_session.IsValid) return; this.m_remoteWindow.SendRestore(); } public void TemporarilyExitExclusiveMode() { if (!this.m_session.IsValid) return; this.m_remoteWindow.SendTemporarilyExitExclusiveMode(); } public IHwndHostWindow CreateHwndHostWindow() => new HwndHostWindow(this); public void UnlockForegroundWindow() { if (!this.m_session.IsValid) return; this.m_remoteWindow.SendUpdateForegroundLockState(); } public void BringToTop() { if (!this.m_session.IsValid) return; this.m_remoteWindow.SendBringToTop(); } public void LockMouseActive(bool fLock) { if (fLock) { ++this.m_nMouseLockCount; if (this.m_nMouseLockCount != 1) return; this.SetWindowOptions(WindowOptions.LockMouseActive, true); } else { this.m_nMouseLockCount = Math.Max(this.m_nMouseLockCount - 1, 0); if (this.m_nMouseLockCount != 0) return; this.SetWindowOptions(WindowOptions.LockMouseActive, false); } } private void UpdateText(bool fChanged) { if (!(this.m_hwnd != HWND.NULL) || this.m_stText == null && !fChanged || !this.m_session.IsValid) return; this.m_remoteWindow.SendSetText(this.Text); } private void UpdateCursors() { Cursor cursor1 = Cursor.NullCursor; Cursor nullCursor = Cursor.NullCursor; Cursor cursor2 = null; if (this.m_stkWaitCursors != null && this.m_stkWaitCursors.Count > 0) cursor2 = this.m_stkWaitCursors.Peek() as Cursor; Cursor cursor3; if (cursor2 != null) { cursor1 = cursor3 = cursor2; } else { if (this.m_cursor != null) cursor1 = this.m_cursor; cursor3 = this.m_cursorIdle == null ? cursor1 : this.m_cursorIdle; } if (!this.m_session.IsValid) return; this.m_remoteWindow.SendSetCursors(cursor1.ResourceId, cursor3.ResourceId); } public bool IsPreProcessedInput => this.m_fPreProcessedInput; public delegate void RendererSuspendedHandler( object sender, RenderWindow.RendererSuspendedArgs args); internal class ShutdownHookInfo { private string m_stHookId; public ShutdownHookInfo(string stHookId) => this.m_stHookId = stHookId; public event EventHandler Handler; public void OnHook(object sender, EventArgs args) { if (this.Handler == null) return; this.Handler(sender, args); } public override bool Equals(object obj) => obj is RenderWindow.ShutdownHookInfo shutdownHookInfo && this.m_stHookId == shutdownHookInfo.m_stHookId; public override int GetHashCode() => this.m_stHookId.GetHashCode(); } internal class RendererSuspendedArgs : EventArgs { private bool m_fSuspended; public RendererSuspendedArgs(bool fSuspended) => this.m_fSuspended = fSuspended; public bool Suspended => this.m_fSuspended; } [System.Flags] internal enum RenderFlags { None = 0, DebugPainting = 1, OutlineMarked = 2, OutlineAll = 4, RenderDump = 8, Wireframe = 16, // 0x00000010 InvalidationDebug = 32, // 0x00000020 NoLighting = 64, // 0x00000040 NoVertexAlpha = 128, // 0x00000080 NoTextures = 256, // 0x00000100 NoAlpha = 512, // 0x00000200 RemoteDebugMode = 1024, // 0x00000400 DumpRopsOneTime = 2048, // 0x00000800 All = DumpRopsOneTime | RemoteDebugMode | NoAlpha | NoTextures | NoVertexAlpha | NoLighting | InvalidationDebug | Wireframe | RenderDump | OutlineAll | OutlineMarked | DebugPainting, // 0x00000FFF } [ComVisible(false)] private struct FormStateCallbackMsg { public uint cbSize; public int nMsg; public RENDERHANDLE idObjectSubject; public uint uRecentlyChanged; public uint uCurrentMode; public uint uActivation; public int fVisible; public int szClientDims_cx; public int szClientDims_cy; public int rcWindowGlobal_left; public int rcWindowGlobal_top; public int rcWindowGlobal_right; public int rcWindowGlobal_bottom; public uint idDisplay; public uint cSpanningMonitors; public int fExclusive; public int fOnSecondaryMonitor; } } }