C# 禁用 全局快捷鍵

本文經原作者授權以原創方式二次分享,歡迎轉載、分享。

原文作者:唐宋元明清

原文地址:https://www.cnblogs.com/kybs0/p/12558056.html

?C# 禁用 全局快捷鍵
給軟件添加快捷鍵時,經常遇到其它軟件或者系統已設置的快捷鍵,導致功能沖突。

HotKey函數

  • 下面介紹一個user32.dllRegisterHotKey以及UnregisterHotKey熱鍵處理的函數;

    • 注冊熱鍵 RegisterHotKey function [1];

BOOL?RegisterHotKey(HWND?hWnd,?//響應熱鍵的窗口句柄,如果為空,則注冊到調用線程上Int?id,?//熱鍵的唯一標識UINT?fsModifiers,?//熱鍵的輔助按鍵UINT?vk?//熱鍵的鍵值
);
    • 解除注冊熱鍵UnregisterHotKey function [2];

BOOL?WINAPI?UnregisterHotKey(?HWND?hWnd,//熱鍵注冊的窗口?int??id//要解除注冊的熱鍵ID?
);

添加熱鍵注冊和注銷函數

Register方法 - ?注冊user32.dll函數RegisterHotKey以禁用全局鍵,并在緩存內添加禁用記錄;

ProcessHotKey方法 - 外界全局鍵調用時,調用回調函數;

