Hide multiple Taskbar in Windows 8/10 - c#

I have the following class to Hide or Show all Taskbars. But I get only one handle and so only one taskbar is hidden.
public static class Taskbar
{
[DllImport("user32.dll")]
private static extern int ShowWindow(int hwnd, int command);
[DllImport("user32.dll")]
private static extern int FindWindowEx(int parent, int afterWindow, string className, string windowText);
private const int _SW_HIDE = 0;
private const int _SW_SHOW = 1;
/// <summary>
/// Show all taskbars
/// </summary>
public static void ShowAll()
{
int result = 0;
do
{
result = FindWindowEx(0, result, "Shell_TrayWnd", null);
ShowWindow(result, _SW_SHOW);
}
while (result != 0);
}
/// <summary>
/// Hide all taskbars
/// </summary>
public static void HideAll()
{
int result = 0;
do
{
result = FindWindowEx(0, result, "Shell_TrayWnd", null);
ShowWindow(result, _SW_HIDE);
}
while (result != 0);
}
}
I have used this snippet: https://stackoverflow.com/a/18257222/6229375
Do I have something wrong? I have 3 screens with 3 taskbars on windows 10.

Related

clicked window on mouseHook

I have a small desktop app where I'm using a mousehook to monitor a mouse click event inside and outside a window's form. So I want a Custom Control to raise an event whenever a mouse is click out of that control, but when the control itself clicked, or child controls within this custom control clicked, I want to ignore the event, or act differently.
The problem is all mousehooks I found so far, has no way of knowing the control window that is about to receive a click event.
I need to know which control window is about to receive the click event ahead of time, so that I can differentiate whether it is a child control of the Custom Control or any other control or outside of the form.
Here is the mousehook class I'm using. I found it online.
using System;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Reflection;
using System.Threading;
using Microsoft;
namespace library
{
/// <summary>
/// Abstract base class for Mouse and Keyboard hooks
/// </summary>
public abstract class GlobalHook
{
/// <summary>
///
/// </summary>
#region Windows API Code
[StructLayout(LayoutKind.Sequential)]
protected class POINT
{
public int x;
public int y;
}
[StructLayout(LayoutKind.Sequential)]
protected class MouseHookStruct
{
public POINT pt;
public int hwnd;
public int wHitTestCode;
public int dwExtraInfo;
}
[StructLayout(LayoutKind.Sequential)]
protected class MouseLLHookStruct
{
public POINT pt;
public int mouseData;
public int flags;
public int time;
public int dwExtraInfo;
}
[StructLayout(LayoutKind.Sequential)]
protected class KeyboardHookStruct
{
public int vkCode;
public int scanCode;
public int flags;
public int time;
public int dwExtraInfo;
}
[DllImport("user32.dll", CharSet = CharSet.Auto,
CallingConvention = CallingConvention.StdCall, SetLastError = true)]
protected static extern int SetWindowsHookEx(
int idHook,
HookProc lpfn,
IntPtr hMod,
int dwThreadId);
[DllImport("user32.dll", CharSet = CharSet.Auto,
CallingConvention = CallingConvention.StdCall, SetLastError = true)]
protected static extern int UnhookWindowsHookEx(int idHook);
[DllImport("user32.dll", CharSet = CharSet.Auto,
CallingConvention = CallingConvention.StdCall)]
protected static extern int CallNextHookEx(
int idHook,
int nCode,
IntPtr wParam,
IntPtr lParam);
[DllImport("user32")]
protected static extern int ToAscii(
int uVirtKey,
int uScanCode,
byte[] lpbKeyState,
byte[] lpwTransKey,
int fuState);
[DllImport("user32")]
protected static extern int GetKeyboardState(byte[] pbKeyState);
[DllImport("user32.dll", CharSet = CharSet.Auto,
CallingConvention = CallingConvention.StdCall)]
protected static extern short GetKeyState(int vKey);
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr GetThreadDesktop(uint dwThreadId);
protected delegate int HookProc(int nCode, IntPtr wParam, IntPtr lParam);
protected const int WH_MOUSE_LL = 14;
protected const int WH_KEYBOARD_LL = 13;
protected const int WH_MOUSE = 7;
protected const int WH_KEYBOARD = 2;
protected const int WM_MOUSEMOVE = 0x200;
protected const int WM_LBUTTONDOWN = 0x201;
protected const int WM_RBUTTONDOWN = 0x204;
protected const int WM_MBUTTONDOWN = 0x207;
protected const int WM_LBUTTONUP = 0x202;
protected const int WM_RBUTTONUP = 0x205;
protected const int WM_MBUTTONUP = 0x208;
protected const int WM_LBUTTONDBLCLK = 0x203;
protected const int WM_RBUTTONDBLCLK = 0x206;
protected const int WM_MBUTTONDBLCLK = 0x209;
protected const int WM_MOUSEWHEEL = 0x020A;
protected const int WM_KEYDOWN = 0x100;
protected const int WM_KEYUP = 0x101;
protected const int WM_SYSKEYDOWN = 0x104;
protected const int WM_SYSKEYUP = 0x105;
protected const byte VK_SHIFT = 0x10;
protected const byte VK_CAPITAL = 0x14;
protected const byte VK_NUMLOCK = 0x90;
protected const byte VK_LSHIFT = 0xA0;
protected const byte VK_RSHIFT = 0xA1;
protected const byte VK_LCONTROL = 0xA2;
protected const byte VK_RCONTROL = 0x3;
protected const byte VK_LALT = 0xA4;
protected const byte VK_RALT = 0xA5;
protected const byte LLKHF_ALTDOWN = 0x20;
#endregion
/// <summary>
///
/// </summary>
#region Private Variables
protected int _hookType;
protected int _handleToHook;
protected bool _isStarted;
protected HookProc _hookCallback;
#endregion
/// <summary>
///
/// </summary>
#region Properties
public bool IsStarted
{
///
get
{
return _isStarted;
}
}
#endregion
/// <summary>
///
/// </summary>
#region Constructor
public GlobalHook()
{
///
Application.ApplicationExit += new EventHandler(Application_ApplicationExit);
}
#endregion
/// <summary>
///
/// </summary>
#region Methods
public void Start()
{
///
if (!_isStarted && _hookType != 0)
{
// Make sure we keep a reference to this delegate!
// If not, GC randomly collects it, and a NullReference exception is thrown
_hookCallback = new HookProc(HookCallbackProcedure);
//
IntPtr pp = Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]);
///
_handleToHook = SetWindowsHookEx(
_hookType,
_hookCallback,
(IntPtr)0/*Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0])*/,
/*0*/(int)GetThreadDesktop((uint)Thread.CurrentThread.ManagedThreadId));
/// Were we able to sucessfully start hook?
if (_handleToHook != 0)
{
///
_isStarted = true;
}
}
}
public void Stop()
{
///
if (_isStarted)
{
///
UnhookWindowsHookEx(_handleToHook);
///
_isStarted = false;
}
}
protected virtual int HookCallbackProcedure(int nCode, IntPtr wParam, IntPtr lParam)
{
// This method must be overriden by each extending hook
return 0;
}
protected void Application_ApplicationExit(object sender, EventArgs e)
{
///
if (_isStarted)
{
///
Stop();
}
}
#endregion
}
/// <summary>
/// Captures global mouse events
/// </summary>
public class MouseHook : GlobalHook
{
/// <summary>
///
/// </summary>
#region MouseEventType Enum
private enum MouseEventType
{
None,
MouseDown,
MouseUp,
DoubleClick,
MouseWheel,
MouseMove
}
#endregion
/// <summary>
///
/// </summary>
#region Events
public event MouseEventHandler MouseDown;
public event MouseEventHandler MouseUp;
public event MouseEventHandler MouseMove;
public event MouseEventHandler MouseWheel;
public event EventHandler Click;
public event EventHandler DoubleClick;
#endregion
/// <summary>
///
/// </summary>
#region Constructor
public MouseHook()
{
_hookType = WH_MOUSE_LL;
}
#endregion
/// <summary>
///
/// </summary>
#region Methods
protected override int HookCallbackProcedure(int nCode, IntPtr wParam, IntPtr lParam)
{
///
if (nCode > -1 && (MouseDown != null || MouseUp != null || MouseMove != null))
{
///
MouseLLHookStruct mouseHookStruct =
(MouseLLHookStruct)Marshal.PtrToStructure(lParam, typeof(MouseLLHookStruct));
///
MouseButtons button = GetButton((Int32)wParam);
MouseEventType eventType = GetEventType((Int32)wParam);
///
MouseEventArgs e = new MouseEventArgs(
button,
(eventType == MouseEventType.DoubleClick ? 2 : 1),
mouseHookStruct.pt.x,
mouseHookStruct.pt.y,
(eventType == MouseEventType.MouseWheel ?
(short)((mouseHookStruct.mouseData >> 16) & 0xffff) : 0));
// Prevent multiple Right Click events (this probably happens for popup menus)
if (button == MouseButtons.Right && mouseHookStruct.flags != 0)
{
///
eventType = MouseEventType.None;
}
///
switch (eventType)
{
///
//Control cont = Control.FromHandle(wParam);
///
case MouseEventType.MouseDown:
///
if (MouseDown != null)
{
///
MouseDown(this, e);
}
break;
case MouseEventType.MouseUp:
if (Click != null)
{
///
Click(this, new EventArgs());
}
if (MouseUp != null)
{
///
MouseUp(this, e);
}
break;
case MouseEventType.DoubleClick:
if (DoubleClick != null)
{
///
DoubleClick(this, new EventArgs());
}
break;
case MouseEventType.MouseWheel:
if (MouseWheel != null)
{
///
MouseWheel(this, e);
}
break;
case MouseEventType.MouseMove:
if (MouseMove != null)
{
///
MouseMove(this, e);
}
break;
default:
break;
}
}
///
return CallNextHookEx(_handleToHook, nCode, wParam, lParam);
}
private MouseButtons GetButton(Int32 wParam)
{
///
switch (wParam)
{
///
case WM_LBUTTONDOWN:
case WM_LBUTTONUP:
case WM_LBUTTONDBLCLK:
return MouseButtons.Left;
case WM_RBUTTONDOWN:
case WM_RBUTTONUP:
case WM_RBUTTONDBLCLK:
return MouseButtons.Right;
case WM_MBUTTONDOWN:
case WM_MBUTTONUP:
case WM_MBUTTONDBLCLK:
return MouseButtons.Middle;
default:
return MouseButtons.None;
}
}
private MouseEventType GetEventType(Int32 wParam)
{
///
switch (wParam)
{
///
case WM_LBUTTONDOWN:
case WM_RBUTTONDOWN:
case WM_MBUTTONDOWN:
return MouseEventType.MouseDown;
case WM_LBUTTONUP:
case WM_RBUTTONUP:
case WM_MBUTTONUP:
return MouseEventType.MouseUp;
case WM_LBUTTONDBLCLK:
case WM_RBUTTONDBLCLK:
case WM_MBUTTONDBLCLK:
return MouseEventType.DoubleClick;
case WM_MOUSEWHEEL:
return MouseEventType.MouseWheel;
case WM_MOUSEMOVE:
return MouseEventType.MouseMove;
default:
return MouseEventType.None;
}
}
#endregion
}
}

