My keyboard hook captures all keys - c#

using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace ScreenYos
{
public class KeyboardHook : IDisposable
{
private bool Global = false;
public delegate void LocalKeyEventHandler(Keys key, bool Printscreen);
public event LocalKeyEventHandler KeyDown;
public event LocalKeyEventHandler KeyUp;
public delegate int CallbackDelegate(int Code, int W, int L);
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct KBDLLHookStruct
{
public Int32 vkCode;
public Int32 scanCode;
public Int32 flags;
public Int32 time;
public Int32 dwExtraInfo;
}
[DllImport("user32", CallingConvention = CallingConvention.StdCall)]
private static extern int SetWindowsHookEx(HookType idHook, CallbackDelegate lpfn, int hInstance, int threadId);
[DllImport("user32", CallingConvention = CallingConvention.StdCall)]
private static extern bool UnhookWindowsHookEx(int idHook);
[DllImport("user32", CallingConvention = CallingConvention.StdCall)]
private static extern int CallNextHookEx(int idHook, int nCode, int wParam, int lParam);
[DllImport("kernel32.dll", CallingConvention = CallingConvention.StdCall)]
private static extern int GetCurrentThreadId();
public enum HookType : int
{
WH_JOURNALRECORD = 0,
WH_JOURNALPLAYBACK = 1,
WH_KEYBOARD = 2,
WH_GETMESSAGE = 3,
WH_CALLWNDPROC = 4,
WH_CBT = 5,
WH_SYSMSGFILTER = 6,
WH_MOUSE = 7,
WH_HARDWARE = 8,
WH_DEBUG = 9,
WH_SHELL = 10,
WH_FOREGROUNDIDLE = 11,
WH_CALLWNDPROCRET = 12,
WH_KEYBOARD_LL = 13,
WH_MOUSE_LL = 14
}
private int HookID = 0;
private CallbackDelegate TheHookCB = null;
public KeyboardHook(bool Global)
{
this.Global = Global;
TheHookCB = new CallbackDelegate(KeybHookProc);
if (Global)
{
HookID = SetWindowsHookEx(HookType.WH_KEYBOARD_LL, TheHookCB,
0,
0);
}
else
{
HookID = SetWindowsHookEx(HookType.WH_KEYBOARD, TheHookCB,
0,
GetCurrentThreadId());
}
}
private bool IsFinalized;
~KeyboardHook()
{
if (!IsFinalized)
{
UnhookWindowsHookEx(HookID);
IsFinalized = true;
}
}
public void Dispose()
{
if (!IsFinalized)
{
UnhookWindowsHookEx(HookID);
IsFinalized = true;
}
}
private int KeybHookProc(int Code, int W, int L)
{
KBDLLHookStruct LS = new KBDLLHookStruct();
if (Code < 0)
{
return CallNextHookEx(HookID, Code, W, L);
}
try
{
if (!Global)
{
if (Code == 3)
{
IntPtr ptr = IntPtr.Zero;
int keydownup = L >> 30;
if (keydownup == 0)
{
if (KeyDown != null)
KeyDown((Keys) W, GetPrintscreenPressed());
}
if (keydownup == -1)
{
if (KeyUp != null) KeyUp((Keys) W, GetPrintscreenPressed());
}
//System.Diagnostics.Debug.WriteLine("KeyDown: " + (Keys)W);
}
}
else
{
KeyEvents kEvent = (KeyEvents) W;
Int32 vkCode = Marshal.ReadInt32((IntPtr) L);
if (kEvent != KeyEvents.KeyDown && kEvent != KeyEvents.KeyUp && kEvent != KeyEvents.SKeyDown &&
kEvent != KeyEvents.SKeyUp)
{
}
if (kEvent == KeyEvents.KeyDown || kEvent == KeyEvents.SKeyDown)
{
if (KeyDown != null)
KeyDown((Keys) vkCode, GetPrintscreenPressed());
}
if (kEvent == KeyEvents.KeyUp || kEvent == KeyEvents.SKeyUp)
{
if (KeyUp != null) KeyUp((Keys) vkCode, GetPrintscreenPressed());
}
}
}
catch (Exception e)
{
//Console.WriteLine(e.Message);
}
return CallNextHookEx(HookID, Code, W, L);
}
public enum KeyEvents
{
KeyDown = 0x0100,
KeyUp = 0x0101,
SKeyDown = 0x0104,
SKeyUp = 0x0105
}
[DllImport("user32.dll")]
public static extern short GetKeyState(Keys nVirtKey);
public static bool GetPrintscreenPressed()
{
int state = GetKeyState(Keys.PrintScreen);
if (state > 1 || state < -1) return true;
return false;
}
}
}
My usage:
private static void Kh_KeyDown(Keys key, bool Printscreen)
{
if (new Form1().ShowDialog() == DialogResult.OK)
{
Application.Run(new Form1());
}
}
So program runs in system tray and the aim of the code is capture keys globally and when printscreen is pressed run Form1 yet it captures every key and no matter what key i press, it runs form1.

I assume that's because you initialized a general callback for all Keys on KeyDown.
You must either filter by Keys.PrintScreen when you call the event
or
Filter by Keys.PrintScreen in your Eventhandler.
private static void Kh_KeyDown(Keys key, bool Printscreen)
{
if (key == Keys.PrintScreen && new Form1().ShowDialog() == DialogResult.OK)
{
Application.Run(new Form1());
}
}
Thomas

Related

c# global keyboard hook with Microsoft.Office.Interop.PowerPoint COMException

