Give a windows handle (Native), how to close the windows using C#? - c#

Given a handle of a window, how can I close the window by using the window handle?

The easiest way is to use PInvoke and do a SendMessage with WM_CLOSE.
[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
private const UInt32 WM_CLOSE = 0x0010;
void CloseWindow(IntPtr hwnd) {
SendMessage(hwnd, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
}

Not sure if there is another way but you could PInvoke the following:
// close the window using API
SendMessage(iHandle, WM_SYSCOMMAND, SC_CLOSE, 0);

Call CloseWindow via P/Invoke:
http://www.pinvoke.net/default.aspx/user32.closewindow
Or DestroyWindow
http://www.pinvoke.net/default.aspx/user32/DestroyWindow.html

Related

Sending a string of characters as a keystroke to any application in WPF [duplicate]

I want to simulate F5 key press in my C# program. When IE is open, I want to be able refresh my website automatically.
How can I do that?
Here's an example...
static class Program
{
[DllImport("user32.dll")]
public static extern int SetForegroundWindow(IntPtr hWnd);
[STAThread]
static void Main()
{
while(true)
{
Process [] processes = Process.GetProcessesByName("iexplore");
foreach(Process proc in processes)
{
SetForegroundWindow(proc.MainWindowHandle);
SendKeys.SendWait("{F5}");
}
Thread.Sleep(5000);
}
}
}
a better one... less anoying...
static class Program
{
const UInt32 WM_KEYDOWN = 0x0100;
const int VK_F5 = 0x74;
[DllImport("user32.dll")]
static extern bool PostMessage(IntPtr hWnd, UInt32 Msg, int wParam, int lParam);
[STAThread]
static void Main()
{
while(true)
{
Process [] processes = Process.GetProcessesByName("iexplore");
foreach(Process proc in processes)
PostMessage(proc.MainWindowHandle, WM_KEYDOWN, VK_F5, 0);
Thread.Sleep(5000);
}
}
}
You can use the Win32 API FindWindow or FindWindowEx to find the window handle of the open browser and then just call SendMessage with WM_KEYDOWN. Typically it's easiest just to pass the window caption to FindWindowEx and have it find the associated window handle for you.
If you are starting the browser process yourself via a Process process object then you can use process.MainWindowHandle instead of calling FindWindowEx.
Spy++ is a very useful tool when you want to start working with other windows. It basically allows you to learn another program's hierarchy of UI elements. You can also monitor all of the messages that go into the window you're monitoring. I have more info in this thread.
The F5 keystroke has this virtual key code:
const int VK_F5 = 0x74;
The p/invoke signature for FindWindowEx in C# is:
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
You can p/invoke (bring in) the Win32 API SendMessage like this:
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
So to recap, you call FindWindowEx directly from your C# code after having the above code somewhere inside your class. FindWindowEx will return a window handle. Then once you have the window handle, you can send any keystroke(s) to the window, or call many other Win32 API calls on the window handle. Or even find a child window by using another call to FindWindowEx. For example you could select the edit control of the browser even and then change it's text.
If all else goes wrong and you think you're sending the right key to the window, you can use spy++ to see what messages are sent to the window when you manually set focus to the browser and manually press F5.
The easiest way to send (simulate) KeyStrokes to any window is to use the SendKeys.Send method of .NET Framework.
Checkout this very intuitive MSDN article http://msdn.microsoft.com/en-us/library/system.windows.forms.sendkeys.aspx
Particularly for your case, if your browser window is in focus, sending F5 would just involve the following line of code:
SendKeys.Send("{F5}");
Simple one, add before Main
[DllImport("USER32.DLL", CharSet = CharSet.Unicode)]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("USER32.DLL")]
public static extern bool SetForegroundWindow(IntPtr hWnd);
Code inside Main/Method:
string className = "IEFrame";
string windowName = "New Tab - Windows Internet Explorer";
IntPtr IE = FindWindow(className, windowName);
if (IE == IntPtr.Zero)
{
return;
}
SetForegroundWindow(IE);
InputSimulator.SimulateKeyPress(VirtualKeyCode.F5);
Note:
Add InputSimulator as reference. To download Click here
To find Class & Window name, use WinSpy++. To download Click here
Another alternative to simulating a F5 key press would be to simply host the WebBrowser control in the Window Forms application. You use the WebBrowser.Navigate method to load your web page and then use a standard Timer and on each tick of the timer you just re-Navigate to the url which will reload the page.
Easy, short and no need window focus:
Also here a usefull list of Virtual Key Codes
[DllImport("user32.dll")]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll")]
static extern bool PostMessage(IntPtr hWnd, UInt32 Msg, int wParam, int lParam);
private void button1_Click(object sender, EventArgs e)
{
const int WM_SYSKEYDOWN = 0x0104;
const int VK_F5 = 0x74;
IntPtr WindowToFind = FindWindow(null, "Google - Mozilla Firefox");
PostMessage(WindowToFind, WM_SYSKEYDOWN, VK_F5, 0);
}
Use mouse_event or keybd_event. They say not to use them anymore but you don't have to find the window at all.
using System;
using System.Runtime.InteropServices;
public class SimulatePCControl
{
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern void keybd_event(uint bVk, uint bScan, uint dwFlags, uint dwExtraInfo);
private const int VK_LEFT = 0x25;
public static void LeftArrow()
{
keybd_event(VK_LEFT, 0, 0, 0);
}
}
Virtual Key Codes are here for this one: http://www.kbdedit.com/manual/low_level_vk_list.html
Also for mouse:
using System.Runtime.InteropServices;
using UnityEngine;
public class SimulateMouseClick
{
[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);
//Mouse actions
private const int MOUSEEVENTF_LEFTDOWN = 0x02;
private const int MOUSEEVENTF_LEFTUP = 0x04;
private const int MOUSEEVENTF_RIGHTDOWN = 0x08;
private const int MOUSEEVENTF_RIGHTUP = 0x10;
public static void Click()
{
//Call the imported function with the cursor's current position
uint X = (uint)0;
uint Y = (uint)0;
mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, X, Y, 0, 0);
Debug.LogError("SIMULATED A MOUSE CLICK JUST NOW...");
}
//...other code needed for the application
}
Instead of forcing an F5 keypress when you're just trying to get the page to postback, you can call a postback based on a JS event (even mousemove or timer_tick if you want it to fire all the time). Use the code at http://weblogs.asp.net/mnolton/archive/2003/06/04/8260.aspx as a reference.

