C# text import from external window - c#

I'm working on an existing project that has a text import tool written in C#. It essentially shuffles to the last window that had focus, copies the text, switches back and pastes the text in the textbox. To do this it essentially issues keyboard commands so: Alt + Tab, Ctrl + A, Ctrl + C, Alt + Tab and then finally get the text from the clipboard and add it to the textbox.
Currently, it works terrific on XP. It doesn't, however, work on Vista/Win 7. It will switch to the new window and that appears to be it but when I go back to the C# it has added whatever was previously in the clipboard (not successfully copying the new text). My guess is that there's some problem telling another window to use the keyboard keys (Select All and Copy).
I have done some moderate searching online and haven't really found anything so I was hoping to see if anyone may have had a similar problem.

Assuming you're using SendKeys, you might want to look at this comment on the SendKeys MSDN page. If this is something introduced with Vista, it'd almost certainly affect Windows 7 as well, Id' think:
Note
The SendKeys class has been updated
for the .NET Framework 3.0 to enable
its use in applications that run on
Windows Vista. The enhanced security
of Windows Vista (known as User
Account Control or UAC) prevents the
previous implementation from working
as expected.
The SendKeys class is susceptible to
timing issues, which some developers
have had to work around. The updated
implementation is still susceptible to
timing issues, but is slightly faster
and may require changes to the
workarounds. The SendKeys class tries
to use the previous implementation
first, and if that fails, uses the new
implementation. As a result, the
SendKeys class may behave differently
on different operating systems.
Additionally, when the SendKeys class
uses the new implementation, the
SendWait method will not wait for
messages to be processed when they are
sent to another process.
If your application relies on
consistent behavior regardless of the
operating system, you can force the
SendKeys class to use the new
implementation by adding the following
application setting to your app.config
file.
To force the SendKeys class to use the
previous implementation, use the value
"JournalHook" instead.
http://msdn.microsoft.com/en-us/library/system.windows.forms.sendkeys.aspx

Related

c# read syslistview32 items tooltips via winapi

