When my code is running I have a messagebox popup from excel that has a retry I just want my code to be able to simulate hitting the enter key if it pops up which it does everytime. This is the Messagebox that come up and freezes my code.
I turned off one of them using the OLE message, but I still get this messagebox any way to simulate a click on retry or enter key,?
//Turn off OLE Error Message
oXL.DisplayAlerts = false;
You can try sendkeys, to send a key stroke to the message box
InputSimulator is a very flexible (and reliable) wrapper that is capable of simulating keyboard and mouse events.
It wraps SendInput under the hood but abstracts away all the PInvoke calls and other complexity. It's a drop in DLL that (for your situation) should only take one line of code.
InputSimulator.SimulateKeyPress(VirtualKeyCode.ENTER);
I'm wondering if the problem is caused because you have a large loop that never makes use of the Application.DoEvents() call? As for dismissing the message that seems like a poor way to handle the problem to me.
Related
I am trying to hide all the windows of my app when a users session time's out. That works great; however, when a MessageBox is left open when the app times out the message box still is there. I want to be able to close the message box or at least hide it. I've looked up hwnds and hinstances and I don't quite know if thats what I am looking for to accomplish this. I thought this would be fairly easy as I thought MessageBox inherited from Window and of course it doesn't. And a top of that you cannot create an instance of message box to keep track of it. At this point I am not sure what to actually do or what to actually search for.
I am in the process of trying to figure some stuff out using reflection. I can create an instance of MessageBox using reflection but don't think I can call Show() using an instance.
Short answer: just create your own window that looks like a message box
Long answer:
Message boxes are normal WinAPI windows (they have an HWND and can be manipulated by the native API windowing functions) however they are not WPF windows and don't have an associated Window object.
Since they are normal windows you can get their HWND (using FindWindow/ FindWindowEx/ EnumWindows) and trick them into closing (for example, by simulating a Cancel button click)
However, because message boxes are not designed to be manipulated like that this trick has some nasty pitfalls you have to take care of.
And, because message boxes are so simple and you can easily create a message box clone it's just easier to create the close and not take care of all the message boxes corner cases.
This is related to my other question.
I used the OnStructureChanged event to detect that the 'Help' window popped up in the 3rd party application that my application is writing data to. I need my application to pause while the end user resolves the data issue in the 3rd party application, then I need my application to resume once the end user closes the 'Help' window. (Either I need to detect that the 'Help' window was closed or I need to display a message box and use the DialogResult to trigger my application to resume).
I've never encountered something like this before. I don't know if it's possible to do what I want to do. If it is possible, I don't know where to start.
Advice?
UPDATES:
I have only used Threading once before and I think it was a fairly "easy peasy" usage, I pulled it off without much effort, considering I'd never used Threading before. I'm playing around with Threading for this issue right now. There's a good chance I've implemented it incorrectly, but my app isn't functioning correctly anymore...I don't know if I'm even playing with the correct tool.
I had to just keep moving with the project - deadlines, you know...
I ended up using UI Automation to detect the "Help" window, then I showed a message box giving instructions to the end user. I check the MessageBox's DialogResult and continue processing based on that. It might not be the "best" way to skin the cat, but I'm a noob and I have a deadline, so I did what I needed to do to keep moving.
I was wondering if there was any way through C# or C++ to send to fake or otherwise trick a program into thinking it has focus? I'm thinking that there's a message you can send to it using SendMessage/PostMessage that'll trick it into having focus.
There is no guaranteed way to trick it into thinking it has focus because there are multiple ways it can check if it has focus. For example, it could be checking for WM_SETFOCUS and then checking it is out of focus when it receives WM_KILLFOCUS. So you could trick it in this case by sending intercepting all WM_KILLFOCUS messages with a window hook.
However, it might also be checking for if it has focus by calling GetFocus. So to trick it in that scenario, you would need to detour GetFocus and fake the return value. You can try both of these methods and they might work and they might not, but I wouldn't expect them to work reliably.
I hooked WM_NCACTIVATE to let the game know that it is still in focus. It worked fine on two games I worked.
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.
In Google Chrome you can retrieve the text of a JavaScript alert/dialog by simply having the dialog open and doing CTRL-C on the dialog. This will put the text in the dialog into the clipboard.
I'm trying to use SendMessage to send CTRL-C to perform a copy on the text of a JavaScript dialog. I've already managed to do this using SendInput but unfortunately that could fail if the window doesn't have focus.
I have tried using SendMessage with WM_COPY message but that didn't work for my needs.
Please if anyone has done this before successfully using SendMessage I would greatly appreciate your help.
If WM_COPY fails, there are a few avenues you could try...
To fake a keypress you can send WM_KEYDOWN and WM_KEYUP messages.
However, what do you send in the message? If you send a "c", then there is no way in these messages for you to inform the application that ctrl was also held down.
You may be able to send a character 0x03 (which is the character code that ctrl+c actually generates), but there is no guarantee that the receiving application will interpret this as a "ctrl+c" action.
Why might it not work? The receiving application might...
ignore WM_KEYDOWN and WM_KEYUP and use other means to read the keyboard (e.g. GetAsyncKeyState to see if a key is down)
handle WM_KEYDOWN and/or WM_KEYUP messages, but look for "c" and then use GetAsyncKeyState() or similar to detect if ctrl is down when the message is processed.
It might still ignore the messages if it doesn't have input focus, or worse, action those messages as though they were received through the input focus window.
So - give it a try, but it may not work.
Alternatively, if SendInput works, then you could just force the input focus to the correct control, SendInput, and then restore the input focus to its previous location.
Another approach (possibly the best one) is if it is a dialog known to you and it contains a static text field, you may just be able to find that child control and GetText on it (send WM_GETTEXT message), and avoid using the clipboard at all. (Or if you need the text on the clipboard, get it like this and then place it on the clipboard yourself). This would avoid tricking the application into providing the text, and fall back to standard Windows behaviour.
Try using these
WM_CUT = 0x300
WM_COPY = 0x301
WM_PASTE = 0x302
WM_CLEAR = 0x303
as the wmsg param depending on your operation.
Since the question is a bit vague as to whether you are talking about sending a Ctrl+C keystroke to terminate a process, or to copy a selection to the clipboard. If it is the former, please see this answer here and here on SO which was asked on a previous occasion, where an OP was asking how to send a Ctrl+C keystrokes to a shell process in order to terminate it.
If you are talking about Ctrl+C for copying a selection to the clipboard, that is even trickier as to whether the selection has indeed being selected first prior to copying to the clipboard...
If I am going off the wrong angle, at least, please edit your question to make it more clearer!
I realise this is an ancient question, but given it hasn't been satisfactorily answered, allow me to oblige for anyone else looking:
SendMessage() is not required. Simply use:
System.Windows.Forms.SendKeys.SendWait("^(c)");
And if you want to paste:
System.Windows.Forms.SendKeys.SendWait("^(v)");