Closing a child window forcefully using window title

I want to close a child window of a running application programmatically. I am using the following code:
const UInt32 WM_CLOSE = 0x0010;
[DllImport("USER32.DLL", CharSet = CharSet.Unicode)]
public static extern IntPtr FindWindow(String lpClassName, String lpWindowName);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
public static bool CloseWindowbyTitle(string titleStr)
{
bool result = false;
IntPtr windowPtr = FindWindow(null, titleStr);
if (windowPtr == IntPtr.Zero)
return result;
SendMessage(windowPtr, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
result = true;
return result;
}
It is working fine. But when the child window is in edit mode, it asks to the user to save edited data and if the user clicks on 'Yes' or 'No' then only child window gets closed.
But I want to close the child window forcefully, so that without asking anything it should get closed. But I don't know how to achieve this.
I can't use Process class to kill child windows as no separate process is getting created for that child window.
Thanks in advance.

Get Active Window of .net application

I have an application named ProLaunch.exe. I want to get the active window in it and close it if the user is not performing any operation for the speicified period. A timer in the application will be used for this purpose.
How can I get the active window and close it?
If I understand the question correctly, you can use the Win32 API GetActiveWindow for this. This should work in both Forms and WPF apps.
[DllImport("user32.dll")]
static extern IntPtr GetActiveWindow();
[DllImport("user32.dll")]
public static extern int SendMessage(int hWnd, IntPtr msg, int wParam, int lParam);
public const int WM_SYSCOMMAND = 0x0112;
public const int SC_CLOSE = 0xF060;
// close the active window using API
private void FindAndCloseActiveWindow()
{
IntPtr handle=GetActiveWindow();
SendMessage(handle, WM_SYSCOMMAND, SC_CLOSE, 0);
}
Try
Form.ActiveForm
http://msdn.microsoft.com/de-de/library/system.windows.forms.form.activeform.aspx

Managed analogue for SendMessage API function or How to send a message to window from C#?

I want to send a window message from one application (console) to the wondow of another application. I can use WinAPI functions SendMessage or PostMessage, but may be there is managed way to do it?
There is no managed alternative to that but you can easily P/Invoke with:
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
private void button1_Click(object sender, EventArgs e)
{
SendMessage(this.Handle, COMMAND_HERE, PARAM_HERE, 0);
}

Scrolling textboxes programmatically using WndProc messages

I'm trying to scroll a textbox using the form's WndProc method. The code I've come up with so far, after scouring the internet, looks like this:
private void ScrollTextBox()
{
scrollMessage = Message.Create(TabContents.Handle, 0x00B6, new IntPtr(0x0003), new IntPtr(0x0000));
this.WndProc(ref scrollMessage);
}
where TabContents is a TextBox.
For some reason, nothing happens when i call this method. I'd like to know why. I realise that i can accomplish the same with the MoveToCaret method, but I'm curious why this is not working.
EDIT:
As in the posted answer from Beaner, I wrote another method using SendMessage:
[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp);
private void ScrollTextBox2(int lines)
{
SendMessage(TabContents.Handle, 0x00B6, new IntPtr(0), new IntPtr(lines));
}
This seems to work %100. I'm still curious why this.WndProc(ref message) doesn't work, given a message created with the same set of parameters.
This may be possible, but I have never tried it that way. I have used SendMessage to send a windows message directly to the textbox to cause scrolling.
private const int WM_VSCROLL = 0x115;
private const int SB_BOTTOM = 7;
[DllImport("user32.dll", CharSet=CharSet.Auto)]
private static extern int SendMessage(IntPtr hWnd, int wMsg, IntPtr wParam,
IntPtr lParam);
// Scroll to the bottom, but don't move the caret position.
SendMessage(TabContents.Handle, WM_VSCROLL, (IntPtr) SB_BOTTOM, IntPtr.Zero);

Categories

Resources