Set DateTimePicker null in C#

So I have a DateTimePicker and I want to set it to null when save it into a database, but by default it has the today's value. If I want to remove it and empty the DateTimePicker I am not able too.
I've tried to put it into the load form:
dateTimePicker1.Format = DateTimePickerFormat.Custom;
dateTimePicker1.CustomFormat = " ";
It actually works, but if I want to set a date it will not display into the DateTimePicker. Do you have any idea how can I solve it?
I have once written a date time picker that accepts null values (and allows week numbers too, as a free bonus).
[DefaultEvent("ValueChanged")]
[ComVisible(true)]
[DefaultProperty("Value")]
[DefaultBindingProperty("Value")]
[ClassInterface(ClassInterfaceType.AutoDispatch)]
[Designer("System.Windows.Forms.Design.DateTimePickerDesigner, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
public class NullableDateTimePicker : DateTimePicker
{
#region Externals
private const int GWL_STYLE = (-16);
private const int MCM_FIRST = 0x1000;
private const int MCM_GETMINREQRECT = (MCM_FIRST + 9);
private const int MCS_WEEKNUMBERS = 0x4;
private const int DTM_FIRST = 0x1000;
private const int DTM_GETMONTHCAL = (DTM_FIRST + 8);
[DllImport("User32.dll")]
public static extern int GetWindowLong(IntPtr h, int index);
[DllImport("User32.dll")]
public static extern int SetWindowLong(IntPtr h, int index, int value);
[DllImport("User32.dll")]
private static extern IntPtr SendMessage(IntPtr h, int msg, int param, int data);
[DllImport("User32.dll")]
private static extern int SendMessage(IntPtr h, int msg, int param, ref Rectangle data);
[DllImport("User32.dll")]
private static extern int MoveWindow(IntPtr h, int x, int y, int width, int height, bool repaint);
[DllImport("user32.dll", ExactSpelling = true, CharSet = CharSet.Auto)]
private static extern IntPtr GetParent(IntPtr hWnd);
#endregion
#region General
public NullableDateTimePicker()
{
this.ShowCheckBox = true;
}
#endregion
#region Properties
/// <summary>
/// Gets or sets the date/time value assigned to the control.
/// </summary>
/// <exception cref="System.ArgumentOutOfRangeException">
/// The set value is less than System.Windows.Forms.DateTimePicker.MinDate or more than System.Windows.Forms.DateTimePicker.MaxDate.
/// </exception>
[RefreshProperties(RefreshProperties.All)]
[Bindable(true)]
public new DateTime? Value
{
get
{
if (!base.Checked)
{
return null;
}
return base.Value;
}
set
{
if (value.HasValue)
{
base.Checked = true;
if (this.Format == DateTimePickerFormat.Short)
{
base.Value = value.Value.Date;
}
else if (this.Format == DateTimePickerFormat.Time)
{
base.Value = default(DateTime).Add(value.Value.TimeOfDay);
}
else
{
base.Value = value.Value;
}
}
else
{
base.Checked = false;
}
}
}
/// <summary>
/// Gets or sets whether to show week numbers.
/// </summary>
[Browsable(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
[DefaultValue(false)]
public bool ShowWeekNumbers
{
get;
set;
}
#endregion
#region Week numbers
/// <summary>
/// Raises the System.Windows.Forms.DateTimePicker.DropDown event.
/// </summary>
/// <param name="e">An System.EventArgs that contains the event data.</param>
protected override void OnDropDown(EventArgs e)
{
IntPtr monthView = SendMessage(this.Handle, DTM_GETMONTHCAL, 0, 0);
int style = GetWindowLong(monthView, GWL_STYLE);
if (this.ShowWeekNumbers)
{
style = style | MCS_WEEKNUMBERS;
}
else
{
style = style & ~MCS_WEEKNUMBERS;
}
Rectangle rect = new Rectangle();
SetWindowLong(monthView, GWL_STYLE, style);
SendMessage(monthView, MCM_GETMINREQRECT, 0, ref rect);
MoveWindow(monthView, 0, 0, rect.Right + 3, rect.Bottom, true);
//
// Resize the surrounding window to let the new text fit
//
IntPtr parent = GetParent(monthView);
Rectangle mainRect = new Rectangle();
SendMessage(parent, MCM_GETMINREQRECT, 0, ref mainRect);
MoveWindow(parent, 0, 0, mainRect.Right + 6, mainRect.Bottom + 6, true);
base.OnDropDown(e);
}
#endregion
}
It shows a checkbox to allow null values, and the new Value property allows null too, so it works from both the designer and code.

Is there any way to global hook the mouse actions like i'm hooking the keyboard keys?

This is the class i'm using for hooking the keyboard keys.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
public class Hook : IDisposable
{
bool Global = false;
public delegate void LocalKeyEventHandler(Keys key, bool Shift, bool Ctrl, bool Alt);
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;
CallbackDelegate TheHookCB = null;
//Start hook
public Hook(bool Global)
{
this.Global = Global;
TheHookCB = new CallbackDelegate(KeybHookProc);
if (Global)
{
HookID = SetWindowsHookEx(HookType.WH_KEYBOARD_LL, TheHookCB,
0, //0 for local hook. eller hwnd til user32 for global
0); //0 for global hook. eller thread for hooken
}
else
{
HookID = SetWindowsHookEx(HookType.WH_KEYBOARD, TheHookCB,
0, //0 for local hook. or hwnd to user32 for global
GetCurrentThreadId()); //0 for global hook. or thread for the hook
}
}
bool IsFinalized = false;
~Hook()
{
if (!IsFinalized)
{
UnhookWindowsHookEx(HookID);
IsFinalized = true;
}
}
public void Dispose()
{
if (!IsFinalized)
{
UnhookWindowsHookEx(HookID);
IsFinalized = true;
}
}
//The listener that will trigger events
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, 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)
{
//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;
}
}
And in form1 a sample how to work with it:
using System;
using System.Windows.Forms;
namespace KeyboardHook
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
Hook kh = new Hook(true);
kh.KeyDown += Kh_KeyDown;
}
private void Kh_KeyDown(Keys key, bool Shift, bool Ctrl, bool Alt)
{
MessageBox.Show(key.ToString());
}
private void Form1_Load(object sender, EventArgs e)
{
}
}
}
I wonder if there is a way using the class or some other way to hook also the mouse ? For exmaple when i click the mouse middle button. Or if i roll the mouse wheel then give once a message i rolled the wheel but the wheel is not so important is more the buttons left,right,middle.
Yes, i used the following code in a project of mine, it allows direct access to most windows mouse events:
using System;
using System.Runtime.InteropServices;
/// <summary>
/// The CallWndProc hook procedure is an application-defined or library-defined
/// callback function used with the SetWindowsHookEx function. The HOOKPROC type
/// defines a pointer to this callback function. CallWndProc is a placeholder for
/// the application-defined or library-defined function name.
/// </summary>
/// <param name="nCode">
/// Specifies whether the hook procedure must process the message.
/// </param>
/// <param name="wParam">
/// Specifies whether the message was sent by the current thread.
/// </param>
/// <param name="lParam">
/// Pointer to a CWPSTRUCT structure that contains details about the message.
/// </param>
/// <returns>
/// If nCode is less than zero, the hook procedure must return the value returned
/// by CallNextHookEx. If nCode is greater than or equal to zero, it is highly
/// recommended that you call CallNextHookEx and return the value it returns;
/// otherwise, other applications that have installed WH_CALLWNDPROC hooks will
/// not receive hook notifications and may behave incorrectly as a result. If the
/// hook procedure does not call CallNextHookEx, the return value should be zero.
/// </returns>
internal delegate int HookProc(int nCode, IntPtr wParam, IntPtr lParam);
internal class NativeMethods
{
/// <summary>
/// The SetWindowsHookEx function installs an application-defined hook
/// procedure into a hook chain. You would install a hook procedure to monitor
/// the system for certain types of events. These events are associated either
/// with a specific thread or with all threads in the same desktop as the
/// calling thread.
/// </summary>
/// <param name="hookType">
/// Specifies the type of hook procedure to be installed
/// </param>
/// <param name="callback">Pointer to the hook procedure.</param>
/// <param name="hMod">
/// Handle to the DLL containing the hook procedure pointed to by the lpfn
/// parameter. The hMod parameter must be set to NULL if the dwThreadId
/// parameter specifies a thread created by the current process and if the
/// hook procedure is within the code associated with the current process.
/// </param>
/// <param name="dwThreadId">
/// Specifies the identifier of the thread with which the hook procedure is
/// to be associated.
/// </param>
/// <returns>
/// If the function succeeds, the return value is the handle to the hook
/// procedure. If the function fails, the return value is 0.
/// </returns>
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr SetWindowsHookEx(HookType hookType,
HookProc callback, IntPtr hMod, uint dwThreadId);
/// <summary>
/// The UnhookWindowsHookEx function removes a hook procedure installed in
/// a hook chain by the SetWindowsHookEx function.
/// </summary>
/// <param name="hhk">Handle to the hook to be removed.</param>
/// <returns>
/// If the function succeeds, the return value is true.
/// If the function fails, the return value is false.
/// </returns>
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern bool UnhookWindowsHookEx(IntPtr hhk);
/// <summary>
/// The CallNextHookEx function passes the hook information to the next hook
/// procedure in the current hook chain. A hook procedure can call this
/// function either before or after processing the hook information.
/// </summary>
/// <param name="idHook">Handle to the current hook.</param>
/// <param name="nCode">
/// Specifies the hook code passed to the current hook procedure.
/// </param>
/// <param name="wParam">
/// Specifies the wParam value passed to the current hook procedure.
/// </param>
/// <param name="lParam">
/// Specifies the lParam value passed to the current hook procedure.
/// </param>
/// <returns>
/// This value is returned by the next hook procedure in the chain.
/// </returns>
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern int CallNextHookEx(IntPtr hhk, int nCode,
IntPtr wParam, IntPtr lParam);
}
internal static class HookCodes
{
public const int HC_ACTION = 0;
public const int HC_GETNEXT = 1;
public const int HC_SKIP = 2;
public const int HC_NOREMOVE = 3;
public const int HC_NOREM = HC_NOREMOVE;
public const int HC_SYSMODALON = 4;
public const int HC_SYSMODALOFF = 5;
}
internal enum HookType
{
WH_KEYBOARD = 2,
WH_MOUSE = 7,
WH_KEYBOARD_LL = 13,
WH_MOUSE_LL = 14
}
[StructLayout(LayoutKind.Sequential)]
internal class POINT
{
public int x;
public int y;
}
/// <summary>
/// The MSLLHOOKSTRUCT structure contains information about a low-level keyboard
/// input event.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
internal struct MOUSEHOOKSTRUCT
{
public POINT pt; // The x and y coordinates in screen coordinates
public int hwnd; // Handle to the window that'll receive the mouse message
public int wHitTestCode;
public int dwExtraInfo;
}
/// <summary>
/// The MOUSEHOOKSTRUCT structure contains information about a mouse event passed
/// to a WH_MOUSE hook procedure, MouseProc.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
internal struct MSLLHOOKSTRUCT
{
public POINT pt; // The x and y coordinates in screen coordinates.
public int mouseData; // The mouse wheel and button info.
public int flags;
public int time; // Specifies the time stamp for this message.
public IntPtr dwExtraInfo;
}
internal enum MouseMessage
{
WM_MOUSEMOVE = 0x0200,
WM_LBUTTONDOWN = 0x0201,
WM_LBUTTONUP = 0x0202,
WM_LBUTTONDBLCLK = 0x0203,
WM_RBUTTONDOWN = 0x0204,
WM_RBUTTONUP = 0x0205,
WM_RBUTTONDBLCLK = 0x0206,
WM_MBUTTONDOWN = 0x0207,
WM_MBUTTONUP = 0x0208,
WM_MBUTTONDBLCLK = 0x0209,
WM_MOUSEWHEEL = 0x020A,
WM_MOUSEHWHEEL = 0x020E,
WM_NCMOUSEMOVE = 0x00A0,
WM_NCLBUTTONDOWN = 0x00A1,
WM_NCLBUTTONUP = 0x00A2,
WM_NCLBUTTONDBLCLK = 0x00A3,
WM_NCRBUTTONDOWN = 0x00A4,
WM_NCRBUTTONUP = 0x00A5,
WM_NCRBUTTONDBLCLK = 0x00A6,
WM_NCMBUTTONDOWN = 0x00A7,
WM_NCMBUTTONUP = 0x00A8,
WM_NCMBUTTONDBLCLK = 0x00A9
}
/// <summary>
/// The structure contains information about a low-level keyboard input event.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
internal struct KBDLLHOOKSTRUCT
{
public int vkCode; // Specifies a virtual-key code
public int scanCode; // Specifies a hardware scan code for the key
public int flags;
public int time; // Specifies the time stamp for this message
public int dwExtraInfo;
}
internal enum KeyboardMessage
{
WM_KEYDOWN = 0x0100,
WM_KEYUP = 0x0101,
WM_SYSKEYDOWN = 0x0104,
WM_SYSKEYUP = 0x0105
}
To use it you have to register the mouse hook. LowLevelMouseProc is the callback. This method is executed every time a new mouse event occures.
private void SetUpHook()
{
Logger.Debug("Setting up global mouse hook");
// Create an instance of HookProc.
_globalLlMouseHookCallback = LowLevelMouseProc;
_hGlobalLlMouseHook = NativeMethods.SetWindowsHookEx(
HookType.WH_MOUSE_LL,
_globalLlMouseHookCallback,
Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]),
0);
if (_hGlobalLlMouseHook == IntPtr.Zero)
{
Logger.Fatal("Unable to set global mouse hook");
throw new Win32Exception("Unable to set MouseHook");
}
}
To clear mouse hook:
private void ClearHook()
{
Logger.Debug("Deleting global mouse hook");
if (_hGlobalLlMouseHook != IntPtr.Zero)
{
// Unhook the low-level mouse hook
if (!NativeMethods.UnhookWindowsHookEx(_hGlobalLlMouseHook))
throw new Win32Exception("Unable to clear MouseHoo;");
_hGlobalLlMouseHook = IntPtr.Zero;
}
}
And last but not least an example of the LowLevelMouseProc, the callback you can use to intercept mouse events:
public int LowLevelMouseProc(int nCode, IntPtr wParam, IntPtr lParam)
{
if (nCode >= 0)
{
// Get the mouse WM from the wParam parameter
var wmMouse = (MouseMessage) wParam;
if (wmMouse == MouseMessage.WM_LBUTTONDOWN && LeftButtonState == ButtonState.Released)
{
Logger.Debug("Left Mouse down");
}
if (wmMouse == MouseMessage.WM_LBUTTONUP && LeftButtonState == ButtonState.Down)
{
Logger.Debug("Left Mouse up");
}
if (wmMouse == MouseMessage.WM_RBUTTONDOWN && RightButtonState == ButtonState.Released)
{
Logger.Debug("Right Mouse down");
}
if (wmMouse == MouseMessage.WM_RBUTTONUP && RightButtonState == ButtonState.Down)
{
Logger.Debug("Right Mouse up");
}
}
// Pass the hook information to the next hook procedure in chain
return NativeMethods.CallNextHookEx(_hGlobalLlMouseHook, nCode, wParam, lParam);
}
As with all direct windows calls, the code gets unnecessarily long. But the only thing you have to do, is to call SetUpHook and provide your own version of LowLevelMouseProc.
EDIT: There are shorter versions to do this. But this method allows you to catch global mouse events. Not just events issued to your window. All mouse events, system wide will be piped into LowLevelMouseProc

