WPFの三种方式实现快捷键

简介: 原文:WPFの三种方式实现快捷键最近,对wpf添加快捷键的方式进行了整理。主要用到的三种方式如下: 一、wpf命令: 资源中添加命令 输入命令绑定 命令执行方法绑定  需要注意的是,绑定命令的时候,也可以,建议用前者,以免造成混乱。
原文: WPFの三种方式实现快捷键

最近,对wpf添加快捷键的方式进行了整理。主要用到的三种方式如下:

一、wpf命令:

资源中添加命令
<Window.Resources>
        <RoutedUICommand x:Key="ToolCapClick" Text="截屏快捷键" />
</Window.Resources>

输入命令绑定
<Window.InputBindings>
        <KeyBinding Gesture="Ctrl+Alt+Q" Command="{StaticResource ToolCapClick}"/>
</Window.InputBindings>

命令执行方法绑定
<Window.CommandBindings>
        <CommandBinding Command="{StaticResource ToolCapClick}"
                    CanExecute="CommandBinding_ToolCapClick_CanExecute"
                    Executed="CommandBinding_ToolCapClick_Executed"/>
</Window.CommandBindings>

 需要注意的是,绑定命令的时候,也可以<KeyBinding Modifiers="Ctrl+Alt" Key="Q" Command="{StaticResource ToolCapClick}"/>,建议用前者,以免造成混乱。

执行方法实现

  #region 截屏快捷键
        private void CommandBinding_ToolCapClick_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = true;
        }

        private void CommandBinding_ToolCapClick_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            try
            {
                CaptureImageTool capture = new CaptureImageTool();
                capture.CapOverToHandWriting += Capture_CapOverToHandWriting;
                capture.CapOverToBlackboard += Capture_CapOverToBlackboard;
                string saveName = String.Empty;
                if (capture.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {

                    //保存截取的内容
                    System.Drawing.Image capImage = capture.Image;
                    //上课存班级内部,不上课存外部
                    string strSavePath = DataBusiness.GetCurrentTeachFilePath(SystemConstant.PATH_CAPS);
                    if (!String.IsNullOrEmpty(strSavePath))
                    {
                        if (!Directory.Exists(strSavePath))
                        {
                            Directory.CreateDirectory(strSavePath);
                        }
                        saveName = strSavePath + DateTime.Now.ToString(SystemConstant.FORMAT_CAPS);
                    }
                    else
                    {

                        saveName = PathExecute.GetPathFile(SystemConstant.PATH_SAVE + Path.DirectorySeparatorChar + SystemConstant.PATH_CAPS, DateTime.Now.ToString(SystemConstant.FORMAT_CAPS));
                    }

                    capImage.Save(saveName + SystemConstant.EXTENSION_PNG, System.Drawing.Imaging.ImageFormat.Png);
                }
            }
            catch (Exception ex)
            {
                new Exception("capscreen module error:" + ex.Message);
            }
        }

 二、利用windows钩子(hook)函数

第一步 引入到Winows API

   1: [DllImport("user32.dll")]
    
   2: public static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk);
    
   3: [DllImport("user32.dll")]
    
   4: public static extern bool UnregisterHotKey(IntPtr hWnd, int id);

这边可以参考两个MSDN的链接

第一个是关于RegisterHotKey函数的,里面有关于id,fsModifiers和vk 的具体说明

http://msdn.microsoft.com/en-us/library/windows/desktop/ms646309%28v=vs.85%29.aspx

第二个是Virtual-Key 的表,即RegisterHotKey的最后一个参数

http://msdn.microsoft.com/en-us/library/windows/desktop/dd375731%28v=vs.85%29.aspx

第二步 注册全局按键

 

这里先介绍一个窗体的事件SourceInitialized,这个时间发生在WPF窗体的资源初始化完毕,并且可以通过WindowInteropHelper获得该窗体的句柄用来与Win32交互。

具体可以参考MSDN http://msdn.microsoft.com/en-us/library/system.windows.window.sourceinitialized.aspx

我们通过重载OnSourceInitialized来在SourceInitialized事件发生后获取窗体的句柄,并且注册全局快捷键

 private const Int32 MY_HOTKEYID = 0x9999;
 protected override void OnSourceInitialized(EventArgs e)
 {
     base.OnSourceInitialized(e);
     IntPtr handle = new WindowInteropHelper(this).Handle;
    RegisterHotKey(handle, MY_HOTKEYID, 0x0001, 0x72);
 }

 

关于几个常熟的解释

MY_HOTKEYID 是一个自定义的ID,取值范围在0x0000 到 0xBFFF。之后我们会根据这个值来判断事件的处理。

RegisterHotKey的第三或第四个参数可以参考第一步

第三步 添加接收所有窗口消息的事件处理程序

上面只是在系统中注册了快捷键,但是还要获取消息的事件,并筛选消息。

