How i can find all the windows created by a particular process using c#?
UPDATE
i need enumerate all the windows belonging to an particular process using the PID (process ID) of the an application.
delegate bool EnumThreadDelegate(IntPtr hWnd, IntPtr lParam);
[DllImport("user32.dll")]
static extern bool EnumThreadWindows(int dwThreadId, EnumThreadDelegate lpfn,
IntPtr lParam);
static IEnumerable<IntPtr> EnumerateProcessWindowHandles(int processId)
{
var handles = new List<IntPtr>();
foreach (ProcessThread thread in Process.GetProcessById(processId).Threads)
EnumThreadWindows(thread.Id,
(hWnd, lParam) => { handles.Add(hWnd); return true; }, IntPtr.Zero);
return handles;
}
and sample usage:
private const uint WM_GETTEXT = 0x000D;
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, int wParam,
StringBuilder lParam);
[STAThread]
static void Main(string[] args)
{
foreach (var handle in EnumerateProcessWindowHandles(
Process.GetProcessesByName("explorer").First().Id))
{
StringBuilder message = new StringBuilder(1000);
SendMessage(handle, WM_GETTEXT, message.Capacity, message);
Console.WriteLine(message);
}
}
Use the Win32 API EnumWindows (if you want child windows EnumChildWindows)), or alternatively you can use EnumThreadWindows .
[DllImport("user32.dll", CharSet=CharSet.Auto, SetLastError=true)]
public static extern bool EnumWindows(EnumThreadWindowsCallback callback, IntPtr extraData);
Then check which process each window belongs to by using the Win32 API GetWindowThreadProcessId
[DllImport("user32.dll", CharSet=CharSet.Auto, SetLastError=true)]
public static extern int GetWindowThreadProcessId(HandleRef handle, out int processId);
Ancient thread, but it got me started so here's a small utility function that will find a child window that matches a lambda (Predicate). Be easy to change to return a list. Multiple criteria are handled in the predicate.
public delegate bool Win32Callback(IntPtr hwnd, IntPtr lParam);
[DllImport("user32.Dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool EnumChildWindows(IntPtr parentHandle, Win32Callback callback, IntPtr lParam);
/// <summary>
/// Find a child window that matches a set of conditions specified as a Predicate that receives hWnd. Returns IntPtr.Zero
/// if the target window not found. Typical search criteria would be some combination of window attributes such as
/// ClassName, Title, etc., all of which can be obtained using API functions you will find on pinvoke.net
/// </summary>
/// <remarks>
/// <para>Example: Find a window with specific title (use Regex.IsMatch for more sophisticated search)</para>
/// <code lang="C#"><![CDATA[var foundHandle = Win32.FindWindow(IntPtr.Zero, ptr => Win32.GetWindowText(ptr) == "Dashboard");]]></code>
/// </remarks>
/// <param name="parentHandle">Handle to window at the start of the chain. Passing IntPtr.Zero gives you the top level
/// window for the current process. To get windows for other processes, do something similar for the FindWindow
/// API.</param>
/// <param name="target">Predicate that takes an hWnd as an IntPtr parameter, and returns True if the window matches. The
/// first match is returned, and no further windows are scanned.</param>
/// <returns> hWnd of the first found window, or IntPtr.Zero on failure </returns>
public static IntPtr FindWindow(IntPtr parentHandle, Predicate<IntPtr> target) {
var result = IntPtr.Zero;
if (parentHandle == IntPtr.Zero)
parentHandle = Process.GetCurrentProcess().MainWindowHandle;
EnumChildWindows(parentHandle, (hwnd, param) => {
if (target(hwnd)) {
result = hwnd;
return false;
}
return true;
}, IntPtr.Zero);
return result;
}
Example
var foundHandle = Win32.FindWindow(IntPtr.Zero, ptr => Win32.GetWindowText(ptr) == "Dashboard");
Related
I am developing a window application to read text which is typed on any application on screen by C#.
Which I used is Win32 API like following - a solution I found on Google:
private const int WM_GETTEXTLENGTH = 0x000E;
private const int WM_GETTEXT = 0x000D;
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
[DllImport("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, int msg, int wParam, StringBuilder lParam);
[DllImport("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, int msg, int wParam, int lParam);
[DllImport("user32.dll")]
public static extern IntPtr GetForegroundWindow();
public Terminal()
{
InitializeComponent();
IntPtr pFoundWindow = GetForegroundWindow();
IntPtr notepad = FindWindow("notepad", null);
IntPtr editx = FindWindowEx(notepad, IntPtr.Zero, "edit", null);
int length = SendMessage(editx, WM_GETTEXTLENGTH, 0, 0);
StringBuilder text = new StringBuilder(length);
int hr = SendMessage(editx, WM_GETTEXT, length, text);
Console.WriteLine(text);
}
But this only read existed text from Notepad.
How should I do to read text when typing on any programs, any windows?
The following codes in your sample
IntPtr notepad = FindWindow("notepad", null);
It means to get the handle of a process which's name is notepad.
And the following one
IntPtr editx = FindWindowEx(notepad, IntPtr.Zero, "edit", null);
Also means you try to find a window handle from notepad, and window title is edit. The edit window is the editable area of notepad.
If you are going to make your application suitable for any process, you can not declare your target is source code. In other word, you need another way to specify a window you want to get text.
My suggestion is: You need the following Windows APIs to get target window in run-time.
For example, you can use SetWindowsHookEx to get a mouse event outside your application, and then it will trigger a callback when user click to a target window. Next, the callback function is triggered, you can use GetCursorPos to get the mouse position, and use WindowFromPoint to get the window which you want to read its text.
UPDATE
I provide my sample code from my other project, and pick up some useful part for you.
/// <summary>
/// A hook handle for grabbing mouse click, used to get the position of target window.
/// </summary>
private IntPtr _hook = IntPtr.Zero;
//button click event
private void selectWindow_Click(object sender, EventArgs e)
{
if (_hook != IntPtr.Zero)
return;
using (Process p = Process.GetCurrentProcess())
{
using (ProcessModule m = p.MainModule)
{
_hook = SafeNativeMethods.SetWindowsHookEx(SafeNativeMethods.WH_MOUSE_LL, hookCallback, SafeNativeMethods.GetModuleHandle(m.ModuleName), 0);
}
}
}
/// <summary>
/// Callback method of mouse hook.
/// </summary>
private IntPtr hookCallback(int code, IntPtr w, IntPtr l)
{
if (code >= 0 && (WMessages)w == WMessages.WM_LBUTTONDOWN)
{
CPoint pt;
SafeNativeMethods.GetCursorPos(out pt);
//hey man! the _windowHandle is what you need
_windowHandle = SafeNativeMethods.WindowFromPoint(pt);
SafeNativeMethods.UnhookWindowsHookEx(_hook);
_hook = IntPtr.Zero;
//...and do your stuff here!
}
return SafeNativeMethods.CallNextHookEx(_hook, code, w, l);
}
And the def. of Windows APIs
/// <summary>
/// Window Hook ID 14 - Low level mouse proc.
/// </summary>
internal const int WH_MOUSE_LL = 14;
/// <summary>
/// Get the window handle from a specified point.
/// </summary>
/// <param name="point">Specified point</param>
/// <returns>Window handle</returns>
[DllImport("user32.dll", SetLastError = true)]
internal static extern IntPtr WindowFromPoint(CPoint point);
/// <summary>
/// Register a hook.
/// </summary>
/// <param name="idHook">Hook type</param>
/// <param name="lpfn">Function pointer</param>
/// <param name="hMod">Module ID</param>
/// <param name="dwThreadId">Thread ID</param>
/// <returns>Hook handle</returns>
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
internal static extern IntPtr SetWindowsHookEx(int idHook, LowLevelMouseProc lpfn, IntPtr hMod, uint dwThreadId);
/// <summary>
/// Unregister a hook.
/// </summary>
/// <param name="hhk">Hook handle</param>
/// <returns>Successful</returns>
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool UnhookWindowsHookEx(IntPtr hhk);
/// <summary>
/// Call next hook (if needed).
/// </summary>
/// <param name="hhk">Hook handle</param>
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
internal static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
/// <summary>
/// Get moudle handle by module name.
/// </summary>
/// <param name="lpModuleName">Module name</param>
/// <returns>Module handle</returns>
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
internal static extern IntPtr GetModuleHandle(string lpModuleName);
/// <summary>
/// Get current cursor position.
/// </summary>
/// <param name="lpPoint">Output position</param>
/// <returns>Successful</returns>
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool GetCursorPos(out CPoint lpPoint);
UPDATE 2
I forgot the CPoint struct lol.
/// <summary>
/// Win32 POINT structure.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
internal struct CPoint
{
public int x;
public int y;
}
i am working on hide task bar of window this code working fine on visual studo 2010 but not working on IIS 7.5 and not give any error .Please tell me why this code not working on iis7.5 (window 7)
This is my code
public static class Taskbar
{
[DllImport("user32.dll")]
private static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern bool EnumThreadWindows(int threadId, EnumThreadProc pfnEnum, IntPtr lParam);
[DllImport("user32.dll", SetLastError = true)]
private static extern System.IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className, string windowTitle);
[DllImport("user32.dll")]
private static extern IntPtr FindWindowEx(IntPtr parentHwnd, IntPtr childAfterHwnd, IntPtr className, string windowText);
[DllImport("user32.dll")]
private static extern int ShowWindow(IntPtr hwnd, int nCmdShow);
[DllImport("user32.dll")]
private static extern uint GetWindowThreadProcessId(IntPtr hwnd, out int lpdwProcessId);
private const int SW_HIDE = 0;
private const int SW_SHOW = 5;
private const string VistaStartMenuCaption = "Start";
private static IntPtr vistaStartMenuWnd = IntPtr.Zero;
private delegate bool EnumThreadProc(IntPtr hwnd, IntPtr lParam);
/// <summary>
/// Show the taskbar.
/// </summary>
public static void Show()
{
SetVisibility(true);
}
/// <summary>
/// Hide the taskbar.
/// </summary>
public static void Hide()
{
SetVisibility(false);
}
/// <summary>
/// Sets the visibility of the taskbar.
/// </summary>
public static bool Visible
{
set { SetVisibility(value); }
}
/// <summary>
/// Hide or show the Windows taskbar and startmenu.
/// </summary>
/// <param name="show">true to show, false to hide</param>
private static void SetVisibility(bool show)
{
// get taskbar window
IntPtr taskBarWnd = FindWindow("Shell_TrayWnd", null);
// try it the WinXP way first...
IntPtr startWnd = FindWindowEx(taskBarWnd, IntPtr.Zero, "Button", "Start");
if (startWnd == IntPtr.Zero)
{
// try an alternate way, as mentioned on CodeProject by Earl Waylon Flinn
startWnd = FindWindowEx(IntPtr.Zero, IntPtr.Zero, (IntPtr)0xC017, "Start");
}
if (startWnd == IntPtr.Zero)
{
// ok, let's try the Vista easy way...
startWnd = FindWindow("Button", null);
if (startWnd == IntPtr.Zero)
{
// no chance, we need to to it the hard way...
startWnd = GetVistaStartMenuWnd(taskBarWnd);
}
}
ShowWindow(taskBarWnd, show ? SW_SHOW : SW_HIDE);
ShowWindow(startWnd, show ? SW_SHOW : SW_HIDE);
}
/// <summary>
/// Returns the window handle of the Vista start menu orb.
/// </summary>
/// <param name="taskBarWnd">windo handle of taskbar</param>
/// <returns>window handle of start menu</returns>
private static IntPtr GetVistaStartMenuWnd(IntPtr taskBarWnd)
{
// get process that owns the taskbar window
int procId;
GetWindowThreadProcessId(taskBarWnd, out procId);
Process p = Process.GetProcessById(procId);
if (p != null)
{
// enumerate all threads of that process...
foreach (ProcessThread t in p.Threads)
{
EnumThreadWindows(t.Id, MyEnumThreadWindowsProc, IntPtr.Zero);
}
}
return vistaStartMenuWnd;
}
/// <summary>
/// Callback method that is called from 'EnumThreadWindows' in 'GetVistaStartMenuWnd'.
/// </summary>
/// <param name="hWnd">window handle</param>
/// <param name="lParam">parameter</param>
/// <returns>true to continue enumeration, false to stop it</returns>
private static bool MyEnumThreadWindowsProc(IntPtr hWnd, IntPtr lParam)
{
StringBuilder buffer = new StringBuilder(256);
if (GetWindowText(hWnd, buffer, buffer.Capacity) > 0)
{
Console.WriteLine(buffer);
if (buffer.ToString() == VistaStartMenuCaption)
{
vistaStartMenuWnd = hWnd;
return false;
}
}
return true;
}
}
It doesn't work because IIS runs as a Windows service and is therefore prohibited from interacting with the desktop.
Did you expect this to happen on the client? If your code did work, it would happen on the server, not the client. But it doesn't, so give up.
I have a C# wrapper for some Win32 operations involving window handles, but I am experiencing an unexpected crash, with no details, when I call a Win32 function.
Interestingly, this whole code sample works fine when the class is constructed (at application init time), but later fails when the same buildCache() method is called.
Here is the relevant code:
public delegate bool CallBack(int hWnd, int lParam);
public class Win32Interop {
private Dictionary<int, string> windowCache = new Dictionary<int, string>();
public Win32Interop() {
buildCache();
}
public void buildCache() {
windowCache.Clear();
CallBack hWndCacher = new CallBack(saveHWndHandler);
EnumWindows(hWndCacher, 0);
}
public void doThings(string title, uint message, bool rebuildCache = false) {
//Use the window title to get its handle
int hWnd = titleToHWnd(title, rebuildCache);
SendMessage(hWnd, message, 0, 0);
}
private bool saveHWndHandler(int hWnd, int lParam) {
if(IsWindow(hWnd) != 0) { / ***** CRASHES HERE ***** /
int length = GetWindowTextLength(hWnd);
StringBuilder title = new StringBuilder(length + 1);
GetWindowText(hWnd, title, title.Capacity);
string formatted = title.ToString().Trim();
windowCache.Add(hWnd, formatted);
}
return true;
}
private int titleToHWnd(string title, bool rebuildCache = false) {
if(rebuildCache)
buildCache();
if(windowCache.ContainsValue(title)) {
return windowCache.FirstOrDefault(x => x.Value.Contains(title)).Key;
} else {
throw new KeyNotFoundException(string.Format("\"{0}\" is not a window title which is available in the cache.", title));
}
}
#region Win32 API Functions
[DllImport("user32.dll")]
private static extern int EnumWindows(CallBack lpEnumFunc, int lParam);
[DllImport("user32.dll")]
private static extern int GetWindowText(int hWnd, StringBuilder lpString, int maxCount);
[DllImport("user32.dll")]
private static extern int GetWindowTextLength(int hWnd);
[DllImport("user32.dll")]
private static extern int IsWindow(int hWnd);
[DllImport("user32.lib")]
private static extern int SendMessage(int hWnd, uint Msg, int wParam, int lParam);
#endregion
}
Inside of the saveHWndHandler() method, I've marked the line were the debugger shows execution stops. Interestingly, there are usually ~300 window handles returned by EnumWindows(), and it always crashes on iteration number 45 or 46. The window handle it crashes on is a reasonable value, such as 12345.
According to MSDN, IsWindow() should return 0, if a window was not associated with the handle, not crash the thread.
Does anyone know why this is happening? There isn't a thrown exception, or any details in the Windows event log.
Thank you.
For those who don't want to figure out the buildCache() process works:
(1.) When buildCache() is called, the dictionary of <HWnd, Title> values is cleared.
(2.) The Win32 function EnumWindows() is called, which calls the saveHWndHandler() method for each window handle.
(3.) saveHWndHandler() will check if the current window handle still exists, the call another Win32 to function to get the window title from the handle.
(4.) The title and window handle are added to the dictionary.
I can't reproduce your issue, but a likely problem is that all of your P/Invoke signatures are wrong. HWND, LPARAM, and WPARAM data types need to at least be mapped to IntPtr in P/Invoke code.
private delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool EnumWindows(EnumWindowsProc lpEnumFunc, IntPtr lParam);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString,
int nMaxCount);
[DllImport("user32.dll", SetLastError = true)]
private static extern int GetWindowTextLength(IntPtr hWnd);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool IsWindow(IntPtr hWnd);
[DllImport("user32.dll")]
private static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam,
IntPtr lParam);
You'll need to change your corresponding instance method signatures and usages to match these correct signatures.
I want to get the name of the printer chosen in Acrobat PrintDialog using SendMessage Windows API.
This is sample code.
static string GetWindowText( hwnd_printDialog_in_Acrobat )
{
int comboBoxCount = 0;
int HWND_PRINTER_NAME = 1 ;
List<IntPtr> ChildPtrList = GetChildWindows(hwnd_printDialog_in_Acrobat);
for( i=0 ; i < ChildPtrList.Size(); i++) {
GetClassName( ChildPtrList[i], sClass, 100);
if (sClass.ToString() == "ComboBox") {
comboBoxCount++;
if (comboBoxCount == HWND_PRINTER_NAME ) {
hwnd = ChildPtrList[i];
break;
}
}
}
ChildPtrList.Clear();
int sSize ;
sSize = SendMessageW( hwnd, WM_GETTEXTLENGTH, IntPtr.Zero, IntPtr.Zero )+1;
StringBuilder sbTitle = new StringBuilder( sSize );
SendMessageW( hwn, WM_GETTEXT, (IntPtr)sSize, sbTitle);
return (sbTitle.ToString());
}
The return value of sSize is 4;
The value of sbTitle.ToString() is "?-" etc.
The expected resu
What is wrong?
Here are my current guesses to your problem:
HWND_PRINTER_NAME is not 1
The class name you are looking for is not "ComboBox"
Problem in the code not listed:
Grabbing the wrong parent window or treating the handle incorrectly
SendMessageW DllImport is wrong, or parameters are treated incorrectly
You do have some bugs in the code listed so, my code isn't exactly the same, but here is the code I used to try to figure your problem. I could not get it to behave the way you describe. My code simply never finds a Child Window with the Class name "ComboBox".
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
namespace PrinterChoosenInAcrobat
{
class Program
{
public const uint WM_GETTEXTLENGTH = 0x000E;
private const uint WM_GETTEXT = 0x000D;
// External OS calls
[DllImport("user32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)]
public static extern bool SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam,
StringBuilder lParam);
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wparam,
IntPtr lparam);
[DllImport("User32.dll")]
public static extern Int32 FindWindow(String lpClassName, String lpWindowName);
[DllImport("user32.dll")]
static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName,
int nMaxCount);
static void Main(string[] args)
{
try
{
IntPtr windowHandle = (IntPtr)FindWindow("AcrobatSDIWindow", null);
string text = GetWindowText(windowHandle);
Console.WriteLine(text);
}
catch (Exception ex)
{
Console.Out.WriteLine(ex.Message);
}
// Don't close before I get to read the results
Console.WriteLine();
Console.WriteLine("Press Enter to quit.");
Console.ReadLine();
}
static string GetWindowText(IntPtr hwnd_printDialog_in_Acrobat)
{
int comboBoxCount = 0;
int HWND_PRINTER_NAME = 1;
List<IntPtr> ChildPtrList = GetChildWindows(hwnd_printDialog_in_Acrobat);
IntPtr hwnd = IntPtr.Zero;
for (int i = 0; i < ChildPtrList.Count; i++)
{
StringBuilder sClass = new StringBuilder();
GetClassName(ChildPtrList[i], sClass, 100);
if (sClass.ToString() == "ComboBox")
{
comboBoxCount++;
if (comboBoxCount == HWND_PRINTER_NAME)
{
hwnd = ChildPtrList[i];
break;
}
}
}
ChildPtrList.Clear();
int sSize;
sSize = (int)SendMessage(hwnd, WM_GETTEXTLENGTH, IntPtr.Zero, IntPtr.Zero) + 1;
StringBuilder sbTitle = new StringBuilder(sSize);
SendMessage(hwnd, WM_GETTEXT, (IntPtr)sSize, sbTitle);
return (sbTitle.ToString());
}
#region Code from http://pinvoke.net/default.aspx/user32/EnumChildWindows.html
[DllImport("user32")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool EnumChildWindows(IntPtr window, EnumWindowProc callback, IntPtr i);
/// <summary>
/// Returns a list of child windows
/// </summary>
/// <param name="parent">Parent of the windows to return</param>
/// <returns>List of child windows</returns>
public static List<IntPtr> GetChildWindows(IntPtr parent)
{
List<IntPtr> result = new List<IntPtr>();
GCHandle listHandle = GCHandle.Alloc(result);
try
{
EnumWindowProc childProc = new EnumWindowProc(EnumWindow);
EnumChildWindows(parent, childProc, GCHandle.ToIntPtr(listHandle));
}
finally
{
if (listHandle.IsAllocated)
listHandle.Free();
}
return result;
}
/// <summary>
/// Callback method to be used when enumerating windows.
/// </summary>
/// <param name="handle">Handle of the next window</param>
/// <param name="pointer">Pointer to a GCHandle that holds a reference to the list to fill</param>
/// <returns>True to continue the enumeration, false to bail</returns>
private static bool EnumWindow(IntPtr handle, IntPtr pointer)
{
GCHandle gch = GCHandle.FromIntPtr(pointer);
List<IntPtr> list = gch.Target as List<IntPtr>;
if (list == null)
{
throw new InvalidCastException("GCHandle Target could not be cast as List<IntPtr>");
}
list.Add(handle);
// You can modify this to check to see if you want to cancel the operation, then return a null here
return true;
}
/// <summary>
/// Delegate for the EnumChildWindows method
/// </summary>
/// <param name="hWnd">Window handle</param>
/// <param name="parameter">Caller-defined variable; we use it for a pointer to our list</param>
/// <returns>True to continue enumerating, false to bail.</returns>
public delegate bool EnumWindowProc(IntPtr hWnd, IntPtr parameter);
#endregion
}
}
I have a situation like this.
I have the window handle of an application. I need to activate it. I tried all these functions but is not working always.(most of the time , it doesn't work the first time and I'll have to manually click on it to activate it. Second attempt onwards it works fine)
The reason why I am doing this is because I have code written in the Form.Activate event of the form which I need to execute.
Application is a single instance application. When a new instance is created , it first checks for the existence of any other process, If found, the handle of old process is passed to the these functions so that user can work on the old form.
Application is called from a different C application.
[DllImport("user32.dll")]
public static extern int ShowWindow(IntPtr hWnd, int nCmdShow);
[DllImport("user32.dll")]
public static extern int SetForegroundWindow(IntPtr hWnd);
[DllImport("user32")]
public static extern bool PostMessage(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam);
SetForgroundWindow only works if its process has input focus. This is what I use:
public static void forceSetForegroundWindow( IntPtr hWnd, IntPtr mainThreadId )
{
IntPtr foregroundThreadID = GetWindowThreadProcessId( GetForegroundWindow(), IntPtr.Zero );
if ( foregroundThreadID != mainThreadId )
{
AttachThreadInput( mainThreadId, foregroundThreadID, true );
SetForegroundWindow( hWnd );
AttachThreadInput( mainThreadId, foregroundThreadID, false );
}
else
SetForegroundWindow( hWnd );
}
You need to find the window using something like Window title and then active it as follows:
public class Win32 : IWin32
{
//Import the FindWindow API to find our window
[DllImport("User32.dll", EntryPoint = "FindWindow")]
private static extern IntPtr FindWindowNative(string className, string windowName);
//Import the SetForeground API to activate it
[DllImport("User32.dll", EntryPoint = "SetForegroundWindow")]
private static extern IntPtr SetForegroundWindowNative(IntPtr hWnd);
public IntPtr FindWindow(string className, string windowName)
{
return FindWindowNative(className, windowName);
}
public IntPtr SetForegroundWindow(IntPtr hWnd)
{
return SetForegroundWindowNative(hWnd);
}
}
public class SomeClass
{
public void Activate(string title)
{
//Find the window, using the Window Title
IntPtr hWnd = win32.FindWindow(null, title);
if (hWnd.ToInt32() > 0) //If found
{
win32.SetForegroundWindow(hWnd); //Activate it
}
}
}
You have to get the form using FromHandle:
f = Control.FromHandle(handle)
then you can can call Activate on the result:
f.Activate()