public?class?HotKeys{#region?注冊快捷鍵///?<summary>///?注冊快捷鍵///?</summary>///?<param?name="modifiers"></param>///?<param?name="key"></param>public?void?Register(int?modifiers,?Keys?key){Register(IntPtr.Zero,?modifiers,?key);}///?<summary>///?注冊快捷鍵///?</summary>///?<param?name="hWnd"></param>///?<param?name="modifiers"></param>///?<param?name="key"></param>///?<param?name="callBack"></param>public?void?Register(IntPtr?hWnd,?int?modifiers,?Keys?key,?HotKeyCallBackHanlder?callBack?=?null){var?registerRecord?=?_hotkeyRegisterRecords.FirstOrDefault(i?=>?i.IntPtr?==?hWnd?&&?i.Modifiers?==?modifiers?&&?i.Key?==?key);if?(registerRecord?!=?null){UnregisterHotKey(hWnd,?registerRecord.Id);_hotkeyRegisterRecords.Remove(registerRecord);}int?id?=?registerId++;if?(!RegisterHotKey(hWnd,?id,?modifiers,?key))throw?new?Exception("注冊失敗!");_hotkeyRegisterRecords.Add(new?HotkeyRegisterRecord(){Id?=?id,IntPtr?=?hWnd,Modifiers?=?modifiers,Key?=?key,CallBack?=?callBack});}#endregion#region?注銷快捷鍵///?<summary>///?注銷快捷鍵///?</summary>///?<param?name="hWnd"></param>///?<param?name="modifiers"></param>///?<param?name="key"></param>public?void?UnRegister(IntPtr?hWnd,?int?modifiers,?Keys?key){var?registerRecord?=?_hotkeyRegisterRecords.FirstOrDefault(i?=>?i.IntPtr?==?hWnd?&&?i.Modifiers?==?modifiers?&&?i.Key?==?key);if?(registerRecord?!=?null){UnregisterHotKey(hWnd,?registerRecord.Id);_hotkeyRegisterRecords.Remove(registerRecord);}}///?<summary>///?注銷快捷鍵///?</summary>///?<param?name="modifiers"></param>///?<param?name="key"></param>public?void?UnRegister(int?modifiers,?Keys?key){var?registerRecord?=?_hotkeyRegisterRecords.FirstOrDefault(i?=>?i.IntPtr?==?IntPtr.Zero?&&?i.Modifiers?==?modifiers?&&?i.Key?==?key);if?(registerRecord?!=?null){UnregisterHotKey(IntPtr.Zero,?registerRecord.Id);_hotkeyRegisterRecords.Remove(registerRecord);}}///?<summary>///?注銷快捷鍵///?</summary>///?<param?name="hWnd"></param>public?void?UnRegister(IntPtr?hWnd){var?registerRecords?=?_hotkeyRegisterRecords.Where(i?=>?i.IntPtr?==?hWnd);//注銷所有foreach?(var?registerRecord?in?registerRecords){UnregisterHotKey(hWnd,?registerRecord.Id);_hotkeyRegisterRecords.Remove(registerRecord);}}#endregion#region?快捷鍵消息處理//?快捷鍵消息處理public?void?ProcessHotKey(Message?message){ProcessHotKey(message.Msg,?message.WParam);}///?<summary>///?快捷鍵消息處理///?</summary>///?<param?name="msg"></param>///?<param?name="wParam">消息Id</param>public?void?ProcessHotKey(int?msg,?IntPtr?wParam){if?(msg?==?0x312){int?id?=?wParam.ToInt32();var?registerRecord?=?_hotkeyRegisterRecords.FirstOrDefault(i?=>?i.Id?==?id);registerRecord?.CallBack?.Invoke();}}#endregion#region?MyRegion//引入系統API[DllImport("user32.dll")]static?extern?bool?RegisterHotKey(IntPtr?hWnd,?int?id,?int?modifiers,?Keys?vk);[DllImport("user32.dll")]static?extern?bool?UnregisterHotKey(IntPtr?hWnd,?int?id);//標識-區分不同的快捷鍵int?registerId?=?10;//添加key值注冊字典,后續調用時有回調處理函數private?readonly?List<HotkeyRegisterRecord>?_hotkeyRegisterRecords?=?new?List<HotkeyRegisterRecord>();public?delegate?void?HotKeyCallBackHanlder();#endregion}public?class?HotkeyRegisterRecord{public?IntPtr?IntPtr?{?get;?set;?}public?int?Modifiers?{?get;?set;?}public?Keys?Key?{?get;?set;?}public?int?Id?{?get;?set;?}public?HotKeys.HotKeyCallBackHanlder?CallBack?{?get;?set;?}}//組合控制鍵public?enum?HotkeyModifiers{Alt?=?1,Control?=?2,Shift?=?4,Win?=?8}
  • 在上方的HotKeys類中,注冊方法Register提供了一個回調函數,后續監聽到外界全局鍵時,可以通知回調函數處理。

  • 參數WParam,是窗口響應時快捷鍵值,在winformWPF窗口消息函數中都是有的。

  • 另,組合快捷鍵內部枚舉類HotkeyModifiers,枚舉值來自官網文檔WM_HOTKEY message;

無感知禁用全局快捷鍵

比如:

  • 禁用Ctrl+Alt+1、Ctrl+Alt+2、Ctrl+Alt+3、Ctrl+Alt+4(Windows桌面圖標大小的調節快捷鍵);

HotKeys?hotKeys?=?new?HotKeys();hotKeys.Register((int)HotkeyModifiers.Control,?Keys.N);hotKeys.Register((int)HotkeyModifiers.Control?+?(int)HotkeyModifiers.Alt,?Keys.D1);hotKeys.Register((int)HotkeyModifiers.Control?+?(int)HotkeyModifiers.Alt,?Keys.D2);hotKeys.Register((int)HotkeyModifiers.Control?+?(int)HotkeyModifiers.Alt,?Keys.D3);hotKeys.Register((int)HotkeyModifiers.Control?+?(int)HotkeyModifiers.Alt,?Keys.D4);

注:

  • 窗口句柄參數,如果提供空的話,則注冊到調用線程上。

  • Keys類型在system.windows.Forms程序集下,如果是WPFKey,可以使用KeyInteropWpf鍵值類型轉換為Winform鍵值再調用此函數。

無感知禁用全局快捷鍵后回調

如果禁用全局快捷鍵的同時,外界觸發快捷鍵時需要此程序回調處理,可以添加窗口消息處理:

1) 新建一個類HotKeyHandleWindow,繼承自Window;

  • 窗口樣式 - 高寬為0,窗口樣式None;

  • 添加熱鍵注冊的調用;

  • 添加WndProc,處理窗口消息;

