Capture text typed from another application - c#

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;
}

Related

Change defaut text on a save button

It's my first message here and I'm not a native English speaker so thank you in advance for not minding to much about my mistakes.
My problem is that I want to change the default text of a OpenFileDialog and SaveFileDialog because in my application there is an option to change the language settings.
The buttons texts are "Save" and "Open".
I can do it for other buttons thanks to the MessageBoxManager, however I need to do it also for the button "Save" and for the button "Open".
Those buttons have to be handled by other means, because I can't find their "ID" (ID_ok = 1, ID_cancel = 2) and I can't find "Save".
So if you have any idea for a solution I will be very grateful.
#pragma warning disable 0618
using System;
using System.Text;
using System.Runtime.InteropServices;
using System.Security.Permissions;
[assembly: SecurityPermission(SecurityAction.RequestMinimum, UnmanagedCode = true)]
namespace System.Windows.Forms {
public class MessageBoxManager {
private delegate IntPtr HookProc(int nCode, IntPtr wParam, IntPtr lParam);
private delegate bool EnumChildProc(IntPtr hWnd, IntPtr lParam);
private const int WH_CALLWNDPROCRET = 12;
private const int WM_DESTROY = 0x0002;
private const int WM_INITDIALOG = 0x0110;
private const int WM_TIMER = 0x0113;
private const int WM_USER = 0x400;
private const int DM_GETDEFID = WM_USER + 0;
private const int MBOK = 1;
private const int MBCancel = 2;
private const int MBAbort = 3;
private const int MBRetry = 4;
private const int MBIgnore = 5;
private const int MBYes = 6;
private const int MBNo = 7;
private const int MBSave = 8;
[DllImport("user32.dll")]
private static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll")]
private static extern IntPtr SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);
[DllImport("user32.dll")]
private static extern int UnhookWindowsHookEx(IntPtr idHook);
[DllImport("user32.dll")]
private static extern IntPtr CallNextHookEx(IntPtr idHook, int nCode, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll", EntryPoint = "GetWindowTextLengthW", CharSet = CharSet.Unicode)]
private static extern int GetWindowTextLength(IntPtr hWnd);
[DllImport("user32.dll", EntryPoint = "GetWindowTextW", CharSet = CharSet.Unicode)]
private static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int maxLength);
[DllImport("user32.dll")]
private static extern int EndDialog(IntPtr hDlg, IntPtr nResult);
[DllImport("user32.dll")]
private static extern bool EnumChildWindows(IntPtr hWndParent, EnumChildProc lpEnumFunc, IntPtr lParam);
[DllImport("user32.dll", EntryPoint = "GetClassNameW", CharSet = CharSet.Unicode)]
private static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
[DllImport("user32.dll")]
private static extern int GetDlgCtrlID(IntPtr hwndCtl);
[DllImport("user32.dll")]
private static extern IntPtr GetDlgItem(IntPtr hDlg, int nIDDlgItem);
[DllImport("user32.dll", EntryPoint = "SetWindowTextW", CharSet = CharSet.Unicode)]
private static extern bool SetWindowText(IntPtr hWnd, string lpString);
[StructLayout(LayoutKind.Sequential)]
public struct CWPRETSTRUCT
{
public IntPtr lResult;
public IntPtr lParam;
public IntPtr wParam;
public uint message;
public IntPtr hwnd;
};
private static HookProc hookProc;
private static EnumChildProc enumProc;
[ThreadStatic]
private static IntPtr hHook;
[ThreadStatic]
private static int nButton;
/// <summary>
/// OK text
/// </summary>
public static string OK = "&OK";
/// <summary>
/// Cancel text
/// </summary>
public static string Cancel = "&Cancel";
/// <summary>
/// Abort text
/// </summary>
public static string Abort = "&Abort";
/// <summary>
/// Retry text
/// </summary>
public static string Retry = "&Retry";
/// <summary>
/// Ignore text
/// </summary>
public static string Ignore = "&Ignore";
/// <summary>
/// Yes text
/// </summary>
public static string Yes = "&Yes";
/// <summary>
/// No text
/// </summary>
public static string No = "&No";
/// No text
/// </summary>
public static string Save = "&Save";
static MessageBoxManager()
{
hookProc = new HookProc(MessageBoxHookProc);
enumProc = new EnumChildProc(MessageBoxEnumProc);
hHook = IntPtr.Zero;
}
/// <summary>
/// Enables MessageBoxManager functionality
/// </summary>
/// <remarks>
/// MessageBoxManager functionality is enabled on current thread only.
/// Each thread that needs MessageBoxManager functionality has to call this method.
/// </remarks>
public static void Register()
{
if (hHook != IntPtr.Zero)
throw new NotSupportedException("One hook per thread allowed.");
hHook = SetWindowsHookEx(WH_CALLWNDPROCRET, hookProc, IntPtr.Zero, AppDomain.GetCurrentThreadId());
}
/// <summary>
/// Disables MessageBoxManager functionality
/// </summary>
/// <remarks>
/// Disables MessageBoxManager functionality on current thread only.
/// </remarks>
public static void Unregister()
{
if (hHook != IntPtr.Zero)
{
UnhookWindowsHookEx(hHook);
hHook = IntPtr.Zero;
}
}
private static IntPtr MessageBoxHookProc(int nCode, IntPtr wParam, IntPtr lParam)
{
if (nCode < 0)
return CallNextHookEx(hHook, nCode, wParam, lParam);
CWPRETSTRUCT msg = (CWPRETSTRUCT)Marshal.PtrToStructure(lParam, typeof(CWPRETSTRUCT));
IntPtr hook = hHook;
if (msg.message == WM_INITDIALOG)
{
int nLength = GetWindowTextLength(msg.hwnd);
StringBuilder className = new StringBuilder(10);
GetClassName(msg.hwnd, className, className.Capacity);
if (className.ToString() == "#32770")
{
nButton = 0;
EnumChildWindows(msg.hwnd, enumProc, IntPtr.Zero);
if (nButton == 1)
{
IntPtr hButton = GetDlgItem(msg.hwnd, MBCancel);
if (hButton != IntPtr.Zero)
SetWindowText(hButton, OK);
}
}
}
return CallNextHookEx(hook, nCode, wParam, lParam);
}
private static bool MessageBoxEnumProc(IntPtr hWnd, IntPtr lParam)
{
StringBuilder className = new StringBuilder(10);
GetClassName(hWnd, className, className.Capacity);
if (className.ToString() == "Button")
{
int ctlId = GetDlgCtrlID(hWnd);
switch (ctlId)
{
case MBOK:
SetWindowText(hWnd, OK);
break;
case MBCancel:
SetWindowText(hWnd, Cancel);
break;
case MBAbort:
SetWindowText(hWnd, Abort);
break;
case MBRetry:
SetWindowText(hWnd, Retry);
break;
case MBIgnore:
SetWindowText(hWnd, Ignore);
break;
case MBYes:
SetWindowText(hWnd, Yes);
break;
case MBNo:
SetWindowText(hWnd, No);
break;
case MBSave:
SetWindowText(hWnd, Save);
break;
case 1038:
SetWindowText(hWnd, Retry);
break;
}
nButton++;
}
return true;
}
}
Edit:
First, thank to correct my mistakes (many of them) ^^.... The reason, I want translate the button is simple. My program have to be translate in 5 languages that can be selected by the menu. I don't have "window ultimate" to change the setting language like i want.
But anyway, I don't want change the language of the OS at every click. i had only two solutions create all messageBox and openDialog by myself and change the 1500 times where the program call messageBox.show by my new form (what will spend many time...) or translate the buttons correctly for messageBox and open/save dialogBox. The computer used is dedied for this program, no any others programs should be used.
Currently I'm able to translate all messageBox correctly, But my problem is for the Buttons "save", "open"(this text change like my button "ok") if you want i can tell you where you can dowload the project to have a better idea of the fonction realized

