This Q&A refers to and can be used for foll. purposes:
- Send message from IE browser to vb6 app via ActiveX dll
- Send message from ActiveX dll to vb6 app
- Send message from C#.net (dll) to vb6 app
I have read this article but doesn't seem to be very clear for my purpose...
I have also referred to this article to create ActiveX object and have implemented an ActiveX dll that I am calling from browser to launch an application on client side.. The dll checks whether the VB6 exe (process) is running, else runs the exe. If the exe is already running then I want to pass a parameter/message to the exe application.
But I am not able to get a solution or reference samples to implement a way to send message from this C#.NET assembly (ActiveX) to an VB6 application... I do have access to source codes of the .NET and VB6 application...
I have tried using:-
Process[] processes = Process.GetProcessesByName("MyProgram");
foreach (Process p in processes)
{
IntPtr pFoundWindow = p.MainWindowHandle;
// how do I pass a value to MyProgram.exe ?
//
}
I have also tried this: using help from following links, however this is not exactly the solution I am looking for!:- e[C#] Reading/Writing textbox on other program This code has been implemented on my activeX DLL which launches a VB6 App.. I am checking via .NET (process) whether the exe is running and if not, then launching it. If the exe is running then I am using the above article code example to send a message to the vb6 application by setting a control (textbox in mycase)... Very helpfull code.. Following code copied from:- c# reading & writing textbox on other program
public class ExternalWriter
{
[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string className, string lpszWindow);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
private static extern int SendMessage(IntPtr hWnd, uint msg, IntPtr wParam, string lParam);
private const int WM_SETTEXT = 12;
public void DoExternalWrite(string text)
{
IntPtr parent = FindWindow("<window class name>", "<window title">);
IntPtr child = GetchildHandle(parent, "<class name>");
SendMessage(child, WM_SETTEXT, IntPtr.Zero, text);
}
private IntPtr GetChildHandle(IntPtr parent, string className)
{
/* Here you need to perform some sort of function to obtain the child window handle, perhaps recursively
*/
IntPtr child = FindWindowEx(parent, IntPtr.Zero, className, null);
child = FindWnidowEx(parent, child, className, null);
/* You can use a tool like Spy++ to discover the hierachy on the Remedy 7 form, to find how many levels you need to search
* to get to the textbox you want */
return child;
}
}
There is one more example in stack overflow, however it is to read data from another application into the .NET (not usefull for my requirement).. However, I am putting it down into this answer so that someone who may want to read from an app as well as write to an app will find solution here.. Following code obtained from:- stack overflow
public class GetWindowTextExample
{
// Example usage.
public static void Main()
{
var allText = GetAllTextFromWindowByTitle("Untitled - Notepad");
Console.WriteLine(allText);
Console.ReadLine();
}
// Delegate we use to call methods when enumerating child windows.
private delegate bool EnumWindowProc(IntPtr hWnd, IntPtr parameter);
[DllImport("user32")]
[return: MarshalAs(UnmanagedType.Bool)]
private 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", CharSet = CharSet.Auto)]
private static extern IntPtr SendMessage(IntPtr hWnd, uint msg, IntPtr wParam, [Out] StringBuilder lParam);
// Callback method used to collect a list of child windows we need to capture text from.
private static bool EnumChildWindowsCallback(IntPtr handle, IntPtr pointer)
{
// Creates a managed GCHandle object from the pointer representing a handle to the list created in GetChildWindows.
var gcHandle = GCHandle.FromIntPtr(pointer);
// Casts the handle back back to a List<IntPtr>
var list = gcHandle.Target as List<IntPtr>;
if (list == null)
{
throw new InvalidCastException("GCHandle Target could not be cast as List<IntPtr>");
}
// Adds the handle to the list.
list.Add(handle);
return true;
}
// Returns an IEnumerable<IntPtr> containing the handles of all child windows of the parent window.
private static IEnumerable<IntPtr> GetChildWindows(IntPtr parent)
{
// Create list to store child window handles.
var result = new List<IntPtr>();
// Allocate list handle to pass to EnumChildWindows.
var listHandle = GCHandle.Alloc(result);
try
{
// Enumerates though all the child windows of the parent represented by IntPtr parent, executing EnumChildWindowsCallback for each.
EnumChildWindows(parent, EnumChildWindowsCallback, GCHandle.ToIntPtr(listHandle));
}
finally
{
// Free the list handle.
if (listHandle.IsAllocated)
listHandle.Free();
}
// Return the list of child window handles.
return result;
}
// Gets text text from a control by it's handle.
private static string GetText(IntPtr handle)
{
const uint WM_GETTEXTLENGTH = 0x000E;
const uint WM_GETTEXT = 0x000D;
// Gets the text length.
var length = (int)SendMessage(handle, WM_GETTEXTLENGTH, IntPtr.Zero, null);
// Init the string builder to hold the text.
var sb = new StringBuilder(length + 1);
// Writes the text from the handle into the StringBuilder
SendMessage(handle, WM_GETTEXT, (IntPtr)sb.Capacity, sb);
// Return the text as a string.
return sb.ToString();
}
// Wraps everything together. Will accept a window title and return all text in the window that matches that window title.
private static string GetAllTextFromWindowByTitle(string windowTitle)
{
var sb = new StringBuilder();
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
var childWindows = GetChildWindows(windowHWnd);
// For each child handle, run GetText
foreach (var childWindowText in childWindows.Select(GetText))
{
// Append the text to the string builder.
sb.Append(childWindowText);
}
// Return the windows full text.
return sb.ToString();
}
catch (Exception e)
{
Console.Write(e.Message);
}
return string.Empty;
}
}