public?class?HotKeyHandleWindow?:?Window{private?readonly?HotKeys?_hotKeys?=?new?HotKeys();public?HotKeyHandleWindow(){WindowStyle?=?WindowStyle.None;Width?=?0;Height?=?0;Loaded?+=?(s,?e)?=>{//這里注冊了Ctrl+Alt+1?快捷鍵_hotKeys.Register(new?WindowInteropHelper(this).Handle,(int)HotkeyModifiers.Control?+?(int)HotkeyModifiers.Alt,?Keys.D1,?CallBack);};}protected?override?void?OnSourceInitialized(EventArgs?e){base.OnSourceInitialized(e);var?hwndSource?=?PresentationSource.FromVisual(this)?as?HwndSource;hwndSource?.AddHook(new?HwndSourceHook(WndProc));}public?IntPtr?WndProc(IntPtr?hwnd,?int?msg,?IntPtr?wParam,?IntPtr?lParam,?ref?bool?handled){//窗口消息處理函數_hotKeys.ProcessHotKey(msg,?wParam);return?hwnd;}//按下快捷鍵時被調用的方法public?void?CallBack(){}}

2)調用窗口類;

var?hotKeyHandleWindow?=?new?HotKeyHandleWindow();
hotKeyHandleWindow.Show();
hotKeyHandleWindow.Hide();

以上有回調響應,但是也是無感知的

源碼下載[3]

參考資料

[1]

RegisterHotKey function : https://docs.microsoft.com/zh-cn/windows/win32/api/winuser/nf-winuser-registerhotkey?redirectedfrom=MSDN

[2]

UnregisterHotKey function : https://docs.microsoft.com/zh-cn/windows/win32/api/winuser/nf-winuser-unregisterhotkey

[3]

源碼下載: https://github.com/Kybs0/DiableGlobalShortcuts

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/284829.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/284829.shtml
英文地址,請注明出處:http://en.pswp.cn/news/284829.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

SegmentFault Hackathon 文藝復興

我有一個 idea&#xff0c;我想實現它&#xff0c;我正實現它&#xff0c;我已實現它。世界上存在一些好奇心旺盛、不愛墨守成規的人&#xff0c;略微偏執但又極度投入的他們崇尚自由&#xff0c;熱衷用技術實現自己的想法&#xff0c;他們帶著不羈的態度生活&#xff0c;利用編…

臥槽!VS Code 上竟然也能畫流程圖了???

作為一款開源的主流代碼編輯器&#xff0c;VSCode 在發布之后一直受到不少開發者的喜愛。 此前&#xff0c;我們也曾在公眾號上分享過多篇文章&#xff0c;向大家推薦了不少 VSCode 上比較實用&#xff08;或沙雕&#xff09;的插件。因此&#xff0c;有很多水友也經常調侃道&…

【QGIS入門實戰精品教程】14.1:QGIS如何加載各種在線地圖?

文章目錄 一、XYZ Tiles連接方式二、插件添加三、WMS/WMTS/OWS連接方式一、XYZ Tiles連接方式 1. 加載OpenStreetMap QGIS默認可以加載OpenStreetMap地圖。在左側點擊XYZ Tiles,默認下面有個OpenStreetMap選項,雙擊打右側會顯示地圖,如下圖所示: 在OpenStreetMap上右鍵→…

Oracle11g不能導出空表問題

ORACLE 11g 用exp命令導出庫文件備份時&#xff0c;發現只能導出來一部分表而且不提示錯誤&#xff0c;之前找不到解決方案只能把沒導出來的表重新建建立。后來發現是所有的空表都沒有導出來。于是想好好查查,因為在以前的10g版本中沒有這樣的問題。查資料發現Oracle 11g中有個…

SkiaSharp 之 WPF 自繪時鐘(案例版)

SkiaSharp是一個跨平臺2D圖形API&#xff0c;用于.NET平臺&#xff0c;基于Googles Skia Graphics庫(skia.org網站). 它提供了一個全面的2D API&#xff0c;可以跨移動、服務器和桌面模型來渲染圖像。該圖形庫可實現獲取指定坐標像素值、繪制2d圖形、繪制文字&#xff08;必須有…

推薦一簡單易用的腦圖制作工具

幕布是什么&#xff1f; 大綱文檔工具&#xff0c;管理你的大腦層級折疊文字&#xff0c;結構化思考助手一鍵轉換思維導圖并編輯&#xff0c;效率翻倍幕布可以做什么&#xff1f; 大綱筆記&#xff0c;思維整理 學習筆記清單工具 管理日程管理待辦購物清單等等內容創作會議記錄…

自動性能統計信息(三)(Automatic Performance Statistics)

1.3 管理自動工作負載庫&#xff08;AWR&#xff09;本節講述如何管理AWR&#xff0c;包含以下主題&#xff1a; 管理快照 管理基線 管理基線模板 傳輸自動工作負載庫數據 使用自動工作負載庫視圖 生成AWR報告 生成AWR對比報告 生成ASH報告 …

su: user tomcat does not exist

http://www.cnblogs.com/allegro/p/5005352.html 問題在于 你的startup.sh 里面設置了 用戶,你需要修改為root或者tomcat用戶 這是開發 遷移碰到的問題 test ".$TOMCAT_USER" . && TOMCAT_USERtomcat # Set JAVA_HOME to working JDK or JRE # JAVA_HOME/op…

【QGIS入門實戰精品教程】4.5:QGIS打開Excel中的點坐標,并生成矢量文件

QGIS中可以很方便添加Excel或其他文本格式的點坐標,并將其轉為矢量等多種格式的文件。 擴展閱讀: 【ArcGIS風暴】ArcGIS 10.2導入Excel數據X、Y坐標(經緯度、平面坐標),生成Shapefile點數據圖層 文章目錄 1. 數據準備2. 添加數據3. 保存文矢量文件1. 數據準備 本實驗使用…

[NOI2014]起床困難綜合癥

從高位往地位貪心即可 # include <bits/stdc.h> # define IL inline # define RG register # define Fill(a, b) memset(a, b, sizeof(a)) using namespace std; typedef long long ll; const int _(1e5 10);IL ll Read(){RG char c getchar(); RG ll x 0, z 1;for(;…

騰訊云EKS 上部署 eshopondapr

騰訊云容器服務&#xff08;Tencent Kubernetes Engine&#xff0c;TKE&#xff09;基于原生 kubernetes 提供以容器為核心的、高度可擴展的高性能容器管理服務。騰訊云容器服務完全兼容原生 kubernetes API &#xff0c;擴展了騰訊云的云硬盤、負載均衡等 kubernetes 插件&…

[轉]一往無前 | 小米十周年,雷軍公開演講全文

2020年8月11日19:30&#xff0c;小米十周年&#xff0c;雷軍公開演講如約而至。在近3小時的演講中&#xff0c;雷軍用20個故事回顧了小米過去的熱血10年&#xff0c;也展望了新的10年&#xff1a; - 創新之火將會照亮每個瘋狂的想法&#xff0c;小米將成為工程師向往的圣地。 -…

JAVA單例之我見

為什么80%的碼農都做不了架構師&#xff1f;>>> 單例模式作為設計模式中最簡單的一種&#xff0c;是一個被說爛了的東西。但是在項目中還是會發現關于單例模式的一些錯誤實現&#xff0c;可見單例也并不是我們想象的那么簡單。最近陸陸續續看了幾篇關于單例的博客&…

「劉一哥GIS」系列專欄《QGIS入門實戰精品教程(配套案例數據)》

「劉一哥GIS」系列專欄《QGIS入門實戰精品教程&#xff08;配套案例數據&#xff09;》全新上線了&#xff0c;歡迎廣大GISer朋友關注&#xff0c;一起探索GIS奧秘&#xff0c;分享GIS價值&#xff01; 本專欄以實戰案例的形式&#xff0c;深入淺出地介紹了QGIS的基本使用方法&…

MyEclipse的Git配置

1.下載&#xff1a;git的插件egit 并解壓 插件 下載地址&#xff1a;http://www.eclipse.org/egit/download/ 所有版本&#xff1a;http://wiki.eclipse.org/EGit/FAQ#Where_can_I_find_older_releases_of_EGit.3F 2.在MyEclipse安裝目錄下的dropins文件夾下創建egit文件夾 3.…

ASP.NET Core 定時刷新第三方 Token

前言在《ASP.NET Core 自動刷新JWT Token》中我們實現了為客戶端自動提供最新的Token。但是&#xff0c;當我們的 ASP.NET Core 應用需要調用第三方 API 時&#xff0c;如何更優雅地刷新第三方提供的 Token 呢&#xff1f;思路我們可以在啟動時就獲取第三方提供的 Token 并保存…

VSCode 插件開發實例(WebView):微信讀書 ^-^邊擼代碼邊看小說^-^

最終效果 主要代碼 package.json {"name": "WeReadForVSCodeJackieZheng","repository": {"type": "git","url": "https://github.com/JackieZheng/WeReadForVSCode.git"},"displayName": &q…

【QGIS入門實戰精品教程】4.7:QGIS如何將矢量數據轉為GeoJSON格式?

本文以案例的形式,講述在QGIS專業軟件中,將矢量數據轉為GeoJSON的方法。 擴展閱讀: 【ArcGIS風暴】如何將矢量數據(點、線、面)折點坐標轉為GeoJSON格式? 在QGIS中,可以直接將數據導出為GeoJSON格式。具體操作方法是:右鍵矢量數據圖層→導出圖層→到文件,如下圖所示:…

Git的純命令操作,Install,Clone , Commit,Push,Pull,版本回退,撤銷更新,分支的創建/切換/更新/提交/合并,代碼沖突...

Git的純命令操作&#xff0c;Install&#xff0c;Clone , Commit&#xff0c;Push&#xff0c;Pull&#xff0c;版本回退&#xff0c;撤銷更新&#xff0c;分支的創建/切換/更新/提交/合并&#xff0c;代碼沖突 這篇是接著上篇分布式版本庫——Windows下Git的環境部署以及在Git…

掌握jQuery插件開發

在實際開發工作中&#xff0c;總會碰到像滾動&#xff0c;分頁&#xff0c;日歷等展示效果的業務需求&#xff0c;對于接觸過jQuery以及熟悉jQuery使用的人來說&#xff0c;首先想到的肯定是尋找現有的jQuery插件來滿足相應的展示需求。目前頁面中常用的一些組件&#xff0c;都…