How do I get the selected text from the focused window using native Win32 API?
My app. will be running on the system try monitoring for a hotkey; when the user selects some text in any window and presses a hotkey, how do I obtain the selected text, when I get the WM_HOTKEY message?
To capture the text on to the clipboard, I tried sending Ctrl + C using keybd_event() and SendInput() to the active window ( GetActiveWindow() ) and forground window ( GetForegroundWindow() ); tried combinations amongst these; all in vain. Can I get the selected text of the focused window in Windows with plain Win32 system APIs?
3 Answers 3
TL;DR: Yes, there is a way to do this using plain win32 system APIs, but it’s difficult to implement correctly.
WM_COPY and WM_GETTEXT may work, but not in all cases. They depend on the receiving window handling the request correctly — and in many cases it will not. Let me run through one possible way of doing this. It may not be as simple as you were hoping, but what is in the adventure filled world of win32 programming? Ready? Ok. Let’s go.
First we need to get the HWND id of the target window. There are many ways of doing this. One such approach is the one you mentioned above: get the foreground window and then the window with focus, etc. However, there is one huge gotcha that many people forget. After you get the foreground window you must AttachThreadInput to get the window with focus. Otherwise GetFocus() will simply return NULL .
There is a much easier way. Simply (miss)use the GUITREADINFO functions. It’s much safer, as it avoids all the hidden dangers associated with attaching your input thread with another program.
Sending the keystrokes to copy the text is a bit more involved.
We’re going to use SendInput instead of keybd_event because it’s faster, and, most importantly, cannot be messed up by concurrent user input, or other programs simulating keystrokes.
This does mean that the program will be required to run on Windows XP or later, though, so, sorry if your running 98!
There. That wasn’t so bad, was it?
Now we just have to take a peek at what’s in the clipboard. This isn’t as simple as you would first think. The «clipboard» can actually hold multiple representations of the same thing. The application that is active when you copy to the clipboard has control over what exactly to place in the clipboard.
When you copy text from Microsoft Office, for example, it places RTF data into the clipboard, alongside a plain-text representation of the same text. That way you can paste it into wordpad and notepad. Wordpad would use the rich-text format, while notepad would use the plain-text format.
For this simple example, though, let’s assume we’re only interested in plaintext.
And there you have it! Just make sure you copy lpstr to some variable you want to use, don’t use lpstr directly, since we have to cede control of the contents of the clipboard before we close it.
Win32 programming can be quite daunting at first, but after a while. it’s still daunting.
Reading from a text field in another application’s window
Is there a way for a Windows application to access another applications data, more specifically a text input field in GUI, and grab the text there for processing in our own application?
If it is possible, is there a way to «shield» your application to prevent it?
EDIT: The three first answers seem to be about getting the another applications window title, not a specific text input field in that window.
I’m no Windows API expect, so could you be more exact how do I find a certain text field in that window, what are the prequisites for it (seems like knowing a window handle something is required, does it require knowing the text field handle as well? How do I get that? etc. )
Code snippets in C++ really would be really appreciated. MSDN help is hard to browse since Win32-API has such horrible naming conventions.
Completed! See my answer below for a how-to in C++.
6 Answers 6
For reading text content from another application’s text box you will need to get that text box control’s window handle somehow. Depending on how your application UI is designed (if it has a UI that is) there are a couple of different ways that you can use to get this handle. You might use «FindWindow»/»FindWindowEx» to locate your control or use «WindowFromPoint» if that makes sense. Either way, once you have the handle to the text control you can send a «WM_GETTEXT» message to it to retrieve its contents (assuming it is a standard text box control). Here’s a concocted sample (sans error checks):
I used «Spy++» to get the handle to a text box window that happened to be lying around.
As for protecting your own text boxes from being inspected like this, you could always sub-class your text box (see «SetWindowLong» with «GWL_WNDPROC» for the «nIndex» parameter) and do some special processing of the «WM_GETTEXT» message to ensure that only requests from the same process are serviced.
OK, I have somewhat figured this out.
The starting point is now knowing the window handle exactly, we only know partial window title, so first thing to do is find that main window:
which enumerates through all the windows on desktop. It makes a callback with each of these window handles:
and by using the wsTitle and little regex magic, we can find the window we want.
By using the before mentioned Spy++ I could figure out the text edit field class name and use it to find wanted field in the hwndWindow:
and then we can read the text from that field:
I hope this helps anyone fighting with the same problem!
Get text from windows application
This forum has migrated to Microsoft Q&A. Visit Microsoft Q&A to post new questions.
Answered by:
Question
How do I use WM_GETTEXT in VB.net to get text from another applications window? (or any other good solution to the task)
Answers
Open NotePad.exe and type some text there,do not close the notepad
Now create a windows application ,Drag a Button and two labels on to the form.
In the Form1 class copy paste the code below
All replies
How do I use WM_GETTEXT in VB.net to get text from another applications window? (or any other good solution to the task)
Open NotePad.exe and type some text there,do not close the notepad
Now create a windows application ,Drag a Button and two labels on to the form.
In the Form1 class copy paste the code below
Open NotePad.exe and type some text there,do not close the notepad
Now create a windows application ,Drag a Button and two labels on to the form.
In the Form1 class copy paste the code below
Send The WM_SETTEXT Message to the window
This looks like a good start for a project I want to do. The problem is when I change the text in the text box and click button1 it replaces the existing text. How can I get it to add to the new text to the end of the file. I would like to log some information when I recieve data from a microprocessor on the serial port. Particularly the time and date the data was recieved and what data was recieved.
ive tried this code and works perfectly for notepad but i am trying to open app » http://www.mediafire.com/?uznzynwmtzx » press the button then copy the textbox text and then close the application without any user interaction.. also want it to close the app if error occurs and display message box to advise of the error..
Can anyone help??
ive adapted the code to show as below’
i have a form with 2 labels and a button, on button click the app required loads and closes fine.
changing label1 to window title does not work, button click event doesn’t work, copying textbox text to label2 doesn’t work.
I see this works for only WM_TEXT and WM_COPYDATA due to restrictions on data access in ASP.NET foundation. Is there a way to use a user defined wMsg and still have access to the data passed between applications? It seems the only data that can be passed not using WM_TEXT,WM_COPYDATA can only be of an integer type for the lParam. Bottom line, how can one allocate a common memory location that can be used by all programmer written (winform) applications?
Thanks for any possible solution.
As right now I only filter the w.Msg via the following methodology:
Protected Overrides Sub WndProc( ByRef m As Message)
‘ Listen for operating system messages
Select Case (m.Msg)
‘ The WM_ACTIVATEAPP message occurs when the application
‘ becomes the active application or becomes inactive.
7 Ways to Copy Text or Error Messages from Windows
If you are having problems with Windows itself or any other software, one of the things you might be asked to do is supply the information in any errors or messages that are being displayed to help with troubleshooting. Some error messages are quite short and not difficult to type in, and others can be long and a real pain to repeat accurately with combinations of numbers, letters and special characters all being used.
It’s often better to also enter an exact error code or phrase into a search engine such as Google to get more precise results for the problem. Of course, taking a screenshot can be used to send an error message to someone else, but this isn’t always that helpful because they might have to re-type the message data in at the other end, and it also won’t help if you want to search the internet.
Windows error dialog boxes and general information windows don’t have a nice and easy button for you to copy all the error messages, and they won’t let you highlight the the text so it can be copied. There are ways for you to do it though and copying information from Windows message boxes, 3rd party software dialogs or the Command Prompt can be made easier when you know how. Here are 7 solutions to try.
Actually there is a very easy way you can copy Windows dialog box and error messages. When the box appears, simply make sure it’s the active window and press the standard Windows copy shortcut combination of Ctrl+C. Now the data is in the clipboard, paste the contents into notepad or webpage etc.
For example, if you type raymond.exe into a Run box (Win key+R), Windows will show a not found error:
Press Ctrl+C, open Notepad and then press Ctrl+V to produce the following:
[Content]
Windows cannot find ‘raymond.exe’. Make sure you typed the name correctly, and then try again.
You will get not just the text content but also the window’s title and the name of any buttons. This is very useful but unfortunately only works on dialog boxes created by Windows. If the window message is custom and created by third party software, this method won’t work. For that, you will need to use one of the other tools below.
2. GetWindowText
GetWindowText is a free and portable tool by the same developer of the popular Q-Dir file manager. To use it to copy the text from control boxes, left click on the question mark icon in the top left and drag the mouse cursor to the box that you want it to read the data from. It can read almost all text from edit, static, sysTreeView, sysListView, combobox and groupbox controls etc. Simply highlight and copy the text from the box in the GetWindowText program.
3. ShoWin
ShoWin is actually a small tool from McAfee and in addition to finding text in a window or dialog, it can also be used to display the password in a dialog hidden behind asterisks. Simply drag the cross hair over the control to get information about it and the included text, the copy button will copy all details, not just the text. Additional features include the ability to enable disabled windows, unhide hidden windows and force windows to stay on top or be placed below others.
4. SysExporter
SysExporter is another small and portable utility from Nirsoft and allows you to grab the data stored in list-views, tree-views, list boxes, combo boxes, text-boxes, and controls from most applications. It also has a drag and drop target icon to catch specific window contents from error message boxes etc, and can be used to capture a folder tree or list of files from an Explorer or application window. Any data can be copied or exported to a text, html or xml file.
5. WinScraper
WinScraper is able to scrape the text from a dialog box control or message box by dragging the target icon over the text or window. The result will show in the “Window Text:” box and can be copied out and pasted as text into an email or forum post etc. It can capture images of controls or windows from applications such as icons, and also can resize application or web browser windows to a specific size for testing alternate screen resolutions.
6. Textractor
Textractor is a text monitoring tool that captures and logs all text a program writes to the screen. The tool works by you supplying the program to monitor and then it captures and records any output from the application to its window. Each line can be right clicked on and copied / removed or the whole text can be saved to a file. This obviously won’t record general Windows errors but can get error dialogs or window text from specific software.
7. Copy Text from Command Prompt
Although not a dialog window, copying text out from the Command Prompt is quite useful if you want to copy the results or errors of a command. It’s very easy when you know how and doesn’t require the use of software, but still many people don’t know you can. There are 2 ways to do it.
1. While you’re in Command Prompt, right click at anywhere inside the window and select Mark.
2. Now use your left mouse button to drag a box over the area of text that you want to copy, scroll can also be used to capture multiple lines. Once you have the text, click the right mouse button or press Enter to copy the selected text to the clipboard. Then you can right click and select Paste to paste into Notepad or a webpage etc.
1. Right click on Command Prompt’s title bar and select Properties. On the options tab, tick to enable QuickEdit Mode and click OK.
Now your left mouse button will permanently be used to mark text and the right mouse will copy it to the clipboard. If there is no highlighted text, the right mouse button will paste any clipboard contents to the window, useful for copying commands off a webpage etc.