开发者

How do you prevent the VS Shell from getting priority on key/command bindings in a VSPackage ToolWindow?

I have wpf a user control that accepts input gestures to perform various commands. In the example image below, the user can press Ctrl+N to execute the New command to create a new item in the TreeView.

How do you prevent the VS Shell from getting priority on key/command bindings in a VSPackage ToolWindow?

When this user control is hosted within a WPF application, the user can create a new item using Ctrl+N when the focus is on the TreeView, and when the user presses Ctrl+N when the focus is elsewhere in the application, the application level New command is executed.

When this user control is hosted within a VSPackage ToolWindow, the VS Shell level New command to create a new file is executed when the user presses Ctrl+N, regardless of focus on the TreeView.

How do you prevent the VS Shell from getting priority on key/command bind开发者_运维百科ings?


Some approaches were suggested by moderator Ryan on MSDN. The VS Shell is passing Winform messages to the ToolWindow, so the current approach is to override PreProcessMessage in the ToolWindow, handle the key combinations such as Ctrl+N that would map to WPF commands, and then translate those messages and pass to ComponentDispatcher.RaiseThreadMessage.

This approach is error prone in that the mapping to WPF commands could get out of sync, plus it doesn't incorporate whether or not the WPF command can execute. If anyone has a more ideal approach, please let me know, or if I find one, will post.

Perhaps there is a way for the WPF control to pass back whether the command was executed, and then only if the command was executed would the message be handled. Then, all this mapping business could be avoided.

    private bool isControlKeyDepressed = false;
    private bool isShifKeyDepressed = false;
    private bool isOtherKeyDepressed = false;
    private bool isCommandCombinationDepressed = false;

    protected override bool PreProcessMessage(ref Message msg)
    {
        // trap keyboard messages if window has focus
        if (msg.Msg == 256)
        {
            if (msg.WParam == (IntPtr)17)
            {
                isControlKeyDepressed = true;
                isOtherKeyDepressed = false;
            }
            else if (msg.WParam == (IntPtr)16)
            {
                isShifKeyDepressed = true;
                isOtherKeyDepressed = false;
            }
            else
            {
                if (isOtherKeyDepressed == true)
                {
                    isControlKeyDepressed = false;
                    isShifKeyDepressed = false;
                }
                isOtherKeyDepressed = true;
                if (isControlKeyDepressed == true)
                {
                    if (isShifKeyDepressed == true)
                    {
                        switch (msg.WParam.ToInt64())
                        {
                            case 65: // Ctrl+Shift+A command
                            case 67: // Ctrl+Shift+C command
                            case 78: // Ctrl+Shift+N command
                            case 79: // Ctrl+Shift+O command
                            case 83: // Ctrl+Shift+S command
                            case 85: // Ctrl+Shift+U command
                            case 88: // Ctrl+Shift+X command
                                isCommandCombinationDepressed = true;
                                break;
                            default:
                                isCommandCombinationDepressed = false;
                                break;
                        }
                    }
                    else
                    {
                        switch (msg.WParam.ToInt64())
                        {
                            case 69: // Ctrl+E command
                            case 78: // Ctrl+N command
                            case 79: // Ctrl+O command
                            case 83: // Ctrl+S command
                                isCommandCombinationDepressed = true;
                                break;
                            default:
                                isCommandCombinationDepressed = false;
                                break;
                        }
                    }
                }
                else
                {
                    isCommandCombinationDepressed = false;
                }
            }

            if (isCommandCombinationDepressed == true)
            {
                // send translated message via component dispatcher
                MSG dispatchMsg = new MSG();
                dispatchMsg.hwnd = msg.HWnd;
                dispatchMsg.lParam = msg.LParam;
                dispatchMsg.wParam = msg.WParam;
                dispatchMsg.message = msg.Msg;
                ComponentDispatcher.RaiseThreadMessage(ref dispatchMsg);
                msg.Result = (IntPtr)1;
                return true;
            }
        }
        return base.PreProcessMessage(ref msg);
    }
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