Esempio n. 1
0
        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);
            }
        }
Esempio n. 2
0
        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);
            }
        }
Esempio n. 3
0
        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
        }
Esempio n. 4
0
        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
        }
Esempio n. 5
0
        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);
        }
Esempio n. 6
0
        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();
        }
Esempio n. 7
0
        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);
        }