继续在OnSourceInitialized函数中操作

 protected override void OnSourceInitialized(EventArgs e)
 {
     base.OnSourceInitialized(e);
 
     IntPtr handle = new WindowInteropHelper(this).Handle;
    RegisterHotKey(handle, MY_HOTKEYID, 0x0001, 0x72);
 
     HwndSource source = PresentationSource.FromVisual(this) as HwndSource;
    source.AddHook(WndProc);
 }

 

下面来完成WndProc函数

 IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handle)
 {
    //Debug.WriteLine("hwnd:{0},msg:{1},wParam:{2},lParam{3}:,handle:{4}"
     //                ,hwnd,msg,wParam,lParam,handle);
    if(wParam.ToInt32() == MY_HOTKEYID)
    {
        //全局快捷键要执行的命令
     }
    return IntPtr.Zero;
 }

 三、给button控件添加快捷键

<UserControl.Resources>
 <RoutedUICommand x:Key="ClickCommand" Text="点击快捷键" />
</UserControl.Resources>

<UserControl.CommandBindings>
    <CommandBinding Command="{StaticResource ClickCommand}" 
                    Executed="ClickHandler" />
</UserControl.CommandBindings>

<UserControl.InputBindings>
    <KeyBinding Key="C" Modifiers="Ctrl" Command="{StaticResource ClickCommand}" />
</UserControl.InputBindings>

<Grid>
    <Button Content="button" Command="{StaticResource ClickCommand}"/>
</Grid>

 执行方法:

private void ClickHandler(object sender, RoutedEventArgs e) 
{
 Message.Show("命令执行!");
 }

 

 
目录
相关文章
|
C#
WPF 界面实现多语言支持 中英文切换 动态加载资源字典
原文:WPF 界面实现多语言支持 中英文切换 动态加载资源字典 1、使用资源字典,首先新建两个字典文件en-us.xaml、zh-cn.xaml。定义中英文的字符串在这里面【注意:添加xmlns:s="clr-namespace:System;assembly=mscorlib】 zh-cn.
3211 0
|
C# 数据可视化 开发工具
WPF实现选项卡效果(1)——使用AvalonDock
原文:WPF实现选项卡效果(1)——使用AvalonDock 简介   公司最近一个项目,软件采用WPF开发,需要实现类似于VS的选项卡(或者是浏览器的选项卡)效果。
2271 0
|
IDE C# 开发工具
WPF钟表效果实现
中WPF中的RotateTransform实现UI元素的旋转,并模拟钟表的秒针、分针和时针。
1204 0
WPF钟表效果实现
|
IDE 编译器 C#
WPF实现强大的动态公式计算
数据库可以定义表不同列之间的计算公式,进行自动公式计算,但如何实现行上的动态公式计算呢?行由于可以动态扩展,在某些应用场景下将能很好的解决实际问题。本文就探讨一下如何在WPF中实现一种基于行字段的动态公式计算。
1087 0
WPF实现强大的动态公式计算
|
网络协议 C# 移动开发
C# WPF上位机实现和下位机TCP通讯
C# WPF上位机实现和下位机TCP通讯下位机使用北京大华程控电源DH1766-1,上位机使用WPF。实现了电压电流实时采集,曲线显示。上午在公司调试成功,手头没有程控电源,使用TCP服务端模拟。昨天写的TCP服务端正好排上用场。
2416 0
|
C#
WPF特效-实现3D足球效果
原文:WPF特效-实现3D足球效果 WPF 实现 3D足球效果,效果图如下:  每个面加载不同贴图。                                                          ...
921 0
|
算法 C# 容器
WPF特效-实现弧形旋转轮播图
原文:WPF特效-实现弧形旋转轮播图        项目遇到,琢磨并实现了循环算法,主要处理循环替换显示问题       (如:12张图组成一个圆弧,但总共有120张图需要呈现,如何在滑动中进行显示块的替换,并毫无卡顿)        处理的自己感觉比较满意,记录一下。
2159 0
|
C#
wpf采用Xps实现文档显示、套打功能
原文:wpf采用Xps实现文档显示、套打功能 近期的一个项目需对数据进行套打,用户要求现场不允许安装office、页面预览显示必须要与文档完全一致,xps文档来对数据进行处理。Wpf的DocumentView 控件可以直接将数据进行显示,xps也是一种开放式的文档,如果我们能够替换里面的标签就最终实现了我们想要的效果。
1805 0
|
C# 开发工具 git
WPF实现选项卡效果(3)——自定义动态添加的AvalonDock选项卡内容
原文:WPF实现选项卡效果(3)——自定义动态添加的AvalonDock选项卡内容 简介   在前面一篇文章里面,我们实现了AvalonDock选项卡的动态添加,但是对于选项卡里面的内容,我们并没有实现任何有用的功能。
1366 0