How to make an application like google transliteration desktop application in c# - c#

Just the functionality of intercepting the keyboard entry , transforming it and sending it back is required.eg if user press a i wold like to send e etc.
To make a application that accepts the entry from keyboard modify it and send it to the active window (may be application like word, excel,notepad windows screens ) etc.
The feature is just like google's transliteration application for windows .
I would like to do it in c# .
I think this involves hooking in the keyboard and sending keys (like sendkey in vb) to the current window.
The working is just like Google transliteration .However the logic for transformation is quite different.

I'm not sure what the question is exactly, so it may get closed for being too vague. However, it sounds like you'll have to buffer all of the keystrokes, send words or phrases to some service asynchronously to be transliterated and then push them back into keyboard buffer with something like sendkeys as you mentioned. The problem is that if your app has focus, we don't know where the user wants the transliterated text to show up, and if the app such as Word has focus, it will receive both the real keystrokes and the transliterated text, which will then be mixed together (a mess). Seems better just to transliterate chunks of text rather than trying to interfere with the keyboard buffer - besides, backspace, undo, etc. will be nearly impossible to honor.

You need to write a dll which uses Windows Text Service framework or legacy IME framework .
This dll will get loaded into langauge bar and when you will activate it ; your code , which has implemented a set of APIS required by TSF or IME framework , will get the key event , You can then pass it to your code which translates it and passes a string back to you.Another of your implemented API can then input to the Current text editor of the windows Application.

Related

GetWindowTextA or GetWindowTextW

