I have a Handle for a ListBox from an external application.
Now I have a Listbox with x Items which I want to select with the WinApi.
I tried this with SETCURSEL but its unfortunatly doesnt work:
private void button2_Click(object sender, EventArgs e)
{
IntPtr chldWnd = NativeMethods.FindWindow("#32770", "Ansichten einfügen");
IntPtr ListBoxHandle = NativeMethods.FindWindowEx(chldWnd, IntPtr.Zero, "ListBox", null);
//MessageBox.Show(ButtonHandle.ToString());
NativeMethods.SendMessageInt(ListBoxHandle, NativeMethods.CB_SETCURSEL, 1, 2);
}
static class NativeMethods
{
public const int BM_CLICK = 0x00F5;
public const int WM_SETTEXT = 0x000C;
public const int VK_DOWN = 0x28;
public const int WM_KEYDOWN = 0x100;
public const int LB_SETSEL = 0x0185;
public const int CB_SETCURSEL = 0x014E;
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
public static extern IntPtr SendMessage(IntPtr hwnd, int wMsg, IntPtr wParam, string lParam);
[DllImport("user32.dll", EntryPoint="PostMessage" ,CharSet = CharSet.Unicode)]
public static extern IntPtr SendMessageInt(IntPtr hWnd, uint Msg, int wParam, int lParam);
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
public static extern IntPtr PostMessage(IntPtr hwnd, int wsg, IntPtr wParam, String lParam);
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className, string windowTitle);
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
}
I believe that the way I use it will meet your need to select an item with a mouse click on the ListBox, Please, try it.
[DllImport("user32.dll")]
private static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);
public void SetListItem(string windowTitle, int index, int item)
{
try
{
var windowHWnd = FindWindowByCaption(IntPtr.Zero, windowTitle);
var childWindows = GetChildWindows(windowHWnd);
const int LB_SETCURSEL = 0x0186;
const int downCode = 0x201;
const int upCode = 0x202;
IntPtr lParam = (IntPtr)9999; // The coordinates
IntPtr wParam = IntPtr.Zero;
SendMessage(childWindows.ToArray()[index], LB_SETCURSEL, item, "0");
SendMessage(childWindows.ToArray()[index], downCode, wParam, lParam); // Mouse button down
SendMessage(childWindows.ToArray()[index], upCode, wParam, lParam);
}
catch (Exception)
{
throw;
}
}
Related
I have a filled image on my form in front of everything but most of it is transparant so i'm trying to click through it. I have this:
public class clickThrough
{
[DllImport("user32.dll", EntryPoint = "SetWindowLongW")]
private static extern IntPtr SetWindowLongPtr32(IntPtr hWnd, int nIndex, IntPtr dwNewLong);
[DllImport("user32.dll", EntryPoint = "SetWindowLongPtrW")]
private static extern IntPtr SetWindowLongPtr64(IntPtr hWnd, int nIndex, IntPtr dwNewLong);
private delegate IntPtr WndProcDelegate(IntPtr hWnd, int message, IntPtr wParam, IntPtr lParam);
private static WndProcDelegate SetWindowProc(IntPtr hWnd, WndProcDelegate newWndProc)
{
IntPtr newWndProcPtr = Marshal.GetFunctionPointerForDelegate(newWndProc);
IntPtr oldWndProcPtr;
if (IntPtr.Size == 4)
oldWndProcPtr = SetWindowLongPtr32(hWnd, -4, newWndProcPtr);
else
oldWndProcPtr = SetWindowLongPtr64(hWnd, -4, newWndProcPtr);
return (WndProcDelegate)Marshal.GetDelegateForFunctionPointer(oldWndProcPtr, typeof(WndProcDelegate));
}
}
private void guna2PictureBox1_Click(object sender, EventArgs e)
{
int initialStyle = SetWindowLongPtrW(this.Handle, -20);
SetWindowLongPtrW(this.Handle, -20, initialStyle | 0x80000 | 0x20);
}
I get this error: The name 'SetWindowLongPtrW' does not exist in the current context
I have a powershell script where i have written the below code to get the hookid. But the setwindowshookex returns null if the user doenot have access to C:/Windows/Temp path. if i give the access then the setwindowshookex returns integer value.
I have tried passing GetCurrentThreadId() as the last parameter of SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hMod, uint dwThreadId);
Add-Type #"
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
public static class NativeMethods{
public static bool KeyEvent { get; set; }
public static bool KeyEventPrevious { get; set; }
public static System.Collections.Generic.List<bool> Buffer = new System.Collections.Generic.List<bool>();
public delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam);
private const int WH_KEYBOARD_LL = 13;
private const int WM_KEYDOWN = 0x0100;
public static HookProc hookProc = HookCallback;
private static IntPtr hookId = IntPtr.Zero;
public delegate IntPtr HookProc(int nCode, IntPtr wParam, IntPtr lParam);
private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam) {
if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN) {
KeyEvent = true;
}
else{
KeyEvent = false;
}
if(KeyEvent != KeyEventPrevious){
Buffer.Add(KeyEvent);
KeyEventPrevious = KeyEvent;
}
return CallNextHookEx(hookId, nCode, wParam, lParam);
}
public static IntPtr GetHookId(HookProc hookProc){
IntPtr moduleHandle = GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName);
return SetWindowsHookEx(WH_KEYBOARD_LL, hookProc, moduleHandle, GetCurrentThreadId());
}
[DllImport("user32.dll")]
private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll")]
private static extern IntPtr SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hMod, uint dwThreadId);
[DllImport("kernel32.dll")]
private static extern IntPtr GetModuleHandle(string lpModuleName);
[DllImport("user32.dll")]
private static extern bool UnhookWindowsHookEx(IntPtr hhk);
[DllImport("kernel32.dll")]
private static extern uint GetCurrentThreadId();
$nativeMethodCode
}
"#
Hookid is required to monitor the keyboard events.
I have list of open Applications. To get this list i have used following code
internal static class NativeMethods
{
public static readonly Int32 GWL_STYLE = -16;
public static readonly UInt64 WS_VISIBLE = 0x10000000L;
public static readonly UInt64 WS_BORDER = 0x00800000L;
public static readonly UInt64 DESIRED_WS = WS_BORDER | WS_VISIBLE;
public delegate Boolean EnumWindowsCallback(IntPtr hwnd, Int32 lParam);
public static List<WindowWrapper> GetAllWindows()
{
List<WindowWrapper> windows = new List<WindowWrapper>();
StringBuilder buffer = new StringBuilder(100);
EnumWindows(delegate(IntPtr hwnd, Int32 lParam)
{
if ((GetWindowLongA(hwnd, GWL_STYLE) & DESIRED_WS) == DESIRED_WS)
{
GetWindowText(hwnd, buffer, buffer.Capacity);
WindowWrapper wnd = new WindowWrapper();
wnd.handle = hwnd;
wnd.title = buffer.ToString();
windows.Add(wnd);
}
return true;
}, 0);
return windows;
}
[DllImport("user32.dll")]
static extern Int32 EnumWindows(EnumWindowsCallback lpEnumFunc, Int32 lParam);
[DllImport("user32.dll")]
public static extern void GetWindowText(IntPtr hWnd, StringBuilder lpString, Int32 nMaxCount);
[DllImport("user32.dll")]
static extern UInt64 GetWindowLongA(IntPtr hWnd, Int32 nIndex);
}
public class WindowWrapper : IWin32Window
{
internal IntPtr handle;
internal String title;
public IntPtr Handle
{
get { return handle; }
}
public String Title
{
get { return title; }
}
}
to call this i used following code
foreach (var wnd in NativeMethods.GetAllWindows())
{
string caption = wnd.title;
string handle = wnd.Handle
// Add this caption and handle to list
}
Now, User will select any of the opened window from the list and my task is to read caption of the selected window, get handle of process and maximize/minimize or close window. How can I do this.
You can use findwindowbycaption to get the handle then maximize or minimize with showwindow
private const int SW_MAXIMIZE = 3;
private const int SW_MINIMIZE = 6;
// more here: http://www.pinvoke.net/default.aspx/user32.showwindow
[DllImport("user32.dll", EntryPoint = "FindWindow")]
public static extern IntPtr FindWindowByCaption(IntPtr ZeroOnly, string lpWindowName);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
Then in your code you use this:
IntPtr hwnd = FindWindowByCaption(IntPtr.Zero, "The window title");
ShowWindow(hwnd, SW_MAXIMIZE);
Although it seems you already have the window handle by using EnumWindows in that case you would only need:
ShowWindow(windows[i].handle, SW_MAXIMIZE);
i is the index of the window.
to close the window you will use:
[DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError=true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool DestroyWindow(IntPtr hwnd);
in the code:
DestroyWindow(hwnd) //or DestroyWindow(windows[i].handle)
this is the unmanaged version of system.windows.forms.form.close()
or you can use:
Process [] proc Process.GetProcessesByName("process name");
proc[0].Kill();
or you can use:
static uint WM_CLOSE = 0x0010;
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("user32.dll", SetLastError = true)]
static extern bool PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
in code:
PostMessage(hWnd, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
You may use native method ShowWindow with SW_MAXIMIZE, SW_MINIMIZE for ncmdShow
Take a look at http://msdn.microsoft.com/en-us/library/windows/desktop/ms633548(v=vs.85).aspx
private const int SW_MAXIMIZE = 3;
private const int SW_MINIMIZE = 6;
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool ShowWindow(IntPtr hWnd, ShowWindowCommands nCmdShow);
// in your code
ShowWindow(wnd.Handle, SW_MAXIMIZE);
you can use ShowWindowAsync
private const int SW_SHOWNORMAL = 1;
private const int SW_SHOWMINIMIZED = 2;
private const int SW_SHOWMAXIMIZED = 3;
[DllImport("user32.dll")]
private static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);
ShowWindowAsync(wnd.Handle, SW_SHOWMINIMIZED );
and it's better and to use
var openWindows = Process.GetProcesses().Where(process=> String.IsNullOrEmpty(process.MainWindowTitle)==false);
to get opened windows
I have test MainWindowTitle in Porcess and it helps to search on window given it's caption.
var handles = Process.GetProcesses().Where(x => x.MainWindowTitle == "Untitled - Notepad").Select(y=>y.Handle).ToList();
I want to make a C# Application with a Keyboard and Mouse on screen.
Every Key or Button that is clicked should be seen in this Application by for example coloring one of the keys ( i know how to do that ). This should also work if the Application is not focused. Currently i am using a global Key- and Mousehook which works fine.
The problem is, the Keyhook does only intercept one Key at a time which means i can only show on Key at a time. I want to be able to show multiple keys at a time on screen.
KeyListeners are unfortunately no option because they dont work outside the Application.
Does anyone has an idea how to make this possible?
Here's the KeyHook i am using:
public class KeyHook
{
private delegate int HookProc(int nCode, IntPtr wParam, IntPtr lParam);
static int hHook = 0;
public static List<Keys> KeyCodes = new List<Keys>();
const int WH_KEYBOARD_LL = 13;
HookProc KeyboardHookProcedure;
[StructLayout(LayoutKind.Sequential)]
private class keyboardHookStruct
{
public int vkCode;
public int scanCode;
public int flags;
public int time;
public int dwExtraInfo;
}
[DllImport("user32.dll", CharSet = CharSet.Auto,
CallingConvention = CallingConvention.StdCall)]
private static extern int SetWindowsHookEx(int idHook, HookProc lpfn,
IntPtr hInstance, int threadId);
[DllImport("user32.dll", CharSet = CharSet.Auto,
CallingConvention = CallingConvention.StdCall)]
private static extern bool UnhookWindowsHookEx(int idHook);
[DllImport("user32.dll", CharSet = CharSet.Auto,
CallingConvention = CallingConvention.StdCall)]
private static extern int CallNextHookEx(int idHook, int nCode,
IntPtr wParam, IntPtr lParam);
[DllImport("kernel32.dll")]
static extern IntPtr LoadLibrary(string lpFileName);
public KeyHook()
{
Hook();
}
~KeyHook()
{
UnHook();
}
public int Hook()
{
KeyboardHookProcedure = new HookProc(KeyHook.KeyboardHookProc);
hHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookProcedure, (IntPtr)LoadLibrary("User32"), 0);
return hHook;
}
public bool UnHook()
{
bool ret = UnhookWindowsHookEx(hHook);
if (ret)
hHook = 0;
return ret;
}
private static int KeyboardHookProc(int nCode, IntPtr wParam, IntPtr lParam)
{
if (nCode < 0)
{
return CallNextHookEx(hHook, nCode, wParam, lParam);
}
else
{
if (((int)wParam == 256) || ((int)wParam == 260))
{
keyboardHookStruct MyKeyboardHookStruct = (keyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(keyboardHookStruct));
//Adding Key to a log i use for other stuff
KeyCodes.Add((Keys)MyKeyboardHookStruct.vkCode);
//Code for coloring Key in the UI for pressed Key
}
return CallNextHookEx(hHook, nCode, wParam, lParam);
}
}
}
I need to know when the enter key is pressed on a specific textbox in another application. I'm able to find the textbox and write/read text from it using the user32.dll. But how do I get one specific key?
The application is just a chat. The goal is to when I type on this application textbox something like '/time' and hit enter I want my application to read this command and output the current time, for exemple.
Here is the code I have to retrieve the handle of the application and its textfield child and writing/reading it.
[DllImport("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, int uMsg, IntPtr wParam, string lParam);
[DllImport("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, int msg, int Param, System.Text.StringBuilder text);
[DllImport("user32.dll")]
private static extern IntPtr PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
public delegate bool Win32Callback(IntPtr hwnd, IntPtr lParam);
[DllImport("user32.Dll")]
public static extern bool EnumChildWindows(IntPtr parentHandle, Win32Callback callback, IntPtr lParam);
[DllImport("user32.dll")]
static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
[DllImport("user32.dll")]
public static extern IntPtr FindWindow(string strClassName, string strWindowName);
private IntPtr handle = IntPtr.Zero;
private string childClassName = "TComboEdit";
public bool findChildHandle(IntPtr hwnd, IntPtr lParam)
{
StringBuilder className = new StringBuilder();
GetClassName(hwnd, className, 120);
if (className.ToString() == childClassName)
{
handle = hwnd;
return false;
}
return true;
}
private void findControl(string className, string title)
{
IntPtr application = IntPtr.Zero;
application = FindWindow(className, title);
if (application == IntPtr.Zero)
MessageBox.Show("Aplicativo não encontrado");
else
EnumChildWindows(application, findChildHandle, IntPtr.Zero);
}
private void setTextToHandle(string msg)
{
SendMessage(handle, 0x000c, IntPtr.Zero, msg); //set text
PostMessage(handle, 0x0100, new IntPtr(0x0D), IntPtr.Zero); // key down (enter)
}
private void getTextFromHandle()
{
StringBuilder t = new StringBuilder();
SendMessage(handle, 0x0D, 100, t); //get text
MessageBox.Show(t.ToString());
}