How to : Given HWND, discover if window is Modal or not - c#

For any given window I handle, I need a way to find out whether or not the given window is Modal.
Far as I can tell, there are no methods that do exactly that, which is why I need some clever workaround to work this out!
Help is appreciated!
EDIT : Why is my GetWindow(,GW_OWNER) failing? :(
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
internal static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll", SetLastError = true)]
internal static extern IntPtr GetWindow(IntPtr hWnd, GetWindow_Cmd uCmd);
[DllImport("user32.dll", ExactSpelling = true)]
internal static extern IntPtr GetAncestor(IntPtr hwnd, GetAncestor_Flags gaFlags);
[DllImport("user32.dll", SetLastError = false)]
internal static extern IntPtr GetDesktopWindow();
[DllImport("user32.dll", SetLastError = true)]
internal static extern int GetWindowLong(IntPtr hWnd, int nIndex);
const UInt32 WS_DISABLED = 0x8000000;
internal enum GetAncestor_Flags
{
GetParent = 1,
GetRoot = 2,
GetRootOwner = 3
}
internal enum GetWindow_Cmd : uint
{
GW_HWNDFIRST = 0,
GW_HWNDLAST = 1,
GW_HWNDNEXT = 2,
GW_HWNDPREV = 3,
GW_OWNER = 4,
GW_CHILD = 5,
GW_ENABLEDPOPUP = 6
}
IntPtr _inspHwnd = FindWindow("rctrl_renwnd32", inspector.Caption); // searching for a window with this name
if (_inspHwnd.ToInt32() != 0) // found window with this name
{
IntPtr _ownerHwnd = GetWindow(_inspHwnd, GetWindow_Cmd.GW_OWNER);
if (_ownerHwnd.ToInt32() != 0)
{
IntPtr _ancestorHwnd = GetAncestor(_ownerHwnd, GetAncestor_Flags.GetParent);
if (_ancestorHwnd == GetDesktopWindow())
{
if (GetWindowLong(_ancestorHwnd, -16) == WS_DISABLED)
{
// inspector is probably modal if you got all the way here
MessageBox.Show("modal flag tripped");
}
}
}
}

Modal windows usually work by disabling their owner, where the owner is a top-level window. So if you test for this situation, you should catch whether a dialog is modal or not.
Check that the HWND is actually a top-level dialog, and not a child window
Get the owner (GetWindow(GW_OWNER))
Check that the owner is itself a top-level window (eg. GetAncestor(GA_PARENT)==GetDesktopWindow())
Check that the owner is disabled (GetWindowLong(GWL_STYLE) & WS_DISABLED)
That should catch all standard Win32-style modal dialogs.
Note that parent and owner are subtly different concepts; it's the owner you want to check here. This can get confusing, because GetParent can return the owner... - more details from Raymond Chen here.

I'm not certain that BrendanMck's solution will always be correct. Let's say that window W displays first a modeless dialog A and then a modal dialog B. Both A and B have W as their parent window. At the time B was displayed, W became disabled and as such applying the algorithm to both A and B will report both of them as being modal dialogs.

I just wrote
GetWindowLong(GetWindow(Hwnd, GW_OWNER), GWL_STYLE) & WS_DISABLED & WS_POPUP
in my code.

Related

how to hide Desktop Icons without restarting your computer [duplicate]

How can I show/hide the desktop icons programmatically, using C#?
I'm trying to create an alternative desktop, which uses widgets, and I need to hide the old icons.
You can do this using the Windows API. Here is sample code in C# that will toggle desktop icons.
[DllImport("user32.dll", SetLastError = true)] static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll", SetLastError = true)] static extern IntPtr GetWindow(IntPtr hWnd, GetWindow_Cmd uCmd);
enum GetWindow_Cmd : uint
{
GW_HWNDFIRST = 0,
GW_HWNDLAST = 1,
GW_HWNDNEXT = 2,
GW_HWNDPREV = 3,
GW_OWNER = 4,
GW_CHILD = 5,
GW_ENABLEDPOPUP = 6
}
[DllImport("user32.dll", CharSet = CharSet.Auto)] static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
private const int WM_COMMAND = 0x111;
static void ToggleDesktopIcons()
{
var toggleDesktopCommand = new IntPtr(0x7402);
IntPtr hWnd = GetWindow(FindWindow("Progman", "Program Manager"), GetWindow_Cmd.GW_CHILD);
SendMessage(hWnd, WM_COMMAND, toggleDesktopCommand, IntPtr.Zero);
}
This sends a message to the SHELLDLL_DefView child window of Progman, which tells it to toggle visibility (by adding or removing the WS_VISIBLE style) of it's only child, "FolderView". "FolderView" is the actual window that contains the icons.
To test to see if icons are visible or not, you can query for the WS_VISIBLE style by using the GetWindowInfo function, shown below:
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("user32.dll", SetLastError = true)]
private static extern bool GetWindowInfo(IntPtr hwnd, ref WINDOWINFO pwi);
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
private int _Left;
private int _Top;
private int _Right;
private int _Bottom;
}
[StructLayout(LayoutKind.Sequential)]
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() // Allows automatic initialization of "cbSize" with "new WINDOWINFO(null/true/false)".
{
cbSize = (UInt32)(Marshal.SizeOf(typeof(WINDOWINFO)));
}
}
Here is a function that calls the above code and returns true if the window is visible, false if not.
static bool IsVisible()
{
IntPtr hWnd = GetWindow(GetWindow(FindWindow("Progman", "Program Manager"), GetWindow_Cmd.GW_CHILD), GetWindow_Cmd.GW_CHILD);
WINDOWINFO info = new WINDOWINFO();
info.cbSize = (uint)Marshal.SizeOf(info);
GetWindowInfo(hWnd, ref info);
return (info.dwStyle & 0x10000000) == 0x10000000;
}
The windows API code along with more information about the window styles can be found here: http://www.pinvoke.net/default.aspx/user32/GetWindowInfo.html
Even though this is quite old when I tried Ondrej Balas's answer, one problem I found with this solution is that it does not work if the ToggleDesktop command is used to show the desktop ( also if wallpaper rotation is enabled ).
In both of these cases the SHELLDLL_DefView window, which is the recipient of the toggleDesktopCommand in the ToggleDesktopIcons function, is not a child of the "Program manager" window but of a 'WorkerW" window. (see WinApi - How to obtain SHELLDLL_DefView and Windows Desktop ListView Handle.
Based on those and building upon Ondrej Balas's earlier answer change the ToggleDesktopIcons function to be :
static void ToggleDesktopIcons()
{
var toggleDesktopCommand = new IntPtr(0x7402);
SendMessage(GetDesktopSHELLDLL_DefView(), WM_COMMAND, toggleDesktopCommand, IntPtr.Zero);
}
And add a GetDesktopSHELLDLL_DefView function:
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className, string windowTitle);
[DllImport("user32.dll", SetLastError = false)]
static extern IntPtr GetDesktopWindow();
static IntPtr GetDesktopSHELLDLL_DefView()
{
var hShellViewWin = IntPtr.Zero;
var hWorkerW = IntPtr.Zero;
var hProgman = FindWindow("Progman", "Program Manager");
var hDesktopWnd = GetDesktopWindow();
// If the main Program Manager window is found
if (hProgman != IntPtr.Zero)
{
// Get and load the main List view window containing the icons.
hShellViewWin = FindWindowEx(hProgman, IntPtr.Zero, "SHELLDLL_DefView", null);
if (hShellViewWin == IntPtr.Zero)
{
// When this fails (picture rotation is turned ON, toggledesktop shell cmd used ), then look for the WorkerW windows list to get the
// correct desktop list handle.
// As there can be multiple WorkerW windows, iterate through all to get the correct one
do
{
hWorkerW = FindWindowEx(hDesktopWnd, hWorkerW, "WorkerW", null);
hShellViewWin = FindWindowEx(hWorkerW, IntPtr.Zero, "SHELLDLL_DefView", null);
} while (hShellViewWin == IntPtr.Zero && hWorkerW != IntPtr.Zero);
}
}
return hShellViewWin;
}
Now regardless of the desktop toggle or wallpaper rotation the ToggleDesktopIcons should always work.
For reference this is my toggle desktop function which caused the issue with the original ToggleDesktopIcons function
static public void ToggleDesktop(object sender, EventArgs e)
{
var shellObject = new Shell32.Shell();
shellObject.ToggleDesktop();
}
In response to James M, this function returns the current state:
bool IconsVisible()
{
var hWnd = GetDesktopListView();
var info = new User32.WINDOWINFO(null);
User32.GetWindowInfo(hWnd, ref info);
return (info.dwStyle & User32.WindowStyle.WS_VISIBLE) == User32.WindowStyle.WS_VISIBLE;
}
A different approach is to create a separate desktop and show it instead. It will not have icons.
Application running itself on a separate desktop
You can do this in RegEdit
HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced
change HideIcons to 1
static void HideIcons()
{
RegistryKey myKey = Registry.CurrentUser.OpenSubKey(#"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced", true);
if (myKey != null)
{
myKey.SetValue("HideIcons", 1);
myKey.Close();
}
}
Use the Registry class as described here.
http://msdn.microsoft.com/en-us/library/microsoft.win32.registry.aspx
You can create a full screen view application and make it the top most window.
Then make your application to be start up with windows.
You are going about this the wrong way. What you are really trying to do is to replace the shell. Windows provides for this so you should just take advantage of it. Write your own shell to replace explorer.
Nice topic. Without actually creating a different desktop it would be visually pleasant to have the running applications minimized in the same swoop.

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.

Sending Click with user32.dll, messages appear in spy++ but button isn't clicked

I have problems with sending a Click to an application with the user32.dll. the button does not be clicked, but in spy++ the message do appear.
i'm using win7 x64
The code is written in c#:
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr FindWindow(string strClassName, string strWindowName);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string lpClassName, string lpWindowTitle);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr SendMessage(IntPtr hwnd, uint Msg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll")]
static extern IntPtr GetWindow(IntPtr hWnd, uint wCmd);
//
// Finds a window in the whole tree of childs for a parent window.
//
static IntPtr FindWindowRecursive(IntPtr hParent, string szClass, string szCaption)
{
IntPtr hResult = FindWindowEx(hParent, IntPtr.Zero, szClass, szCaption);
if (hResult != IntPtr.Zero)
return hResult; // found it
// enumerate all childs and if found one that has childs go in
IntPtr hChild = FindWindowEx(hParent, IntPtr.Zero, null, null); // first child
if (hChild != IntPtr.Zero)
{
// let's enumerate
do
{
hResult = FindWindowRecursive(hChild, szClass, szCaption);
if (hResult != IntPtr.Zero)
return hResult; // found it
} while ((hChild = GetWindow(hChild, GW_HWNDNEXT)) != IntPtr.Zero);
}
return IntPtr.Zero; // no childs, so no window was found
}
static void Main(string[] args)
{
IntPtr win = FindWindow("Omnipage17_MainWnd_Class", "Unbenanntes OmniPage-Dokument 1 - OmniPage");
SetForegroundWindow(win);
ShowWindowAsync(win, SW_RESTORE);
IntPtr ButtonHandle = FindWindowRecursive(win, "BarButton", "c");
SetActiveWindow(win);
//sEND Lbuttondown
IntPtr ptr = SendMessage(ButtonHandle, 0x0201, new IntPtr(0x0001), MakeLParam(81,28));
//Thread.Sleep(10);
//Mousemove
ptr = SendMessage(ButtonHandle, 0x0200, new IntPtr(0x0001), MakeLParam(86,24));
//lbuttonup
ptr = SendMessage(ButtonHandle, 0x0202, new IntPtr(0x0001), MakeLParam(81, 28));
//SendMessage(ButtonHandle, BM_CLICK, IntPtr.Zero, IntPtr.Zero);
}
Here are the messages of spy++ of that button:
If i send the the messages i get following:
i don't if that is that problem but the lbuttondown, buttoup appears 2 times ( S + R ) and if i'm clicking it manuelly it gets 1 message (P)
also tried to do it with WM_CLICK but then i have the same problem with it
Edit:
Using now PostMessage so spy++ shows the same messages as i click it manually, but still the button seems not to be clicked
With this library I have the same problem.
code:
SetForegroundWindow(win);
Rectangle re;
GetWindowRect(ButtonHandle, out re);
Cursor.Position = new Point((re.X + re.Width)/2, (re.Y + re.Height)/2);
WindowsInput.InputSimulator.SimulateKeyDown(WindowsInput.VirtualKeyCode.LBUTTON);
WindowsInput.InputSimulator.SimulateKeyUp(WindowsInput.VirtualKeyCode.LBUTTON);
Message are sent, but button isn't be clicked
Edit:
thanks for that link (http://www.hanselman.com/blog/IntroducingLync2010SuperSimpleAutoAnswerVideoKioskWithFullScreen.aspx), but also with this library i have the same problem :/
code:
SetForegroundWindow(win);
Rectangle re;
GetWindowRect(ButtonHandle, out re);
Cursor.Position = new Point((re.X + re.Width)/2, (re.Y + re.Height)/2);
WindowsInput.InputSimulator.SimulateKeyDown(WindowsInput.VirtualKeyCode.LBUTTON);
WindowsInput.InputSimulator.SimulateKeyUp(WindowsInput.VirtualKeyCode.LBUTTON);
Message are sent, but button isn't be clicked
Edit2:
Answer of user was deleted, because i posted my comment as an answer:
This is not an answer, this belongs in your question. It doesn't match
your code, clearly you are still posting BM_CLICK. Which is wrong, it
should be sent and you should either send BM_CLICK or post the mouse
messages. And you are looking at the wrong window, it is button's
parent that gets the BN_CLICK notification and acts on it. Having the
processs' keyboard state wrong would be a typical failure mode. – Hans
Passant 18 hours ago
Regarding to that, why should it be the parents windows? bcs in spy++ (screenshot below i serached for that button (Class: BarButton) and the handle i get from user32.dll is also the same as that one in spy++
Scott Hanselman recent blogged with something similar to this http://www.hanselman.com/blog/IntroducingLync2010SuperSimpleAutoAnswerVideoKioskWithFullScreen.aspx

How can I get functionality similar to Spy++ in my C# app?

I'm interested in working on a plugin for Keepass, the open-source password manager. Right now, Keepass currently detects what password to copy/paste for you based off of the window title. This prevents Keepass from detecting the current password you need for apps that don't actively update their window title based on the current site (Chrome for instance).
How can I walk through another processes window elements (buttons, labels, textbox) similar to how Spy++ works? When you run Spy++ you can hover over other programs windows and get all kinds of information about various properties concerning various controls (labels, textboxes, etc). Ideally, I'd like my Keepass plugin to enhance the current window detection by walking through the active window's elements in an effort to find a matching account to copy/paste the password.
How can I walk other processes window elements and be able to retrieve label and textbox values using C#?
I've being answering similar questions like this here: How can I detect if a thread has windows handles?. Like it states, the main idea is to enumerate through process windows and their child windows using EnumWindows and EnumChildWindows API calls to get window handles and then call GetWindowText or SendDlgItemMessage with WM_GETTEXT to get window text. I've modified code to make an example which should be doing what you need (sorry it's a bit long :). It iterates through processes and their windows and dumps window text into console.
static void Main(string[] args)
{
foreach (Process procesInfo in Process.GetProcesses())
{
Console.WriteLine("process {0} {1:x}", procesInfo.ProcessName, procesInfo.Id);
foreach (ProcessThread threadInfo in procesInfo.Threads)
{
// uncomment to dump thread handles
//Console.WriteLine("\tthread {0:x}", threadInfo.Id);
IntPtr[] windows = GetWindowHandlesForThread(threadInfo.Id);
if (windows != null && windows.Length > 0)
foreach (IntPtr hWnd in windows)
Console.WriteLine("\twindow {0:x} text:{1} caption:{2}",
hWnd.ToInt32(), GetText(hWnd), GetEditText(hWnd));
}
}
Console.ReadLine();
}
private static IntPtr[] GetWindowHandlesForThread(int threadHandle)
{
_results.Clear();
EnumWindows(WindowEnum, threadHandle);
return _results.ToArray();
}
// enum windows
private delegate int EnumWindowsProc(IntPtr hwnd, int lParam);
[DllImport("user32.Dll")]
private static extern int EnumWindows(EnumWindowsProc x, int y);
[DllImport("user32")]
private static extern bool EnumChildWindows(IntPtr window, EnumWindowsProc callback, int lParam);
[DllImport("user32.dll")]
public static extern int GetWindowThreadProcessId(IntPtr handle, out int processId);
private static List<IntPtr> _results = new List<IntPtr>();
private static int WindowEnum(IntPtr hWnd, int lParam)
{
int processID = 0;
int threadID = GetWindowThreadProcessId(hWnd, out processID);
if (threadID == lParam)
{
_results.Add(hWnd);
EnumChildWindows(hWnd, WindowEnum, threadID);
}
return 1;
}
// get window text
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern int GetWindowTextLength(IntPtr hWnd);
private static string GetText(IntPtr hWnd)
{
int length = GetWindowTextLength(hWnd);
StringBuilder sb = new StringBuilder(length + 1);
GetWindowText(hWnd, sb, sb.Capacity);
return sb.ToString();
}
// get richedit text
public const int GWL_ID = -12;
public const int WM_GETTEXT = 0x000D;
[DllImport("User32.dll")]
public static extern int GetWindowLong(IntPtr hWnd, int index);
[DllImport("User32.dll")]
public static extern IntPtr SendDlgItemMessage(IntPtr hWnd, int IDDlgItem, int uMsg, int nMaxCount, StringBuilder lpString);
[DllImport("User32.dll")]
public static extern IntPtr GetParent(IntPtr hWnd);
private static StringBuilder GetEditText(IntPtr hWnd)
{
Int32 dwID = GetWindowLong(hWnd, GWL_ID);
IntPtr hWndParent = GetParent(hWnd);
StringBuilder title = new StringBuilder(128);
SendDlgItemMessage(hWndParent, dwID, WM_GETTEXT, 128, title);
return title;
}
hope this helps, regards
Have a look at this article here which contains information about the Managed Spy and why the author wrote the tool.
You can use EnumWindows to find every top-level Chrome window and then call EnumChildWindows recursively (see Jeroen Wiert Pluimers' comment) to get every child of the main window. Alternatively, once you have the main Chrome window, you can use GetWindow to manually navigate the tree since you probably know what you're looking for (3rd child's children collection or something similar).
Once you find your window, you can use SendMessage with a WM_GETTEXT parameter to read the window's label.
You can use HWndSpy. Source code is here.
For the functionality of pointing to a window. You need to SetCapture() so that you get mouse messages that are outside of your window. Then use WindowFromPoint() to convert a mouse position to a Window. You will need to convert the moust position from client coordinates to window coordinates first.
If you try an call SetCapture() anywhere but on a mouse click message, you will probably be ignored. This is the reason that Spy++ makes you click on an Icon and drag and drop it on the window you want to point to.

Get active window text (and send more text to it)

I'm creating a small utility in C#, that will add some text to an active textbox when a global hotkey is pressed, it's a type of auto complete function. I have my global hotkey working, but now I don't know how to get the current text in the active textbox (if the active window is a textbox that is.) What I've tried so far is to use
a. GetForegroundWindow and then using that handle calling GetWindowText. This gave me the window title of the active window, not the textbox contents.
b. GetActiveWindow and using that handle to call GetWindowText. That gives me no text at all.
Here's an example of what I've done
[DllImport("user32.dll")]
private static extern bool UnregisterHotKey(IntPtr hWnd, int id);
[ DllImport("user32.dll") ]
static extern int GetForegroundWindow();
[ DllImport("user32.dll") ]
static extern int GetWindowText(int hWnd, StringBuilder text, int count);
[DllImport("user32.dll")]
static extern int GetActiveWindow();
public static void TestA() {
int h = GetForegroundWindow();
StringBuilder b = new StringBuilder();
GetWindowText(h, b, 256);
MessageBox.Show(b.ToString());
}
public static void TestB() {
int h = GetActiveWindow();
StringBuilder b = new StringBuilder();
GetWindowText(h, b, 256);
MessageBox.Show(b.ToString());
}
So, any ideas on how to achieve this?
Edit 28.01.2009:
So, I found out how to do this. This is what I used:
using System;
using System.Text;
using System.Runtime.InteropServices;
public class Example
{
[DllImport("user32.dll")]
static extern int GetFocus();
[DllImport("user32.dll")]
static extern bool AttachThreadInput(uint idAttach, uint idAttachTo, bool fAttach);
[DllImport("kernel32.dll")]
static extern uint GetCurrentThreadId();
[DllImport("user32.dll")]
static extern uint GetWindowThreadProcessId(int hWnd, int ProcessId);
[DllImport("user32.dll") ]
static extern int GetForegroundWindow();
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
static extern int SendMessage(int hWnd, int Msg, int wParam, StringBuilder lParam);
const int WM_SETTEXT = 12;
const int WM_GETTEXT = 13;
public static void Main()
{
//Wait 5 seconds to give us a chance to give focus to some edit window,
//notepad for example
System.Threading.Thread.Sleep(5000);
StringBuilder builder = new StringBuilder(500);
int foregroundWindowHandle = GetForegroundWindow();
uint remoteThreadId = GetWindowThreadProcessId(foregroundWindowHandle, 0);
uint currentThreadId = GetCurrentThreadId();
//AttachTrheadInput is needed so we can get the handle of a focused window in another app
AttachThreadInput(remoteThreadId, currentThreadId, true);
//Get the handle of a focused window
int focused = GetFocus();
//Now detach since we got the focused handle
AttachThreadInput(remoteThreadId, currentThreadId, false);
//Get the text from the active window into the stringbuilder
SendMessage(focused, WM_GETTEXT, builder.Capacity, builder);
Console.WriteLine("Text in active window was " + builder);
builder.Append(" Extra text");
//Change the text in the active window
SendMessage(focused, WM_SETTEXT, 0, builder);
Console.ReadKey();
}
}
Some notes about this. The example waits for 5 seconds before doing anything, giving you the chance to give focus to some edit window. In my real app I'm using a hotkey to trigger this, but that would just confuse this example. Also, in production code you should check the return values of the win32 calls to see if they succeeded or not.
It's reasonable to send keystrokes if you aware of active window and focused input field. See http://www.pinvoke.net/default.aspx/user32/keybd_event.html for API.
Please check, even em_replacesel message may not work across different process, You might need to use WM_COPYDATA or by calling window procedure as given in the url,
http://www.microsoft.com/communities/newsgroups/en-us/default.aspx?dg=microsoft.public.smartphone.developer&tid=4e3a9289-9355-4af7-a5b9-84f1aa601441&cat=&lang=&cr=&sloc=en-us&p=1

Categories

Resources