I'm using the full class provided as best answer in: C# Hook Global Keyboard Events - .net 4.0 without any changes to it. However, when pressing a key when focussed on the powerpoint, I get the following error:
Exception thrown: 'System.Runtime.InteropServices.COMException'
I open the powerpoint by:
PowerPoint.Presentation presentation = (PowerPoint.Presentation)PowerPointItems[0];
PowerPoint.Application application = presentation.Application;
PowerPoint.SlideShowSettings settings = presentation.SlideShowSettings;
settings.ShowType = (PowerPoint.PpSlideShowType)1;
settings.ShowPresenterView = MsoTriState.msoFalse;
PowerPoint.SlideShowWindow sw = settings.Run();
sw.View.AcceleratorsEnabled = MsoTriState.msoFalse;
presentation.SlideShowWindow.View.GotoSlide(1);
presentation.SlideShowWindow.View.FirstAnimationIsAutomatic();
The callback function looks like:
private static void Kh_KeyDown(Keys key, bool Shift, bool Ctrl, bool Alt)
{
Console.WriteLine("a");
PowerPoint.Presentation presentation = (PowerPoint.Presentation)PowerPointItems[0];
Console.WriteLine("b");
int nr_slides = presentation.Slides.Count;
Console.WriteLine("c");
}
However, while a and b are printed in the output, c is not but the exception is. This makes me think for some reason the exception is thrown because of the line
int nr_slides = presentation.Slides.Count;
Any thought on why this could be the case?
The code provided on C# Hook Global Keyboard Events - .net 4.0:
public class KeyboardHook : IDisposable
{
bool Global = false;
public delegate void ErrorEventHandler(Exception e);
public delegate void LocalKeyEventHandler(Keys key, bool Shift, bool Ctrl, bool Alt);
public event LocalKeyEventHandler KeyDown;
public event LocalKeyEventHandler KeyUp;
public event ErrorEventHandler OnError;
public delegate int CallbackDelegate(int Code, IntPtr W, IntPtr L);
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct KBDLLHookStruct
{
public Int32 vkCode;
public Int32 scanCode;
public Int32 flags;
public Int32 time;
public Int32 dwExtraInfo;
}
[DllImport("user32", CallingConvention = CallingConvention.StdCall)]
private static extern IntPtr SetWindowsHookEx(HookType idHook, CallbackDelegate lpfn, IntPtr hInstance, int threadId);
[DllImport("user32", CallingConvention = CallingConvention.StdCall)]
private static extern bool UnhookWindowsHookEx(IntPtr idHook);
[DllImport("user32", CallingConvention = CallingConvention.StdCall)]
private static extern int CallNextHookEx(IntPtr idHook, int nCode, IntPtr wParam, IntPtr lParam);
[DllImport("kernel32.dll", CallingConvention = CallingConvention.StdCall)]
private static extern int GetCurrentThreadId();
[DllImport("kernel32.dll")]
static extern IntPtr LoadLibrary(string lpFileName);
public enum HookType : int
{
WH_JOURNALRECORD = 0,
WH_JOURNALPLAYBACK = 1,
WH_KEYBOARD = 2,
WH_GETMESSAGE = 3,
WH_CALLWNDPROC = 4,
WH_CBT = 5,
WH_SYSMSGFILTER = 6,
WH_MOUSE = 7,
WH_HARDWARE = 8,
WH_DEBUG = 9,
WH_SHELL = 10,
WH_FOREGROUNDIDLE = 11,
WH_CALLWNDPROCRET = 12,
WH_KEYBOARD_LL = 13,
WH_MOUSE_LL = 14
}
private IntPtr HookID = IntPtr.Zero;
CallbackDelegate TheHookCB = null;
//Start hook
public KeyboardHook(bool Global)
{
this.Global = Global;
TheHookCB = new CallbackDelegate(KeybHookProc);
if (Global)
{
IntPtr hInstance = LoadLibrary("User32");
HookID = SetWindowsHookEx(HookType.WH_KEYBOARD_LL, TheHookCB,
hInstance, //0 for local hook. or hwnd to user32 for global
0); //0 for global hook. eller thread for hooken
}
else
{
HookID = SetWindowsHookEx(HookType.WH_KEYBOARD, TheHookCB,
IntPtr.Zero, //0 for local hook. or hwnd to user32 for global
GetCurrentThreadId()); //0 for global hook. or thread for the hook
}
}
public void test()
{
if (OnError != null) OnError(new Exception("test"));
}
bool IsFinalized = false;
~KeyboardHook()
{
if (!IsFinalized)
{
UnhookWindowsHookEx(HookID);
IsFinalized = true;
}
}
public void Dispose()
{
if (!IsFinalized)
{
UnhookWindowsHookEx(HookID);
IsFinalized = true;
}
}
[STAThread]
//The listener that will trigger events
private int KeybHookProc(int Code, IntPtr W, IntPtr L)
{
KBDLLHookStruct LS = new KBDLLHookStruct();
if (Code < 0)
{
return CallNextHookEx(HookID, Code, W, L);
}
try
{
if (!Global)
{
if (Code == 3)
{
IntPtr ptr = IntPtr.Zero;
int keydownup = L.ToInt32() >> 30;
if (keydownup == 0)
{
if (KeyDown != null) KeyDown((Keys)W, GetShiftPressed(), GetCtrlPressed(), GetAltPressed());
}
if (keydownup == -1)
{
if (KeyUp != null) KeyUp((Keys)W, GetShiftPressed(), GetCtrlPressed(), GetAltPressed());
}
//System.Diagnostics.Debug.WriteLine("Down: " + (Keys)W);
}
}
else
{
KeyEvents kEvent = (KeyEvents)W;
Int32 vkCode = Marshal.ReadInt32((IntPtr)L); //Leser vkCode som er de første 32 bits hvor L peker.
if (kEvent != KeyEvents.KeyDown && kEvent != KeyEvents.KeyUp && kEvent != KeyEvents.SKeyDown && kEvent != KeyEvents.SKeyUp)
{
}
if (kEvent == KeyEvents.KeyDown || kEvent == KeyEvents.SKeyDown)
{
if (KeyDown != null) KeyDown((Keys)vkCode, GetShiftPressed(), GetCtrlPressed(), GetAltPressed());
}
if (kEvent == KeyEvents.KeyUp || kEvent == KeyEvents.SKeyUp)
{
if (KeyUp != null) KeyUp((Keys)vkCode, GetShiftPressed(), GetCtrlPressed(), GetAltPressed());
}
}
}
catch (Exception e)
{
if (OnError != null) OnError(e);
//Ignore all errors...
}
return CallNextHookEx(HookID, Code, W, L);
}
public enum KeyEvents
{
KeyDown = 0x0100,
KeyUp = 0x0101,
SKeyDown = 0x0104,
SKeyUp = 0x0105
}
[DllImport("user32.dll")]
static public extern short GetKeyState(System.Windows.Forms.Keys nVirtKey);
public static bool GetCapslock()
{
return Convert.ToBoolean(GetKeyState(System.Windows.Forms.Keys.CapsLock)) & true;
}
public static bool GetNumlock()
{
return Convert.ToBoolean(GetKeyState(System.Windows.Forms.Keys.NumLock)) & true;
}
public static bool GetScrollLock()
{
return Convert.ToBoolean(GetKeyState(System.Windows.Forms.Keys.Scroll)) & true;
}
public static bool GetShiftPressed()
{
int state = GetKeyState(System.Windows.Forms.Keys.ShiftKey);
if (state > 1 || state < -1) return true;
return false;
}
public static bool GetCtrlPressed()
{
int state = GetKeyState(System.Windows.Forms.Keys.ControlKey);
if (state > 1 || state < -1) return true;
return false;
}
public static bool GetAltPressed()
{
int state = GetKeyState(System.Windows.Forms.Keys.Menu);
if (state > 1 || state < -1) return true;
return false;
}
}
In general, you need to catch the COMException, interrogate ErrorCode (HRESULT) property, and search for the error code definition; this will provide direction on how to troubleshoot the issue further.
Reference: COMException Class: Handling a COMException exception on MSDN
One idea, without knowing the error code, is this interaction might need to occur on the thread which instantiated the control. You might be able to resolve this by using Invoke or BeginInvoke.
Control.BeginInvoke Method
If you add more details to the question I will try to provide a better answer.