i want to write an application, which reads under windows xp the quick launch items in the order like they are located in the taskbar,
and sets hotkeys for each of these item.
windows + 1 should start the first application
windows + 2 the second, etc.
(like in windows 7)
all of these items are found i a folder, but if i read the items of this folder, i dont get the right order of these items.
i found two solutions the get the right order - first:
in the registry an entry is found, where its saved how they are located, but not in plain text. i dont know how to read this, and cant reverse engine it.
the second:
read via winapi the items tooltip from the taskbar, so i can (if there are not items with the same name) search via the name in the quick launch folder.
the quick launch bar is just a listview (syslistview32).
via sendmessage i got it work to count the items, and start one (faking a click on this item), but how the hell can i read the tooltip?
i have googled a lot, tried everything, but i didnt get it run.
i hope you have any snippets for me, to solve this problem.
cheers
Determining the order of the items in the Quick Launch toolbar programmatically is going to be inherently fragile. There's not an API exposed for this, which means that it's subject to change in future versions of Windows, breaking your code that relied on assumptions about undocumented implementation details.
However, this is less of a problem in this specific case than it normally would be, since the Quick Launch toolbar doesn't exist anymore (or, at least, no one uses it anymore). The last version of Windows that used the Quick Launch toolbar was Vista, so if you make sure that your code is compatible with Vista and earlier, you should be fine. It won't work with newer versions anyway.
The positions of items in the Quick Launch toolbar is stored in the Registry in the following key:
HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Streams\Desktop
You can extract the information from there, parse and interpret it, and then use it as you like. As you mention, this information isn't stored in plain text form because that would be very slow for the shell to load and parse itself. Since this is undocumented and not designed to be used by clients, they had no particular benefit in making it user (or developer) friendly. All that matters is what's most efficient for the shell, and storing the binary information from its internal structures is the obvious choice.
You will need to reverse engineer this in order for it to be useful to you. The way I'd go about it is probably by setting up a test environment with a couple of items in the Quick Launch bar in a particular order, exporting the information from the Registry, moving one of the items around, exporting the updated information from the Registry, and comparing the two exported Registry files to see what changed. Rinse and repeat as many times as necessary to deduce the pattern. (Really makes you wonder why so many developers actually do take the time to reverse-engineer undocumented aspects of Windows, doesn't it?)
The other option would be to use Spy++ to investigate the windows that implement the taskbar and its Quick Launch toolbar. I don't have a pre-Windows 7 system around, but it sounds like from the question that you've already done this and determined that the Quick Launch toolbar is implemented using a standard ListView. If you know the name of that window (and the names of its ancestor windows), you can walk through those windows to obtain a handle to the window you're interested in. And then you can determine the order of the items in the window as if it were a standard ListView in your own application.
The documentation for ListView controls is here; that should get you started in the right direction. You can get the text of one of the subitems by sending the LVM_GETITEMTEXT message.
This is probably the easier way of doing it. The same caveats apply--there is nothing keeping future versions of Windows from changing the names of those windows or the way that the taskbar is implemented, but since the only versions of Windows that have a Quick Launch toolbar have already been released (and therefore aren't likely to change), this may not be a big problem.
Then again, with the fact of the Quick Launch toolbar's obsolescence in mind, I struggle to comprehend why this endeavor is even worthy of investing developer time.
Also, even once you get this program all written and installed, consider what happens when the user adds a new item to the Quick Launch toolbar or re-arranges the existing items. How is your utility going to know that and adjust the keyboard shortcuts accordingly? What if an installer adds/removes an item from the Quick Launch toolbar?

ActiveX Control created in .NET when hosted in IE doesn't recieve keyboard events

I've been writing an ActiveX plugin for IE using .NET. While I've happily got it to deploy, install and what not, I'm finding that IE isn't passing keyboard events to it.
Is there a way to get IE to pass along keyboard events to it?
This problem has been seen to happen on IE7 and IE8, haven't tested other versions of IE though, mainly because I'm using IE8 and the customer will be using IE7.
Thanks in advance.
Edit:
In this case the particular keys I'm interested in are the delete key and the end key
This is a problem with how the browser loads and exposes the object.
As a security measure, some objects will not be activated, until clicked on, and then receive keyboard input.
I actually found a solution Using JavaScript, to pass the characters to the ActiveX Object, so that you do not have to click on it first, to activate it.
I used it for a bar code scanning solution, as there was no keyboard or mouse attached to the device.
Silver light out of browser mode, made the keyboard input available straight away, and became a better solution. Not sure if the latest version still allows it.

Why does my console application have command history?

I have written a console application, which is essentially a Console.ReadLine()-Loop. When the application is waiting for input, pressing the up arrow key iterates through all previous lines of input. My application does not contain any code for this feature. What part of Windows provides this? How can I disable it?
I can only image that it's either a feature of the console subsystem or implemented in Console.ReadLine().
Here is some sample code that exhibits the described behavior:
namespace ConsoleApplication
{
class Program
{
static void Main(string[] args)
{
string input;
do
{
input = System.Console.ReadLine();
} while (input != "exit");
}
}
}
I would like to disable the history feature for now, and re-implement it later using my own code. The current behavior is too limited.
you can change this behaviour of windows programmatically by calling SetConsoleHistoryInfo with a correctly setup CONSOLE_HISTORY_INFO structure... there seems to be no managed class/method so you will have to use DllImport etc.
http://msdn.microsoft.com/en-us/library/ms686031%28v=VS.85%29.aspx
http://msdn.microsoft.com/en-us/library/ms682077%28v=VS.85%29.aspx
IF need be - several other aspects of the console can be handled in a managed way - see c# console, Console.Clear problem
The history feature is built into the Windows Command shell, it is not a feature of your application. AFAIK there's no way to disable this in your code as it's specific to the Windows Shell Environment (unless there's a setting that can be changed, which there probably is)
You could possibly override the default behavior by using a key listener to get all up arrow keypresses and execute your own code, that way the event doesn't drop down to the shell to handle.
Yes, this is a feature of the console subsystem, not your application. To change it, click the console's control box (top left), properties, options tab: "Command history." The default is 50 items, 4 buffers. Supposedly this can be configured programmatically with DOSKEY from the command line, but a few minutes tinkering didn't lead me anywhere.
ALT+F7 will clear the command history, as will executing the command DOSKEY /reinstall. I tested in Windows 7.
Update: The corresponding Win32 API call is SetConsoleHistoryInfo and the p/invoke signature can be found at http://pinvoke.net/default.aspx/kernel32/SetConsoleHistoryInfo.html
Not tested, but it looks like passing an instance of CONSOLE_HISTORY_INFO to SetConsoleHistoryInfo with buffer size and count set to 1 would give the same control as the console window properties dialogue.
P/Invoke definitions at pinvoke.net
Also note this requires Windows V6 or later (ie. Vista/2008/7/2008R2).

How do I reliably invoke clipboard copy/paste actions in other apps without messing with input queue

A while ago I wrote a simple app, which surrounds selected text in any input field in any application with some unicode symbols when user presses some hotkey. Basically, app's logic is as follows:
Register global hotkey.
Hotkey fired, now set clipboard monitor and invoke clipboard copy to see if some text was selected.
If clipboard has changed and now contains text, surround said text with symbols and then invoke clipboard paste, so input field will be updated with modified text.
The problem is, I can't get copy/paste functionality from other apps in a reliable way. What I have tried to date:
If I send WM_COPY/WM_PASTE, it's more often ignored than not, depending on the application.
If I use SendInput, keybd_event or any other keyboard-messing stuff to press/unpress usual clipboard hotkeys, it will often tamper with user-pressed keys: copy/paste uses control or shift, which are also quite popular for all generic hotkeys in all apps, my app included.
If I use Journal Hook to directly inject keyboard messages into system input queue, sometimes it will work fine, and sometimes weird glitches will occur. Also, other applications may be using JournalHook for themselves, and that will mess my app badly. Not to mention that default security policies make journal hook hard to use.
I've been trying to get/set text in the input fields using Windows UI automation instead of clipboard magic, but it rarely works.
So, if you know other ways to make other applications reliably use copy/paste functionality, or can even devise entirely different approach, I'd really appreciate you telling me :)
I think your approach isn't that bad, maybe you can start with WM_DRAWCLIPBOARD so you can monitor the clipboard. A nice sample code can be found here.
Next I'd take a look at SendKeys class - Attention: Flush, Buffer, etc. Use this to send ctrl+c/v instead of a windows message! You should get a notification from your monitor if it worked.
Now I'd use the Cliboard class to maniplulate the Data and paste it back.
Oh, it seems that I could only find more or less reliable way of invoking copy-paste without SendInput or journal hook, but I have to deal with it :-) So here it is, in case someone find it useful:
Remember and reset keyboard modifiers via AttachThreadInput(yourAppThreadId, targetAppThreadId) + SetKeyboardState(keyStateWithoutKeyboardModifiers).
Set Ctrl key modifier via SetKeyboardState(keyStateWithControl) for Ctrl+C/V hotkey.
Then PostMessage to focused control handle with WM_KEYDOWN message for C or V key, whether you want it to copy or paste.
Call Thread.CurrentThread.Join(20) to let other app process messages — and that's the most retarded moment in the whole deal, since I couldn't find the sure way to know when other app will have empty message queue.
Restore remembered keyboard modifiers.
Also, every time you do SetKeyboardState, call SetForegroundWindow(focusedControlHandle) and SetFocus(focusedControlHandle) afterwards.

How to give an Exceed X-window focus in a C# application?

Currently our software is running on AIX Unix machines, but we use Windows boxes running Exceed to display the UI in X-windows. I'm writing a Windows application ( modernizing the UI in C# ), but some of the legacy windows still need to be displayed in Exceed. When a user clicks a button on my windows application, it sends a message to the Unix server which displays the X-window. My problem is that these X-windows are not getting focus, so they are popping up BEHIND all of my .NET windows/forms.
A user of this software can easily have 5+ windows forms open at any given time, so it is a big inconvenience if every time they want to display a legacy X-window, they have to minimise all of the .NET windows. What is the best way for me to solve this? Is there a way for me to give Exceed focus so that it brings the X-window to the top? I tried using Application.OpenForms, but calling .SendToBack() on each form didn't help me.
If the pop-up windows are coming from a process other than the Windows app which you're creating, you'll probably need to resort to a hack. Microsoft put code into WinXP to prevent apps from being able to throw their windows in front of everything, unless it's part of the app the user is working on. To do this, you need to monkey with the ForegroundLockTimeout registry value, and the Windows APIs to pull a window to the front.
More info:
http://social.msdn.microsoft.com/forums/en-US/winforms/thread/54826e98-9faa-4457-ba1d-b645af88170b/ (The last entry contains the conclusion, but you'll need to read some of the previous entries. I also suggest you set the ForegroundLockTimeout to zero, do the switch, then set ForegroundLockTimeout back to its previous value.)

Categories