PostMessage does not work in Windows 7 x64 - c#

I need to simulate a keypress in game window. I try to send key "A", but it don't work:
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("USER32.DLL")]
public static extern bool SetForegroundWindow(IntPtr hWnd);
[DllImport("user32.dll")]
public static extern IntPtr PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
private void button1_Click(object sender, EventArgs e)
{
IntPtr hWnd = FindWindow(null, "Game Name"); // it's work!
if (hWnd == IntPtr.Zero)
{
MessageBox.Show("Game is not running");
return;
}
SetForegroundWindow(hWnd); // it's work too and now I have active window of game
System.Threading.Thread.Sleep(3000);
const int WM_KEYDOWN = 0x0100;
PostMessage(hWnd, WM_KEYDOWN, (IntPtr)Keys.A, IntPtr.Zero); // don't work ;-(
}

What error do you get? Is the game running as administrator? You could be blocked by UIPI.

Related

C# running foreign exe inside windows form

I'm trying to run discord.exe inside a windows form but im getting this error. Can someone help me, thanks. Here is the error message: Error message in English ("The system cannot find the file specified")
These are my codes:
[DllImport("user32.dll")]
static extern IntPtr SetParent(IntPtr child, IntPtr newParent);
[DllImport("user32.dll")]
static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int Iparam);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool IsWindowVisible(IntPtr hWnd);
private const int WM_SYSCOMMAND = 274;
private const int SC_MAXIMIZE = 61488;
private void button1_Click(object sender, EventArgs e)
{
string anan = "discord.exe";
Process calistir = Process.Start(anan);
while (calistir.MainWindowHandle == IntPtr.Zero || !IsWindowVisible(calistir.MainWindowHandle))
{
System.Threading.Thread.Sleep(10);
calistir.Refresh();
}
SetParent(calistir.MainWindowHandle, this.Handle);
SendMessage(calistir.MainWindowHandle, WM_SYSCOMMAND, SC_MAXIMIZE, 0);
}
if you wanna run the software, first you have to give the path of the file. I changed the code but you have to change it according to the information on your computer. Then it will work.
You can see the screenshot here: Discord App => Properties
https://i.hizliresim.com/1p5ZYG.jpg
string anan = #"C:\Users\YouPC\AppData\Local\Discord\Discord.exe";
Process calistir = Process.Start(anan);
while (calistir.MainWindowHandle == IntPtr.Zero ||
!IsWindowVisible(calistir.MainWindowHandle))
{
System.Threading.Thread.Sleep(10);
calistir.Refresh();
}
SetParent(calistir.MainWindowHandle, this.Handle);
SendMessage(calistir.MainWindowHandle, WM_SYSCOMMAND, SC_MAXIMIZE, 0);

C# .NET - Detecting and handling "extended" USB HID keyboard codes