cant send key stroke only to Word Through my program that use KeyboardHook

i have my program that Captures weighing and send it to a open window.
its work excellent , except with a single software - Microsoft Word
I have tried everything and have no idea why.
my code:
this is the GlobalKeyBoardHook.cs class
public class GlobalKeyboardHook
{
[DllImport("user32.dll")]
static extern int CallNextHookEx(IntPtr hhk, int code, int wParam, ref keyBoardHookStruct lParam);
[DllImport("user32.dll")]
static extern IntPtr SetWindowsHookEx(int idHook, LLKeyboardHook callback, IntPtr hInstance, uint theardID);
[DllImport("user32.dll")]
static extern bool UnhookWindowsHookEx(IntPtr hInstance);
[DllImport("kernel32.dll")]
static extern IntPtr LoadLibrary(string lpFileName);
public delegate int LLKeyboardHook(int Code, int wParam, ref keyBoardHookStruct lParam);
public struct keyBoardHookStruct
{
public int vkCode;
public int scanCode;
public int flags;
public int time;
public int dwExtraInfo;
}
const int WH_KEYBOARD_LL = 13;
const int WM_KEYDOWN = 0x0100;
const int WM_KEYUP = 0x0101;
const int WM_SYSKEYDOWN = 0x0104;
const int WM_SYSKEYUP = 0x0105;
LLKeyboardHook llkh;
public List<Keys> HookedKeys = new List<Keys>();
IntPtr Hook = IntPtr.Zero;
public event KeyEventHandler KeyDown;
public event KeyEventHandler KeyUp;
// This is the Constructor. This is the code that runs every time you create a new GlobalKeyboardHook object
public GlobalKeyboardHook()
{
llkh = new LLKeyboardHook(HookProc);
// This starts the hook. You can leave this as comment and you have to start it manually (the thing I do in the tutorial, with the button)
// Or delete the comment mark and your hook will start automatically when your program starts (because a new GlobalKeyboardHook object is created)
// That's why there are duplicates, because you start it twice! I'm sorry, I haven't noticed this...
// hook(); <-- Choose!
}
~GlobalKeyboardHook()
{ unhook(); }
public void hook()
{
IntPtr hInstance = LoadLibrary("User32");
Hook = SetWindowsHookEx(WH_KEYBOARD_LL, llkh, hInstance, 0);
}
public void unhook()
{
UnhookWindowsHookEx(Hook);
}
public int HookProc(int Code, int wParam, ref keyBoardHookStruct lParam)
{
if (Code >= 0)
{
Keys key = (Keys)lParam.vkCode;
if (HookedKeys.Contains(key))
{
KeyEventArgs kArg = new KeyEventArgs(key);
if ((wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN) && (KeyDown != null))
KeyDown(this, kArg);
else if ((wParam == WM_KEYUP || wParam == WM_SYSKEYUP) && (KeyUp != null))
KeyUp(this, kArg);
if (kArg.Handled)
return 1;
}
}
return CallNextHookEx(Hook, Code, wParam, ref lParam);
}
// --- from here start the program --
GlobalKeyboardHook gHook;
gHook = new GlobalKeyboardHook(); // Create a new GlobalKeyboardHook
gHook.KeyDown += new KeyEventHandler(gHook_KeyDown);
foreach (Keys key in Enum.GetValues(typeof(Keys)))
{
gHook.HookedKeys.Add(key);
}
gHook.hook();
public void gHook_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyValue == KeyPressg) //Pause-Break //19
{
ProccName = (GetActiveWindowTitle().ToString());
Start(ProccName);
gHook.unhook();
gHook.hook();
}
else
{
}
}
private string GetActiveWindowTitle()
{
const int nChars = 256;
StringBuilder Buff = new StringBuilder(nChars);
IntPtr handle = GetForegroundWindow();
if (GetWindowText(handle, Buff, nChars) > 0)
{
return Buff.ToString();
}
return null;
}
[DllImport("user32.dll")]
static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count);
[DllImport("user32.dll")]
private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll")]
private static extern bool SetForegroundWindow(IntPtr hWnd);
public void Start(string NAME)
{
MSG = lblMSG.Text.Trim();
IntPtr zero = IntPtr.Zero;
for (int i = 0; (i < 60) && (zero == IntPtr.Zero); i++)
{
Thread.Sleep(500);
zero = FindWindow(null, NAME);
}
if (zero != IntPtr.Zero)
{
try
{
string text = lblMSG.Text.Trim();
text = text.Replace("gHook", "");
//OLD
//foreach (char c in text)
// SendKeys.SendWait(c.ToString());
//NEW
if (text.Length == 0) return;
SendKeys.SendWait(text);
if (MyParam._KeyAfter == "Enter")
{
MyParam.FromKEY = true;
SendKeys.SendWait("{ENTER}");
}
else if (MyParam._KeyAfter == "TAB")
{
SendKeys.SendWait("{TAB}");
}
else if (MyParam._KeyAfter == "Key Down")
{
SendKeys.SendWait("{DOWN}");
}
SendKeys.Flush();
}
catch { }
}
}
Any ideas why ?
thanks
EDIT
i fount the problem place:
public void Start(string NAME)
{
// --> NAME Contain --> Word‪ - 123.docx for example when Word window open
MSG = lblMSG.Text.Trim();
IntPtr zero = IntPtr.Zero;
for (int i = 0; (i < 60) && (zero == IntPtr.Zero); i++)
{
Thread.Sleep(500);
zero = FindWindow(null, NAME); // <-- in Word zero Always Contain 0 And never goes on in the code so stuck
}
// <--- the program stops here and stuck
if (zero != IntPtr.Zero)
{

C# Global keyboard hook in Office Addin 2013

I encounter a problem to make my Office Addin works with my global keyboard on Powerpoint 2013 but not on the previous versions (2007 and 2010).
I do not get any exception but it seems that the OnKeyDown event is never triggered on Powerpoint 2013, and I don't know why.
I get the same problems on all versions of Windows (XP, 7, 8 & 8.1), on 32 & 64 bits environments. The version of Microsoft Office is 32 bits.
Here is a code sample :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using PowerPoint = Microsoft.Office.Interop.PowerPoint;
using Office = Microsoft.Office.Core;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Diagnostics;
namespace testHook
{
public partial class ThisAddIn
{
Hook hook;
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
hook = new Hook(Hook.HookType.KeyBoard, Hook.HookVisibility.Global);
hook.OnKeyDown += new KeyEventHandler(hook_OnKeyDown);
hook.Start();
}
void hook_OnKeyDown(object sender, KeyEventArgs e)
{
MessageBox.Show(e.KeyCode.ToString());
}
private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
{
hook.Stop();
hook = null;
}
#region VSTO generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InternalStartup()
{
this.Startup += new System.EventHandler(ThisAddIn_Startup);
this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown);
}
#endregion
class Hook
{
private IntPtr m_Hook = (IntPtr)0;
private HookVisibility m_Visibility;
private HookType m_HookType;
private HookProc m_Proc;
public enum HookType { KeyBoard };
public enum KeyBoardEventType { KeyDown, KeyUp, SysKeyDown, SysKeyUp, KeyShift, KeyCapital, NumLock };
public enum HookVisibility { Global, Local };
private delegate IntPtr HookProc(int nCode, int wParam, IntPtr lParam);
private KeyPressEventHandler m_onKeyPress;
private KeyEventHandler m_onKeyUp;
private KeyEventHandler m_onKeyDown;
public event KeyPressEventHandler OnKeyPress
{
add
{
m_onKeyPress += value;
}
remove
{
m_onKeyPress -= value;
}
}
public event KeyEventHandler OnKeyUp
{
add
{
m_onKeyUp += value;
}
remove
{
m_onKeyUp -= value;
}
}
public event KeyEventHandler OnKeyDown
{
add
{
m_onKeyDown += value;
}
remove
{
m_onKeyDown -= value;
}
}
#region DLLImport
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
private static extern IntPtr SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hmod, int dwThreadId);
[DllImport("user32.dll")]
private static extern IntPtr CallNextHookEx(IntPtr hHook, int nCode, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
private static extern bool UnhookWindowsHookEx(IntPtr hHook);
[DllImport("Kernel32.dll", SetLastError = true)]
private static extern IntPtr GetModuleHandle(IntPtr lpModuleName);
[DllImport("Kernel32.dll", SetLastError = true)]
private static extern IntPtr GetModuleHandle(String lpModuleName);
[DllImport("Kernel32.dll")]
private static extern IntPtr GetCurrentThreadId();
[DllImport("user32")]
private static extern int ToAscii(int uVirtKey, int uScanCode, byte[] lpbKeyState, byte[] lpwTransKey, int fuState);
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
private static extern short GetKeyState(int vKey);
[DllImport("user32")]
private static extern int GetKeyboardState(byte[] pbKeyState);
#endregion
[StructLayout(LayoutKind.Sequential)]
private class KeyboardHookStruct
{
public int vkCode;
public int scanCode;
public int flags;
public int time;
public int dwExtraInfo;
}
public Hook(HookType H, HookVisibility H2)
{
m_HookType = H;
m_Visibility = H2;
}
public bool Start()
{
if (m_HookType == HookType.KeyBoard)
m_Proc = new HookProc(KeyProc);
if (m_Visibility == HookVisibility.Global)
m_Hook = SetWindowsHookEx(getHookType(m_HookType, m_Visibility), m_Proc, GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName), 0);
else if (m_Visibility == HookVisibility.Local)
m_Hook = SetWindowsHookEx(getHookType(m_HookType, m_Visibility), m_Proc, GetModuleHandle((IntPtr)0), (int)GetCurrentThreadId());
if (m_Hook == (IntPtr)0)
return false;
return true;
}
public bool Stop()
{
return UnhookWindowsHookEx(m_Hook);
}
private int getHookType(HookType H, HookVisibility V)
{
if (H == HookType.KeyBoard && V == HookVisibility.Local)
return 2;
if (H == HookType.KeyBoard && V == HookVisibility.Global)
return 13;
else return -1;
}
private int getKeyBoardEventType(KeyBoardEventType K)
{
if (K == KeyBoardEventType.KeyDown)
return 0x100;
if (K == KeyBoardEventType.KeyUp)
return 0x101;
if (K == KeyBoardEventType.SysKeyDown)
return 0x104;
if (K == KeyBoardEventType.SysKeyUp)
return 0x105;
if (K == KeyBoardEventType.KeyShift)
return 0x10;
if (K == KeyBoardEventType.KeyCapital)
return 0x14;
if (K == KeyBoardEventType.NumLock)
return 0x90;
else return -1;
}
private IntPtr KeyProc(int nCode, int wParam, IntPtr lParam)
{
bool handled = false;
if ((nCode >= 0) && (m_onKeyDown != null || m_onKeyUp != null || m_onKeyPress != null))
{
KeyboardHookStruct MyKeyboardHookStruct = (KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct));
if (m_onKeyDown != null && (wParam == 0x100 || wParam == 0x104))
{
Keys keyData = (Keys)MyKeyboardHookStruct.vkCode;
KeyEventArgs e = new KeyEventArgs(keyData);
m_onKeyDown(this, e);
handled = handled || e.Handled;
}
if (m_onKeyPress != null && wParam == 0x100)
{
bool isShift = ((GetKeyState(0x10) & 0x80) == 0x80 ? true : false);
bool isCapslock = (GetKeyState(0x14) != 0 ? true : false);
byte[] keyState = new byte[256];
GetKeyboardState(keyState);
byte[] inBuffer = new byte[2];
if (ToAscii(MyKeyboardHookStruct.vkCode, MyKeyboardHookStruct.scanCode, keyState, inBuffer, MyKeyboardHookStruct.flags) == 1)
{
char key = (char)inBuffer[0];
if ((isCapslock ^ isShift) && Char.IsLetter(key))
key = Char.ToUpper(key);
KeyPressEventArgs e = new KeyPressEventArgs(key);
m_onKeyPress(this, e);
handled = handled || e.Handled;
}
}
if (m_onKeyUp != null && (wParam == 0x101 || wParam == 0x105))
{
Keys keyData = (Keys)MyKeyboardHookStruct.vkCode;
KeyEventArgs e = new KeyEventArgs(keyData);
m_onKeyUp(this, e);
handled = handled || e.Handled;
}
}
if (handled)
return (IntPtr)1;
else
return CallNextHookEx(m_Hook, nCode, (IntPtr)wParam, (IntPtr)lParam);
}
}
}
My application need to fire events during the slideshow because I have some others windows which are displayed during the presentation, and I have to update them according to the keys that the user presses. I have tried a lot of solutions but the hook is the only one that can do perfectly the job.
I tried too a local keyboard hook instead of a global one. I actually think that it is the only way to make it works because it is a bug from Microsoft, and not from the code. However, I can't make the local one works properly on any version of Powerpoint.
The issue is not Powerpoint specific, it occurs with any Office product.
I'm working on a Outlook addin and fancing this problem.
It has been reported (without any answer unfortunely) to Microsoft:
https://social.msdn.microsoft.com/Forums/office/en-US/93d08ccc-9e77-4f72-9c51-477468d89681/keyboardhook-will-not-work-in-word-2013?forum=worddev
I have been able to make a "workaround": i have register a Global Hook AND a Local one ("Thread"). It works, but the keyProc is called "weirdly" when it's local, not respecting documented parameters:
- wParam is not one of WM_*, but contains directly the vkCode
- lParam cannot be accessed (AccessViolation)
As I understood, it's because some "TranslateMessage" processing.
I have also adapted your code to be able to catch ALT combination.
private bool wParamAlt;
private IntPtr KeyProc(int nCode, int wParam, IntPtr lParam)
{
bool handled = false;
if ((nCode == 0) && (m_onKeyDown != null || m_onKeyUp != null || m_onKeyPress != null))
{
KeyboardHookStruct MyKeyboardHookStruct;
if (wParam >= 0x100)
{
MyKeyboardHookStruct = (KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct));
wParamAlt = false;
}
else
{
MyKeyboardHookStruct = new KeyboardHookStruct();
MyKeyboardHookStruct.vkCode = wParam;
if (wParamAlt)
{
wParamAlt = (wParam == 18);
wParam = 0x104;
}
else
{
wParamAlt = (wParam == 18);
wParam = 0x100;
}
}
if (m_onKeyDown != null && (wParam == 0x100 || wParam == 0x104))
{
Keys keyData = (Keys)MyKeyboardHookStruct.vkCode;
if (wParam == 0x104)
keyData |= Keys.Alt;
KeyEventArgs e = new KeyEventArgs(keyData);
m_onKeyDown(this, e);
handled = handled || e.Handled;
}
if (m_onKeyPress != null && wParam == 0x100)
{
bool isShift = ((GetKeyState(0x10) & 0x80) == 0x80 ? true : false);
bool isCapslock = (GetKeyState(0x14) != 0 ? true : false);
byte[] keyState = new byte[256];
GetKeyboardState(keyState);
byte[] inBuffer = new byte[2];
if (ToAscii(MyKeyboardHookStruct.vkCode, MyKeyboardHookStruct.scanCode, keyState, inBuffer, MyKeyboardHookStruct.flags) == 1)
{
char key = (char)inBuffer[0];
if ((isCapslock ^ isShift) && Char.IsLetter(key))
key = Char.ToUpper(key);
KeyPressEventArgs e = new KeyPressEventArgs(key);
m_onKeyPress(this, e);
handled = handled || e.Handled;
}
}
if (m_onKeyUp != null && (wParam == 0x101 || wParam == 0x105))
{
Keys keyData = (Keys)MyKeyboardHookStruct.vkCode;
if (wParam == 0x105)
keyData |= Keys.Alt;
KeyEventArgs e = new KeyEventArgs(keyData);
m_onKeyUp(this, e);
handled = handled || e.Handled;
}
}
if (handled)
return (IntPtr)1;
else
return CallNextHookEx(m_Hook, nCode, (IntPtr)wParam, (IntPtr)lParam);
}

