none
Capturing Function Keys (F5, F3, F1)

    Question

  •  I have a silverlight application that I am developing that's supposed to replace a windows client.  The windows client implements common "browser" functionality internally (F5 refreshing the data in the application).  To this end I need to prevent F5 from causing a browser refresh.

     I found/tweaked javascript so that I can prevent most keys from propagating to the browser if the document has focus (I understand that I cannot, and do not want to capture alt-F4, ctrl-alt-del, winkey, alt-tab, may be others).

     function showDown(evt) {
                evt = (evt) ? evt : ((event) ? event : null);
                if (evt)
                {
                    if(evt.keyCode!=17) {
                    cancelKey(evt);
                    //******** Handle key here ********//
                    }
                }
            }

            function cancelKey(evt) {
                if (evt.stopPropagation) {
                    evt.stopPropagation();
                }
                if (evt.preventDefault) {
                    evt.preventDefault();
                    return false;
                }
                else {
                    evt.keyCode = 0;
                    evt.returnValue = false;
                }
            }
            
            function returnFalse() { return false; }
            
            // Additional code for NS
            if (navigator.appName=="Netscape") {
                document.addEventListener("keypress",showDown,true);
            }
            document.onkeydown = showDown;
            document.onhelp = returnFalse;
            document.onkeypress = showDown;

     This works great on a test page without a silverlight control.  It even prevents refreshes on a page with a silverlight control, until that control takes focus,  it properly calls the javascript for standard keys, but F5 still refreshes, F3 still brings up the find dialog, etc.

    I'm guessing this is a FF/IE7+ frame issue, where there is some element above "document" that is handling the keypress before the document can cancel the event.  Is there a way to prevent this propagation?  I've considered constantly putting focus inside the document, but that's very hackish and unreliable.  Any help would be greatly appreciated.

     I understand the "woes" of altering browser behavior and the potential user unfriendliness.  I do not need to stop the browser refresh button, I need to not make my users stay away from keys that were formerly functional.
     

    Saturday, June 07, 2008 1:32 AM

Answers

  • No there isn't any support for that. As an ActiveX control (or plugin) we do not receive some of the "sacred" type of keys such as F5. But this does differ based upon the browser. In general we give you what the browser gives us, nothing more/less.

    -mark
    Silverlight Program Manager
    Microsoft
    This post is provided "as-is"


     

    Thursday, June 19, 2008 8:40 PM