I'm looking to detect and handle keycodes from a USB HID keyboard that fall outside the "normal" set of codes, i.e. codes above 100 (0x64) in a .NET Windows Forms application (.NET Framework 4.5).
Specifically, in my case I need to detect codes between 0x68 and 0x78, but I'd like to be able to detect anything up to 0xA4, which seems to be the upper limit of HID keyboard codes (aside from things like Ctrl, Alt, Win, etc.)
This question here seemed to be exactly what I was looking for, but I have had no success getting the advice on that answer to work. I have KeyPreview set to true for the form, and event handlers registered for KeyDown, KeyPress, and PreviewKeyDown, but none of them fire on reception of an 0x68 (F13) code. For now I'd just like to print the pressed key to a richtextbox control:
public mainFrm()
{
InitializeComponent();
this.KeyPreview = true;
this.KeyDown += new KeyEventHandler(KeyDownHandler);
this.KeyPress += new KeyPressEventHandler(KeyPressHandler);
this.PreviewKeyDown += new PreviewKeyDownEventHandler(PreviewKeyHandler);
}
private void KeyPressHandler(object sender, KeyPressEventArgs e)
{
rtb_hidLog.AppendText("Press: " + e.KeyChar.ToString() + "\r\n");
}
private void KeyDownHandler(object sender, KeyEventArgs e)
{
rtb_hidLog.AppendText("KeyDown: "+ e.KeyCode.ToString() + "\r\n");
}
private void PreviewKeyHandler(object sender, PreviewKeyDownEventArgs e)
{
rtb_hidLog.AppendText("Preview: " + e.KeyCode.ToString() + "\r\n");
}
I even tried overriding ProcessCmdKey (as per this question) and that also does not fire on 0x68:
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
rtb_hidLog.AppendText("CmdKey: " + keyData.ToString() + "\r\n");
return base.ProcessCmdKey(ref msg, keyData);
}
I have a USB HID Keyboard device connected (a PSoC microcontroller as a HID keyboard) that sends the 0x68 (F13) keycode when I press a button, but it doesn't fire the PreviewKeyHander. A standard 'A' code (0x04) from the PSoC device fires the KeyDownHandler and KeyPressHandler events with no problem. I have confirmed via USB Analyzer that the 0x68 code is being sent correctly, I just can't seem to force .NET to recognize it and fire an event. Is there something I'm missing or a trick I need to do to force my application to fire an event on these codes?
I've now also tried using Interop to use the win32 API (User32.dll) to hook into the keyboard input, and that also does not work. I get the same results; the hooked event will fire for all the keys on my keyboard, but anything not in that range does not fire a key pressed event.
My USB HID descriptor for the keyboard device, in case there is some issue there:
You can use a keyboard interceptor "in a separate DLL project that is referenced in your application" that is used by Form like this:
public delegate IntPtr KeyBoardHook( int nCode, IntPtr wParam, IntPtr lParam);
public class InterceptKeys : IDisposable
{
private const int WH_KEYBOARD_LL = 13;
private const int WM_KEYDOWN = 0x0100;
private KeyBoardHook _proc;
public event KeyBoardHook OnKeyBoardKeyClicked;
private static IntPtr _hookID = IntPtr.Zero;
public InterceptKeys()
{
_proc = HookCallback;
_hookID = SetHook(_proc);
if(_hookID == IntPtr.Zero)
{
throw new Exception($"Error Happened [{Marshal.GetLastWin32Error()}]");
}
}
public void Dispose()
{
UnhookWindowsHookEx(_hookID);
}
private IntPtr SetHook(KeyBoardHook proc)
{
using (Process curProcess = Process.GetCurrentProcess())
using (ProcessModule curModule = curProcess.MainModule)
{
return SetWindowsHookEx(WH_KEYBOARD_LL, proc,
GetModuleHandle(curModule.ModuleName), 0);
}
}
private IntPtr HookCallback(
int nCode, IntPtr wParam, IntPtr lParam)
{
OnKeyBoardKeyClicked?.Invoke(nCode, wParam, lParam);
//if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
//{
// int vkCode = Marshal.ReadInt32(lParam);
// Console.WriteLine((char)vkCode);
//}
return CallNextHookEx(_hookID, nCode, wParam, lParam);
}
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr SetWindowsHookEx(int idHook,
KeyBoardHook lpfn, IntPtr hMod, uint dwThreadId);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool UnhookWindowsHookEx(IntPtr hhk);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode,
IntPtr wParam, IntPtr lParam);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr GetModuleHandle(string lpModuleName);
}
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr GetModuleHandle(string lpModuleName);
}

True minimizing for another application

I just want to do real minimized, all public codes are not minimizing in right way! It just minimize it as shown, but not minimize like if I click on Minimize button. How did I know that? Or what benefit will I get from that? When I press on minimize button, it reduce from CPU usage! (It's a game anyway.)
My code is :
[DllImport("User32.Dll", EntryPoint = "PostMessageA", SetLastError = true)]
public static extern bool PostMessage(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);
List<int> ProcIDs = new List<int>();
private void timer1_Tick(object sender, EventArgs e)
{
foreach (Process process in Process.GetProcesses())
{
if (process.ProcessName == "League of Legends")
{
// MinimizeWindow((IntPtr)hProcess);
if (!ProcIDs.Contains(process.Id))
{
IntPtr hProcess = GetProcessWindow(process.Id);
ProcIDs.Add(process.Id);
PostMessage(hProcess, WM_SYSCOMMAND, (IntPtr)SC_MINIMIZE, IntPtr.Zero);
}
}
}
}
const int WM_SYSCOMMAND = 274;
const int SC_MINIMIZE = 0xF020;
I also tried other methods and it does the same, just minimize as show, but not real minimize! :)
You can try this
[DllImport("user32.dll")]
private static extern bool ShowWindow(IntPtr hWnd, WindowShowStyle nCmdShow);
with window style as ShowMinimized = 2,
http://www.pinvoke.net/default.aspx/user32.showwindow

send display to sleep mode in c#

