Control the application using C# application - c#

i want to clicked the save button of another application from my c# application.if there is data in that application then save dialogbox will appear while in absence of data message box will appear.After i want to give the filename as date and time similarly i want to click the ok button for messagebox.
i did it using 3 button save,enter filename button and ok button but the problem is when i clicked the save button window is changed to either save dialogbox or message box after that my c# application freezed. if i restart c# application it will work.how to solve this?
if possible i want to do it using single button.
private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll")]static public extern bool GetWindowRect(IntPtr hWnd, out Rectangle lpRect);
[DllImport("user32.dll")]
private static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpClassName, string lpWindowName);
[DllImport("user32.dll")]
private static extern int SendMessage(IntPtr hWnd, int wMsg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll")]
private static extern int SendNotifyMessage(IntPtr hWnd, int wMsg, IntPtr wParam, IntPtr lParam);
[DllImport("User32.dll", CharSet = CharSet.Auto)]
private static extern int SetForegroundWindow(IntPtr points);
[DllImport("user32.dll")]
private static extern bool PostMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
//save button
private void saveBtn_Click(object sender, EventArgs e)
{
IntPtr maindHwnd = FindWindow(null, "app1");
IntPtr maindHwnd1 = FindWindow(null, "Error");
if (maindHwnd != IntPtr.Zero)
{
IntPtr panel = FindWindowEx(maindHwnd, IntPtr.Zero, "MDIClient", null);
IntPtr panel1 = FindWindowEx(panel, IntPtr.Zero, "TAveForm", null);
IntPtr panel2 = FindWindowEx(panel1, IntPtr.Zero, "TPanel", "Panel5");
IntPtr panel3 = FindWindowEx(panel2, IntPtr.Zero, "TPanel", null);
IntPtr childHwnd = FindWindowEx(panel3, IntPtr.Zero, "TBitBtn", "Save");
if (childHwnd != IntPtr.Zero)
{
SendMessage(childHwnd, BM_CLICK, IntPtr.Zero, IntPtr.Zero);
}
}
}
//click messagebox
private void button4_Click(object sender, EventArgs e)
{
IntPtr hWnd = FindWindow(null, "Error");
if (hWnd != IntPtr.Zero)
{
IntPtr childHwnd = FindWindowEx(hWnd, IntPtr.Zero, "Button", "Ok");
if (childHwnd != IntPtr.Zero)
{
SendMessage(childHwnd, BM_CLICK, IntPtr.Zero, IntPtr.Zero);
}
else
{
textBox3.BackColor = Color.Yellow;
textBox3.Text = "error;
}
}
else
{
textBox3.BackColor = Color.Yellow;
textBox3.Text = "hmd is zero";
}
}
//save dialogbox
String textBox = DateTime.Now.ToString("yyyyMMdd_HH-mm-ss");
IntPtr maindHwnd = FindWindow(null, "save");
IntPtr hWnd = FindWindow(null, "Error");
if (maindHwnd != IntPtr.Zero)
{
{
IntPtr panel = FindWindowEx(maindHwnd, IntPtr.Zero, "ComboBoxEx32", null);
IntPtr panel1 = FindWindowEx(panel, IntPtr.Zero, "ComboBox", null);
IntPtr panel2 = FindWindowEx(panel1, IntPtr.Zero, "Edit", null);
if (panel2 != IntPtr.Zero)
{
SendKeys.Send(textBox);
}
} ```

IMHO the easiest way is to first, find out the target application Window Handle and target application's process ID.
Then you can interrupt with it's child objects.
Example:
public static void chooseMode(IntPtr hnd, int PID)
{
if (hnd != IntPtr.Zero)
{
var proc = Process.GetProcessById(PID);
proc.WaitForInputIdle();
SetForegroundWindow(hnd);
SendKeys.SendWait(#"%V {UP 3} ~");
}
}

Related

How to Clicked ok button of messagebox pops up on click the xyz application from my c# application

i am trying to click the ok button of messagebox pops up when i click the button of xyz application from my c# application. i have tried the following code so that the button of xyz is clicked but C# application freeze after pops up message box is appeared.
i have created two button
button1- to click the button of xyz application
button2- to click the ok button of message box.
//button1 code
IntPtr maindHwnd = FindWindow(null,"xyz application");
if (maindHwnd != IntPtr.Zero)
{
IntPtr panel = FindWindowEx(maindHwnd, IntPtr.Zero, "MDIClient", null);
IntPtr panel1 = FindWindowEx(panel, IntPtr.Zero, "TAveForm", null);
IntPtr panel2 = FindWindowEx(panel1, IntPtr.Zero, "TPanel", "Panel5");
IntPtr panel3 = FindWindowEx(panel2, IntPtr.Zero, "TPanel", null);
IntPtr childHwnd = FindWindowEx(panel3, IntPtr.Zero, "TBitBtn", "Save");
if (childHwnd != IntPtr.Zero)
{
SendMessage(childHwnd, BM_CLICK, IntPtr.Zero, IntPtr.Zero);
}
}
//button2 code
IntPtr hWnd = FindWindow(null, "Error");
if (hWnd != IntPtr.Zero)
{
IntPtr childHwnd = FindWindowEx(hWnd, IntPtr.Zero, "Button", "Ok");
if (childHwnd != IntPtr.Zero)
{
SendMessage(childHwnd, BM_CLICK, IntPtr.Zero, IntPtr.Zero);
}
}
You can try this;
[DllImport("user32.dll", SetLastError = true)]
static public extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll")]
static public extern bool GetWindowRect(IntPtr hWnd, out Rectangle lpRect);
var hwnd = FindWindow(null, "WindowTitle");
if (hwnd != IntPtr.Zero)
{
if (GetWindowRect(hwnd, out Rectangle rect))
{
// rect..
}
}
You can use pinvoke.net for signature differences.

click button on a dialog opened by p/invoke

This code opens a Dialog by clicking a Button on a Form
IntPtr m = FindWindow("TForm1", "Smart Design");
IntPtr b = FindWindowEx(m, IntPtr.Zero, "TButton", "Update List");
SendMessage(b, BM_CLICK, 0, 0);
How to click OK button on the opened dialog?
I tried this code but it fails:
IntPtr d = FindWindow("TDialog4", "Information");
IntPtr k = FindWindowEx(d, IntPtr.Zero, "TButton7", "OK");
SendMessage(k, BM_CLICK, 0, 0);
I'd try sending the dialog a WM_COMMAND instead.
private const uint WM_COMMAND = 0x0111;
private const int BM_CLICKED = 245;
[DllImport("user32.dll", CharSet=CharSet.Auto)]
public static extern int SendMessage(IntPtr hWnd, uint msg,
int wParam, IntPtr lParam);
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr FindWindowEx(IntPtr parentHandle,
IntPtr childAfter, string className, string windowTitle);
SendMessage(k, WM_COMMAND, (BM_CLICKED << 16) | 1, k);

Click A MessageBox button programmatically

As the title suggests, I'm trying to simulate a button-click in a MessageBox programmatically. I earlier tried to close the MessageBox by finding its handle via its caption, and applying WM_CLOSE or SC_CLOSE in SendMessage(). However, due to the presence of Yes/No buttons, that did not work (the X button is grayed out).
Now I'm trying to click the No button as follows -:
List<IntPtr> result = new List<IntPtr>();
GCHandle listHandle = GCHandle.Alloc(result);
try
{
IntPtr Window_hWnd = CloseMessageBox.FindWindowByCaption("#32770", "LastQuestion"); //Could use null as the first argument too. "#32770" represents classname Dialog.
CloseMessageBox.EnumChildWindows(Window_hWnd, (hWnd, lParam) =>
{
StringBuilder sb = new StringBuilder();
foreach (var control in GCHandle.FromIntPtr(lParam).Target as List<IntPtr>)
{
CloseMessageBox.GetWindowText(control, sb, 250);
if (sb.Equals("&No"))
{
CloseMessageBox.PostMessage(hWnd, CloseMessageBox.MouseDown, 0, 0);
CloseMessageBox.PostMessage(hWnd, CloseMessageBox.MouseUp, 0, 0);
}
}
return false;
}, GCHandle.ToIntPtr(listHandle));
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
}
finally
{
if (listHandle.IsAllocated)
listHandle.Free();
}
Having come this far on the advice of someone from IRC, I find that a few edits earlier, I was getting the button handle (only the "&Yes" button) but not all of them. He then suggested this approach, but the control List is not populated and hence it never goes inside the foreach. What do I do to remedy this?
Here you go.
// A delegate which is used by EnumChildWindows to execute a callback method.
public delegate bool EnumWindowProc(IntPtr hWnd, IntPtr parameter);
// This method accepts a string which represents the title name of the window you're looking for the controls on.
public static void ClickButtonLabeledNo(string windowTitle)
{
try
{
// Find the main window's handle by the title.
var windowHWnd = FindWindowByCaption(IntPtr.Zero, windowTitle);
// Loop though the child windows, and execute the EnumChildWindowsCallback method
EnumChildWindows(windowHWnd, EnumChildWindowsCallback, IntPtr.Zero);
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
}
}
private static bool EnumChildWindowsCallback(IntPtr handle, IntPtr pointer)
{
const uint WM_LBUTTONDOWN = 0x0201;
const uint WM_LBUTTONUP = 0x0202;
var sb = new StringBuilder(256);
// Get the control's text.
GetWindowCaption(handle, sb, 256);
var text = sb.ToString();
// If the text on the control == &No send a left mouse click to the handle.
if (text == #"&No")
{
PostMessage(handle, WM_LBUTTONDOWN, IntPtr.Zero, IntPtr.Zero);
PostMessage(handle, WM_LBUTTONUP, IntPtr.Zero, IntPtr.Zero);
}
return true;
}
[DllImport("user32")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool EnumChildWindows(IntPtr window, EnumWindowProc callback, IntPtr i);
[DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
private static extern IntPtr FindWindowByCaption(IntPtr ZeroOnly, string lpWindowName);
[DllImport("user32.dll", EntryPoint = "GetWindowText", CharSet = CharSet.Auto)]
private static extern IntPtr GetWindowCaption(IntPtr hwnd, StringBuilder lpString, int maxCount);
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("user32.dll", SetLastError = true)]
private static extern bool PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);

How to handle Message Boxes while using webbrowser in C#?

I'm using this webbrowswer feature of C#. Trying to log in a website through my application. Everything goes fine, except when a wrong ID or password is entered there's little message box (that is set on the webpage itself) which pops up and blocks everything until "Ok" is clicked.
So the question is: Is there any possible way to manage this little window (like reading the text inside of it)? If it is then great!
But if there's no way to do that then is there anyway to simply make this message box go away programatically?
You can "manage" the message box dialog by importing some window functions from user32.dll and getting the messagebox dialog's handle by it's class name and window name. For example to click its OK button:
public class Foo
{
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
[DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
private 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);
private void ClickOKButton()
{
IntPtr hwnd = FindWindow("#32770", "Message from webpage");
hwnd = FindWindowEx(hwnd, IntPtr.Zero, "Button", "OK");
uint message = 0xf5;
SendMessage(hwnd, message, IntPtr.Zero, IntPtr.Zero);
}
}
Some reading material from MSDN.
Copy paste from Sires anwser: https://stackoverflow.com/a/251524/954225
private void InjectAlertBlocker() {
HtmlElement head = webBrowser1.Document.GetElementsByTagName("head")[0];
HtmlElement scriptEl = webBrowser1.Document.CreateElement("script");
IHTMLScriptElement element = (IHTMLScriptElement)scriptEl.DomElement;
string alertBlocker = "window.alert = function () { }";
element.text = alertBlocker;
head.AppendChild(scriptEl);
}
here is refined version of Saeb's answer. Saeb's code was not working for me, I added one more step to activate the button and then clicking on it.
using System;
using System.Runtime.InteropServices;
namespace IE_Automation
{
public class IEPoppupWindowClicker
{
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
[DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, int wParam, int lParam);
private const int BM_CLICK = 0xF5;
private const uint WM_ACTIVATE = 0x6;
private const int WA_ACTIVE = 1;
public void ActivateAndClickOkButton()
{
// find dialog window with titlebar text of "Message from webpage"
var hwnd = FindWindow("#32770", "Message from webpage");
if (hwnd != IntPtr.Zero)
{
// find button on dialog window: classname = "Button", text = "OK"
var btn = FindWindowEx(hwnd, IntPtr.Zero, "Button", "OK");
if (btn != IntPtr.Zero)
{
// activate the button on dialog first or it may not acknowledge a click msg on first try
SendMessage(btn, WM_ACTIVATE, WA_ACTIVE, 0);
// send button a click message
SendMessage(btn, BM_CLICK, 0, 0);
}
else
{
//Interaction.MsgBox("button not found!");
}
}
else
{
//Interaction.MsgBox("window not found!");
}
}
}
}

Using WM_Close in c#

I am using the below code to close the window, by searching the window name in taskbar.
But i one case, my window will not appear in the taskbar. In that case, WM_Close could not close the window. Whats the other way to do it using WM_Close ???
void DaemonTerminamtionHook_KeyPressed(object sender, KeyPressedEventArgs e)
{
DaemonResult = MessageBox.Show("Are you sure, you want to Terminate Daemon?", "Terminate Daemon", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation);
if (DaemonResult == DialogResult.Yes)
{
//Free the resources of ShellBasics and terminate Daemon here.
IntPtr hWnd = FindWindowByCaption(IntPtr.Zero, "DAEMON TAB BAR");
bool ret = CloseWindow(hWnd);
}
}
//WM_Close
[DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
static extern IntPtr FindWindowByCaption(IntPtr ZeroOnly, string lpWindowName);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
static uint WM_CLOSE = 0x10;
static bool CloseWindow(IntPtr hWnd)
{
SendMessage(hWnd, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
return true;
}
Now using the below code...But getting error in
"IntPtr hWnd = PostMessage(IntPtr.Zero, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);"
where to provide the window name in order to close that ???
void DaemonTerminamtionHook_KeyPressed(object sender, KeyPressedEventArgs e)
{
DaemonResult = MessageBox.Show("Are you sure, you want to Terminate Daemon?", "Terminate Daemon", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation);
if (DaemonResult == DialogResult.Yes)
{
IntPtr hWnd = PostMessage(IntPtr.Zero, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
bool ret = CloseWindow(hWnd);
}
}
static uint WM_CLOSE = 0x10;
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("user32.dll", SetLastError = true)]
static extern bool PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
static bool CloseWindow(IntPtr hWnd)
{
bool returnValue = PostMessage(hWnd, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
if (!returnValue)
throw new Win32Exception(Marshal.GetLastWin32Error());
return true;
}
Edit: Sorry misread your question.
Use FindWindow/FindWindowEx instead.

Categories

Resources