HwndKeyboardInputProvider.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ DotNET / DotNET / 8.0 / untmp / WIN_WINDOWS / lh_tools_devdiv_wpf / Windows / wcp / Core / System / Windows / InterOp / HwndKeyboardInputProvider.cs / 2 / HwndKeyboardInputProvider.cs

                            using System.Windows.Input; 
using System.Windows.Media;
using System.Windows.Threading;
using System.Diagnostics;
using System.Runtime.InteropServices; 
using System.Security;
using System.Security.Permissions; 
using MS.Utility; 
using MS.Internal;
using MS.Win32; 
using MS.Internal.PresentationCore;

using SR=MS.Internal.PresentationCore.SR;
using SRID=MS.Internal.PresentationCore.SRID; 

namespace System.Windows.Interop 
{ 

    internal sealed class HwndKeyboardInputProvider : DispatcherObject, IKeyboardInputProvider, IDisposable 
    {
        /// 
        ///     Accesses and store critical data. This class is also critical (_site and _source)
        ///  
        [SecurityCritical]
        internal HwndKeyboardInputProvider(HwndSource source) 
        { 
            (new UIPermission(PermissionState.Unrestricted)).Assert();
            try //Blessed assert for InputManager.Current.RegisterInputProvider 
            {
                _site = new SecurityCriticalDataClass(InputManager.Current.RegisterInputProvider(this));
            }
            finally 
            {
                UIPermission.RevertAssert(); 
            } 
            _source = new SecurityCriticalDataClass(source);
        } 



        ///  
        ///     Critical:This class accesses critical data, _site.
        ///     TreatAsSafe: This class does not expose the critical data 
        ///  
        [SecurityCritical, SecurityTreatAsSafe]
        public void Dispose() 
        {
            if(_site != null)
            {
                _site.Value.Dispose(); 
                _site = null;
            } 
            _source = null; 
        }
 
        public void OnRootChanged(Visual oldRoot, Visual newRoot)
        {
            if(_active && newRoot != null)
            { 
                Keyboard.Focus(null); // internally we will set the focus to the root.
            } 
        } 
        /// 
        ///     Critical: As this accesses critical data HwndSource 
        ///     TreatAsSafe:Information about whether a given input provider services
        ///     a visual is safe to expose. This method does not expose the critical data either.
        /// 
        [SecurityCritical,SecurityTreatAsSafe] 
        bool IInputProvider.ProvidesInputForRootVisual(Visual v)
        { 
            Debug.Assert( null != _source ); 

            return _source.Value.RootVisual == v; 
        }

        void IInputProvider.NotifyDeactivate()
        { 
            _active        = false;
            _partialActive = false; 
        } 

