I'm making an app that lets you navigate between items using SendKeys. All works pretty well except when I try to send the Application Key (context menu) to do a right click on the selected item.
I use:
SendKeys.Send("{APPSKEY}");
I get an Error saying 'Keyword "APPSKEY" is not valid.'
I googled it and found it on this website:
http://www.autohotkey.com/docs/commands/Send.htm
But i'm guessing that doesn't work for c#.
is there any other way to do a rightclick on the selected item?
is there a way to tell the app where the item is located to move the mouse there and do a right click?
my program can send MouseClicks:
public partial class Form1 : Form
{
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention =
CallingConvention.StdCall)]
public static extern void mouse_event(uint dwFlags, uint dx, uint dy, uint
cButtons, uint dwExtraInfo);
private const int MOUSEEVENTF_LEFTDOWN = 0x02;
private const int MOUSEEVENTF_LEFTUP = 0x04;
private const int MOUSEEVENTF_RIGHTDOWN = 0x08;
private const int MOUSEEVENTF_RIGHTUP = 0x10;
private void MoveCursor(Point loc)
{
this.Cursor = new Cursor(Cursor.Current.Handle);
Cursor.Position = loc;
Cursor.Clip = new Rectangle(0, 0, 0, 0);
}
private void DoMouseClick(bool isLeft)
{
int X = Cursor.Position.X;
int Y = Cursor.Position.Y;
if (isLeft) mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, (uint)X, (uint)Y, 0, 0);
else mouse_event(MOUSEEVENTF_RIGHTDOWN | MOUSEEVENTF_RIGHTUP, (uint)X, (uint)Y, 0, 0);
}
}
But in order to simulate a right click on that item the app has to know where it is located.
Try
SendKeys.Send("+{F10}");
Regards,
Related
I have a problem with C# virtual mouse click.. you know that we should use "user32.dll" library and the mouse_event functions..
I use the following function :
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern void mouse_event(uint dwFlags, uint dx, uint dy, uint cButtons, uint dwExtraInfo);
private const int MOUSEEVENTF_LEFTDOWN = 0x0002;
private const int MOUSEEVENTF_LEFTUP = 0x0004;
private const int MOUSEEVENTF_MIDDLEDOWN = 0x0020;
private const int MOUSEEVENTF_MIDDLEUP = 0x0040;
private const int MOUSEEVENTF_MOVE = 0x0001;
private const int MOUSEEVENTF_XDOWN = 0x0080;
private const int MOUSEEVENTF_XUP = 0x0100;
private const int MOUSEEVENTF_RIGHTDOWN = 0x08;
private const int MOUSEEVENTF_RIGHTUP = 0x0010;
and use this like that :
mouse_event(MOUSEEVENTF_LEFTDOWN, X, Y, 0, 0);
Guys, It is work on the all applications very good and Ok ! But in Flash Applications no
I have seen a post in here :
Problem automating mouse and interacting with Flash apps
They said that use from the all mouse_event functions , I used all of them but no one couldn't help me...
An other person who says use SendInput , You know better than me that the shapes that made by flash player doesn't have handle. and just main program has access to them. so we can't use SendInput...
I wanna do my problem with this code.. ( I don't like use difficult methods like Dynamic Data Exchange , etc... ) I wanna do it with my learnings... Can i ?
Thank you very much...
I found it...
You should Run your process as Administrator to do that...
what i need to do is that I need to control another application installed on the same machine using my custom application. For example if i needed to use the standard windows calculator I would simply send the input events to the calculator. I have used some code snippets to make this possible and I have now triggered both mouse and keyboard events. but the problem is that i can be sure that the keyboard event will hit the target application because it has the process handle. but i cannot be sure about the mouse. and also if the target application goes into background, i cannot initiate mouse clicks on it. I need help to find a way to make sure that the mouse click is done on the application only.
I need to send mouse co-ordinates and click as well. for example "sendMouseClick("Notepad", 100, 400); which will send a click to Notepad, even though it stays minimized.
IMPORTANT NOTE
A similar question is answered previously but that is in reference to first finding the state of the other application and then sending the inputs either keyboard or mouse, what i need to do is to send an application a set of instructions that must work whether the application is in foreground or not.
For "The other Guys":: if you dont want to help or cant help, thats okay but please do know that i havent stolen the question or anything. I simply want to achieve this task in C#.
The code I have to simulate keyboard key Press is:
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Drawing;
using System.Windows.Forms;
namespace SimulateKeyPress
{
partial class Form1 : Form
{
private Button button1 = new Button();
private Button button2 = new Button();
private Button button3 = new Button();
[STAThread]
public static void Main()
{
Application.EnableVisualStyles();
Application.Run(new Form1());
}
public Form1()
{
button1.Location = new Point(10, 10);
button1.TabIndex = 1;
button1.Text = "Click to automate Calculator";
button1.AutoSize = true;
button1.Click += new EventHandler(button1_Click);
button2.Location = new Point(150, 140);
button2.TabIndex = 0;
button2.Text = "Click to Exit Calculator";
button2.AutoSize = true;
button2.Location = new Point(80, 80);
button2.TabIndex = 2;
button2.Text = "Click to Run Calculator";
button2.AutoSize = true;
button2.Click += new EventHandler(button2_Click);
this.DoubleClick += new EventHandler(Form1_DoubleClick);
this.Controls.Add(button1);
this.Controls.Add(button2);
// this.Controls.Add(button3);
}
// Get a handle to an application window.
[DllImport("USER32.DLL", CharSet = CharSet.Unicode)]
public static extern IntPtr FindWindow(string lpClassName,
string lpWindowName);
// Activate an application window.
[DllImport("USER32.DLL")]
public static extern bool SetForegroundWindow(IntPtr hWnd);
// Send a series of key presses to the Calculator application.
private void button1_Click(object sender, EventArgs e)
{
// Get a handle to the Calculator application. The window class
// and window name were obtained using the Spy++ tool.
IntPtr calculatorHandle = FindWindow("CalcFrame", "Calculator");
//Process firstProc = new Process();
//firstProc.StartInfo.FileName = "calc.exe";
//firstProc.EnableRaisingEvents = true;
//firstProc.Start();
// Verify that Calculator is a running process.
if (calculatorHandle == IntPtr.Zero)
{
MessageBox.Show("Calculator is not running.");
return;
}
// Make Calculator the foreground application and send it
// a set of calculations.
SetForegroundWindow(calculatorHandle);
SendKeys.SendWait("1024");
SendKeys.SendWait("*");
SendKeys.SendWait("32");
SendKeys.SendWait("=");
}
private void button2_Click(object sender, EventArgs e)
{
System.Diagnostics.Process.Start("calc.exe");
}
private void button3_Click(object sender,EventArgs e)
{
Process [] proc =Process.GetProcessesByName("Calculator");
proc[0].Kill();
}
// Send a key to the button when the user double-clicks anywhere
// on the form.
private void Form1_DoubleClick(object sender, EventArgs e)
{
// Send the enter key to the button, which raises the click
// event for the button. This works because the tab stop of
// the button is 0.
SendKeys.Send("{ENTER}");
}
}
}
the previous help on stack overflow, msdn and other sites provides the code to simulate a mouse click in the same application. But i need to send mouse hits to another application.
Maybe this could help you
Code
The task
Getting the mouse's current position
Sending the mouse event
Windows forms
...
using System.Runtime.InteropServices;
namespace yournamespace
{
public partial class yourclassname
{
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern void mouse_event(uint dwFlags, uint dx, uint dy, uint cButtons, uint dwExtraInfo);
private const int MOUSEEVENTF_LEFTDOWN = 0x02;
private const int MOUSEEVENTF_LEFTUP = 0x04;
private const int MOUSEEVENTF_RIGHTDOWN = 0x08;
private const int MOUSEEVENTF_RIGHTUP = 0x10;
int X = Cursor.Position.X;
int Y = Cursor.Position.Y;
mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, X, Y, 0, 0);
}
}
WPF
Things are a bit harder in WPF
double mousePointX;
double mousePointY;
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool GetCursorPos(out POINT lpPoint);
[StructLayout(LayoutKind.Sequential)]
public struct POINT
{
public int X;
public int Y;
public POINT(int x, int y)
{
this.X = x;
this.Y = y;
}
}
private void WritePoint(object sender, RoutedEventArgs e)
{
POINT p;
if (GetCursorPos(out p))
{
System.Console.WriteLine(Convert.ToString(p.X) + ";" + Convert.ToString(p.Y));
}
}
[DllImport("User32.dll")]
static extern IntPtr GetDC(IntPtr hwnd);
[DllImport("gdi32.dll")]
static extern int GetDeviceCaps(IntPtr hdc, int nIndex);
[DllImport("user32.dll")]
static extern bool ReleaseDC(IntPtr hWnd, IntPtr hDC);
private Point ConvertPixelsToUnits(int x, int y)
{
// get the system DPI
IntPtr dDC = GetDC(IntPtr.Zero); // Get desktop DC
int dpi = GetDeviceCaps(dDC, 88);
bool rv = ReleaseDC(IntPtr.Zero, dDC);
// WPF's physical unit size is calculated by taking the
// "Device-Independant Unit Size" (always 1/96)
// and scaling it by the system DPI
double physicalUnitSize = (1d / 96d) * (double)dpi;
Point wpfUnits = new Point(physicalUnitSize * (double)x,
physicalUnitSize * (double)y);
return wpfUnits;
}
private void WriteMouseCoordinatesInWPFUnits()
{
POINT p;
if (GetCursorPos(out p))
{
Point wpfPoint = ConvertPixelsToUnits(p.X, p.Y);
System.Console.WriteLine(Convert.ToString(wpfPoint.X) + ";" + Convert.ToString(wpfPoint.Y));
mousePointY = wpfPoint.Y;
mousePointX = wpfPoint.X
}
}
Now the most important part of the code
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern void mouse_event(uint dwFlags, uint dx, uint dy, uint cButtons, uint dwExtraInfo);
private const int MOUSEEVENTF_LEFTDOWN = 0x02;
private const int MOUSEEVENTF_LEFTUP = 0x04;
private const int MOUSEEVENTF_RIGHTDOWN = 0x08;
private const int MOUSEEVENTF_RIGHTUP = 0x10;
...
mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, Convert.ToUInt32(mousePointX), Convert.ToUInt32(mousePointY), 0, 0);
...
Warning
The code is tested
The code is not a "copy & paste code
This question already has answers here:
How do you simulate Mouse Click in C#?
(7 answers)
Closed 2 years ago.
I'd like to perform a click in a windows application, without using the real mouse (so I can minimize it). Much like a bot would behave.
How would I do this?
I think the function you're looking for is PostMessage
[DllImport("user32.dll", SetLastError = true)]
public static extern bool PostMessage(int hWnd, uint Msg, int wParam, int lParam);
You can read more about it here on codeproject, and download a demo project, which sends keystrokes.
This method posts messages directly on the input queue associated with the program, based on the process handle you use (hWnd)
You can also use this function to send mouse clicks with it, by posting button events, like so:
PostMessage(hWnd, WM_LBUTTONDBLCLK, 0, l);
More information about those button events can be found here on MSDN.
I'm sure if you search around the internet for samples for PostMessage mouse events you'll find plenty
You can use a timer, or handle key press, and create in the timer tick or key press function simulate a mouse click, using the user32.dll file (better be in a form shape so you can handle timer interval...):
using System;
using System.Windows.Forms;
namespace Clicker
{
public partial class Form1 : Form
{
[System.Runtime.InteropServices.DllImport("user32.dll")]
public static extern void mouse_event(int dwFlags, int dx, int dy, int cButtons, int dwExtraInfo);
private const int MOUSEEVENT_LEFTDOWN = 0x02;
private const int MOUSEEVENT_LEFTUP = 0x04;
private const int MOUSEEVENT_MIDDLEDOWN = 0x20;
private const int MOUSEEVENT_MIDDLEUP = 0x40;
private const int MOUSEEVENT_RIGHTDOWN = 0x08;
private const int MOUSEEVENT_RIGHTUP = 0x10;
private int count = 0;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
timer1.Start();
label2.Text = "Timer is on";
}
private void button2_Click(object sender, EventArgs e)
{
timer1.Stop();
label2.Text = "Timer is off";
}
private void timer1_Tick(object sender, EventArgs e)
{
mouse_event(MOUSEEVENT_LEFTDOWN, 0, 0, 0, 0);
mouse_event(MOUSEEVENT_LEFTUP, 0, 0, 0, 0);
count++;
label3.Text = count + " amount of clicks";
}
}
}
[System.Runtime.InteropServices.DllImport("user32.dll")]
public static extern void mouse_event(int dwFlags, int dx, int dy, int cButtons, int dwExtraInfo);
public const int MOUSEEVENTF_LEFTDOWN = 0x02;
public const int MOUSEEVENTF_LEFTUP = 0x04;
public const int MOUSEEVENTF_RIGHTDOWN = 0x08;
public const int MOUSEEVENTF_RIGHTUP = 0x10;
public void MouseClick()
{
int x = 100;
int y = 100;
mouse_event(MOUSEEVENTF_LEFTDOWN, x, y, 0, 0);
mouse_event(MOUSEEVENTF_LEFTUP, x, y, 0, 0);
}
I found this at http://social.msdn.microsoft.com/forums/en-US/winforms/thread/86dcf918-0e48-40c2-88ae-0a09797db1ab/.
You'll need the resolution of the machine that it's on, use the System.Windows.Forms.Screen class, here: SO
You will then need to move the mouse to that location, or avoiding that, you may need to hook to the program that's running, and send it an event that causes it to minimize.
It's going to be hard to get something like this to work with C#, as you'll need to inject that DLL into the program. A lower level language like C may be helpful.
Here's a brief explanation / question
You can use Window Automation to find Minimize button in window and perform click. I find it easy and used a lot. here is the link to understand the whole concept.
https://msdn.microsoft.com/en-us/library/windows/desktop/ff486375(v=vs.85).aspx
I am developing WinForms MDI app in VS2010 (.NET 4.0) and I just hate 3D border in MDI parent form.
So any ideas on how to remove it (make it flat or just no border it all) ?
I know this is an old post but I have spent some time and pain working the 3D border stuff out (because I needed it too) from fragments across the internet including:
Elements from Jacob Slusser's page at codeproject.com (Accessed 1st Aug'12)
So here goes:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace MDITest
{
public static class MDIClientSupport
{
[DllImport("user32.dll")]
private static extern int GetWindowLong(IntPtr hWnd, int nIndex);
[DllImport("user32.dll")]
private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
[DllImport("user32.dll", ExactSpelling = true)]
private static extern int SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
private const int GWL_EXSTYLE = -20;
private const int WS_EX_CLIENTEDGE = 0x200;
private const uint SWP_NOSIZE = 0x0001;
private const uint SWP_NOMOVE = 0x0002;
private const uint SWP_NOZORDER = 0x0004;
private const uint SWP_NOREDRAW = 0x0008;
private const uint SWP_NOACTIVATE = 0x0010;
private const uint SWP_FRAMECHANGED = 0x0020;
private const uint SWP_SHOWWINDOW = 0x0040;
private const uint SWP_HIDEWINDOW = 0x0080;
private const uint SWP_NOCOPYBITS = 0x0100;
private const uint SWP_NOOWNERZORDER = 0x0200;
private const uint SWP_NOSENDCHANGING = 0x0400;
public static bool SetBevel(this Form form, bool show)
{
foreach (Control c in form.Controls)
{
MdiClient client = c as MdiClient;
if (client != null)
{
int windowLong = GetWindowLong(c.Handle, GWL_EXSTYLE);
if (show)
{
windowLong |= WS_EX_CLIENTEDGE;
}
else
{
windowLong &= ~WS_EX_CLIENTEDGE;
}
SetWindowLong(c.Handle, GWL_EXSTYLE, windowLong);
// Update the non-client area.
SetWindowPos(client.Handle, IntPtr.Zero, 0, 0, 0, 0,
SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER |
SWP_NOOWNERZORDER | SWP_FRAMECHANGED);
return true;
}
}
return false;
}
}
}
In the form load event call:
form.SetBevel(false);
Don't forget to change the namespace and remember this is an extension method but it could be changed to be just a method call in another class or in you MDI parent form.
If you would prefer not to import external libraries there is also following cheat which repositions/resizes the mdi container control.
protected override void OnLoad(EventArgs e)
{
var mdiclient = this.Controls.OfType<MdiClient>().Single();
this.SuspendLayout();
mdiclient.SuspendLayout();
var hdiff = mdiclient.Size.Width - mdiclient.ClientSize.Width;
var vdiff = mdiclient.Size.Height - mdiclient.ClientSize.Height;
var size = new Size(mdiclient.Width + hdiff, mdiclient.Height + vdiff);
var location = new Point(mdiclient.Left - (hdiff / 2), mdiclient.Top - (vdiff / 2));
mdiclient.Dock = DockStyle.None;
mdiclient.Size = size;
mdiclient.Location = location;
mdiclient.Anchor = AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Right | AnchorStyles.Bottom;
mdiclient.ResumeLayout(true);
this.ResumeLayout(true);
base.OnLoad(e);
}
Try changing the FormBorderStyle property to FixedSingle
how to change the window style of a form outside your app?hard question?
i am actually trying to move a form witch is topmost and has no border.
i have the handle(hWnd) of the window.
i can write thousands of lines of code if guaranteed to work.
Assuming that this window could be from any app produced from any kind of Win32-based runtime, it looks like you'll have to resort to p/invoke of the core Win32 apis for window operations.
For example, you could use SetWindowPos, which can be imported from user32.dll. It's signature is this:
BOOL SetWindowPos(HWND hWnd,
HWND hWndInsertAfter,
int X,
int Y,
int cx,
int cy,
UINT uFlags
);
I'm not going to assume that you've done a p/invoke import before, so let's go from the top. Let's just bash out a windows forms app:
1) Create a windows forms app and then add these declarations to the Form1 class:
/* hWndInsertAfter constants. Lifted from WinUser.h,
* lines 4189 onwards depending on Platform SDK version */
public static IntPtr HWND_TOP = (IntPtr)0;
public static IntPtr HWND_BOTTOM = (IntPtr)1;
public static IntPtr HWND_TOPMOST = (IntPtr)(-1);
public static IntPtr HWND_NOTOPMOST = (IntPtr)(-2);
/* uFlags constants. Lifted again from WinUser.h,
* lines 4168 onwards depending on Platform SDK version */
/* these can be |'d together to combine behaviours */
public const int SWP_NOSIZE = 0x0001;
public const int SWP_NOMOVE = 0x0002;
public const int SWP_NOZORDER = 0x0004;
public const int SWP_NOREDRAW = 0x0008;
public const int SWP_NOACTIVATE = 0x0010;
public const int SWP_FRAMECHANGED = 0x0020;
public const int SWP_SHOWWINDOW = 0x0040;
public const int SWP_HIDEWINDOW = 0x0080;
public const int SWP_NOCOPYBITS = 0x0100;
public const int SWP_NOOWNERZORDER = 0x0200; /* Don't do owner Z ordering */
public const int SWP_NOSENDCHANGING = 0x0400; /* Don't send WM_WINDOWPOSCHANGING */
public const int SWP_DRAWFRAME = SWP_FRAMECHANGED;
public const int SWP_NOREPOSITION = SWP_NOOWNERZORDER;
public const int SWP_DEFERERASE = 0x2000;
public const int SWP_ASYNCWINDOWPOS = 0x4000;
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern int SetWindowsPos(IntPtr hWnd,
IntPtr hWndInsertAfter,
int x,
int y,
int cx,
int cy,
UInt32 uFlags);
The annoying thing with p/invoke of Win32 windows methods is that you then have to start importing various numeric constants etc that Win32 uses - hence all the gumph beforehand.
Refer to the MSDN link for the SetWindowPos method for an explanation of what they do.
2) Add a button to the form called cmdMakeHidden and then write the handler as follows:
private void cmdMakeHidden_Click(object sender, EventArgs e)
{
//also causes the icon in the start bar to disappear
//SWP_HIDEWINDOW is the 'kill -9' of the windows world without actually killing!
SetWindowPos(this.Handle, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_HIDEWINDOW);
}
Replace the 'this.Handle' with the window handle of your choice to hide that window.
This method is actually used to apply multiple changes at once, hence the need to use some of the SWP_NO* options. For example, you should specify SWP_NOSIZE otherwise passing 0 for cx and cy will cause the window to shrink to zero width and height at the same time.
To demonstrate moving a window, add another button your form called cmdMove and then write the click handler as follows:
private void cmdMove_Click(object sender, EventArgs e)
{
SetWindowPos(this.Handle, HWND_TOP, 100, 100, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOREPOSITION);
}
This code moves your form to 100,100 whenever you hit the button.
Again, replace the this.Handle as you see fit. HWND_TOP here is completely optional, since reordering has been disabled with the SWP_NOZORDER and SWP_NOREPOSITION flags.
Hope this helps get you on the right track!