Global hotkey in console application

Does anyone know how to use the RegisterHotKey/UnregisterHotKey API calls in a console application? I assume that setting up/removing the hotkey is the same, but how do I get the call back when the key was pressed?
Every example I see is for Winforms, and uses protected override void WndProc(ref Message m){...}, which isn't available to me.
update: what I have is below, but the event is never hit. I thought it could be because when you load ConsoleShell it does block further execution, but even if I put SetupHotkey into a different thread nothing happens. Any thoughts?
class Program
{
static void Main(string[] args)
{
new Hud().Init(args);
}
}
class Hud
{
int keyHookId;
public void Init(string[] args)
{
SetupHotkey();
InitPowershell(args);
Cleanup();
}
private void Cleanup()
{
HotKeyManager.UnregisterHotKey(keyHookId);
}
private void SetupHotkey()
{
keyHookId = HotKeyManager.RegisterHotKey(Keys.Oemtilde, KeyModifiers.Control);
HotKeyManager.HotKeyPressed += new EventHandler<HotKeyEventArgs>(HotKeyManager_HotKeyPressed);
}
void HotKeyManager_HotKeyPressed(object sender, HotKeyEventArgs e)
{
//never executed
System.IO.File.WriteAllText("c:\\keyPressed.txt", "Hotkey pressed");
}
private static void InitPowershell(string[] args)
{
var config = RunspaceConfiguration.Create();
ConsoleShell.Start(config, "", "", args);
}
}
What you can do is Create a hidden window in your Console application which is used to handle the hotkey notification and raise an event.
The code HERE demonstrates the principal. HERE is an article on handling messages in a Console application, using this you should be able to enhance HotKeyManager to run in a Console Application.
The following update to the HotKeyManager creates a background thread which runs the message loop and handles the windows messages.
using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Threading;
namespace ConsoleHotKey
{
public static class HotKeyManager
{
public static event EventHandler<HotKeyEventArgs> HotKeyPressed;
public static int RegisterHotKey(Keys key, KeyModifiers modifiers)
{
_windowReadyEvent.WaitOne();
int id = System.Threading.Interlocked.Increment(ref _id);
_wnd.Invoke(new RegisterHotKeyDelegate(RegisterHotKeyInternal), _hwnd, id, (uint)modifiers, (uint)key);
return id;
}
public static void UnregisterHotKey(int id)
{
_wnd.Invoke(new UnRegisterHotKeyDelegate(UnRegisterHotKeyInternal), _hwnd, id);
}
delegate void RegisterHotKeyDelegate(IntPtr hwnd, int id, uint modifiers, uint key);
delegate void UnRegisterHotKeyDelegate(IntPtr hwnd, int id);
private static void RegisterHotKeyInternal(IntPtr hwnd, int id, uint modifiers, uint key)
{
RegisterHotKey(hwnd, id, modifiers, key);
}
private static void UnRegisterHotKeyInternal(IntPtr hwnd, int id)
{
UnregisterHotKey(_hwnd, id);
}
private static void OnHotKeyPressed(HotKeyEventArgs e)
{
if (HotKeyManager.HotKeyPressed != null)
{
HotKeyManager.HotKeyPressed(null, e);
}
}
private static volatile MessageWindow _wnd;
private static volatile IntPtr _hwnd;
private static ManualResetEvent _windowReadyEvent = new ManualResetEvent(false);
static HotKeyManager()
{
Thread messageLoop = new Thread(delegate()
{
Application.Run(new MessageWindow());
});
messageLoop.Name = "MessageLoopThread";
messageLoop.IsBackground = true;
messageLoop.Start();
}
private class MessageWindow : Form
{
public MessageWindow()
{
_wnd = this;
_hwnd = this.Handle;
_windowReadyEvent.Set();
}
protected override void WndProc(ref Message m)
{
if (m.Msg == WM_HOTKEY)
{
HotKeyEventArgs e = new HotKeyEventArgs(m.LParam);
HotKeyManager.OnHotKeyPressed(e);
}
base.WndProc(ref m);
}
protected override void SetVisibleCore(bool value)
{
// Ensure the window never becomes visible
base.SetVisibleCore(false);
}
private const int WM_HOTKEY = 0x312;
}
[DllImport("user32", SetLastError=true)]
private static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk);
[DllImport("user32", SetLastError = true)]
private static extern bool UnregisterHotKey(IntPtr hWnd, int id);
private static int _id = 0;
}
public class HotKeyEventArgs : EventArgs
{
public readonly Keys Key;
public readonly KeyModifiers Modifiers;
public HotKeyEventArgs(Keys key, KeyModifiers modifiers)
{
this.Key = key;
this.Modifiers = modifiers;
}
public HotKeyEventArgs(IntPtr hotKeyParam)
{
uint param = (uint)hotKeyParam.ToInt64();
Key = (Keys)((param & 0xffff0000) >> 16);
Modifiers = (KeyModifiers)(param & 0x0000ffff);
}
}
[Flags]
public enum KeyModifiers
{
Alt = 1,
Control = 2,
Shift = 4,
Windows = 8,
NoRepeat = 0x4000
}
}
Here is an example of using HotKeyManager from a Console application
using System;
using System.Windows.Forms;
namespace ConsoleHotKey
{
class Program
{
static void Main(string[] args)
{
HotKeyManager.RegisterHotKey(Keys.A, KeyModifiers.Alt);
HotKeyManager.HotKeyPressed += new EventHandler<HotKeyEventArgs>(HotKeyManager_HotKeyPressed);
Console.ReadLine();
}
static void HotKeyManager_HotKeyPressed(object sender, HotKeyEventArgs e)
{
Console.WriteLine("Hit me!");
}
}
}
I just wanted to offer an alternative solution.
I was answering a question for someone who was using this script and I figured this might help someone else who has trouble setting up a global key hook.
Edit: Don't forget to add a reference to System.Windows.Forms
You can do this by selecting Project🢂Add Reference and checking System.Windows.Forms
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace ConsoleKeyhook
{
class Hooky
{
///////////////////////////////////////////////////////////
//A bunch of DLL Imports to set a low level keyboard hook
///////////////////////////////////////////////////////////
[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)]
[return: MarshalAs(UnmanagedType.Bool)]
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);
////////////////////////////////////////////////////////////////
//Some constants to make handling our hook code easier to read
////////////////////////////////////////////////////////////////
private const int WH_KEYBOARD_LL = 13; //Type of Hook - Low Level Keyboard
private const int WM_KEYDOWN = 0x0100; //Value passed on KeyDown
private const int WM_KEYUP = 0x0101; //Value passed on KeyUp
private static LowLevelKeyboardProc _proc = HookCallback; //The function called when a key is pressed
private static IntPtr _hookID = IntPtr.Zero;
private static bool CONTROL_DOWN = false; //Bool to use as a flag for control key
public static void Main()
{
_hookID = SetHook(_proc); //Set our hook
Application.Run(); //Start a standard application method loop
}
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) //A Key was pressed down
{
int vkCode = Marshal.ReadInt32(lParam); //Get the keycode
string theKey = ((Keys)vkCode).ToString(); //Name of the key
Console.Write(theKey); //Display the name of the key
if (theKey.Contains("ControlKey")) //If they pressed control
{
CONTROL_DOWN = true; //Flag control as down
}
else if (CONTROL_DOWN && theKey == "B") //If they held CTRL and pressed B
{
Console.WriteLine("\n***HOTKEY PRESSED***"); //Our hotkey was pressed
}
else if (theKey == "Escape") //If they press escape
{
UnhookWindowsHookEx(_hookID); //Release our hook
Environment.Exit(0); //Exit our program
}
}
else if (nCode >= 0 && wParam == (IntPtr)WM_KEYUP) //KeyUP
{
int vkCode = Marshal.ReadInt32(lParam); //Get Keycode
string theKey = ((Keys)vkCode).ToString(); //Get Key name
if (theKey.Contains("ControlKey")) //If they let go of control
{
CONTROL_DOWN = false; //Unflag control
}
}
return CallNextHookEx(_hookID, nCode, wParam, lParam); //Call the next hook
}
}
}
I came up with a solution based on Chris' answer that uses WPF instead of WinForms:
public sealed class GlobalHotkeyRegister : IGlobalHotkeyRegister, IDisposable
{
private const int WmHotkey = 0x0312;
private Application _app;
private readonly Dictionary<Hotkey, Action> _hotkeyActions;
public GlobalHotkeyRegister()
{
_hotkeyActions = new Dictionary<Hotkey, Action>();
var startupTcs = new TaskCompletionSource<object>();
Task.Run(() =>
{
ComponentDispatcher.ThreadPreprocessMessage += OnThreadPreProcessMessage;
_app = new Application();
_app.Startup += (s, e) => startupTcs.SetResult(null);
_app.Run();
});
startupTcs.Task.Wait();
}
public void Add(Hotkey hotkey, Action action)
{
_hotkeyActions.Add(hotkey, action);
var keyModifier = (int) hotkey.KeyModifier;
var key = KeyInterop.VirtualKeyFromKey(hotkey.Key);
_app.Dispatcher.Invoke(() =>
{
if (!RegisterHotKey(IntPtr.Zero, hotkey.GetHashCode(), keyModifier, key))
throw new Win32Exception(Marshal.GetLastWin32Error());
});
}
public void Remove(Hotkey hotkey)
{
_hotkeyActions.Remove(hotkey);
_app.Dispatcher.Invoke(() =>
{
if (!UnregisterHotKey(IntPtr.Zero, hotkey.GetHashCode()))
throw new Win32Exception(Marshal.GetLastWin32Error());
});
}
private void OnThreadPreProcessMessage(ref MSG msg, ref bool handled)
{
if (msg.message != WmHotkey)
return;
var key = KeyInterop.KeyFromVirtualKey(((int) msg.lParam >> 16) & 0xFFFF);
var keyModifier = (KeyModifier) ((int) msg.lParam & 0xFFFF);
var hotKey = new Hotkey(keyModifier, key);
_hotkeyActions[hotKey]();
}
public void Dispose()
{
_app.Dispatcher.InvokeShutdown();
}
[DllImport("user32.dll", SetLastError = true)]
private static extern bool RegisterHotKey(IntPtr hWnd, int id, int fsModifiers, int vlc);
[DllImport("user32.dll", SetLastError = true)]
private static extern bool UnregisterHotKey(IntPtr hWnd, int id);
}
public class Hotkey
{
public Hotkey(KeyModifier keyModifier, Key key)
{
KeyModifier = keyModifier;
Key = key;
}
public KeyModifier KeyModifier { get; }
public Key Key { get; }
#region ToString(), Equals() and GetHashcode() overrides
}
[Flags]
public enum KeyModifier
{
None = 0x0000,
Alt = 0x0001,
Ctrl = 0x0002,
Shift = 0x0004,
Win = 0x0008,
NoRepeat = 0x4000
}
To use this, you need to add references to PresentationFramework.dll and WindowsBase.dll.
public static void Main()
{
using (var hotkeyManager = new GlobalHotkeyManager())
{
var hotkey = new Hotkey(KeyModifier.Ctrl | KeyModifier.Alt, Key.S);
hotkeyManager.Add(hotkey, () => System.Console.WriteLine(hotkey));
System.Console.ReadKey();
}
}
Changed the HotKeyManager class
public static class HotKeyManager
{
public static event EventHandler<HotKeyEventArgs> HotKeyPressed;
public static int RegisterHotKey(Keys key, HotKeyEventArgs.KeyModifiers modifiers)
{
_windowReadyEvent.WaitOne();
_wnd.Invoke(new RegisterHotKeyDelegate(RegisterHotKeyInternal), _hwnd, Interlocked.Increment(ref _id), (uint)modifiers, (uint)key);
return Interlocked.Increment(ref _id);
}
public static void UnregisterHotKey(int id)
{
_wnd.Invoke(new UnRegisterHotKeyDelegate(UnRegisterHotKeyInternal), _hwnd, id);
}
private delegate void RegisterHotKeyDelegate(IntPtr hwnd, int id, uint modifiers, uint key);
private delegate void UnRegisterHotKeyDelegate(IntPtr hwnd, int id);
private static void RegisterHotKeyInternal(IntPtr hwnd, int id, uint modifiers, uint key)
{
RegisterHotKey(hWnd: hwnd, id: id, fsModifiers: modifiers, vk: key);
}
private static void UnRegisterHotKeyInternal(IntPtr hwnd, int id)
{
UnregisterHotKey(_hwnd, id);
}
private static void OnHotKeyPressed(HotKeyEventArgs e)
{
HotKeyPressed?.Invoke(null, e);
}
private static volatile MessageWindow _wnd;
private static volatile IntPtr _hwnd;
private static ManualResetEvent _windowReadyEvent = new ManualResetEvent(false);
static HotKeyManager()
{
new Thread(delegate ()
{
Application.Run(new MessageWindow());
})
{
Name = "MessageLoopThread",
IsBackground = true
}.Start();
}
private class MessageWindow : Form
{
public MessageWindow()
{
_wnd = this;
_hwnd = Handle;
_windowReadyEvent.Set();
}
protected override void WndProc(ref Message m)
{
if (m.Msg == WM_HOTKEY)
{
var e = new HotKeyEventArgs(hotKeyParam: m.LParam);
OnHotKeyPressed(e);
}
base.WndProc(m: ref m);
}
protected override void SetVisibleCore(bool value)
{
// Ensure the window never becomes visible
base.SetVisibleCore(false);
}
private const int WM_HOTKEY = 0x312;
}
[DllImport("user32", SetLastError = true)]
private static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk);
[DllImport("user32", SetLastError = true)]
private static extern bool UnregisterHotKey(IntPtr hWnd, int id);
private static int _id = 0;
}
Class HotKeyEventArgs:
public partial class HotKeyEventArgs : EventArgs
{
public readonly Keys Key;
public readonly KeyModifiers Modifiers;
public HotKeyEventArgs(Keys key, KeyModifiers modifiers)
{
Key = key;
Modifiers = modifiers;
}
public HotKeyEventArgs(IntPtr hotKeyParam)
{
Key = (Keys)(((uint)hotKeyParam.ToInt64() & 0xffff0000) >> 16);
Modifiers = (KeyModifiers)((uint)hotKeyParam.ToInt64() & 0x0000ffff);
}
}
And class: HotKeyEventArgs
public partial class HotKeyEventArgs
{
[Flags]
public enum KeyModifiers
{
Alt = 1,
Control = 2,
Shift = 4,
Windows = 8,
NoRepeat = 0x4000
}
}