        ///  
        ///     SecurityCritical: This code calls into GetWindowLong/GetFocus both of which are
        ///     critical.It also retrieves the handle to the current
        ///     window that has focus.Additionally it also calls into SetFocus which also
        ///     returns a critical resouce in the form of a window handle. In this case all that is 
        ///     retrieved is the extended window style and that data is not exposed.
        ///     It is simply used to detect if the window is set to WS_EX_NOACTIVATE. 
        ///     The risky operation here is the call to SetFocus. 
        /// 
        [SecurityCritical] 
        bool IKeyboardInputProvider.AcquireFocus()
        {
            bool success = false;
 
            Debug.Assert( null != _source );
 
            try 
            {
                int windowStyle = UnsafeNativeMethods.GetWindowLong(new HandleRef(this, _source.Value.CriticalHandle), NativeMethods.GWL_EXSTYLE); 
                if((windowStyle & NativeMethods.WS_EX_NOACTIVATE) == NativeMethods.WS_EX_NOACTIVATE)
                {
                    // If this window has the WS_EX_NOACTIVATE style, then we do
                    // not request keyboard focus.  Doing so will actually activate 
                    // the window.  If this window is part of a thread with other
                    // windows, keyboard input from them can actually be directed 
                    // to elements within this window.  Menus/ComboBoxes use this. 
                }
                else 
                {
                    // Attempt to set the focus to ourselves.
                    //
                    // However, there are scenarios where this won't work: if a 
                    // worker thread calls this API, Win32 will ignore it.  If
                    // we are running while a window that a different thread 
                    // created has focus, then Win32 will also ignore it. 

                    // we do not want the resulting WM_SETFOCUS message 
                    // to give focus to a child window
                    _restoreFocusWindow = IntPtr.Zero;

                    UnsafeNativeMethods.SetFocus(new HandleRef(this, _source.Value.CriticalHandle)); 
                }
 
                // We can only claim the attempt to acquire focus succeeded if 
                // one of our windows has focus.  In that case, keyboard input
                // will get properly forwarded to the element. 
                if(!_active)
                {
                    IntPtr focus = UnsafeNativeMethods.GetFocus();
                    success = IsOurWindow(focus); 
                }
                else 
                { 
                    success = true;
                } 
            }
            catch(System.ComponentModel.Win32Exception)
            {
                System.Diagnostics.Debug.WriteLine("HwndMouseInputProvider: GetFocus failed!"); 
            }
 
            return success; 
        }
        //[CodeAnalysis("AptcaMethodsShouldOnlyCallAptcaMethods")] //Tracking Bug: 29647 
        /// 
        ///     Critical: This code is critical since it handles all keyboard messages and could be used to spoof input
        /// 
        [SecurityCritical] 
        internal IntPtr FilterMessage(IntPtr hwnd, int message, IntPtr wParam, IntPtr lParam, ref bool handled)
        { 
            IntPtr result = IntPtr.Zero ; 

            // It is possible to be re-entered during disposal.  Just return. 
            if(null == _source || null == _source.Value)
            {
                return result;
            } 

            _msgTime = 0; 
            try 
            {
                _msgTime = SafeNativeMethods.GetMessageTime(); 
            }
            catch(System.ComponentModel.Win32Exception)
            {
                System.Diagnostics.Debug.WriteLine("HwndKeyboardInputProvider: GetMessageTime failed!"); 
            }
 
            // MITIGATION: HANDLED_KEYDOWN_STILL_GENERATES_CHARS 
            if(message ==  HwndSource._msgEnableCharMessages)
            { 
                // This is our cue to go back to accepting character messages
                HwndSource._eatCharMessages = false;
            }
 
            switch(message)
            { 
                // WM_KEYDOWN is sent when a nonsystem key is pressed. 
                // A nonsystem key is a key that is pressed when the ALT key
                // is not pressed. 
                // WM_SYSKEYDOWN is sent when a system key is pressed.
                case NativeMethods.WM_SYSKEYDOWN:
                case NativeMethods.WM_KEYDOWN:
                { 
                    // If we have a IKeyboardInputSite, then we should have already
                    // called ProcessKeyDown (from TranslateAccelerator) 
                    // But there are several paths (our message pump / app's message 
                    // pump) where we do (or don't) call through IKeyboardInputSink.
                    // So the best way is to just check here if we already did it. 
                    if(_source.Value.IsRepeatedKeyboardMessage(hwnd, message, wParam, lParam))
                    {
                        break;
                    } 

                    // We will use the current time before generating KeyDown events so we can filter 
                    // the later posted WM_CHAR. 
                    int currentTime = 0;
                    try 
                    {
                        currentTime = SafeNativeMethods.GetTickCount();
                    }
                    catch(System.ComponentModel.Win32Exception) 
                    {
                        System.Diagnostics.Debug.WriteLine("HwndMouseInputProvider: GetTickCount failed!"); 
                    } 

                    // MITIGATION: HANDLED_KEYDOWN_STILL_GENERATES_CHARS 
                    // In case a nested message pump is used before we return
                    // from processing this message, we disable character
                    // messages.
                    HwndSource._eatCharMessages = true; 

                    MSG msg = new MSG(hwnd, message, wParam, lParam, _msgTime, 0, 0); 
                    ProcessKeyAction(ref msg, ref handled); 

                    // MITIGATION: HANDLED_KEYDOWN_STILL_GENERATES_CHARS 
                    HwndSource._eatCharMessages = handled;
                    if(HwndSource._eatCharMessages)
                    {
                        UnsafeNativeMethods.PostMessage(new HandleRef(this, hwnd), HwndSource._msgEnableCharMessages, IntPtr.Zero, IntPtr.Zero); 

                    } 
 
                    // System.Console.WriteLine("KEYDOWN(message={0}, wParam={1})={2}", message, wParam, handled);
                } 
                break;

                // WM_KEYUP is sent when a nonsystem key is released.
                // A nonsystem key is a key that is pressed when the ALT key 
                // is not pressed.
                // WM_SYSKEYUP is sent when a system key is released. 
                case NativeMethods.WM_SYSKEYUP: 
                case NativeMethods.WM_KEYUP:
                { 
                    if(_source.Value.IsRepeatedKeyboardMessage(hwnd, message, wParam, lParam))
                    {
                        break;
                    } 

                    MSG msg = new MSG(hwnd, message, wParam, lParam, _msgTime, 0, 0); 
                    ProcessKeyAction(ref msg, ref handled); 
                    // System.Console.WriteLine("KEYUP  (message={0}, wParam={1})={2}", message, wParam, handled);
                } 
                break;

                //
 
                case NativeMethods.WM_CHAR:
                case NativeMethods.WM_DEADCHAR: 
                case NativeMethods.WM_SYSCHAR: 
                case NativeMethods.WM_SYSDEADCHAR:
                { 
                    if(_source.Value.IsRepeatedKeyboardMessage(hwnd, message, wParam, lParam))
                    {
                        break;
                    } 

                    // MITIGATION: HANDLED_KEYDOWN_STILL_GENERATES_CHARS 
                    if(HwndSource._eatCharMessages) 
                    {
                        break; 
                    }

                    ProcessTextInputAction(hwnd, message, wParam, lParam, ref handled);
                    // System.Console.WriteLine("CHAR(message={0}, wParam={1})={2}", message, wParam, handled); 
                }
                break; 
 
                case NativeMethods.WM_EXITMENULOOP:
                case NativeMethods.WM_EXITSIZEMOVE: 
                {
                    // MITIGATION: KEYBOARD_STATE_OUT_OF_SYNC
                    //
                    // Avalon relies on keeping it's copy of the keyboard 
                    // state.  This is for a number of reasons, including that
                    // we need to be able to give this state to worker threads. 
                    // 
                    // There are a number of cases where Win32 eats the
                    // keyboard messages, and this can cause our keyboard 
                    // state to become stale.  Obviously this can happen when
                    // another app is in the foreground, but we handle that
                    // by re-synching our keyboard state when we get focus.
                    // 
                    // Other times are when Win32 enters a nested loop.  While
                    // any one could enter a nested loop at any time for any 
                    // reason, Win32 is nice enough to let us know when it is 
                    // finished with the two common loops: menus and sizing.
                    // We re-sync our keyboard device in response to these. 
                    //
                    if(_active)
                    {
                        _partialActive = true; 

                        ReportInput(hwnd, 
                                    InputMode.Foreground, 
                                    _msgTime,
                                    RawKeyboardActions.Activate, 
                                    0,
                                    false,
                                    false,
                                    0); 
                    }
                } 
                break; 

                // WM_SETFOCUS is sent immediately after focus is granted. 
                // This is our clue that the keyboard is active.
                case NativeMethods.WM_SETFOCUS:
                {
                    if(!_active) 
                    {
                        // Console.WriteLine("WM_SETFOCUS"); 
 
                        ReportInput(hwnd,
                                    InputMode.Foreground, 
                                    _msgTime,
                                    RawKeyboardActions.Activate,
                                    0,
                                    false, 
                                    false,
                                    0); 
 
                        // MITIGATION: KEYBOARD_STATE_OUT_OF_SYNC
                        // 
                        // This is how we deal with the fact that Win32 sometimes sends
                        // us a WM_SETFOCUS message BEFORE it has updated it's internal
                        // internal keyboard state information.  When we get the
                        // WM_SETFOCUS message, we activate the keyboard with the 
                        // keyboard state (even though it could be wrong).  Then when
                        // we get the first "real" keyboard input event, we activate 
                        // the keyboard again, since Win32 will have updated the 
                        // keyboard state correctly by then.
                        // 
                        _partialActive = true;

                        // Restore the keyboard focus to the child window or element that had
                        // the focus before we last lost Win32 focus.  If nothing 
                        // had focus before, set it to null.
                        if (_restoreFocusWindow != IntPtr.Zero) 
                        { 
                            IntPtr hwndRestoreFocus = _restoreFocusWindow;
                            _restoreFocusWindow = IntPtr.Zero; 

                            UnsafeNativeMethods.TrySetFocus(new HandleRef(this, hwndRestoreFocus), ref hwndRestoreFocus);
                        }
                        else 
                        {
                            IInputElement restoreFocus = _restoreFocus; 
                            _restoreFocus = null; 

                            Keyboard.Focus(restoreFocus); 
                        }
                    }

                    handled = true; 
                }
                break; 
 
                // WM_KILLFOCUS is sent immediately before focus is removed.
                // This is our clue that the keyboard is inactive. 
                case NativeMethods.WM_KILLFOCUS:
                {
                    if(_active  &&  wParam != _source.Value.CriticalHandle )
                    { 
                        // Console.WriteLine("WM_KILLFOCUS");
 
                        // when the window that's acquiring focus (wParam) is 
                        // a descendant of our window, remember the immediate
                        // child so that we can restore focus to it. 
                        _restoreFocusWindow = GetImmediateChildFor((IntPtr)wParam, _source.Value.CriticalHandle);

                        // Remember the element that currently has keyboard
                        // focus so that we can restore focus to it when this 
                        // window gets Win32 keyboard focus again.
                        if (_restoreFocusWindow == IntPtr.Zero) 
                        { 
                            _restoreFocus = Keyboard.FocusedElement;
                        } 

                        PossiblyDeactivate((IntPtr)wParam);

                    } 

                    handled = true; 
                } 
                break;
 
                // WM_UPDATEUISTATE is sent when the user presses ALT, expecting
                // the app to display accelerator keys.  We don't always hear the
                // keystroke - another message loop may handle it.  So report it
                // here. 
                case NativeMethods.WM_UPDATEUISTATE:
                { 
                    RawUIStateInputReport report = 
                        new RawUIStateInputReport(_source.Value,
                                                   InputMode.Foreground, 
                                                   _msgTime,
                                                   (RawUIStateActions)NativeMethods.SignedLOWORD((int)wParam),
                                                   (RawUIStateTargets)NativeMethods.SignedHIWORD((int)wParam));
 
                    _site.Value.ReportInput(report);
 
                    handled = true; 
                }
                break; 
            }

            if (handled && EventTrace.IsEnabled(EventTrace.Flags.performance, EventTrace.Level.normal))
            { 
                EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.HWNDMESSAGEGUID),
                                                     MS.Utility.EventType.Info, 
                                                     Dispatcher.GetHashCode(), 
                                                     hwnd.ToInt64(),
                                                     message, 
                                                     (int)wParam,
                                                     (int)lParam);
            }
 