How to restore a window to its orginal state(the same heigth and width as it's before)?

Here (below sample program) if the notepad is resized--> maximized and then minized. the window position (maximize) is not retained.
I want to retain the window position as it is before minimizing.
i have tried out the below code. Pls help.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private readonly IntPtr HWND_TOPMOST = new IntPtr(0);
private void button1_Click(object sender, EventArgs e)
{
Process[] Processes = Process.GetProcessesByName("notepad");
string processString = string.Format("Untitled - Notepad");
IntPtr res;
foreach (Process theprocess in Processes)
{
if (theprocess.MainWindowTitle.Contains(processString))
{
if (theprocess.MainWindowHandle == IntPtr.Zero)
{
continue;
}
WindowsNativeCalls.SetActiveWindow(theprocess.MainWindowHandle);
if (theprocess.MainWindowHandle != IntPtr.Zero)
{
if (theprocess.MainWindowTitle.Contains(processString))
{
WindowsNativeCalls.WINDOWPLACEMENT placement = new WindowsNativeCalls.WINDOWPLACEMENT();
WindowsNativeCalls.GetWindowPlacement(theprocess.MainWindowHandle, ref placement);
switch (placement.showCmd)
{
case 1:// SW_NORMAL
case 3:// SW_MAXIMIZE does the job of bring to front
WindowsNativeCalls.SetWindowPos(theprocess.MainWindowHandle, HWND_TOPMOST, 0, 0, 0, 0, WindowsNativeCalls.SWP_NOMOVE | WindowsNativeCalls.SWP_NOSIZE | WindowsNativeCalls.SWP_SHOWWINDOW);
break;
case 2: // SW_SHOWMINIMIZED
placement.showCmd = 9;
WindowsNativeCalls.SetWindowPlacement(theprocess.MainWindowHandle, ref placement);
//res = WindowsNativeCalls.SendMessage(theprocess.MainWindowHandle, WindowsNativeCalls.WM_SYSCOMMAND, (IntPtr)WindowsNativeCalls.SW_SHOWNORMAL, IntPtr.Zero);
break;
}
}
}
}
}
}
}
public class WindowsNativeCalls
{
#region Fields
/// <summary>
/// Hide Window
/// </summary>
public const int SW_HIDE = 0;
/// <summary>
/// Show Normal
/// </summary>
public const int SW_SHOWNORMAL = 1;
/// <summary>
/// Minimize Window
/// </summary>
public const int SW_SHOWMINIMIZED = 2;
/// <summary>
/// Maxiize Window
/// </summary>
public const int SW_SHOWMAXIMIZED = 3;
/// <summary>
/// Activate Window
/// </summary>
public const int SW_SHOWNOACTIVATE = 4;
/// <summary>
/// Restore Window
/// </summary>
public const int SW_RESTORE = 9;
/// <summary>
/// SW_SHOW
/// </summary>
public const int SW_SHOW = 5;
/// <summary>
/// Default Window
/// </summary>
public const int SW_SHOWDEFAULT = 10;
/// <summary>
/// Close Windows message
/// </summary>
public const uint WM_CLOSE = 0x10;
/// <summary>
/// Screen Window Position to No Size Change
/// </summary>
public const UInt32 SWP_NOSIZE = 0x0001;
/// <summary>
/// Screen Window Position to No Move Change
/// </summary>
public const UInt32 SWP_NOMOVE = 0x0002;
/// <summary>
/// Screen Window Position to Show Window
/// </summary>
public const UInt32 SWP_SHOWWINDOW = 0x0040;
/// <summary>
/// Maximize Window in Graphics mode
/// </summary>
public const int SC_MAXIMIZE = 0xF030;
/// <summary>
/// Resize Windows message
/// </summary>
public const uint WM_SYSCOMMAND = 0x0112;
public struct POINTAPI
{
public int x;
public int y;
}
public struct RECT
{
public int left;
public int top;
public int right;
public int bottom;
}
public struct WINDOWPLACEMENT
{
public int length;
public int flags;
public int showCmd;
public POINTAPI ptMinPosition;
public POINTAPI ptMaxPosition;
public RECT rcNormalPosition;
}
#endregion
#region DllImport Functions
/// <summary>
/// Sets the show state of a window created.
/// </summary>
/// <param name="hWnd">Window Handle</param>
/// <param name="nCmdShow">Show state</param>
/// <returns>Returns True if successful</returns>
[DllImport("user32.dll")]
public static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);
/// <summary>
/// Sets window in Forefront and activates it
/// </summary>
/// <param name="hWnd">Window Handle</param>
/// <returns>Returns True if successfu</returns>
[DllImport("user32.dll")]
public static extern bool SetForegroundWindow(IntPtr hWnd);
/// <summary>
/// Sets the show state of a window created.
/// </summary>
/// <param name="hWnd">Window Handle</param>
/// <param name="nCmdShow">Show state</param>
/// <returns>Returns True if successful</returns>
[DllImport("user32.dll")]
public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetWindowPlacement(IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl);
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll")]
public static extern bool SetWindowPlacement(IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl);
[DllImport("user32.dll")]
public static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll")]
public static extern int GetWindowText(IntPtr hWnd, System.Text.StringBuilder text, int count);
[DllImport("user32.dll")]
public static extern bool IsIconic(IntPtr hWnd);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
public static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool EnumWindows(EnumedWindow lpEnumFunc, ArrayList lParam);
public delegate bool EnumedWindow(IntPtr handleWindow, ArrayList handles);
[DllImport("user32")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool EnumChildWindows(IntPtr window, EnumedWindow callback, ArrayList lParam);
[DllImport("user32.dll")]
public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr SetActiveWindow(IntPtr hWnd);
[StructLayout(LayoutKind.Sequential)]
public struct WINDOWINFO
{
public uint cbSize;
public RECT rcWindow;
public RECT rcClient;
public uint dwStyle;
public uint dwExStyle;
public uint dwWindowStatus;
public uint cxWindowBorders;
public uint cyWindowBorders;
public ushort atomWindowType;
public ushort wCreatorVersion;
public WINDOWINFO(Boolean? filler)
: this()
{
cbSize = (UInt32)(Marshal.SizeOf(typeof(WINDOWINFO)));
}
}
[DllImport("user32.dll", SetLastError = true)]
public static extern bool GetWindowInfo(IntPtr hwnd, ref WINDOWINFO pwi);
#endregion
}
If you want the window to use its previous position, then don't overwrite the window position information by calling SetWindowPos().
Instead, just minimize the window by calling ShowWindow() with the appropriate command (i.e. SW_MINIMIZE). Then when you restore it, its previous position information will still be there.
<aside>
By the way, any particular reason your code is checking both the window handle for null and the window title twice?
</aside>
switch (placement.showCmd)
{
case 2: // Activates and displays the window -- This case only when the window is minimized.
WindowsNativeCalls.ShowWindow(theprocess.MainWindowHandle, WindowsNativeCalls.SW_RESTORE);
break;
default: // Bring to Front - For all other cases
WindowsNativeCalls.SetWindowPos(theprocess.MainWindowHandle, HWND_TOPMOST, 0, 0, 0, 0, WindowsNativeCalls.SWP_NOMOVE | WindowsNativeCalls.SWP_NOSIZE | WindowsNativeCalls.SWP_SHOWWINDOW);
break;
}

Hide window task bar code not working on iis7.5

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.

How to enumerate all windows belonging to a particular process using .NET?

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");

How to set a Wpf Window as the Owner of a Winforms Form

How to set a System.Windows.Window as the Owner of a System.Windows.Forms.Form?
After I searched for this for a while only to realize that I already have the answer in one of my utils classes I decided to put the answer on stackoverflow. Hopefully someone finds this useful.
Use this method:
[DllImport("user32.dll")]
private static extern int SetWindowLong(HandleRef hWnd, int nIndex, int dwNewLong);
/// <summary>
/// sets the owner of a System.Windows.Forms.Form to a System.Windows.Window
/// </summary>
/// <param name="form"></param>
/// <param name="owner"></param>
public static void SetOwner(System.Windows.Forms.Form form, System.Windows.Window owner)
{
WindowInteropHelper helper = new WindowInteropHelper(owner);
SetWindowLong(new HandleRef(form, form.Handle), -8, helper.Handle.ToInt32());
}
Isn't SetParent considered "more correct" than SetWindowLong with GWL_HWDPARENT (-8)?
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);

Categories