Автор: ComradG
Дата сообщения: 04.09.2010 18:10
Я уже сталкивался с такой проблебой - нужно было захучить клавишу Win на клаве во время отладки одной программы. Браться за чистый Си не хотелось, да и времени было мало, поэтому я написал тогда простой хучер на Си Шарпе. Правда тогда он представлял из себя обычное консольное приложение висевшее в процессах до тех пор, пока его не грохнешь в таскменеджере. Спустя время я вернулся к данной тулзе и написал его ГУИшную версию, которая сворачивается в трей, а потому для того, чтобы вырубить ее, достаточно заглянуть в контекстное меню. В общем вот
[more=код]using System;
using System.Drawing;
using System.Diagnostics;
using System.Windows.Forms;
using System.Runtime.InteropServices;
public class frmMain:Form
{
private const int WH_KEYBOARD_LL = 13;
private const int WM_KEYDOWN = 0x0100;
private static LowLevelKeyboardProc _proc = HookCallback;
private static IntPtr _hookID = IntPtr.Zero;
public frmMain()
{
InitializeComponent();
}
private Label lblCaption;
private Label lblHowdoit;
private Button btnExit;
private Button btnTray;
private NotifyIcon ntfContext;
private ContextMenu mnuContext;
private MenuItem mnuRestore;
private MenuItem mnuSplit;
private MenuItem mnuExit;
private void InitializeComponent()
{
this.lblCaption = new Label();
this.lblHowdoit = new Label();
this.btnExit = new Button();
this.btnTray = new Button();
this.ntfContext = new NotifyIcon();
this.mnuContext = new ContextMenu();
this.mnuRestore = new MenuItem();
this.mnuSplit = new MenuItem();
this.mnuExit = new MenuItem();
//
//lblCaption
//
this.lblCaption.Font = new Font("Microsoft Sans Serif", 9, FontStyle.Bold);
this.lblCaption.Location = new Point(71, 9);
this.lblCaption.Size = new Size(139, 23);
this.lblCaption.Text = "WinKey Hooker";
this.lblCaption.TextAlign = ContentAlignment.MiddleCenter;
//
//lblHowdoit
//
this.lblHowdoit.Location = new Point(12, 32);
this.lblHowdoit.Size = new Size(273, 29);
this.lblHowdoit.Text = "Press \"Tray\" if you wish block WinKey or \"Exit\" to leave this application.";
this.lblHowdoit.TextAlign = ContentAlignment.MiddleCenter;
//
//btnExit
//
this.btnExit.Location = new Point(12, 74);
this.btnExit.Text = "E&xit";
this.btnExit.Click += new EventHandler(btnExit_Click);
//
//btnTray
//
this.btnTray.Location = new Point(210, 74);
this.btnTray.Text = "&Tray";
this.btnTray.Click += new EventHandler(btnTray_Click);
//
//ntfContext
//
this.ntfContext.ContextMenu = this.mnuContext;
this.ntfContext.Icon = this.Icon;
//
//mnuContext
//
this.mnuContext.MenuItems.AddRange(new MenuItem[] { this.mnuRestore,
this.mnuSplit,
this.mnuExit } );
//
//mnuRestore
//
this.mnuRestore.Text = "Restore";
this.mnuRestore.Click += new EventHandler(mnuRestore_Click);
//
//mnuSplit
//
this.mnuSplit.Text = "-";
//
//mnuExit
//
this.mnuExit.Text = "Exit";
this.mnuExit.Click += new EventHandler(mnuExit_Click);
//
//frmMain
//
this.ClientSize = new Size(297, 111);
this.Controls.AddRange(new Control[] { this.lblCaption,
this.lblHowdoit,
this.btnExit,
this.btnTray } );
this.FormBorderStyle = FormBorderStyle.FixedSingle;
this.MaximizeBox = false;
this.StartPosition = FormStartPosition.CenterScreen;
this.Text = "WinKey";
this.Load += new EventHandler(frmMain_Load);
}
private static IntPtr SetHook(LowLevelKeyboardProc proc)
{
using (Process curProcess = Process.GetCurrentProcess())
using (ProcessModule curModule = curProcess.MainModule)
{
return SetWindowsHookEx(WH_KEYBOARD_LL, proc, GetModuleHandle(curModule.ModuleName), 0);
}
}
private delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam);
private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
{
if ((nCode >= 0) && (wParam == (IntPtr)WM_KEYDOWN))
{
int vkCode = Marshal.ReadInt32(lParam);
if (((Keys)vkCode == Keys.LWin) || ((Keys)vkCode == Keys.RWin))
{
return (IntPtr)1;
}
}
return CallNextHookEx(_hookID, nCode, wParam, lParam);
}
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProc lpfn,
IntPtr hMod, uint dwThreadId);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern bool UnhookWindowsHookEx(IntPtr hhk);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode,
IntPtr wParam, IntPtr lParam);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr GetModuleHandle(string lpModuleName);
private void btnExit_Click(object sender, EventArgs e)
{
this.Close();
}
private void btnTray_Click(object sender, EventArgs e)
{
this.Hide();
ntfContext.Visible = true;
ntfContext.Text = "WinKey Hooker";
}
private void mnuRestore_Click(object sender, EventArgs e)
{
ntfContext.Visible = false;
this.Show();
}
private void mnuExit_Click(object sender, EventArgs e)
{
ntfContext.Visible = false;
Application.Exit();
}
[STAThread]
public static void Main()
{
_hookID = SetHook(_proc);
Application.EnableVisualStyles();
Application.Run(new frmMain());
UnhookWindowsHookEx(_hookID);
}
}[/more] Написано полностью руками без всякой VisualStudio, собрано через csc.exe. Версия фреймворка должна быть не ниже 2.0. Может кому пригодится в качестве примера.