am trying to simulate mouse right click in my WinForm app as follow :
public const int WM_RBUTTONDOWN = 0x204;
public const int WM_RBUTTONUP = 0x205;
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);
public static IntPtr MakeLParam(int LoWord, int HiWord)
{
return (IntPtr)((HiWord << 16) | (LoWord & 0xffff));
}
public static void Click(int x, int y)
{
SendMessage(this.Handle, WM_RBUTTONDOWN, IntPtr.Zero, MakeLParam(x,y));
SendMessage(this.Handle, WM_RBUTTONUP, IntPtr.Zero, MakeLParam(x,y));
}
(x,y) the coords inside the app window form, but nothing happens what am missing here?
EDIT: I have also tried FindWindow(null,"Form1"); and it gives same Handle as this.Handle..
Why you dont use the Events built-in in Windows Forms??
Use de MouseDown Event of any control, example the Form:
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Right)
{
}
}
The MouseDown Event take the control in a any mouse button pressed.
Related
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);
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);
}
I'm trying to send text to the console when it requires Console.Readline() input, from a different thread (Windows form with a textbox). The problem is I can't seem to figure out how to send text and have it show up exactly as I wrote it.
Example: "test TEST 123" will show up in the console as: test test &é"
Image: http://puu.sh/gIjW8/e9f4d94bd5.png
using System;
using System.Windows.Forms;
using System.IO;
using System.Runtime.InteropServices;
using System.Diagnostics;
namespace ConsoleApplication1
{
public partial class Form1 : Form
{
[DllImport("User32.Dll", EntryPoint = "PostMessageA")]
private static extern bool PostMessage(IntPtr hWnd, uint msg, IntPtr wParam, int lParam);
[DllImport("user32.dll")]
static extern short VkKeyScan(char ch);
[DllImport("user32.dll", EntryPoint = "SendMessageA")]
public static extern int SendMessage(IntPtr hWnd, int uMsg, int wParam, string lParam);
[DllImport("kernel32.dll")]
internal static extern IntPtr GetConsoleWindow();
public static IntPtr hWnd = GetConsoleWindow();
public Form1()
{
InitializeComponent();
}
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyData == Keys.Enter)
{
e.SuppressKeyPress = true;
TextBox tb = (sender as TextBox);
/*for (int i = 0; i < tb.Text.Length; i++)
{
PostMessage(hWnd, 0x100, (IntPtr)VkKeyScan(tb.Text[i]), 0); -> This crap doesn't support UPPERCASE and numbers <.<
}*/
PostMessage(hWnd, 0x100, (IntPtr)Keys.Enter, 0);
tb.Clear();
}
SendMessage(hWnd, 0x000C, 0, "HerpityDerp"); // -> This crap only changes the console title -_-
}
}
}
I tried using SendMessage, but it only changes the Console's title :/
I'd be very thankful if you guys could come up with a solution
A console app usually doesnt have a windows message pump, you might want to see how you can hook the console's stdout...
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
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