In an c# app, I am performing a EnumWindows of all windows on the desktop and in the callback I get the window title for each window. One 3rd party app in particular can be run in ansi or unicode mode, is it safe to use GetWindowTextW all the time even though the app is running in ansi mode or do I need to be able to detect whether unicode mode is enabled for all external apps in order to determine which GetWindowText I need to call? The problem I'm hitting is we have been using GetWindowTextA even on the unicode apps and has worked up until now. It fails to return the correct window title for obvious reasons when there are chinese characters in the title bar.
The wide functions are always the best choice (assuming you don't care about Windows 95/98/ME).
The window text can come from two places:
Unicode text "stored internally in the HWND". Most top-level windows store their text here. GetWindowTextW is always able to retrieve this text.
Some applications dynamically handle the WM_*TEXT* messages. The window manager handles character conversion for you (SendMessageA vs SendMessageW) so you don't have to think about it.
GetWindowTextW will not send the WM_*TEXT* messages if you call it on a window in a different process. If you want to always get the "correct" text of windows in other processes you manually have to call SendMessageTimeoutW(..., WM_GETTEXT, ...) first and if that fails with a timeout, fall back to GetWindowTextW.

Window CE 4.2 - Enumerating through the controls of a different running process

I have been charged with the task to send data from COM 1 to COM 2 in Windows CE 4.2. A running application takes data from COM 1 and displays it to the user in a form (textbox I assume). I then have to take that data and send it out COM 2. COM 1 is being used by the program displaying the data and I know of no way to hijack COM 1.
I figure trying to do a screen scrap would be the next step. Unfortunately this is compact framework and an old version at that and from a lot of research it seems managed code is out of the question . Many of the API functions I would use are not available; FindWindowEx for example.
Here is where I am at now. I have created two projects. One runs with a TextBox and some wording. A separate application runs and tries to read the text in that TextBox. I have been able to find the running process based off the name of the form using FindWindow API. Using code I have found on this site I have even been able to enumerate through the controls of the form. However my TextBox is never found and many of the controls that are found where never placed on the form by myself (listbox, button). I assume those are the form's initial controls.
Does anyone have any experience with this? Currently this is in C# but VB or Visual C++ will be fine. Even if you have any ideas on a third party application. BTW I am not given the option to upgrade to a higher version of compact framework.
Thank you.
An update I just found out about. It does not look like I only screen scrape only new data but instead have to screen scrape the entire screen and send it out COM2. Someone will scan a barcode and I will send out all screen data through COM2. The data may include a picture etc.
For a native C application I have one sceleton that enumerates all child windows and controls inside a dialog: http://code.google.com/p/rdp-auto-login/source/browse/trunk/rdp-auto-login/tscDialog.cpp. See ScanTSCWindow and the results found in the comment "TSC dialog elements".
I started with remote spy and looked thru the RDM window to find the CtrlID values. There is also a nice tool called zDump (http://www.hjgode.de/wp/2009/06/11/zdump-take-a-look-inside-windows-ce/) that runs on device and enables you to look at window elements.
The theory is that every element in Windows (either Mobile or desktop) is a window. Windows are accesible by there window handle. The handle is assign by the OS during CreateWindow/Ex. Inside dialogs, elements can be identified by there control ID (a resource value), the window class (ie "EDIT", "LISTBOX") and window text and internally by the window handle at creation.
The problem with Compact Framework apps is that they hide many of these basics and dialog (Form) elements can not be easily identified from another process.
As you say you are not able to capture COM1, what is, if you stop the application and then open COM1? As knonw, normally on one application can access a serial port at the same time. You can then read the serial data directly and do not need to access a foreign window.
There are also drivers that enable port mirroring or multiple access. Even for Windows CE based OS (ie http://www.virtual-serial-port.org/products/serial-splitter-mobile/).
If the application is a compact framework one you can take a look inside the code using .Net Reflector or similar .Net decompilers. I use that often to mimik or learn from other apps.
You say "I have been charged with the task to send data from COM 1 to COM 2 in Windows CE 4.2. A running application takes data from COM 1 and displays it to the user in a form (textbox I assume). I then have to take that data and send it out COM 2. COM 1 is being used by the program displaying the data and I know of no way to hijack COM 1." and if you do not start the other app you can write your own and do not need to parse the foreign app.
Possibly you can post the other app or more details of what it does what you can not do.
EDIT/UPDATE:
as we now know it is Intermec TE2000 (terminal emulation) the answer is to use the XMLRPC interface provided by TE2000. The interface is able to call back a function hosted by an xmlrpc server and send all screen content (text, fields and attributes) on screen changes. I have working c++ stl windowsce code for that.
If the device is connected via network, the xmlrpc server can even run on a PC.
As TE2000 does use native drwastring API you will not success in reading texts from the window. If you screen capture the window, you will have to do OCR on the image. XMLRPC does avoid all this.
UPDATE2:
I finished a class lib to get async screen updates using TE2000 xmlrpc: see https://github.com/hjgode/ITE_xml_rpc/tree/master/XmlRpcCS/XmlRpcCF
and http://community.intermec.com/t5/Thin-Client-Based-Development/Printing-CV60-Screen-Windows-CE-4-2/m-p/28663/highlight/false#M473

My app won't recognize keystrokes sent from SendKeys or SendInput, but does from the Keyboard

I've got a homegrown app (Master) that has a bunch of hotkeys defined. I need to automate the app with another external app (Control). I cannot rebuild the Master app, it runs, is already installed and can't be messed with.
Using hotkeys on Master works like a charm if I use a keyboard.
So, I figure I an use SendKeys.SendWait or SendKeys.Send to send the commands. While my code works fine with other apps (such as Notepad) it is not working with my custom app, Master. This could be for a number of reasons - Master is older, has .NET, C++ mixed... some low level video controls... who knows what's under the covers.
I need to get something higher level. I need to be able to send the keystrokes as if they are coming from the keyboard itself. I don't want the computer to be able to differentiate between the physical keyboard sending the keys and my app sending the keys.
What can I use and how will it be different?
The problem was not SendKeys.
I tried SendKeys.Send, SendKeys.SendWait, SendInput and keybd_event.
I later realized that the time between activating the application and the time sending the keystrokes was too short. I was waiting 200ms but simply by increasing this to 500ms I solved my problem.
The application took a long time to draw because of the embedded video players. Giving it another 300ms allowed it to be ready for the keystrokes I was sending it.

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.

Multiple keyboards and low-level hooks

I have a system where I have multiple keyboards and really need to know which keyboard the key stroke is coming from. To explain the set up:
I have a normal PC and USB keyboard
I have an external VGA screen with some hard-keys
The hard keys are mapped as a standard USB keyboard, sending a limited number of key-codes (F1, F2, Return, + and -)
I have a low-level hook (in C# but actually calling upon Win32 functionality) which is able to deal with the input even when my application is not focused.
The problem is that when using the normal keyboard, some of the mapped key-codes at picked up by the application being driven on the external screen. One of the key-presses sent by the external screen and used for confirmation is VK_RETURN. Unless I can identify the "device" and filter upon it, the user could be performing actions and confirming them on a screen their not even looking at.
How do I know which keyboard was responsible for the key-press?
Yes I stand corrected, my bad, learning something new every day.
Here's my attempt at making up for it :) :
Register the devices you want to use for raw input (the two keyboards) with ::RegisterRawInputDevices().
You can get these devices from GetRawInputDeviceList()
After you've registered your devices, you will start getting WM_INPUT messages.
The lParam of the WM_INPUT message contains a RAWKEYBOARD structure that you can use to determine the keyboard where the input came from, plus the virtual keycode and the type of message (WM_KEYDOWN, WM_KEYUP, ...)
So you can set a flag of where the last message came from and then dispatch it to the regular keyboard input handlers.
No way to do this. Windows abstracts this for you. As mentioned, you need to write/modify a device driver.

Categories