internal static void UnhookHwndSubclass(HwndSubclass subclass) { // if exiting the AppDomain, ignore this call. This avoids changing // the list during the loop in OnAppDomainProcessExit if (_exiting) return; lock (_hwndList) { _hwndList.Remove(subclass); } }
internal static void UnhookHwndSubclass(HwndSubclass subclass) { // if exiting the AppDomain, ignore this call. This avoids changing // the list during the loop in OnAppDomainProcessExit if (_exiting) { return; } lock (_hwndList) { _hwndList.Remove(subclass); } }
internal static void TrackHwndSubclass(HwndSubclass subclass, IntPtr hwnd) { lock (_hwndList) { // We use HwndSubclass as the key and the hwnd ptr as the value. // This supports the case where two (or more) HwndSubclasses // get attached to the same Hwnd. At AppDomain shutdown, we may // end up sending the Detach message to the Hwnd more than once, // but that won't cause any harm. _hwndList[subclass] = hwnd; } #if LOGGING LogStartHWND(hwnd, "Core HwndWrapper..ctor"); #endif }
public HwndWrapper( int classStyle, int style, int exStyle, int x, int y, int width, int height, string name, IntPtr parent, HwndWrapperHook[] hooks) { _ownerThreadID = new SecurityCriticalDataForSet <int>(Thread.CurrentThread.ManagedThreadId); // First, add the set of hooks. This allows the hooks to receive the // messages sent to the window very early in the process. if (hooks != null) { for (int i = 0, iEnd = hooks.Length; i < iEnd; i++) { if (null != hooks[i]) { AddHook(hooks[i]); } } } _wndProc = new SecurityCriticalData <HwndWrapperHook>(new HwndWrapperHook(WndProc)); // We create the HwndSubclass object so that we can use its // window proc directly. We will not be "subclassing" the // window we create. HwndSubclass hwndSubclass = new HwndSubclass(_wndProc.Value); // Register a unique window class for this instance. NativeMethods.WNDCLASSEX_D wc_d = new NativeMethods.WNDCLASSEX_D(); IntPtr hNullBrush = UnsafeNativeMethods.CriticalGetStockObject(NativeMethods.NULL_BRUSH); if (hNullBrush == IntPtr.Zero) { throw new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error()); } IntPtr hInstance = UnsafeNativeMethods.GetModuleHandle(null); // We need to keep the Delegate object alive through the call to CreateWindowEx(). // Subclass.WndProc will install a better delegate (to the same function) when it // processes the first message. // But this first delegate needs be held alive until then. NativeMethods.WndProc initialWndProc = new NativeMethods.WndProc(hwndSubclass.SubclassWndProc); // The class name is a concat of AppName, ThreadName, and RandomNumber. // Register will fail if the string gets over 255 in length. // So limit each part to a reasonable amount. string appName; if (null != AppDomain.CurrentDomain.FriendlyName && 128 <= AppDomain.CurrentDomain.FriendlyName.Length) { appName = AppDomain.CurrentDomain.FriendlyName.Substring(0, 128); } else { appName = AppDomain.CurrentDomain.FriendlyName; } string threadName; if (null != Thread.CurrentThread.Name && 64 <= Thread.CurrentThread.Name.Length) { threadName = Thread.CurrentThread.Name.Substring(0, 64); } else { threadName = Thread.CurrentThread.Name; } // Create a suitable unique class name. _classAtom = 0; string randomName = Guid.NewGuid().ToString(); string className = String.Format(CultureInfo.InvariantCulture, "HwndWrapper[{0};{1};{2}]", appName, threadName, randomName); wc_d.cbSize = Marshal.SizeOf(typeof(NativeMethods.WNDCLASSEX_D)); wc_d.style = classStyle; wc_d.lpfnWndProc = initialWndProc; wc_d.cbClsExtra = 0; wc_d.cbWndExtra = 0; wc_d.hInstance = hInstance; wc_d.hIcon = IntPtr.Zero; wc_d.hCursor = IntPtr.Zero; wc_d.hbrBackground = hNullBrush; wc_d.lpszMenuName = ""; wc_d.lpszClassName = className; wc_d.hIconSm = IntPtr.Zero; // Register the unique class for this instance. // Note we use a GUID in the name so we are confident that // the class name should be unique. And RegisterClassEx won't // fail (for that reason). _classAtom = UnsafeNativeMethods.RegisterClassEx(wc_d); // call CreateWindow _isInCreateWindow = true; try { _handle = new SecurityCriticalDataClass <IntPtr>(UnsafeNativeMethods.CreateWindowEx(exStyle, className, name, style, x, y, width, height, new HandleRef(null, parent), new HandleRef(null, IntPtr.Zero), new HandleRef(null, IntPtr.Zero), null)); } finally { _isInCreateWindow = false; if (_handle == null || _handle.Value == IntPtr.Zero) { // Because the HwndSubclass is pinned, but the HWND creation failed, // we need to manually clean it up. hwndSubclass.Dispose(); } } GC.KeepAlive(initialWndProc); }
private void BuildWindow(HandleRef hwndParent) { // Demand unmanaged code to the caller. IT'S RISKY TO REMOVE THIS DemandIfUntrusted(); // Allow the derived class to build our HWND. _hwnd = BuildWindowCore(hwndParent); if(_hwnd.Handle == IntPtr.Zero || !UnsafeNativeMethods.IsWindow(_hwnd)) { throw new InvalidOperationException(SR.Get(SRID.ChildWindowNotCreated)); } // Make sure that the window that was created is indeed a child window. int windowStyle = UnsafeNativeMethods.GetWindowLong(new HandleRef(this,_hwnd.Handle), NativeMethods.GWL_STYLE); if((windowStyle & NativeMethods.WS_CHILD) == 0) { throw new InvalidOperationException(SR.Get(SRID.HostedWindowMustBeAChildWindow)); } // Make sure the child window is the child of the expected parent window. if(hwndParent.Handle != UnsafeNativeMethods.GetParent(_hwnd)) { throw new InvalidOperationException(SR.Get(SRID.ChildWindowMustHaveCorrectParent)); } // Only subclass the child HWND if it is owned by our thread. int idWindowProcess; int idWindowThread = UnsafeNativeMethods.GetWindowThreadProcessId(_hwnd, out idWindowProcess); #if WCP_SERVER2003_OR_LATER_ENABLED IntPtr hCurrentThread = UnsafeNativeMethods.GetCurrentThread(); if ((idWindowThread == SafeNativeMethods.GetThreadId(hCurrentThread)) && (idWindowProcess == UnsafeNativeMethods.GetProcessIdOfThread(hCurrentThread))) #else if ((idWindowThread == SafeNativeMethods.GetCurrentThreadId()) && (idWindowProcess == SafeNativeMethods.GetCurrentProcessId())) #endif { _hwndSubclass = new HwndSubclass(_hwndSubclassHook); _hwndSubclass.CriticalAttach(_hwnd.Handle); } // Initially make sure the window is hidden. We will show it later during rendering. UnsafeNativeMethods.ShowWindowAsync(_hwnd, NativeMethods.SW_HIDE); // Assume the desired size is the initial size. If the window was // created with a 0-length dimension, we assume this means we // should fill all available space. NativeMethods.RECT rc = new NativeMethods.RECT(); SafeNativeMethods.GetWindowRect(_hwnd, ref rc); // Convert from pixels to measure units. // PresentationSource can't be null if we get here. PresentationSource source = PresentationSource.CriticalFromVisual(this, false /* enable2DTo3DTransition */); Point ptUpperLeft = new Point(rc.left, rc.top); Point ptLowerRight = new Point(rc.right, rc.bottom); ptUpperLeft = source.CompositionTarget.TransformFromDevice.Transform(ptUpperLeft); ptLowerRight = source.CompositionTarget.TransformFromDevice.Transform(ptLowerRight); _desiredSize = new Size(ptLowerRight.X - ptUpperLeft.X, ptLowerRight.Y - ptUpperLeft.Y); // We have a new desired size, so invalidate measure. InvalidateMeasure(); }
public HwndWrapper( int classStyle, int style, int exStyle, int x, int y, int width, int height, string name, IntPtr parent, HwndWrapperHook[] hooks) { _ownerThreadID = new SecurityCriticalDataForSet<int>(Thread.CurrentThread.ManagedThreadId); // First, add the set of hooks. This allows the hooks to receive the // messages sent to the window very early in the process. if(hooks != null) { for(int i = 0, iEnd = hooks.Length; i < iEnd; i++) { if(null != hooks[i]) AddHook(hooks[i]); } } _wndProc = new SecurityCriticalData<HwndWrapperHook>(new HwndWrapperHook(WndProc)); // We create the HwndSubclass object so that we can use its // window proc directly. We will not be "subclassing" the // window we create. HwndSubclass hwndSubclass = new HwndSubclass(_wndProc.Value); // Register a unique window class for this instance. NativeMethods.WNDCLASSEX_D wc_d = new NativeMethods.WNDCLASSEX_D(); IntPtr hNullBrush = UnsafeNativeMethods.CriticalGetStockObject(NativeMethods.NULL_BRUSH); if (hNullBrush == IntPtr.Zero) { throw new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error()); } IntPtr hInstance = UnsafeNativeMethods.GetModuleHandle( null ); // We need to keep the Delegate object alive through the call to CreateWindowEx(). // Subclass.WndProc will install a better delegate (to the same function) when it // processes the first message. // But this first delegate needs be held alive until then. NativeMethods.WndProc initialWndProc = new NativeMethods.WndProc(hwndSubclass.SubclassWndProc); // The class name is a concat of AppName, ThreadName, and RandomNumber. // Register will fail if the string gets over 255 in length. // So limit each part to a reasonable amount. string appName; if(null != AppDomain.CurrentDomain.FriendlyName && 128 <= AppDomain.CurrentDomain.FriendlyName.Length) appName = AppDomain.CurrentDomain.FriendlyName.Substring(0, 128); else appName = AppDomain.CurrentDomain.FriendlyName; string threadName; if(null != Thread.CurrentThread.Name && 64 <= Thread.CurrentThread.Name.Length) threadName = Thread.CurrentThread.Name.Substring(0, 64); else threadName = Thread.CurrentThread.Name; // Create a suitable unique class name. _classAtom = 0; string randomName = Guid.NewGuid().ToString(); string className = String.Format(CultureInfo.InvariantCulture, "HwndWrapper[{0};{1};{2}]", appName, threadName, randomName); wc_d.cbSize = Marshal.SizeOf(typeof(NativeMethods.WNDCLASSEX_D)); wc_d.style = classStyle; wc_d.lpfnWndProc = initialWndProc; wc_d.cbClsExtra = 0; wc_d.cbWndExtra = 0; wc_d.hInstance = hInstance; wc_d.hIcon = IntPtr.Zero; wc_d.hCursor = IntPtr.Zero; wc_d.hbrBackground = hNullBrush; wc_d.lpszMenuName = ""; wc_d.lpszClassName = className; wc_d.hIconSm = IntPtr.Zero; // Register the unique class for this instance. // Note we use a GUID in the name so we are confident that // the class name should be unique. And RegisterClassEx won't // fail (for that reason). _classAtom = UnsafeNativeMethods.RegisterClassEx(wc_d); // call CreateWindow _isInCreateWindow = true; try { _handle = new SecurityCriticalDataClass<IntPtr>(UnsafeNativeMethods.CreateWindowEx(exStyle, className, name, style, x, y, width, height, new HandleRef(null,parent), new HandleRef(null,IntPtr.Zero), new HandleRef(null,IntPtr.Zero), null)); } finally { _isInCreateWindow = false; if(_handle == null || _handle.Value == IntPtr.Zero) { new UIPermission(UIPermissionWindow.AllWindows).Assert(); //BlessedAssert to call Dispose try { // Because the HwndSubclass is pinned, but the HWND creation failed, // we need to manually clean it up. hwndSubclass.Dispose(); } finally { CodeAccessPermission.RevertAssert(); } } } GC.KeepAlive(initialWndProc); }