Soft Keyboard overlaping control (WPF, desktop)

first I would like to stress that I am looking for a Windows DESKTOP WPF solution, so please no android. Thank you.
Second, I am fairly new to WPF and designing software for Windows Tablet, so please bear with me... And please do be explicit in your answers.
Third, the target software will run on a Windows Tablet (Win 8.0/8.1) and is being developed with Visual Studio 2013 Pro (C#, Desktop App, WPF).
OK, here is my problem:
I have been using a Textbox inherited class to show the Soft Keyboard when the user touches the Textbox (class code bellow). This part actually works well.
My problem is that the Soft Keyboard may popup over my actual control. In WinRT this would not happen since the OS seems to scroll the said control up until it becomes visible, but with DESKTOP app no such feature exists.
So my question is: does anyone know how to solve this overlap issue?
How could I (in Win desktop app) replicate the normal WinRT behavior?
Should I be using some other API to call the Soft Keyboard?
Code for the "TouchTextbox" class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;
namespace WPF_DT_Soft_Keyboard
{
class TouchTextbox : TextBox
{
[DllImport("user32.dll")]
public static extern int FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll")]
public static extern int SendMessage(int hWnd, uint Msg, int wParam, int lParam);
public const int WM_SYSCOMMAND = 0x0112;
public const int SC_CLOSE = 0xF060;
protected override void OnGotFocus(System.Windows.RoutedEventArgs e)
{
base.OnGotFocus(e);
ShowSoftKeyboard();
}
protected override void OnLostFocus(System.Windows.RoutedEventArgs e)
{
base.OnLostFocus(e);
HideSoftKeyboard();
}
protected override void OnPreviewKeyUp(System.Windows.Input.KeyEventArgs e)
{
base.OnPreviewKeyUp(e);
if (e.Key == System.Windows.Input.Key.Enter) HideSoftKeyboard();
}
private void ShowSoftKeyboard()
{
System.Diagnostics.Process.Start(#"C:\Program Files\Common Files\Microsoft Shared\ink\TabTip.exe");
}
private void HideSoftKeyboard()
{
int iHandle = FindWindow("IPTIP_Main_Window", "");
if (iHandle > 0)
{
SendMessage(iHandle, WM_SYSCOMMAND, SC_CLOSE, 0);
}
}
}
}
Ok, I think I finally found a decent solution.
I have encapsulated it into the TouchTextbox class bellow.
For it to work properly, the TouchTextbox must be contained withing a [ScrollViewer] control.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;
using System.Windows.Threading;
namespace WPF_DT_Soft_Keyboard
{
class TouchTextbox : TextBox
{
/// <summary>
/// Private Container
/// </summary>
DispatcherTimer mBringIntoViewTimer = new DispatcherTimer();
/// <summary>
/// DLL imports
/// </summary>
[DllImport("user32.dll")]
public static extern int FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll")]
public static extern int SendMessage(int hWnd, uint Msg, int wParam, int lParam);
[DllImport("user32.dll")]
public static extern int MoveWindow(int hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);
[DllImport("user32.dll")]
public static extern int SetWindowPos(int hWnd, int hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
[DllImport("Kernel32.dll")]
public static extern uint GetLastError();
/// <summary>
/// Constante
/// </summary>
public const int WM_SYSCOMMAND = 0x0112;
public const int SC_CLOSE = 0xF060;
public const int HWND_TOP = 0;
public const int SWP_NOSIZE = 0x0001;
public const int SWP_NOZORDER = 0x0004;
public const int SWP_SHOWWINDOW = 0x0040;
public const int BRING_INTO_VIEW_DELAY = 500;
/// <summary>
/// TouchTextbox
/// </summary>
public TouchTextbox()
{
mBringIntoViewTimer.IsEnabled = false;
mBringIntoViewTimer.Tick += MyTimer_Tick;
mBringIntoViewTimer.Interval = new TimeSpan(0, 0, 0, 0, BRING_INTO_VIEW_DELAY);
}
/// <summary>
/// MyTimer_Tick
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void MyTimer_Tick(object sender, EventArgs e)
{
mBringIntoViewTimer.IsEnabled = false;
this.BringIntoView();
}
/// <summary>
/// OnGotFocus
/// </summary>
/// <param name="e"></param>
protected override void OnGotFocus(System.Windows.RoutedEventArgs e)
{
base.OnGotFocus(e);
ShowSoftKeyboard();
mBringIntoViewTimer.IsEnabled = true;
}
///// <summary>
///// OnLostFocus
///// </summary>
///// <param name="e"></param>
//protected override void OnLostFocus(System.Windows.RoutedEventArgs e)
//{
// base.OnLostFocus(e);
// HideSoftKeyboard();
//}
/// <summary>
/// OnPreviewKeyUp
/// </summary>
/// <param name="e"></param>
protected override void OnPreviewKeyUp(System.Windows.Input.KeyEventArgs e)
{
base.OnPreviewKeyUp(e);
if (e.Key == System.Windows.Input.Key.Enter) HideSoftKeyboard();
}
/// <summary>
/// ShowSoftKeyboard
/// </summary>
private void ShowSoftKeyboard()
{
Microsoft.Win32.Registry.CurrentUser.OpenSubKey(#"Software\Microsoft\TabletTip\1.7", true).SetValue("EdgeTargetDockedState", "1", Microsoft.Win32.RegistryValueKind.DWord);
System.Diagnostics.Process.Start(#"C:\Program Files\Common Files\Microsoft Shared\ink\TabTip.exe");
}
/// <summary>
/// HideSoftKeyboard
/// </summary>
private void HideSoftKeyboard()
{
int iHandle = FindWindow("IPTIP_Main_Window", "");
if (iHandle > 0)
{
SendMessage(iHandle, WM_SYSCOMMAND, SC_CLOSE, 0);
}
}
}
}

Combo box drop down width on suggest

I have a form which has a Combo Box Control. I have selected the drop down style property to DropDown. I have also set the DropDown Width to 250. I have set the auto complete mode to suggest and the auto complete source to listitems. it works absolutely fine when i click on the drop down. but when i type in somethin, the auto complete mode activates a drop down which has a small width.
any help appreciate. i wanna know how to increase the width of the auto complete drop down via code so that the list items are viewed properly. I am using C#.
I had asked this a couple of months back but didn't get a proper answer. now the customer wants it bad :(
??
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
/// <summary>
/// Represents an ComboBox with additional properties for setting the
/// size of the AutoComplete Drop-Down window.
/// </summary>
public class ComboBoxEx : ComboBox
{
private int acDropDownHeight = 106;
private int acDropDownWidth = 170;
//<EditorBrowsable(EditorBrowsableState.Always), _
[Browsable(true), Description("The width, in pixels, of the auto complete drop down box"), DefaultValue(170)]
public int AutoCompleteDropDownWidth
{
get { return acDropDownWidth; }
set { acDropDownWidth = value; }
}
//<EditorBrowsable(EditorBrowsableState.Always), _
[Browsable(true), Description("The height, in pixels, of the auto complete drop down box"), DefaultValue(106)]
public int AutoCompleteDropDownHeight
{
get { return acDropDownHeight; }
set { acDropDownHeight = value; }
}
protected override void OnHandleCreated(EventArgs e)
{
base.OnHandleCreated(e);
ACWindow.RegisterOwner(this);
}
#region Nested type: ACWindow
/// <summary>
/// Provides an encapsulation of an Auto complete drop down window
/// handle and window proc.
/// </summary>
private class ACWindow : NativeWindow
{
private static readonly Dictionary<IntPtr, ACWindow> ACWindows;
#region "Win API Declarations"
private const UInt32 WM_WINDOWPOSCHANGED = 0x47;
private const UInt32 WM_NCDESTROY = 0x82;
private const UInt32 SWP_NOSIZE = 0x1;
private const UInt32 SWP_NOMOVE = 0x2;
private const UInt32 SWP_NOZORDER = 0x4;
private const UInt32 SWP_NOREDRAW = 0x8;
private const UInt32 SWP_NOACTIVATE = 0x10;
private const UInt32 GA_ROOT = 2;
private static readonly List<ComboBoxEx> owners;
[DllImport("user32.dll")]
private static extern bool EnumThreadWindows(int dwThreadId, EnumThreadDelegate lpfn, IntPtr lParam);
[DllImport("user32.dll")]
private static extern IntPtr GetAncestor(IntPtr hWnd, UInt32 gaFlags);
[DllImport("kernel32.dll")]
private static extern int GetCurrentThreadId();
[DllImport("user32.dll")]
private static extern void GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
[DllImport("user32.dll")]
private static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy,
uint uFlags);
[DllImport("user32.dll")]
private static extern bool GetWindowRect(IntPtr hWnd, ref RECT lpRect);
#region Nested type: EnumThreadDelegate
private delegate bool EnumThreadDelegate(IntPtr hWnd, IntPtr lParam);
#endregion
#region Nested type: RECT
[StructLayout(LayoutKind.Sequential)]
private struct RECT
{
public readonly int Left;
public readonly int Top;
public readonly int Right;
public readonly int Bottom;
public Point Location
{
get { return new Point(Left, Top); }
}
}
#endregion
#endregion
private ComboBoxEx owner;
static ACWindow()
{
ACWindows = new Dictionary<IntPtr, ACWindow>();
owners = new List<ComboBoxEx>();
}
/// <summary>
/// Creates a new ACWindow instance from a specific window handle.
/// </summary>
private ACWindow(IntPtr handle)
{
AssignHandle(handle);
}
/// <summary>
/// Registers a ComboBoxEx for adjusting the Complete Dropdown window size.
/// </summary>
public static void RegisterOwner(ComboBoxEx owner)
{
if ((owners.Contains(owner)))
{
return;
}
owners.Add(owner);
EnumThreadWindows(GetCurrentThreadId(), EnumThreadWindowCallback, IntPtr.Zero);
}
/// <summary>
/// This callback will receive the handle for each window that is
/// associated with the current thread. Here we match the drop down window name
/// to the drop down window name and assign the top window to the collection
/// of auto complete windows.
/// </summary>
private static bool EnumThreadWindowCallback(IntPtr hWnd, IntPtr lParam)
{
if ((GetClassName(hWnd) == "Auto-Suggest Dropdown"))
{
IntPtr handle = GetAncestor(hWnd, GA_ROOT);
if ((!ACWindows.ContainsKey(handle)))
{
ACWindows.Add(handle, new ACWindow(handle));
}
}
return true;
}
/// <summary>
/// Gets the class name for a specific window handle.
/// </summary>
private static string GetClassName(IntPtr hRef)
{
var lpClassName = new StringBuilder(256);
GetClassName(hRef, lpClassName, 256);
return lpClassName.ToString();
}
/// <summary>
/// Overrides the NativeWindow's WndProc to handle when the window
/// attributes changes.
/// </summary>
protected override void WndProc(ref Message m)
{
if ((m.Msg == WM_WINDOWPOSCHANGED))
{
// If the owner has not been set we need to find the ComboBoxEx that
// is associated with this dropdown window. We do it by checking if
// the upper-left location of the drop-down window is within the
// ComboxEx client rectangle.
if ((owner == null))
{
Rectangle ownerRect = default(Rectangle);
var acRect = new RECT();
foreach (ComboBoxEx cbo in owners)
{
GetWindowRect(Handle, ref acRect);
ownerRect = cbo.RectangleToScreen(cbo.ClientRectangle);
if ((ownerRect.Contains(acRect.Location)))
{
owner = cbo;
break; // TODO: might not be correct. Was : Exit For
}
}
owners.Remove(owner);
}
if (((owner != null)))
{
SetWindowPos(Handle, IntPtr.Zero, -5, 0, owner.AutoCompleteDropDownWidth,
owner.AutoCompleteDropDownHeight, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
}
}
if ((m.Msg == WM_NCDESTROY))
{
ACWindows.Remove(Handle);
}
base.WndProc(ref m);
}
}
#endregion
}
This is what I did and it actually works really well. Good to find an answer atlast :)
This answer is an addition to reggie's answer.
If you want the user to be able to resize the auto-complete dropdown, then add the following code inside the WndProc method:
private const int WM_SIZING = 0x214;
if (m.Msg == WM_SIZING) {
if (owner != null) {
RECT rr = (RECT) Marshal.PtrToStructure(m.LParam, typeof(RECT));
owner.acDropDownWidth = (rr.Right - rr.Left);
owner.acDropDownHeight = (rr.Bottom - rr.Top);
}
}
kind of a bad design decision to do that. Why not set it to a static large size to start with? You can always use one of the events to get the text width and then use that to set the combobox width. Possibly the onPaint? easier way might be to create your own combobox class that inherits from combo box and then override the methods to do this yourself.

Categories