تعطيل اختصارات الوصول في تطبيق .NET؟
-
09-09-2019 - |
سؤال
مقالة MSDN هذه - http://msdn.microsoft.com/en-us/library/bb219746(vs.85).aspx#disabling_accessibility_shortcut_keys. - يوفر معلومات للمبرمجين C ++ حول كيفية تعطيل اختصارات Windows مؤقتا لإمكانية الوصول (مثل تعليق التحول لمدة 8 ثوان، أو الضغط على التحول أكثر من 5 مرات في تتابع سريع).
بالتأكيد هناك طريقة سهلة للقيام بذلك في C #، لكن لا يمكنني العثور على أي موارد في هذا. أنا أستخدم directinput في تطبيق غير ملء الشاشة.
كل ما أريد القيام به ليس لديه النوافذ المنبثقة المزعجة تأتي؛ أفضل شيء لا يضطر إلى الوحل مع إعدادات Windows، على الرغم من أنه في حالة إيقاف تشغيل التطبيق بطريقة غير رشيقة (أفضل عدم تغيير إعدادات المستخدم بشكل دائم في تلك المواقف) وبعد
أي أفكار؟
المحلول
سوف تضطر إلى القيام بنفس الشيء الذي يتم في الارتباط الذي تشير إليه. يمكن استدعاء وظيفة SystemParametersInfo API من خلال طبقة P / Invoke ويمكنك العثور على التعريف هنا:
http://www.pinvoke.net/default.aspx/user32/systemparametersinfo.html.
نصائح أخرى
فقط في حالة احتياجات أي شخص آخر هذا، إليك رمز C # المحول، الذي يعمل في النهاية يعمل:
[DllImport( "user32.dll", EntryPoint = "SystemParametersInfo", SetLastError = false )]
private static extern bool SystemParametersInfo( uint action, uint param,
ref SKEY vparam, uint init );
[DllImport( "user32.dll", EntryPoint = "SystemParametersInfo", SetLastError = false )]
private static extern bool SystemParametersInfo( uint action, uint param,
ref FILTERKEY vparam, uint init );
private const uint SPI_GETFILTERKEYS = 0x0032;
private const uint SPI_SETFILTERKEYS = 0x0033;
private const uint SPI_GETTOGGLEKEYS = 0x0034;
private const uint SPI_SETTOGGLEKEYS = 0x0035;
private const uint SPI_GETSTICKYKEYS = 0x003A;
private const uint SPI_SETSTICKYKEYS = 0x003B;
private static bool StartupAccessibilitySet = false;
private static SKEY StartupStickyKeys;
private static SKEY StartupToggleKeys;
private static FILTERKEY StartupFilterKeys;
private const uint SKF_STICKYKEYSON = 0x00000001;
private const uint TKF_TOGGLEKEYSON = 0x00000001;
private const uint SKF_CONFIRMHOTKEY = 0x00000008;
private const uint SKF_HOTKEYACTIVE = 0x00000004;
private const uint TKF_CONFIRMHOTKEY = 0x00000008;
private const uint TKF_HOTKEYACTIVE = 0x00000004;
private const uint FKF_CONFIRMHOTKEY = 0x00000008;
private const uint FKF_HOTKEYACTIVE = 0x00000004;
[StructLayout( LayoutKind.Sequential, CharSet = CharSet.Auto )]
public struct SKEY
{
public uint cbSize;
public uint dwFlags;
}
[StructLayout( LayoutKind.Sequential, CharSet = CharSet.Auto )]
public struct FILTERKEY
{
public uint cbSize;
public uint dwFlags;
public uint iWaitMSec;
public uint iDelayMSec;
public uint iRepeatMSec;
public uint iBounceMSec;
}
private static uint SKEYSize = sizeof( uint ) * 2;
private static uint FKEYSize = sizeof( uint ) * 6;
public static void ToggleAccessibilityShortcutKeys( bool ReturnToStarting )
{
if ( !StartupAccessibilitySet )
{
StartupStickyKeys.cbSize = Configuration.SKEYSize;
StartupToggleKeys.cbSize = Configuration.SKEYSize;
StartupFilterKeys.cbSize = Configuration.FKEYSize;
SystemParametersInfo( SPI_GETSTICKYKEYS, SKEYSize, ref StartupStickyKeys, 0 );
SystemParametersInfo( SPI_GETTOGGLEKEYS, SKEYSize, ref StartupToggleKeys, 0 );
SystemParametersInfo( SPI_GETFILTERKEYS, FKEYSize, ref StartupFilterKeys, 0 );
StartupAccessibilitySet = true;
}
if ( ReturnToStarting )
{
// Restore StickyKeys/etc to original state and enable Windows key
SystemParametersInfo( SPI_SETSTICKYKEYS, SKEYSize, ref StartupStickyKeys, 0 );
SystemParametersInfo( SPI_SETTOGGLEKEYS, SKEYSize, ref StartupToggleKeys, 0 );
SystemParametersInfo( SPI_SETFILTERKEYS, FKEYSize, ref StartupFilterKeys, 0 );
}
else
{
// Disable StickyKeys/etc shortcuts but if the accessibility feature is on,
// then leave the settings alone as its probably being usefully used
SKEY skOff = StartupStickyKeys;
//if ( ( skOff & SKF_STICKYKEYSON ) == 0 )
{
// Disable the hotkey and the confirmation
skOff.dwFlags &= ~SKF_HOTKEYACTIVE;
skOff.dwFlags &= ~SKF_CONFIRMHOTKEY;
SystemParametersInfo( SPI_SETSTICKYKEYS, SKEYSize, ref skOff, 0 );
}
SKEY tkOff = StartupToggleKeys;
//if ( ( tkOff & TKF_TOGGLEKEYSON ) == 0 )
{
// Disable the hotkey and the confirmation
tkOff.dwFlags &= ~TKF_HOTKEYACTIVE;
tkOff.dwFlags &= ~TKF_CONFIRMHOTKEY;
rs = SystemParametersInfo( SPI_SETTOGGLEKEYS, SKEYSize, ref tkOff, 0 );
}
FILTERKEY fkOff = StartupFilterKeys;
//if ( ( fkOff & FKF_FILTERKEYSON ) == 0 )
{
// Disable the hotkey and the confirmation
fkOff.dwFlags &= ~FKF_HOTKEYACTIVE;
fkOff.dwFlags &= ~FKF_CONFIRMHOTKEY;
SystemParametersInfo( SPI_SETFILTERKEYS, FKEYSize, ref fkOff, 0 );
}
}
}
لاحظ أنه لم أتمكن من تحويل ثلاثة من العبارات من C ++ (يتم تعليقها). توصي Microsoft بتلك، لكنني لا أعرف طريقة لجعلها تعمل في C #. بالإضافة إلى ذلك، أنا لا أستخدم Sizeof () () على الهياكل (بدلا من ذلك إنشاء متغيرات يدويا لحجمها)، لأن القيام بذلك سيتطلب رمز غير آمن، ولا أريد أن يكون هناك شرط لبرنامجي الخاص.
شكرا يا شباب مع بعض الانتهاء البسيط الذي عمل في لعبة XNA الخاصة بي لمنع المنبثقة الرئيسية لزجة.
هنا هو الرمز النهائي:
using System;
using System.Diagnostics;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using System.Runtime.InteropServices;
namespace Engine
{
#if WINDOWS
/// <summary>
/// Helper for Windows to temporarily disable the popup caused by the
/// Accessibility features.
/// See: http://stackoverflow.com/questions/734618/disabling-accessibility-shortcuts-in-net-application
/// and: http://msdn.microsoft.com/en-us/library/ee416808(v=vs.85).aspx
/// </summary>
public class WindowsHelperAccessibilityKeys
{
[DllImport("user32.dll", EntryPoint = "SystemParametersInfo", SetLastError = false)]
private static extern bool SystemParametersInfo(uint action, uint param,
ref SKEY vparam, uint init);
[DllImport("user32.dll", EntryPoint = "SystemParametersInfo", SetLastError = false)]
private static extern bool SystemParametersInfo(uint action, uint param,
ref FILTERKEY vparam, uint init);
private const uint SPI_GETFILTERKEYS = 0x0032;
private const uint SPI_SETFILTERKEYS = 0x0033;
private const uint SPI_GETTOGGLEKEYS = 0x0034;
private const uint SPI_SETTOGGLEKEYS = 0x0035;
private const uint SPI_GETSTICKYKEYS = 0x003A;
private const uint SPI_SETSTICKYKEYS = 0x003B;
private static bool StartupAccessibilitySet = false;
private static SKEY StartupStickyKeys;
private static SKEY StartupToggleKeys;
private static FILTERKEY StartupFilterKeys;
private const uint SKF_STICKYKEYSON = 0x00000001;
private const uint TKF_TOGGLEKEYSON = 0x00000001;
private const uint SKF_CONFIRMHOTKEY = 0x00000008;
private const uint SKF_HOTKEYACTIVE = 0x00000004;
private const uint TKF_CONFIRMHOTKEY = 0x00000008;
private const uint TKF_HOTKEYACTIVE = 0x00000004;
private const uint FKF_CONFIRMHOTKEY = 0x00000008;
private const uint FKF_HOTKEYACTIVE = 0x00000004;
private const uint FKF_FILTERKEYSON = 0x00000001;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct SKEY
{
public uint cbSize;
public uint dwFlags;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct FILTERKEY
{
public uint cbSize;
public uint dwFlags;
public uint iWaitMSec;
public uint iDelayMSec;
public uint iRepeatMSec;
public uint iBounceMSec;
}
private static uint SKEYSize = sizeof(uint) * 2;
private static uint FKEYSize = sizeof(uint) * 6;
/// <summary>
/// False to stop the sticky keys popup.
/// True to return to whatever the system has been set to.
/// </summary>
public static void AllowAccessibilityShortcutKeys(bool bAllowKeys)
{
if (!StartupAccessibilitySet)
{
StartupStickyKeys.cbSize = SKEYSize;
StartupToggleKeys.cbSize = SKEYSize;
StartupFilterKeys.cbSize = FKEYSize;
SystemParametersInfo(SPI_GETSTICKYKEYS, SKEYSize, ref StartupStickyKeys, 0);
SystemParametersInfo(SPI_GETTOGGLEKEYS, SKEYSize, ref StartupToggleKeys, 0);
SystemParametersInfo(SPI_GETFILTERKEYS, FKEYSize, ref StartupFilterKeys, 0);
StartupAccessibilitySet = true;
}
if (bAllowKeys)
{
// Restore StickyKeys/etc to original state and enable Windows key
SystemParametersInfo(SPI_SETSTICKYKEYS, SKEYSize, ref StartupStickyKeys, 0);
SystemParametersInfo(SPI_SETTOGGLEKEYS, SKEYSize, ref StartupToggleKeys, 0);
SystemParametersInfo(SPI_SETFILTERKEYS, FKEYSize, ref StartupFilterKeys, 0);
}
else
{
// Disable StickyKeys/etc shortcuts but if the accessibility feature is on,
// then leave the settings alone as its probably being usefully used
SKEY skOff = StartupStickyKeys;
if ( ( skOff.dwFlags & SKF_STICKYKEYSON ) == 0 )
{
// Disable the hotkey and the confirmation
skOff.dwFlags &= ~SKF_HOTKEYACTIVE;
skOff.dwFlags &= ~SKF_CONFIRMHOTKEY;
SystemParametersInfo(SPI_SETSTICKYKEYS, SKEYSize, ref skOff, 0);
}
SKEY tkOff = StartupToggleKeys;
if ( ( tkOff.dwFlags & TKF_TOGGLEKEYSON ) == 0 )
{
// Disable the hotkey and the confirmation
tkOff.dwFlags &= ~TKF_HOTKEYACTIVE;
tkOff.dwFlags &= ~TKF_CONFIRMHOTKEY;
SystemParametersInfo(SPI_SETTOGGLEKEYS, SKEYSize, ref tkOff, 0);
}
FILTERKEY fkOff = StartupFilterKeys;
if ( ( fkOff.dwFlags & FKF_FILTERKEYSON ) == 0 )
{
// Disable the hotkey and the confirmation
fkOff.dwFlags &= ~FKF_HOTKEYACTIVE;
fkOff.dwFlags &= ~FKF_CONFIRMHOTKEY;
SystemParametersInfo(SPI_SETFILTERKEYS, FKEYSize, ref fkOff, 0);
}
}
}
}
#endif
}
يمكنني استخدامها في بداية اللعبة مع المعلمة تعيين كاذبة وقبل خروج اللعبة فقط مع المعلمة تعيين إلى TRUE:
/// <summary>
/// This is the preferred way to return to the operating system.
/// </summary>
public void ExitAndTidyUP()
{
#if WINDOWS
WindowsHelperAccessibilityKeys.AllowAccessibilityShortcutKeys(true);
#endif
Exit();
}
إنه يعمل تماما بقدر ما أستطيع أن أقول.
يعتبر
ملاحظة فيما يتعلق برمز C # المنشور أعلاه: يمكنك تحويل هذه الخطوط المشكلات عن طريق وحقل الأعلام في مجال الهيكل مثل ذلك: إذا ((SKOFF.DWFLAGS & SKF_STICKYKEYSON) == 0) ستحتاج إلى إضافة خط: Private const uint fkf_filterkeyson = 0x00000001؛ تحت تعريفات const كذلك.
قد تبدو هذا أيضا C #
using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace WindowsFormsApplication1 {
public partial class Form1 : Form {
private const int MYKEYID = 0; // In case you want to register more than one...
public Form1() {
InitializeComponent();
RegisterHotKey(this.Handle, MYKEYID, MOD_ALT, Keys.Tab);
this.FormClosing += Form1_FormClosing;
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e) {
UnregisterHotKey(this.Handle, MYKEYID);
}
protected override void WndProc(ref Message m) {
if (m.Msg == WM_HOTKEY && m.WParam.ToInt32() == MYKEYID) {
Console.Beep();
}
base.WndProc(ref m);
}
// P/Invoke declarations
private const int WM_HOTKEY = 0x312;
private const int MOD_ALT = 1;
private const int MOD_CONTROL = 2;
private const int MOD_SHIFT = 4;
[DllImport("user32.dll")]
private static extern int RegisterHotKey(IntPtr hWnd, int id, int modifier, Keys vk);
[DllImport("user32.dll")]
private static extern bool UnregisterHotKey(IntPtr hWnd, int id);
}
}
في صحتك