it's a standard windows function that the display goes into sleep mode after the configured time. is it somehow possible to send the display into sleep mode immediately from a c# .net application in windows 7? i've already tried one thing i found but it didn't work for me.
[DllImport("user32.dll")]
static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
public static extern IntPtr GetDesktopWindow();
private const int SC_MONITORPOWER = 0xF170;
private const UInt32 WM_SYSCOMMAND = 0x0112;
private const int MONITOR_ON = -1;
private const int MONITOR_OFF = 2;
private const int MONITOR_STANBY = 1;
public static void DisplayToSleep()
{
var hWnd = GetDesktopWindow();
var ret = SendMessage(hWnd , Constants.WM_SYSCOMMAND, (IntPtr)Constants.SC_MONITORPOWER, (IntPtr)Constants.MONITOR_OFF);
}
hWnd seems to have a valid value but ret is always 0.
thx, kopi_b
This works fine in a WinForms application:
public partial class Form1 : Form
{
private int SC_MONITORPOWER = 0xF170;
private uint WM_SYSCOMMAND = 0x0112;
[DllImport("user32.dll")]
static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
SendMessage(this.Handle, WM_SYSCOMMAND, (IntPtr)SC_MONITORPOWER, (IntPtr)2);
}
}
The problem seems to come from the GetDesktopWindow function.
You need to use HWND_BROADCAST instead of the desktop window handle to ensure that the monitor powers off:
private const int HWND_BROADCAST = 0xFFFF;
var ret = SendMessage((IntPtr)HWND_BROADCAST, WM_SYSCOMMAND, (IntPtr)SC_MONITORPOWER, (IntPtr)MONITOR_OFF);
I have Visual Studio 2010 and Windows 7 and created a Windows Form Application with a 'Sleep' and 'Hibernate' button. The following worked for me:
private void Sleep_Click(object sender, EventArgs e)
{
bool retVal = Application.SetSuspendState(PowerState.Suspend, false, false);
if (retVal == false)
MessageBox.Show("Could not suspend the system.");
}
private void Hibernate_Click(object sender, EventArgs e)
{
bool retVal = Application.SetSuspendState(PowerState.Hibernate, false, false);
if (retVal == false)
MessageBox.Show("Could not hybernate the system.");
}
I found this here

How to Suppress task switch keys (winkey, alt-tab, alt-esc, ctrl-esc) using low-level keyboard hook in c#

Can anyone please tell me how to disable the task switch keys using c#
I've got the complete code to disable Windows Key , Alt + Tab and so on..
And now I'm providing the following code as a reference for others:
/* Code to Disable WinKey, Alt+Tab, Ctrl+Esc Starts Here */
// Structure contain information about low-level keyboard input event
[StructLayout(LayoutKind.Sequential)]
private struct KBDLLHOOKSTRUCT
{
public Keys key;
public int scanCode;
public int flags;
public int time;
public IntPtr extra;
}
//System level functions to be used for hook and unhook keyboard input
private delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr SetWindowsHookEx(int id, LowLevelKeyboardProc callback, IntPtr hMod, uint dwThreadId);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern bool UnhookWindowsHookEx(IntPtr hook);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr CallNextHookEx(IntPtr hook, int nCode, IntPtr wp, IntPtr lp);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr GetModuleHandle(string name);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern short GetAsyncKeyState(Keys key);
//Declaring Global objects
private IntPtr ptrHook;
private LowLevelKeyboardProc objKeyboardProcess;
private IntPtr captureKey(int nCode, IntPtr wp, IntPtr lp)
{
if (nCode >= 0)
{
KBDLLHOOKSTRUCT objKeyInfo = (KBDLLHOOKSTRUCT)Marshal.PtrToStructure(lp, typeof(KBDLLHOOKSTRUCT));
// Disabling Windows keys
if (objKeyInfo.key == Keys.RWin || objKeyInfo.key == Keys.LWin || objKeyInfo.key == Keys.Tab && HasAltModifier(objKeyInfo.flags) || objKeyInfo.key == Keys.Escape && (ModifierKeys & Keys.Control) == Keys.Control)
{
return (IntPtr)1; // if 0 is returned then All the above keys will be enabled
}
}
return CallNextHookEx(ptrHook, nCode, wp, lp);
}
bool HasAltModifier(int flags)
{
return (flags & 0x20) == 0x20;
}
/* Code to Disable WinKey, Alt+Tab, Ctrl+Esc Ends Here */
Then Inside the Form_Load();
private void Form_Load(object sender, EventArgs e)
{
ProcessModule objCurrentModule = Process.GetCurrentProcess().MainModule;
objKeyboardProcess = new LowLevelKeyboardProc(captureKey);
ptrHook = SetWindowsHookEx(13, objKeyboardProcess, GetModuleHandle(objCurrentModule.ModuleName), 0);
}
You can use the OnKeyDown event to capture the keys pressed and suppress the ones you don't want to allow.
Scott Hanselman's BabySmash application does disable most key strokes like alt-tab alt-esc, etc. Most of the source and development can be found on his blog. The source is on GitHub. In the source, you will see he InterceptKeys class that uses many win32 calls to get low level hooks to the keys pressed. He then handles these in HookCallback in the App.xaml.cs file. Hope this helps.
Similar Question
Another Similar

Categories

Resources