So I know this is a topic that has been touched on quite a lot on this website and this is yet another question devoted to it.
I'm trying to send keystrokes to a certain game and I believe the game to be ignoring my keystrokes. I know I've found the window because before I send the keystroke, I set the game to the foreground and that is working. I've tried SendKeys.Send, SendWait, and am currently trying the Windows API via SendMessage, and that's not working either. I'm using a method that I found via another user on SO. Here's what I'm working with:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Diagnostics;
namespace KeySendTest2
{
class Program
{
[DllImport("user32.dll")]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll")]
public static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool SetForegroundWindow(IntPtr hWnd);
public static void SendKeyStroke(IntPtr window, ushort key)
{
const uint WM_KEYDOWN = 0x100;
const uint WM_KEYUP = 0x0101;
SendMessage(window, WM_KEYDOWN, ((IntPtr)key), (IntPtr)0);
SendMessage(window, WM_KEYUP, ((IntPtr)key), (IntPtr)0);
}
static void Main(string[] args)
{
IntPtr hWnd = FindWindow("the class here", null);
SetForegroundWindow(hWnd);
System.Threading.Thread.Sleep(3000);
while (true)
{
SendKeyStroke(hWnd, (ushort)Keys.F3); // Doesn't work
//SendKeys.SendWait(Keys.F3); -- Also doesn't work
}
}
}
}
The game is a Windows application that is not a web browser. Does anyone have any idea that could point me in the right direction of why it might be ignoring the keystrokes? I know it can be done as there are several utilities built for the game that send keystrokes to the game, but they aren't open source so I have no way of seeing what method they are using.
In spite of official recommendations, many games don't use the message loop for input. Rather, they use the depreciated DirectInput API or other means.
I have had success using the AutoIT library from C# code for this purpose.
Related
There're a lot of ways to simulate a mouse click in an inactive window. I want my program to make clicks even when it's minimized and of course without capturing the main mouse.
Specifically, my C# program will contain a Web Control displaying some flash content and this is where I want the clicks to occur.
here's the techniques I tried:
1.[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);
2.[DllImport("user32.dll", SetLastError = true)]
public static extern bool SendMessage(int hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
Both of them did not do any good in my case. Surprisingly, I was able to use the SendMessage() function to send mouse clicks in a minimized chrome displaying some flash content. but, it doesn't seem to do that in my C# program. Is there a possibility that my program not receiving the message for some reason?
Any Hints on how can I do this?
I am using c#.net to develop a winform application.My winform application is using the below components
1)Win 32 dlls (using System.Runtime.InteropServices)
2)Timers(3 in count) (System.Timers)
3)Excel Interop
The memory of the application is not at all coming down .As timers are running continuosly so i cannot dispose the
So would like to implement dispose patterns .
Is it necessary to dispose the win32 APIs apart from Excel interop.?
If necessary can you please suggest the best way to call and dispose the win32 APIs.
Some of the Win32 APIs Used in application are listed below.
DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern uint RegisterWindowMessage(string lpString);
[DllImport("wininet.dll")]
private extern static bool InternetGetConnectedState(out int netConnection, int val);
[DllImport("Oleacc.dll")]
private static extern int AccessibleObjectFromWindow(IntPtr hwnd, uint dwObjectID, byte[] riid, ref Excel.Window ptr);
[DllImport("WtsApi32.dll")]
private static extern bool WTSRegisterSessionNotification(IntPtr hWnd, [MarshalAs(UnmanagedType.U4)]int dwFlags);
[DllImport("WtsApi32.dll")]
private static extern bool WTSUnRegisterSessionNotification(IntPtr hWnd);
The hWnd parameters in your function calls are all window handles. As a general rule, whenever you have finished using a window handle in the windows API, you need to explicitly release it using the CloseHandle function
I'm writing a WPF application in Caliburn.Micro that needs to minimize to the Taskbar when closed. That part is easy using Hardcodet TaskbarIcon control. This app should also be a single instance application which I'm using a global mutex for.
The problem I'm running into is: I want to maximize the current instance from the taskbar if another instance of the application is trying to start. So check the mutex, if it cant get a lock, find the other instance and maximize it from the taskbar and shut itself down. I can't do a user32.dll ShowWindow because there is no window handle to grab when its in the taskbar.
I ideally want to do a SendMessage from the opening instance to the existing instance and tell it to maximize itself, but I cant figure out how to handle a SendMessage event using Caliburn.Micro. Unfortunately, this is the only solution I can think of and I can't figure out how to do it.
Have a look at PostMessage
Here is a great example of someone using PostMessage to do exactly what you're talking about.
Basically, you use PostMessage to broadcast a custom message:
NativeMethods.PostMessage(
(IntPtr)NativeMethods.HWND_BROADCAST,
NativeMethods.WM_SHOWME,
IntPtr.Zero,
IntPtr.Zero);
Then you override WndProc to receive the message:
protected override void WndProc(ref Message m)
{
if(m.Msg == NativeMethods.WM_SHOWME)
{
// code here to maximize
}
base.WndProc(ref m);
}
Note that you need to register your custom message and extern in the needed win32 stuff:
internal class NativeMethods
{
public const int HWND_BROADCAST = 0xffff;
public static readonly int WM_SHOWME = RegisterWindowMessage("WM_SHOWME");
[DllImport("user32")]
public static extern bool PostMessage(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam);
[DllImport("user32")]
public static extern int RegisterWindowMessage(string message);
}
I've been using SendMessage to send mouse clicks to a couple of windows. One being a game(everything works perfectly), but the other window, being a 3rd party tool for the game is having trouble with SendMessage. If the window is 'not minimized' everything works fine, don't matter if window is completely covered up by another. But if that same window is minimized then nothing happens, I checked with spy++ and the messages are indeed getting received but not being processed (correct term?). I've tried to solve this last couple days, doing both searches on here and Google alike, many of topics but nothing helped?
//MyImports
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
And this is how I have it wrapped
public static void LClick(string windowclass, int x, int y)
{
IntPtr WHandle = FindWindow(windowclass, null);
SendMessage(WHandle, (int)WMessages.WM_LBUTTONDOWN, (IntPtr)1, (IntPtr)MakeLParam(x, y));
SendMessage(WHandle, (int)WMessages.WM_LBUTTONUP, (IntPtr)0, (IntPtr)MakeLParam(x, y));
}
I have tried focus, activate. One thing that might be useful info is that the third party program is being loaded as module("Qt5QWindowIcon") of the game.
I tried PostMessage as well, and it does the same thing as SendMessage() same problem when minimized.
This game does allow for macroing and unattended macroing, Hints the third part tool designed to execute the macros (published by the creators) I'm just trying to simulate a mouse click on the program to start the macro.
I would just use SendInput, but the entire purpose of my program is to run in background.
I 've faced same problem .Please change assembly name and project name (Changed name not started with name on that you are throwing/posting windows message)then rebuild it and check it. Now you will able to debug.
I am working on VS 2010 Ultimate. I have created a simple console application about 25-30 rows. So I want in the Main() function simply to simulate pressing "ALT+TAB" in a while cycle. Hoh can I do that - I cant use SendKeys class cause it "Provides methods for sending keystrokes to an application." I want just when I start my console application to simulate 1000 times pressing "ALT+TAB" without attaching it to anny applications. Something like this:
using System;
using System.Windows.Forms;
namespace nagradite
{
class Program
{
static void Main()
{
int i = 1000;
while( i > 0 )
{
// PRESS "ALT+TAB"
i--;
}
}
}
}
what should I type instead of // PRESS "ALT+TAB"
Use "%{TAB}" for Alt+TAB
SendKeys.Send("%{TAB}");
SendKeys.Send("%{TAB} 1000"); //if you want to do same by 1000 times as you stated
Reference http://msdn.microsoft.com/en-us/library/system.windows.forms.sendkeys.send.aspx
I think you can use SendMessage for finding keys you can see http://www.blizzhackers.cc/viewtopic.php?t=396398, your parent window is null (desktop)
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
You can try a Win32 API called SendInput. It allows you to simulate keyboard/mouse input events and does not require a HWND target. However, I don't know if this will actually trigger system-wide keyboard shortcuts such as ALT+TAB.
MSDN - http://msdn.microsoft.com/en-us/library/ms646310(v=vs.85).aspx
PInvoke.Net - http://www.pinvoke.net/default.aspx/user32.sendinput