error in PInvoke signature while trying to write mouse click code - c#

class DoubleClickHover : Form
{
Thread T1;
System.Timers.Timer timer = new System.Timers.Timer(4000); //3 seconds
public DoubleClickHover()
{
T1 = new Thread(new ThreadStart(DoubleClickEvent));
timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
}
#region Timer Mouse Double Click event
//Here, the timer for Timer click event will start when mouse hovers over an area
private void form_MouseHover(object sender, System.EventArgs e)
{
timer.Start();
}
private void form_MouseLeave(object sender, System.EventArgs e)
{
timer.Stop();
}
void timer_Elapsed(object sender, ElapsedEventArgs e)
{
timer.Stop();
DoubleClickEvent();
}
//This method allows the user to click a file/folder by hovering/keeping still the mouse for specified time
public void DoubleClickEvent()
{
// Set the cursor position
// System.Windows.Forms.Cursor.Position();
DoClickMouse(0x2); // Left mouse button down
DoClickMouse(0x4); // Left mouse button up
DoClickMouse(0x2); // Left mouse button down
DoClickMouse(0x4); // Left mouse button up
}
static void DoClickMouse(int mouseButton)
{
var input = new INPUT()
{
dwType = 0, // Mouse input
mi = new MOUSEINPUT() { dwFlags = mouseButton }
};
if (SendInput(1, input, Marshal.SizeOf(input)) == 0)
{
throw new Exception();
}
}
[StructLayout(LayoutKind.Sequential)]
struct MOUSEINPUT
{
int dx;
int dy;
int mouseData;
public int dwFlags;
int time;
IntPtr dwExtraInfo;
}
struct INPUT
{
public uint dwType;
public MOUSEINPUT mi;
}
[DllImport("user32.dll", SetLastError = true)]
static extern uint SendInput(uint cInputs, INPUT input, int size);
#endregion
}
error:
A call to PInvoke function 'DoubleClickHover::SendInput' has unbalanced the stack. This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature.
please help.
thank u