Problem in hiding the taskbar using c#

i am using the below class to hid the task bar.
but the problem is, after hiding there is no focus in that place.
Its something like blocked. How to overcome this. Thanks.
public class Taskbar
{
[DllImport("user32.dll")]
public static extern int FindWindow(string className, string windowText);
[DllImport("user32.dll")]
public static extern int ShowWindow(int hwnd, int command);
public const int SW_HIDE = 0;
public const int SW_SHOW = 1;
public int _taskbarHandle;
protected static int Handle
{
get
{
return FindWindow("Shell_TrayWnd", "");
}
}
public Taskbar()
{
_taskbarHandle = FindWindow("Shell_TrayWnd", "");
}
public static void Show()
{
ShowWindow(Handle, SW_SHOW);
}
public static void Hide()
{
ShowWindow(Handle, SW_HIDE);
}
}
Are you trying to run a full screen application? If yes then read How To Cover the Task Bar with a Window and How To Make a Windows Form App Truly Full Screen (and Hide Taskbar) in C#
From the same article, you can use this code to run true full screen application
public class WinApi
{
[DllImport(”user32.dll”, EntryPoint = “GetSystemMetrics”)]
public static extern int GetSystemMetrics(int which);
[DllImport(”user32.dll”)]
public static extern void
SetWindowPos(IntPtr hwnd, IntPtr hwndInsertAfter,
int X, int Y, int width, int height, uint flags);
private const int SM_CXSCREEN = 0;
private const int SM_CYSCREEN = 1;
private static IntPtr HWND_TOP = IntPtr.Zero;
private const int SWP_SHOWWINDOW = 64; // 0×0040
public static int ScreenX
{
get { return GetSystemMetrics(SM_CXSCREEN);}
}
public static int ScreenY
{
get { return GetSystemMetrics(SM_CYSCREEN);}
}
public static void SetWinFullScreen(IntPtr hwnd)
{
SetWindowPos(hwnd, HWND_TOP, 0, 0, ScreenX, ScreenY, SWP_SHOWWINDOW);
}
}
Use this code:
public class FullScreenEngine
{
// Fields
private IntPtr _hWndInputPanel;
private IntPtr _hWndSipButton;
private IntPtr _hWndTaskBar;
private Rectangle _desktopArea;
public FullScreenEngine()
{
Init();
}
public bool SetFullScreen(bool mode)
{
try
{
if (mode)
{
if (_hWndTaskBar.ToInt64() != 0L)
{
ShowWindow(_hWndTaskBar, SW_HIDE);
}
if (_hWndInputPanel.ToInt64() != 0L)
{
ShowWindow(_hWndInputPanel, SW_HIDE);
}
if (_hWndSipButton.ToInt64() != 0L)
{
ShowWindow(_hWndSipButton, SW_HIDE);
}
WorkArea.SetWorkArea(new RECT(Screen.PrimaryScreen.Bounds));
}
else
{
if (_hWndTaskBar.ToInt64() != 0L)
{
ShowWindow(_hWndTaskBar, SW_SHOW);
}
if (_hWndInputPanel.ToInt64() != 0L)
{
//ShowWindow(_hWndInputPanel, SW_SHOW);
}
if (_hWndSipButton.ToInt64() != 0L)
{
ShowWindow(_hWndSipButton, SW_SHOW);
}
WorkArea.SetWorkArea(new RECT(_desktopArea));
}
}
catch (Exception)
{
return false;
}
return true;
}
private bool Init()
{
try
{
_desktopArea = Screen.PrimaryScreen.WorkingArea;
_hWndInputPanel = FindWindowW("SipWndClass", null);
_hWndSipButton = FindWindowW("MS_SIPBUTTON", null);
_hWndTaskBar = FindWindowW("HHTaskBar", null);
}
catch (Exception)
{
return false;
}
return true;
}
private const uint SW_HIDE = 0;
private const uint SW_SHOW = 1;
[DllImport("coredll.dll")]
private static extern int ShowWindow(IntPtr hwnd, uint command);
[DllImport("coredll.dll")]
private static extern IntPtr FindWindowW(string lpClassName, string lpWindowName);
// Nested Types
public struct RECT
{
public int Left;
public int Top;
public int Right;
public int Bottom;
public RECT(Rectangle rect) : this()
{
Left = rect.Left;
Right = rect.Left+rect.Width;
Top = rect.Top;
Bottom = rect.Top + rect.Height;
}
}
private static class WorkArea
{
[DllImport("coredll.dll")]
private static extern bool SystemParametersInfo(uint uAction, uint uparam, ref RECT rect, uint fuWinIni);
private const uint WM_SETTINGCHANGE = 0x1a;
const uint SPI_GETWORKAREA = 48;
const uint SPI_SETWORKAREA = 47;
public static bool SetWorkArea(RECT rect)
{
return SystemParametersInfo(SPI_SETWORKAREA, 0, ref rect, WM_SETTINGCHANGE);
}
public static RECT GetWorkArea()
{
var rect = new RECT();
SystemParametersInfo(SPI_GETWORKAREA, 0, ref rect, 0);
return rect;
}
}
}

Categories