All replies

  • I wonder if making the app fullscreen can do the trick or not.

    Saturday, June 07, 2008 8:03 AM
  • Full screen apps do not capture keyboard input, they also require the user initiate the fullscreen mode.  When in fullscreen mode F5 is not refreshing, but neither my javascript nor the silverlight keypress events are firing.  I appreciate the suggestion, but it doesn't provide the functionality needed.

     Thank you.
     

    Saturday, June 07, 2008 3:56 PM
  • Anyone with any luck capturing function key input?

    Monday, June 09, 2008 1:56 PM
  • Sorry to keep bumping this; but this is really a showstopper for me, any help would be appreciated, thank you.

    Thursday, June 19, 2008 4:23 PM
  • No there isn't any support for that. As an ActiveX control (or plugin) we do not receive some of the "sacred" type of keys such as F5. But this does differ based upon the browser. In general we give you what the browser gives us, nothing more/less.

    -mark
    Silverlight Program Manager
    Microsoft
    This post is provided "as-is"


     

    Thursday, June 19, 2008 8:40 PM
  • Thank you for the reply.  I'm going to do my best to work around this limitation as it's vital to my application, I can live with the silverlight control never officially having focus, so all events go directly to the base document (and then javascript can redirect the key events), is there a way to have the silverlight control behave as if it has focus (cursors in textboxes blinking) when it doesn't?  That way I can just raise javascript keydown events that are handled in the .NET code.

     Simplifying the question: if I have a plain HTML textbox with focus outside of my silverlight control, and I have a keydown event for this textbox send a keydown event to .NET, how can I; from the .NET handler, call the appropriate keydown event for whatever item has focus in the silverlight control, and is there a way to get that control to "cursor blink" or have the proper "focus highlight"?

    Friday, June 20, 2008 10:18 AM
  • We don't have any mechanism to drive a pseudo-focus inside of Silverlight plug-in when it really doesn't have it. You would need to animate your own cursor and determine where you want it to show up. You will also need to update the Text property of the TextBox since there isn't any way to "forward" keystroke events from javascript.

    -mark
    Silverlight Program Manager
    Microsoft
    This post is provided "as-is"


     

     

    Friday, June 20, 2008 4:17 PM
  • Why I do not have event? aspx.net

    Thursday, October 30, 2008 5:58 AM
  •  Try to use windowless mode for your silverlight control. I think your JavaScript would get fired then.

    Thursday, October 30, 2008 9:48 AM
  • Simbalight, thank you for the suggestion, sadly it does not solve the problem.

    Windowless will fire the javascript events on the document for keydown, when I press a key and the silverlight object has focus, but it will not fire the events for any of the special keys (F5 for example).

     The project that required this functionality has been scrapped until the features I need are implemented in silverlight, particuarly function key support, and being able to establish a socket connection over arbitrary ports.  I understand the security limitations of both of these requests, and would be fine with a user initiated security confirmation dialog like the extend local storage dialog.  These are major hurdles in creating full desktop replacement apps I have encountered.

    Friday, November 07, 2008 11:30 AM
  • Yes. you are right. i can disable f5,f1 without silverlight but if i use silverlight, i can catch all keys without f1,f5. so i cant disable them.
    it makes me crazy too.
    but in firefox is ok! use firefox...

    Tuesday, February 24, 2009 8:41 AM
  • here is a near perfect key-handler in JS...

    i wonder if its possible to raise the event on the SL control... !? ...

    <script type="text/javascript">
            window.onload = function() {
                document.onkeydown = function(e) { handleKeys(e); }
                document.onkeypress = function(e) { handleKeys(e); }
            }
            
            var nonChar = false;
            var Combo = false;
            function handleKeys(e) {
                isScrolling = false;
                ScrollingX = false;
                ScrollingY = false;
    
                var character;
                var evt = (e) ? e : window.event;       //IE reports window.event not arg
    
                if (!evt.stopPropagation) {
                    evt.stopPropagation = function() { this.cancelBubble = true; };
                    evt.preventDefault = function() { this.returnValue = false; };
                }
    
                if (!evt.stop) {
                    evt.stop = function() {
                        this.stopPropagation();
                        this.preventDefault();
                    };
                }
    
                if (evt.ctrlKey && evt.keyCode == 9) {
                    if (evt.type == "keypress")
                        Editor.fireOnCtrlTab(evt.shiftKey);
                    evt.stop();
                    evt.returnValue = false;
                    return false;
                }
    
                if (evt.type == "keydown") {
                    character = evt.keyCode;
                    if (character < 16 ||                    // non printables
                        (character > 16 && character < 32) ||     // avoid shift
                        (character > 32 && character < 41) ||     // navigation keys
                        character == 46 ||                   // Delete Key (Add to these if you need)
                        character == 45 ||                   // Insert Key
                        (character >= 112 && character <= 123)    // F1 to F12
                    ) {
                        nonChar = true;
                        Keyhandler_Meta(character, evt, e);     // function to handle non Characters
                    } else
                        nonChar = false;
                }
                else {                                       // This is keypress
                    if (nonChar) return;                // Already Handled on keydown
                    character = (evt.charCode) ? evt.charCode : evt.keyCode;
                    if (character > 31 && character < 256)        // safari and opera
                        if ((evt.ctrlKey && evt.altKey) || (!evt.ctrlKey && !evt.altKey)) //allow AltGr
                        Keyhandler_Char(character, evt);
                }
    
                if (evt.ctrlKey && !nonChar && evt.type == "keydown") {
                    var tmp = Keyhandler_Combo(character, evt) //love tristate boolean :D
                    Combo = (tmp == undefined) ? Combo : tmp;
    
                    if (!Combo) {
                        evt.stop();
                        evt.returnValue = false;
                    }
                }
    
                if (e && !Combo && nonChar)				// Non IE
                    evt.stop(); 						// Using prototype
                else if (evt.keyCode == 8 || evt.keyCode == 9)
                    evt.returnValue = false;            // and stop it!
            }
    
            function Keyhandler_Char(character, evt) {
                var A = String.fromCharCode(character);
                evt.stop();
            }
            
            function Keyhandler_Meta(Meta, evt, e)
            {
                if (!evt.kill)
                {
                    evt.kill = function()
                    {
                        if (e == undefined) evt.keyCode = false; //Kill IE6+7
                        evt.stop();
                        evt.returnValue = false;
                    }
                }
                switch (Meta)
                {
                    case 116: //F5
                    case 117: //F6
                    case 115: //F4
                    case 114: //F3
                    case 113: //F2
                    case 118: //F7
                    case 119: //F8
                    case 120: //F9
                    case 121: //F10
                    case 122: //F11
                    case 112: //F1 (note: F1 can't be disabled in IE7... Motherfuckers)
                        evt.kill();
                        window.focus();
                        break;
                    default:
                        Keyhandler_Combo(Meta, evt)
                        break;
                }
                return false;
            }
            function Keyhandler_Combo(character, evt) {
                //	Some steps must return a boolean:
                //	return FALSE if Editor handles the event (ctrl + a|d|s)
                //	return TRUE if the browser-event is needed (ctrl + c|v|x)
                /* window.focus(); <-- for IE */
    
                if (evt.altKey)
                    return true;
    
                switch (String.fromCharCode(character).toUpperCase()) {
                    case '1': //Sort selected
                        return false;
                    case '2': alert("hotkey: 2"); window.focus(); return false;
                    case '3': alert("hotkey: 3"); window.focus(); return false;
                    case '4': alert("hotkey: 4"); window.focus(); return false;
                    case '5': alert("hotkey: 5"); window.focus(); return false;
                    case ' ': //Intellisense
                        return false;
                    case 'A': //SELECT ALL
                        return false;
                    case 'B': //BOLD
                        return false;
                    case 'D': //DUPLICATE LINE TO NEXT
                        return false; 
                    case 'H':
                        setTimeout(function() {
                            window.focus();
                        }, 0);
                        return false;
                    case 'I': //BOLD
                        return false;
                    case 'L': //SELECT LINE
                        return false;
                    case 'C': //COPY
                        return true;
                    case 'T': // Allow new Tab in FF
                        return true;
                    case 'V': //PASTE
                        return true;
                    case 'X': //CLIP
                        return true;
                    case 'Z':
                        return false;
                    case 'Y':
                        return false;
                }
                return undefined;
            }
         
    Wednesday, May 20, 2009 4:01 AM
  • You can use timer in SL to keep focus in document body. In this case you can catch F5 and other keys in javascript and route them to silverlight application.

     http://forums.silverlight.net/forums/p/85402/220411.aspx

    You can also put invisible IFRAME above SL plugin which can catch keys.

     Andrus.

    Thursday, January 14, 2010 2:52 PM
  • In general we give you what the browser gives us

    F5 can be catched in javascript even in IE.

    Why browser does not give F5 to SL plugin but gives it to javascript ?

    Andrus.

    Thursday, January 14, 2010 2:54 PM
  •  

    You can use timer in SL to keep focus in document body. In this case you can catch F5 and other keys in javascript and route them to silverlight application.

     http://forums.silverlight.net/forums/p/85402/220411.aspx

    You can also put invisible IFRAME above SL plugin which can catch keys.

     Andrus.

     

    That will not work for the function keys like F1 and F5 because the browsers keys will still be focused. It's an interresting read but basically all it does is give focus to the document body to check if an Alt key is pressed down. The browser will still refresh if you press F5 with that solution.

     I'm looking for a solution for this problem as well. I really wanted to implement the F1 key to show help in our application. Frankly I do not understand why these keys would be disabled. It would really give people the idea they're working in an application in their browser.

    Tuesday, June 08, 2010 8:40 AM
  • I opened this issue in MS Connect:

    https://connect.microsoft.com/VisualStudio/feedback/details/525760/silverlight-in-ie8-ctrl-p-and-some-other-ctrl-shortcuts-cannot-catched

     It was closed with an explanation from SL product manager "IE does not pass some keys to plugins so SL team cannot fix it".

    FireFox allows to catch all keys  without any tricks. So best solution is check for borwser and redirect to FireFox installation if IE is used.

    I tried to use focus trick but this causes  bad side effects like Ctrl+C / Ctrl+V does no more paste / copy in IE bowser URL field. So I stopped using it.

    Andrus..

    Tuesday, June 08, 2010 9:12 AM