            return result;
        } 
 
        /// 
        ///     Critical:This can be used to spoof input 
        /// 
        [SecurityCritical]
        internal void ProcessKeyAction(ref MSG msg, ref bool handled)
        { 
            // Remember the last message
            MSG previousMSG = ComponentDispatcher.UnsecureCurrentKeyboardMessage; 
            ComponentDispatcher.UnsecureCurrentKeyboardMessage = msg; 

            try 
            {
                int virtualKey = GetVirtualKey(msg.wParam, msg.lParam);
                int scanCode = GetScanCode(msg.wParam, msg.lParam);
                bool isExtendedKey = IsExtendedKey(msg.lParam); 
                bool isSystemKey = ((msg.message == NativeMethods.WM_SYSKEYDOWN) || (msg.message == NativeMethods.WM_SYSKEYUP));
                RawKeyboardActions action = GetKeyUpKeyDown(msg.message); 
 
                // Console.WriteLine("WM_KEYDOWN: " + virtualKey + "," + scanCode);
                handled = ReportInput(msg.hwnd, 
                                      InputMode.Foreground,
                                      _msgTime,
                                      action,
                                      scanCode, 
                                      isExtendedKey,
                                      isSystemKey, 
                                      virtualKey); 
            }
            finally 
            {
                // Restore the last message
                ComponentDispatcher.UnsecureCurrentKeyboardMessage = previousMSG;
            } 
        }
 
        /// 
        /// Critical - calls a critical method _source.Value.
        /// 
        [SecurityCritical ]
        internal void ProcessTextInputAction(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
        {
            char charcode = (char)wParam; 
            bool isDeadChar = ((msg == NativeMethods.WM_DEADCHAR) || (msg == NativeMethods.WM_SYSDEADCHAR));
            bool isSystemChar = ((msg == NativeMethods.WM_SYSCHAR) || (msg == NativeMethods.WM_SYSDEADCHAR)); 
            bool isControlChar = false; 

            // If the control is pressed but Alt is not, the char is control char. 
            try
            {
                if (((UnsafeNativeMethods.GetKeyState(NativeMethods.VK_CONTROL) & 0x8000) != 0) &&
                    ((UnsafeNativeMethods.GetKeyState(NativeMethods.VK_MENU) & 0x8000) == 0) && 
                    Char.IsControl(charcode))
                { 
                    isControlChar = true; 
                }
            } 
            catch(System.ComponentModel.Win32Exception)
            {
                System.Diagnostics.Debug.WriteLine("HwndMouseInputProvider: GetKeyState failed!");
            } 

            RawTextInputReport report = new RawTextInputReport(_source.Value , 
                                                               InputMode.Foreground, 
                                                               _msgTime,
                                                               isDeadChar, 
                                                               isSystemChar,
                                                               isControlChar,
                                                               charcode);
 
            handled = _site.Value.ReportInput(report);
        } 
 
        internal static int GetVirtualKey(IntPtr wParam, IntPtr lParam)
        { 
            int virtualKey = NativeMethods.IntPtrToInt32( wParam);
            int scanCode = 0;
            int keyData = NativeMethods.IntPtrToInt32(lParam);
 
            // Find the left/right instance SHIFT keys.
            if(virtualKey == NativeMethods.VK_SHIFT) 
            { 
                scanCode = (keyData & 0xFF0000) >> 16;
                try 
                {
                    virtualKey = SafeNativeMethods.MapVirtualKey(scanCode, 3);
                    if(virtualKey == 0)
                    { 
                        virtualKey = NativeMethods.VK_LSHIFT;
                    } 
                } 
                catch(System.ComponentModel.Win32Exception)
                { 
                    System.Diagnostics.Debug.WriteLine("HwndMouseInputProvider: MapVirtualKey failed!");

                    virtualKey = NativeMethods.VK_LSHIFT;
                } 
            }
 
            // Find the left/right instance ALT keys. 
            if(virtualKey == NativeMethods.VK_MENU)
            { 
                bool right = ((keyData & 0x1000000) >> 24) != 0;

                if(right)
                { 
                    virtualKey = NativeMethods.VK_RMENU;
                } 
                else 
                {
                    virtualKey = NativeMethods.VK_LMENU; 
                }
            }

            // Find the left/right instance CONTROL keys. 
            if(virtualKey == NativeMethods.VK_CONTROL)
            { 
                bool right = ((keyData & 0x1000000) >> 24) != 0; 

                if(right) 
                {
                    virtualKey = NativeMethods.VK_RCONTROL;
                }
                else 
                {
                    virtualKey = NativeMethods.VK_LCONTROL; 
                } 
            }
 
            return virtualKey;
        }

        internal static int GetScanCode(IntPtr wParam, IntPtr lParam) 
        {
            int keyData = NativeMethods.IntPtrToInt32(lParam); 
 
            int scanCode = (keyData & 0xFF0000) >> 16;
            if(scanCode == 0) 
            {
                try
                {
                    int virtualKey = GetVirtualKey(wParam, lParam); 
                    scanCode = SafeNativeMethods.MapVirtualKey(virtualKey, 0);
                } 
                catch(System.ComponentModel.Win32Exception) 
                {
                    System.Diagnostics.Debug.WriteLine("HwndMouseInputProvider: MapVirtualKey failed!"); 
                }
            }

            return scanCode; 
        }
 
        internal static bool IsExtendedKey(IntPtr lParam) 
        {
            int keyData = NativeMethods.IntPtrToInt32(lParam); 
            return ((keyData & 0x01000000) != 0) ? true : false;
        }

        /// 
        ///     Returns the set of modifier keys currently pressed as determined by calling to Win32
        /// 
        /// 
        ///     Marked as FriendAccessAllowed so HwndHost in PresentationFramework can call it
        /// 
        ///
        ///     Critical: It calls an UnsafeNativeMethod (GetKeyState).
        ///     TreatAsSafe: It's safe to return whether shift, control or alt keys are being pressed or not.
        /// 
        [FriendAccessAllowed]
        [SecurityCritical,SecurityTreatAsSafe] 
        internal static ModifierKeys GetSystemModifierKeys() 
        {
            ModifierKeys modifierKeys = ModifierKeys.None; 

            short keyState = UnsafeNativeMethods.GetKeyState(NativeMethods.VK_SHIFT);
            if((keyState & 0x8000) == 0x8000)
            { 
                modifierKeys |= ModifierKeys.Shift;
            } 
 
            keyState = UnsafeNativeMethods.GetKeyState(NativeMethods.VK_CONTROL);
            if((keyState & 0x8000) == 0x8000) 
            {
                modifierKeys |= ModifierKeys.Control;
            }
 
            keyState = UnsafeNativeMethods.GetKeyState(NativeMethods.VK_MENU);
            if((keyState & 0x8000) == 0x8000) 
            { 
                modifierKeys |= ModifierKeys.Alt;
            } 

            return modifierKeys;
        }
 
        private RawKeyboardActions GetKeyUpKeyDown(int msg)
        { 
            if(  msg == NativeMethods.WM_KEYDOWN || msg == NativeMethods.WM_SYSKEYDOWN ) 
                return RawKeyboardActions.KeyDown;
            if(  msg == NativeMethods.WM_KEYUP || msg == NativeMethods.WM_SYSKEYUP ) 
                return RawKeyboardActions.KeyUp;
            throw new ArgumentException(SR.Get(SRID.OnlyAcceptsKeyMessages));
        }
 
        /// 
        ///     Critical: This code causes this window to loose focus not ok to expose 
        ///               It also calls into a critical code path. 
        /// 
        [SecurityCritical] 
        private void PossiblyDeactivate(IntPtr hwndFocus)
        {
            Debug.Assert( null != _source );
 
            // We are now longer active ourselves, but it is possible that the
            // window the keyboard is going to intereact with is in the same 
            // Dispatcher as ourselves.  If so, we don't want to deactivate the 
            // keyboard input stream because the other window hasn't activated
            // it yet, and it may result in the input stream "flickering" between 
            // active/inactive/active.  This is ugly, so we try to supress the
            // uneccesary transitions.
            //
            bool deactivate = !IsOurWindow(hwndFocus); 

            // This window itself should not be active anymore. 
            _active = false; 

            // Only deactivate the keyboard input stream if needed. 
            if(deactivate)
            {
                ReportInput(_source.Value.CriticalHandle,
                            InputMode.Foreground, 
                            _msgTime,
                            RawKeyboardActions.Deactivate, 
                            0, 
                            false,
                            false, 
                            0);
            }
        }
 
        /// 
        ///     Critical: This code does not store any critical data, it accesses PresentationSource 
        ///     TreatAsSafe: This information is safe to expose 
        /// 
        [SecurityCritical,SecurityTreatAsSafe] 
        private bool IsOurWindow(IntPtr hwnd)
        {
            bool isOurWindow = false;
 
            Debug.Assert( null != _source );
 
            if(hwnd != IntPtr.Zero) 
            {
                HwndSource hwndSource = HwndSource.CriticalFromHwnd(hwnd); 
                if(hwndSource != null)
                {
                    if(hwndSource.Dispatcher == _source.Value.Dispatcher)
                    { 
                        // The window has the same dispatcher, must be ours.
                        isOurWindow = true; 
                    } 
                    else
                    { 
                        // The window has a different dispatcher, must not be ours.
                        isOurWindow = false;
                    }
                } 
                else
                { 
                    // The window is non-Avalon. 
                    // Such windows are never ours.
                    isOurWindow = false; 
                }
            }
            else
            { 
                // This is not even a window.
                isOurWindow = false; 
            } 

            return isOurWindow; 
        }

        // return the immediate child (if any) of hwndRoot that governs the
        // given hwnd.  If hwnd is not a descendant of hwndRoot, return 0. 
        /// 
        ///     Critical:This method calls critical methods 
        ///  
        [SecurityCritical]
        private IntPtr GetImmediateChildFor(IntPtr hwnd, IntPtr hwndRoot) 
        {
            while (hwnd != IntPtr.Zero)
            {
                IntPtr hwndParent = UnsafeNativeMethods.GetParent(new HandleRef(this, hwnd)); 

                if (hwndParent == hwndRoot) 
                { 
                    return hwnd;
                } 

                hwnd = hwndParent;
            }
 
            return IntPtr.Zero;
        } 
 
        /// 
        ///     Critical:This code can cause input simulation and hence is critical. 
        ///     The current code path is only hit under RootBrowserWindow scenario for now.
        /// 
        [SecurityCritical]
        private bool ReportInput( 
            IntPtr hwnd,
            InputMode mode, 
            int timestamp, 
            RawKeyboardActions actions,
            int scanCode, 
            bool isExtendedKey,
            bool isSystemKey,
            int virtualKey)
        { 
            Debug.Assert( null != _source );
 
            // The first event should also activate the keyboard device. 
            if((actions & RawKeyboardActions.Deactivate) == 0)
            { 
                if(!_active || _partialActive)
                {
                    try
                    { 
                        // Include the activation action.
                        actions |= RawKeyboardActions.Activate; 
 
                        // Remember that we are active.
                        _active = true; 
                        _partialActive = false;
                    }
                    catch(System.ComponentModel.Win32Exception)
                    { 
                        System.Diagnostics.Debug.WriteLine("HwndMouseInputProvider: GetKeyboardState failed!");
 
                        // We'll go ahead and report the input, but we'll try to "activate" next time. 
                    }
                } 
            }

            // Get the extra information sent along with the message.
            IntPtr extraInformation = IntPtr.Zero; 
            try
            { 
                extraInformation = UnsafeNativeMethods.GetMessageExtraInfo(); 
            }
            catch(System.ComponentModel.Win32Exception) 
            {
                System.Diagnostics.Debug.WriteLine("HwndMouseInputProvider: GetMessageExtraInfo failed!");
            }
 
            RawKeyboardInputReport report = new RawKeyboardInputReport(_source.Value,
                                                                       mode, 
                                                                       timestamp, 
                                                                       actions,
                                                                       scanCode, 
                                                                       isExtendedKey,
                                                                       isSystemKey,
                                                                       virtualKey,
                                                                       extraInformation); 

 
            bool handled = _site.Value.ReportInput(report); 

            return handled; 
        }

        private int  _msgTime;
        ///  
        /// This is got under an elevation and is hence critical. This data is not ok to expose.
        ///  
        private SecurityCriticalDataClass _source; 
        /// 
        /// This is got under an elevation and is hence critical.This data is not ok to expose. 
        /// 
        private SecurityCriticalDataClass _site;
        private IInputElement _restoreFocus;
        ///  
        /// This is got under an elevation and is hence critical.This data is not ok to expose.
        ///  
        [SecurityCritical] 
        private IntPtr _restoreFocusWindow;
        private bool _active; 
        private bool _partialActive;
    }
}
 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK