PDA

View Full Version : چجوری می شه تاثیر یک کلید فشار داده شده رو خنثی کرد؟



molana alavi
جمعه 03 خرداد 1387, 11:40 صبح
سلام
چجوری می شه تاثیر یک کلید فشار داده شده رو خنثی کرد؟
مثلا وقتی کلید ویندوز از صفحه کلید فشار داده شد دیگر منوی استارت باز نشه و یا وقتی کلید Alt + Tab فشار داده شد دیالوگ مربوط به تغییر برنامه فعال ظاهر نشه؟
ممنون می شم اگه راهنمائی کنید

علیرضا مداح
جمعه 03 خرداد 1387, 12:10 عصر
سلام دوست عزیز
یک راه اینست که متد ProcessCmdKey مربوط به Form را Override کنید ، به طور مثال برای غیر فعال کردن کلید TAB میتوانید از کد زیر استفاده نمایید :


if (keyData == Keys.Tab)
{
MessageBox.Show("Sorry , Tab Key is disabled!");
return true;
}
else
return base.ProcessCmdKey(ref msg, keyData);


اما برای غیر فعال کردن کلیدهای LWin و RWin در ویندوز اکس پی باید از تکنیک LowLevelKeyboardHoocking و از تابع API به نام LowLevelKeyboardProc استفاده نمایید :


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using Microsoft.Win32;
using System.Xml;
using System.Collections;
using System.IO.Ports;
using System.Runtime.InteropServices;
using System.Diagnostics;
namespace WindowsApplication64
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

public class KeyboardFilter
{
private Keys[] mFilter;
private IntPtr mHook;
private LowLevelKeyboardProc mProc;
public KeyboardFilter(Keys[] keysToFilter)
{
// Install hook
mFilter = keysToFilter;
ProcessModule mod = Process.GetCurrentProcess().MainModule;
mProc = new LowLevelKeyboardProc(KeyboardProc); // Avoid garbage collector problems
mHook = SetWindowsHookEx(13, mProc, GetModuleHandle(mod.ModuleName), 0);
if (mHook == IntPtr.Zero) throw new Win32Exception(Marshal.GetLastWin32Error(), "Failed to set hook");
}
public void Dispose()
{
// Release hook
if (mHook != IntPtr.Zero)
{
UnhookWindowsHookEx(mHook);
mHook = IntPtr.Zero;
}
}
private IntPtr KeyboardProc(int nCode, IntPtr wp, IntPtr lp)
{
// Callback, filter key
if (nCode >= 0)
{
KBDLLHOOKSTRUCT info = (KBDLLHOOKSTRUCT)Marshal.PtrToStructure(lp, typeof(KBDLLHOOKSTRUCT));
foreach (Keys key in mFilter)
if ((key & Keys.KeyCode) == info.key && CheckModifier(key)) return (IntPtr)1;
}
return CallNextHookEx(mHook, nCode, wp, lp);
}
private bool CheckModifier(Keys key)
{
// Check if modifier key in required state
if ((key & Keys.Control) == Keys.Control &&
GetAsyncKeyState(Keys.LControlKey) == 0 && GetAsyncKeyState(Keys.RControlKey) == 0) return false;
if ((key & Keys.Shift) == Keys.Shift &&
GetAsyncKeyState(Keys.LShiftKey) == 0 && GetAsyncKeyState(Keys.RShiftKey) == 0) return false;
if ((key & Keys.Alt) == Keys.Alt &&
GetAsyncKeyState(Keys.LMenu) == 0 && GetAsyncKeyState(Keys.RMenu) == 0) return false;
return true;
}
// P/Invoke declarations
[StructLayout(LayoutKind.Sequential)]
private struct KBDLLHOOKSTRUCT
{
public Keys key;
public int scanCode;
public int flags;
public int time;
public IntPtr extra;
}
private delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr SetWindowsHookEx(int id, LowLevelKeyboardProc callback, IntPtr hMod, uint dwThreadId);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern bool UnhookWindowsHookEx(IntPtr hook);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr CallNextHookEx(IntPtr hook, int nCode, IntPtr wp, IntPtr lp);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr GetModuleHandle(string name);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern short GetAsyncKeyState(Keys key);
}
private void Form1_Load(object sender, EventArgs e)
{
KeyboardFilter filter = new KeyboardFilter(new Keys[] { Keys.LWin, Keys.RWin });
}

}
}
//ref : http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2143470&SiteID=1

molana alavi
جمعه 03 خرداد 1387, 15:53 عصر
با تشکر فراوان از پاسخ بسیار جالبتون
اما یه مشکلی که وجود داره اینه کهبا استفاده از این کد برنامه من هم نمی تونه تشخیص فشار داده شدن مثلا کلید ویندوز رو بده
در واقع من می خوام برنامه من متوجه فشار داده شدن این کلید بشه اما خود ویندوز و برنامه های دیگه نه
اصلا آیا این کار عملی هستش؟
بازم تشکر برای پاسخ جالبتون

unassigned_identifier
جمعه 03 خرداد 1387, 16:10 عصر
همه ی برنامه ها تحت سیستم عامل در حال اجرا شدن هستند. وکنترل اجرای آنها توسط سیستم عامل انجام میشه. حتی برنامه شماا توسط سیستم عامل متوجه فشردن شدن کلید ها میشه.

molana alavi
جمعه 03 خرداد 1387, 16:50 عصر
این خوب درست اما راه حلی برای مشکل من وجود نداره
مثلا برنامه VMware که همون ماشین مجازی است وقتی در یه ویندوز مجازی اون ماشین در حال کار هستیم مثلا وقتی کلید ویندوز رو فشار می دیم منوی Start ویندوز اصلی باز نمی شه بلکه منوی استارت ویندوز مجازی باز می شه مشکل من هم همینه که نمی دونم چجوری باید این کار رو بکونم