Yes, your definition of SendInput is wrong. The second parameter is a pointer to a structure, which you need to declare as being passed by reference:
[DllImport("user32.dll", SetLastError = true)]
static extern uint SendInput(uint nInputs, ref INPUT pInputs, int cbSize);
Alternatively you could declare pInputs as an array (since that's what it really is):
[DllImport("user32.dll", SetLastError = true)]
static extern uint SendInput(uint nInputs, INPUT[] pInputs, int cbSize);

Related

How do I manually toggle the NumLock Key with C# in WPF?

I've been searching for a while and there are mostly results in C++ or other languages, and not C#. Things I've seen:
keybd_event() // A c++ method that theoretically can be included with a DLL import, but hasn't worked in testing
System.Windows.Forms.SendKeys.Send("{NUMLOCK}"}; // Forms namespace doesn't exist in Windows
Currently, I have code that executes every second or so to watch the state of numlock and update a graphic in my form accordingly. If a bool toggle is set, I also want it to force NumLock on:
internal partial class Interop
{
public static int VK_NUMLOCK = 0x90;
public static int VK_SCROLL = 0x91;
public static int VK_CAPITAL = 0x14;
public static int KEYEVENTF_EXTENDEDKEY = 0x0001; // If specified, the scan code was preceded by a prefix byte having the value 0xE0 (224).
public static int KEYEVENTF_KEYUP = 0x0002; // If specified, the key is being released. If not specified, the key is being depressed.
[DllImport("User32.dll", SetLastError = true)]
public static extern void keybd_event(
byte bVk,
byte bScan,
int dwFlags,
IntPtr dwExtraInfo);
[DllImport("User32.dll", SetLastError = true)]
public static extern short GetKeyState(int nVirtKey);
[DllImport("User32.dll", SetLastError = true)]
public static extern short GetAsyncKeyState(int vKey);
}
private void watcher(object source, ElapsedEventArgs e)
{
bool NumLock = (((ushort)GetKeyState(0x90)) & 0xffff) != 0;
if (!NumLock && fixers.watchNumL)
{
// Force NumLock back on
// Simulate a key press
Interop.keybd_event((byte)0x90,0x45,Interop.KEYEVENTF_EXTENDEDKEY | 0,IntPtr.Zero);
// Simulate a key release
Interop.keybd_event((byte)0x90,0x45,Interop.KEYEVENTF_EXTENDEDKEY | Interop.KEYEVENTF_KEYUP, IntPtr.Zero);
NumLock = (((ushort)GetKeyState(0x90)) & 0xffff) != 0;
}
if (NumLock)
{
this.Dispatcher.Invoke(() =>
{
fixerBoxes["NumL"].FixerImg.Source = new BitmapImage(new Uri(#"/graphics/num_lock_on.png", UriKind.Relative));
StatusBox.Text = "Num Lock ON";
});
}
else {
this.Dispatcher.Invoke(() =>
{
fixerBoxes["NumL"].FixerImg.Source = new BitmapImage(new Uri(#"/graphics/num_lock_off.png", UriKind.Relative));
StatusBox.Text = "Num Lock OFF";
});
}
}
public MainWindow()
{
// Start the watcher
System.Timers.Timer myTimer = new System.Timers.Timer();
// Tell the timer what to do when it elapses
myTimer.Elapsed += new ElapsedEventHandler(watcher);
// Set it to go off every second
myTimer.Interval = 1000;
// And start it
myTimer.Enabled = true;
}
Here is a class (with a library) that can do this for you. the library does much more, so it's maybe a bit overkill to use just for this. The approach uses the keybd_event function using pinvoke:
// Simulate a key press
Interop.keybd_event((byte)virtualKey,
0x45,
Interop.KEYEVENTF_EXTENDEDKEY | 0,
IntPtr.Zero);
// Simulate a key release
Interop.keybd_event((byte)virtualKey,
0x45,
Interop.KEYEVENTF_EXTENDEDKEY | Interop.KEYEVENTF_KEYUP,
IntPtr.Zero);
Pressing and releasing the button changes the state of the LED. virtualKey is one of the VK_ constants.
Here are the declarations:
internal partial class Interop
{
public static int VK_NUMLOCK = 0x90;
public static int VK_SCROLL = 0x91;
public static int VK_CAPITAL = 0x14;
public static int KEYEVENTF_EXTENDEDKEY = 0x0001; // If specified, the scan code was preceded by a prefix byte having the value 0xE0 (224).
public static int KEYEVENTF_KEYUP = 0x0002; // If specified, the key is being released. If not specified, the key is being depressed.
[DllImport("User32.dll", SetLastError = true)]
public static extern void keybd_event(
byte bVk,
byte bScan,
int dwFlags,
IntPtr dwExtraInfo);
[DllImport("User32.dll", SetLastError = true)]
public static extern short GetKeyState(int nVirtKey);
[DllImport("User32.dll", SetLastError = true)]
public static extern short GetAsyncKeyState(int vKey);
}

To prevent entering special characters on textbox ( Already have thousand of textboxes in solution )

We have a advanced software written by using c# ( windows forms ). In their we have 1000 or more textboxes. I need to validate user input on all these textboxes to stop entering special characters and any scripts. Textboxes are hard coded.
for eg :
I can use following piece of code on every keypress to check whether user has entered the allowed characters or not.
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
var regex = new Regex(#"[^a-zA-Z0-9\s]");
if (regex.IsMatch(e.KeyChar.ToString()))
{
e.Handled = true;
}
}
but then we have to implement this on every textboxes key press events ( if there is no other solution this is the last thing to do). Is there any way to handle this from a single place and affect for every textboxes (on some places textboxes have their own key press events as well). What I need is a common method which will be fire on every key press events of any textbox.
Solution : Create a Custom Control derived from TextBox (or TextBoxBase) that contains all the logic required for my validation, so it's all done in one place.
But still I have to again change all the existing textboxes my new textbox.
Is there any way to change behavior of current event handler?
Note: What I need is to override current keypress event of the textbox and run my validation code plus need to run if there is any explicitly mentioned code inside key press events.
If you want to add the KeyDown Event to all TextBoxes you can loop through them and add the same EventHandler for all of them.
To do that first of all we need to create a function that loop through all our TextBoxes.
GetChildControls Function:
public static IEnumerable<TControl> GetChildControls<TControl>(this Control control)
where TControl : Control
{
var children = (control.Controls != null) ?
control.Controls.OfType<TControl>() : Enumerable.Empty<TControl>();
return children.SelectMany(c => GetChildControls<TControl>(c)).Concat(children);
}
We can now use that function after the InitializeComponent(); to assign the Txt_KeyDown() EventHandler to all TextBoxes.
Calling the Function:
public Example() {
InitializeComponent();
var allTextBoxes = this.GetChildControls<TextBox>();
foreach (TextBox tb in allTextBoxes)
{
tb.KeyDown += Txt_KeyDown;
}
}
private void Txt_KeyDown(object sender, System.Windows.Input.KeyEventArgs e) {
// Your code here
}
"Is there any way to handle this from a single place and affect for
every textboxes"
There's a few ways. But it seems you don't want to edit the textbox itself, so there's only one reliable way I'm aware of; attaching a global keyboard hook. Code follows:
class GlobalKeyboardHook
{
#region DLL Imports
[DllImport("user32.dll")]
static extern IntPtr SetWindowsHookEx(int hookEventId, keyboardProc callback, IntPtr handleInstance, uint threadId);
[DllImport("user32.dll")]
static extern bool UnhookWindowsHookEx(IntPtr handleInstance);
[DllImport("user32.dll")]
static extern int CallNextHookEx(IntPtr ignoredParameter, int hookCode, int wParam, ref KeyboardHookStruct lParam);
[DllImport("kernel32.dll")]
static extern IntPtr LoadLibrary(string libFileName);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr GetModuleHandle(string lpModuleName);
#endregion DLL Imports
#region Class Declarations
private delegate int keyboardProc(int code, int wParam, ref KeyboardHookStruct lParam);
private keyboardProc kbdProc;
public struct KeyboardHookStruct
{
public int vkCode;
public int scanCode;
public int flags;
public int time;
public int extraInfo;
}
private static class KeyboardMessages
{
public const int WH_KEYBOARD_LL = 13;
public const int WM_KEYDOWN = 0x100;
public const int WM_KEYUP = 0x101;
public const int WM_SYSKEYDOWN = 0x104;
public const int WM_SYSKEYUP = 0x105;
}
IntPtr HookPointer = IntPtr.Zero;
IntPtr ModuleInstance = IntPtr.Zero;
public event KeyEventHandler KeyDown;
public event KeyEventHandler KeyUp;
#endregion Class Declarations
#region Class Functions
public GlobalKeyboardHook() {
EnableHook(true, null);
}
public GlobalKeyboardHook(Process P) {
EnableHook(true, P);
}
~GlobalKeyboardHook() {
EnableHook(false, null);
}
public void EnableHook(bool Enabled)
{
EnableHook(Enabled, null);
}
public void EnableHook(bool Enabled, Process P) {
if (Enabled)
{
HookPointer = SetWindowsHookEx(KeyboardMessages.WH_KEYBOARD_LL, kbdProc = HookCallback, ModuleInstance = P == null ? LoadLibrary("User32") : GetModuleHandle(P.MainModule.ModuleName), 0);
}
else
{
UnhookWindowsHookEx(HookPointer);
HookPointer = IntPtr.Zero;
ModuleInstance = IntPtr.Zero;
kbdProc = null;
}
}
public int HookCallback(int code, int wParam, ref KeyboardHookStruct lParam) {
if (code >= 0) {
KeyEventArgs key = new KeyEventArgs((Keys)lParam.vkCode);
if ((wParam == KeyboardMessages.WM_KEYDOWN || wParam == KeyboardMessages.WM_SYSKEYDOWN) && (KeyDown != null)) {
KeyDown(this, key) ;
} else if ((wParam == KeyboardMessages.WM_KEYUP || wParam == KeyboardMessages.WM_SYSKEYUP) && (KeyUp != null)) {
KeyUp(this, key);
}
if (key.Handled)
return 1;
}
return CallNextHookEx(HookPointer, code, wParam, ref lParam);
}
#endregion Class Functions
}
To activate we add the following:
GlobalKeyboardHook ghk = new GlobalKeyboardHook(Process.GetCurrentProcess());
Type tbType = typeof(TextBox);
ghk.KeyDown += new KeyEventHandler(() => {
if (typeof(this.ActiveControl) == tbType)
RunValidation(this.ActiveControl.Text);
});
Once you have the boilerplate hook, adding validation becomes pretty simple. No loops means you're not wasting processor time iterating over a thousand text boxes.
Just remember this will apply to ALL controls of type TextBox within the current process. If you add a custom TextBox control or don't want to check all of them - that should be accounted for prior to calling RunValidation().

how can minimize and maximize window folders in C#

I'm trying to minimize window folders and applications with voice ( speech recognition ) and this is my code :
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool GetWindowPlacement(IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl);
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll")]
static extern bool SetWindowPlacement(IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl);
private struct POINTAPI
{
public int x;
public int y;
}
private struct RECT
{
public int left;
public int top;
public int right;
public int bottom;
}
private struct WINDOWPLACEMENT
{
public int length;
public int flags;
public int showCmd;
public POINTAPI ptMinPosition;
public POINTAPI ptMaxPosition;
public RECT rcNormalPosition;
}
private void button1_Click(object sender, EventArgs e)
{
WindowAction_MinimizeNotepad();
}
void WindowAction_MinimizeNotepad()
{
System.IntPtr app_hwnd;
WINDOWPLACEMENT wp = new WINDOWPLACEMENT();
app_hwnd = FindWindow("chrome", null);
GetWindowPlacement(app_hwnd, ref wp);
wp.showCmd = 2;
SetWindowPlacement(app_hwnd, ref wp);
}
i know how to use that code with button but i don't know how to use it with speech recognition so, how can i minimize windows with voice ? thanks.
First You need to Register for speech recognition event like:
On Page load
// Register handler for the SpeechRecognized event.
recognizer.SpeechRecognized += new EventHandler<SpeechRecognizedEventArgs>(srEvent_SpeechRecognized);
Then create a speech recognition event handler, Like :
void srEvent_SpeechRecognized(object sender, SpeechRecognizedEventArgs e)
{
this.WindowState = FormWindowState.Minimized;
}
You may want to have a look at Microsoft.Speech.Recognition.SpeechRecognitionEngine.
Using this you can subscribe to events and proceed with whatever action you want to perform on those events.
Get more information at https://msdn.microsoft.com/en-us/library/hh378426(v=office.14).aspx

How to detect if window is flashing

I'm using FlashWindowEx() to flash an application window when it needs to attract a user's attention. The window caption and taskbar button flashes continuously until the application receives focus. How can I check whether the application is currently flashing (i.e. has not received focus since it was instructed to flash).
Here are two possible solutions. One uses WH_SHELL, and one uses a NativeWindow. You will have to provide your own extension method (FlashWindow()) to start the flashing.
// base class. Two different forms subclass this form to illustrate two
// different solutions.
public class FormFlash : Form {
protected Label lb = new Label { Text = "Not flashing", Dock = DockStyle.Top };
public FormFlash() {
Controls.Add(lb);
Thread t = new Thread(() => {
Thread.Sleep(3000);
if (Form.ActiveForm == this)
SetForegroundWindow(GetDesktopWindow()); // deactivate the current form by setting the desktop as the foreground window
this.FlashWindow(); // call extension method to flash window
lb.BeginInvoke((Action) delegate {
lb.Text = "Flashing";
});
});
t.IsBackground = true;
t.Start();
}
[DllImport("user32.dll")]
private static extern bool SetForegroundWindow(IntPtr hWnd);
[DllImport("user32.dll")]
private static extern IntPtr GetDesktopWindow();
}
// this solution is a bit simpler. Relies on the programmer knowing when the
// flashing started. Uses a NativeWindow to detect when a WM_ACTIVATEAPP
// message happens, that signals the end of the flashing.
class FormFlashNW : FormFlash {
NW nw = null;
public FormFlashNW() {
}
protected override void OnHandleCreated(EventArgs e) {
base.OnHandleCreated(e);
nw = new NW(this.Handle, lb);
}
protected override void OnHandleDestroyed(EventArgs e) {
base.OnHandleDestroyed(e);
nw.ReleaseHandle();
}
class NW : NativeWindow {
Label lb = null;
public NW(IntPtr handle, Label lb) {
AssignHandle(handle);
this.lb = lb;
}
protected override void WndProc(ref Message m) {
base.WndProc(ref m);
const int WM_ACTIVATEAPP = 0x1C;
if (m.Msg == WM_ACTIVATEAPP) {
lb.BeginInvoke((Action) delegate {
lb.Text = "Not flashing";
});
}
}
}
}
// this solution is more complicated. Relies on setting up the hook proc.
// The 'isFlashing' bool fires true and false alternating while the flashing
// is active.
public class FormShellHook : FormFlash {
public FormShellHook() {
FlashWindowExListener.Register(this);
FlashWindowExListener.FlashEvent += FlashExListener_FlashEvent;
}
void FlashExListener_FlashEvent(Form f, bool isFlashing) {
if (f == this) {
lb.Text = DateTime.Now.ToLongTimeString() + " is flashing: " + isFlashing;
}
}
}
public class FlashWindowExListener {
private delegate IntPtr CallShellProc(int nCode, IntPtr wParam, IntPtr lParam);
private static CallShellProc procShell = new CallShellProc(ShellProc);
private static Dictionary<IntPtr,Form> forms = new Dictionary<IntPtr,Form>();
private static IntPtr hHook = IntPtr.Zero;
public static event FlashWindowExEventHandler FlashEvent = delegate {};
public delegate void FlashWindowExEventHandler(Form f, bool isFlashing);
static FlashWindowExListener() {
int processID = GetCurrentThreadId();
// we are interested in listening to WH_SHELL events, mainly the HSHELL_REDRAW event.
hHook = SetWindowsHookEx(WH_SHELL, procShell, IntPtr.Zero, processID);
System.Windows.Forms.Application.ApplicationExit += delegate {
UnhookWindowsHookEx(hHook);
};
}
public static void Register(Form f) {
if (f.IsDisposed)
throw new ArgumentException("Cannot use disposed form.");
if (f.Handle == IntPtr.Zero) {
f.HandleCreated += delegate {
forms[f.Handle] = f;
};
}
else
forms[f.Handle] = f;
f.HandleDestroyed += delegate {
Unregister(f);
};
}
public static void Unregister(Form f) {
forms.Remove(f.Handle);
}
private static IntPtr ShellProc(int nCode, IntPtr wParam, IntPtr lParam) {
if (nCode == HSHELL_REDRAW) {
Form f = null;
// seems OK not having to call f.BeginInvoke
if (forms.TryGetValue(wParam, out f))
FlashEvent(f, (int) lParam == 1);
}
return CallNextHookEx(hHook, nCode, wParam, lParam);
}
private const int WH_SHELL = 10;
private const int HSHELL_REDRAW = 6;
[DllImport("user32.dll")]
private static extern int UnhookWindowsHookEx(IntPtr idHook);
[DllImport("user32.dll")]
private static extern IntPtr SetWindowsHookEx(int idHook, CallShellProc lpfn, IntPtr hInstance, int threadId);
[DllImport("kernel32.dll")]
private static extern int GetCurrentThreadId();
[DllImport("user32.dll")]
private static extern IntPtr CallNextHookEx(IntPtr idHook, int nCode, IntPtr wParam, IntPtr lParam);
}

Middle button click to scroll

How do I achieve this in a WinForms container control when the scroll bars are visible?
Highlighted here (Google Chrome browser):
EDIT: This cursor is the only one that is visible on a screenshot. I hope it's clear what i mean.
EDIT:
Tried this on my control. Does not work.
const int WM_MBUTTONDOWN = 0x207;
protected override void WndProc(ref Message m)
{
if (m.Msg == WM_MBUTTONDOWN)
DefWndProc(ref m);
else
base.WndProc(ref m);
}
Here's what I have so far. It exits "reader mode" if I release the middle button, and I haven't implemented scrolling within the control (I used a textbox), but it may give you something to start with.
[DllImport("comctl32.dll", SetLastError=true, EntryPoint="#383")]
static extern void DoReaderMode(ref READERMODEINFO prmi);
public delegate bool TranslateDispatchCallbackDelegate(ref MSG lpmsg);
public delegate bool ReaderScrollCallbackDelegate(ref READERMODEINFO prmi, int dx, int dy);
[StructLayout(LayoutKind.Sequential)]
public struct READERMODEINFO
{
public int cbSize;
public IntPtr hwnd;
public int fFlags;
public IntPtr prc;
public ReaderScrollCallbackDelegate pfnScroll;
public TranslateDispatchCallbackDelegate fFlags2;
public IntPtr lParam;
}
[StructLayout(LayoutKind.Sequential)]
public struct MSG
{
public IntPtr hwnd;
public UInt32 message;
public IntPtr wParam;
public IntPtr lParam;
public UInt32 time;
public POINT pt;
}
[StructLayout(LayoutKind.Sequential)]
public struct POINT
{
public int x;
public int y;
}
[StructLayout(LayoutKind.Sequential)]
struct RECT
{
public int left, top, right, bottom;
}
private bool TranslateDispatchCallback(ref MSG lpMsg)
{
return false;
}
private bool ReaderScrollCallback(ref READERMODEINFO prmi, int dx, int dy)
{
// TODO: Scroll around within your control here
return false;
}
private void EnterReaderMode()
{
READERMODEINFO readerInfo = new READERMODEINFO
{
hwnd = this.textBox1.Handle,
fFlags = 0x00,
prc = IntPtr.Zero,
lParam = IntPtr.Zero,
fFlags2 = new TranslateDispatchCallbackDelegate(this.TranslateDispatchCallback),
pfnScroll = new ReaderScrollCallbackDelegate(this.ReaderScrollCallback)
};
readerInfo.cbSize = Marshal.SizeOf(readerInfo);
DoReaderMode(ref readerInfo);
}
private void textBox1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Middle)
{
EnterReaderMode();
}
}
The RichTextBox control does it by default when you press the mouse wheel button.
Edit: Sorry I misunderstood and thought you were asking about doing it within a textbox not a container control

Categories

Resources