Esempio n. 1
0
        public async Task <int> TranslateAcceleratorAsync(MSG msg)
        {
            var message = new Message
            {
                hwnd    = msg.hwnd,
                message = (int)msg.message,
                wParam  = msg.wParam,
                lParam  = msg.lParam,
                time    = (int)msg.time,
                pt_x    = msg.pt.x,
                pt_y    = msg.pt.y
            };

            var used = ComponentDispatcher.RaiseThreadMessage(ref message);

            if (used)
            {
                msg.message = (uint)message.message;
                msg.wParam  = message.wParam;
                msg.lParam  = message.lParam;

                return(VSConstants.S_OK);
            }

            if (_propertyPageSite != null)
            {
                await _projectThreadingService.SwitchToUIThread();

                return(_propertyPageSite.TranslateAccelerator(new MSG[] { msg }));
            }

            return(VSConstants.S_OK);
        }
Esempio n. 2
0
        /// <summary>
        /// Preprocess input (keyboard) messages in order to translate them to editor commands if they map. Since we are in a modal dialog
        /// we need to tell the shell to allow pre-translate during a modal loop as well as instructing it to use the editor keyboard scope
        /// even though, as far as the shell knows, there is no editor active (in a document or tool window, the shell knows nothing about
        /// random modal dialogs such as this one).
        /// </summary>
        private void FilterThreadMessage(ref System.Windows.Interop.MSG msg, ref bool handled)
        {
            if (msg.message >= WM_KEYFIRST && msg.message <= WM_KEYLAST)
            {
                IVsFilterKeys2 filterKeys = (IVsFilterKeys2)ServiceProvider.GlobalProvider.GetService(typeof(SVsFilterKeys));
                Microsoft.VisualStudio.OLE.Interop.MSG oleMSG = new Microsoft.VisualStudio.OLE.Interop.MSG()
                {
                    hwnd = msg.hwnd, lParam = msg.lParam, wParam = msg.wParam, message = (uint)msg.message
                };

                //Ask the shell to do the command mapping for us and fire off the command if it succeeds with that mapping. We pass no 'custom' scopes
                //(third and fourth argument) because we pass VSTAEXF_UseTextEditorKBScope to indicate we want the shell to apply the text editor
                //command scope to this call.
                Guid cmdGuid;
                uint cmdId;
                int  fTranslated;
                int  fStartsMultiKeyChord;
                int  res = filterKeys.TranslateAcceleratorEx(new Microsoft.VisualStudio.OLE.Interop.MSG[] { oleMSG },
                                                             (uint)(__VSTRANSACCELEXFLAGS.VSTAEXF_UseTextEditorKBScope | __VSTRANSACCELEXFLAGS.VSTAEXF_AllowModalState),
                                                             0 /*scope count*/,
                                                             new Guid[0] /*scopes*/,
                                                             out cmdGuid,
                                                             out cmdId,
                                                             out fTranslated,
                                                             out fStartsMultiKeyChord);

                if (fStartsMultiKeyChord == 0)
                {
                    //HACK: Work around a bug in TranslateAcceleratorEx that will report it DIDN'T do the command mapping
                    //when in fact it did :( Problem has been fixed (since I found it while writing this code), but in the
                    //mean time we need to successfully eat keystrokes that have been mapped to commands and dispatched,
                    //we DON'T want them to continue on to Translate/Dispatch. "Luckily" asking TranslateAcceleratorEx to
                    //do the mapping WITHOUT firing the command will give us the right result code to indicate if the command
                    //mapped or not, unfortunately we can't always do this as it would break key-chords as it causes the shell
                    //to not remember the first input match of a multi-part chord, hence the reason we ONLY hit this block if
                    //it didn't tell us the input IS part of key-chord.
                    res = filterKeys.TranslateAcceleratorEx(new Microsoft.VisualStudio.OLE.Interop.MSG[] { oleMSG },
                                                            (uint)(__VSTRANSACCELEXFLAGS.VSTAEXF_NoFireCommand | __VSTRANSACCELEXFLAGS.VSTAEXF_UseTextEditorKBScope | __VSTRANSACCELEXFLAGS.VSTAEXF_AllowModalState),
                                                            0,
                                                            new Guid[0],
                                                            out cmdGuid,
                                                            out cmdId,
                                                            out fTranslated,
                                                            out fStartsMultiKeyChord);
                    handled = (res == VSConstants.S_OK);
                    return;
                }

                //We return true (that we handled the input message) if we managed to map it to a command OR it was the
                //beginning of a multi-key chord, anything else should continue on with normal processing.
                handled = ((res == VSConstants.S_OK) || (fStartsMultiKeyChord != 0));
            }
        }
 public static System.Windows.Interop.MSG MSGFromOleMSG(ref Microsoft.VisualStudio.OLE.Interop.MSG oleMsg)
 {
     System.Windows.Interop.MSG msg = new System.Windows.Interop.MSG();
     msg.hwnd    = oleMsg.hwnd;
     msg.message = (int)oleMsg.message;
     msg.wParam  = oleMsg.wParam;
     msg.lParam  = oleMsg.lParam;
     msg.time    = (int)oleMsg.time;
     msg.pt_x    = oleMsg.pt.x;
     msg.pt_y    = oleMsg.pt.y;
     return(msg);
 }
        public static bool HandleComponentMessage(Microsoft.VisualStudio.OLE.Interop.MSG msg)
        {
            // Swallow all keyboard input
            if ((msg.message >= VSIntegrationUtilities.NativeMethods.WM_KEYFIRST &&
                 msg.message <= VSIntegrationUtilities.NativeMethods.WM_KEYLAST) ||
                (msg.message >= VSIntegrationUtilities.NativeMethods.WM_IME_FIRST &&
                 msg.message <= VSIntegrationUtilities.NativeMethods.WM_IME_LAST))
            {
                /*
                 * // Special case when the Alt key is down
                 * if (Keyboard.IsKeyDown(Key.LeftAlt) ||
                 *  Keyboard.IsKeyDown(Key.RightAlt))
                 * {
                 * // Give the main window focus. This will allow it to handle
                 * // the ALT + <key> commands and bring up the menu.
                 * //
                 * // This works because we lose focus and revoke IOleComponent tracking status
                 * Utilities.NativeMethods.SetFocus(Shell.MainWindow.Handle);
                 * return false;
                 * }
                 * }
                 */

                // Otherwise it's our message. Don't let the shell translate it
                // into some goofy command.

                // Give WPF a chance to translate.
                System.Windows.Interop.MSG windowsMsg = NativeMethods.MSGFromOleMSG(ref msg);
                if (!System.Windows.Interop.ComponentDispatcher.RaiseThreadMessage(ref windowsMsg))
                {
                    VSIntegrationUtilities.NativeMethods.TranslateMessage(ref msg);
                    VSIntegrationUtilities.NativeMethods.DispatchMessage(ref msg);
                }
                return(true);
            }

            return(false);
        }
        /// <summary>
        /// Preprocess input (keyboard) messages in order to translate them to editor commands if they map. Since we are in a modal dialog
        /// we need to tell the shell to allow pre-translate during a modal loop as well as instructing it to use the editor keyboard scope
        /// even though, as far as the shell knows, there is no editor active (in a document or tool window, the shell knows nothing about
        /// random modal dialogs such as this one).
        /// </summary>
        private void FilterThreadMessage(ref System.Windows.Interop.MSG msg, ref bool handled)
        {
            if (msg.message >= WM_KEYFIRST && msg.message <= WM_KEYLAST)
            {
                IVsFilterKeys2 filterKeys = (IVsFilterKeys2)ServiceProvider.GlobalProvider.GetService(typeof(SVsFilterKeys));
                Microsoft.VisualStudio.OLE.Interop.MSG oleMSG = new Microsoft.VisualStudio.OLE.Interop.MSG() { hwnd = msg.hwnd, lParam = msg.lParam, wParam = msg.wParam, message = (uint)msg.message };

                //Ask the shell to do the command mapping for us and fire off the command if it succeeds with that mapping. We pass no 'custom' scopes
                //(third and fourth argument) because we pass VSTAEXF_UseTextEditorKBScope to indicate we want the shell to apply the text editor
                //command scope to this call.
                Guid cmdGuid;
                uint cmdId;
                int fTranslated;
                int fStartsMultiKeyChord;
                int res = filterKeys.TranslateAcceleratorEx(new Microsoft.VisualStudio.OLE.Interop.MSG[] { oleMSG },
                                                            (uint)(__VSTRANSACCELEXFLAGS.VSTAEXF_UseTextEditorKBScope | __VSTRANSACCELEXFLAGS.VSTAEXF_AllowModalState),
                                                            0 /*scope count*/,
                                                            new Guid[0] /*scopes*/,
                                                            out cmdGuid,
                                                            out cmdId,
                                                            out fTranslated,
                                                            out fStartsMultiKeyChord);

                if (fStartsMultiKeyChord == 0)
                {
                    //HACK: Work around a bug in TranslateAcceleratorEx that will report it DIDN'T do the command mapping
                    //when in fact it did :( Problem has been fixed (since I found it while writing this code), but in the
                    //mean time we need to successfully eat keystrokes that have been mapped to commands and dispatched,
                    //we DON'T want them to continue on to Translate/Dispatch. "Luckily" asking TranslateAcceleratorEx to
                    //do the mapping WITHOUT firing the command will give us the right result code to indicate if the command
                    //mapped or not, unfortunately we can't always do this as it would break key-chords as it causes the shell
                    //to not remember the first input match of a multi-part chord, hence the reason we ONLY hit this block if
                    //it didn't tell us the input IS part of key-chord.
                    res = filterKeys.TranslateAcceleratorEx(new Microsoft.VisualStudio.OLE.Interop.MSG[] { oleMSG },
                                                            (uint)(__VSTRANSACCELEXFLAGS.VSTAEXF_NoFireCommand | __VSTRANSACCELEXFLAGS.VSTAEXF_UseTextEditorKBScope | __VSTRANSACCELEXFLAGS.VSTAEXF_AllowModalState),
                                                            0,
                                                            new Guid[0],
                                                            out cmdGuid,
                                                            out cmdId,
                                                            out fTranslated,
                                                            out fStartsMultiKeyChord);
                    handled = (res == VSConstants.S_OK);
                    return;
                }

                //We return true (that we handled the input message) if we managed to map it to a command OR it was the
                //beginning of a multi-key chord, anything else should continue on with normal processing.
                handled = ((res == VSConstants.S_OK) || (fStartsMultiKeyChord != 0));
            }
        }