I'm using the WinEvents API for listening to an object focus, my problem is that I need to run some callback after the window focus was finished already (i.e. after the window has become the foreground window).
It seems that when listening to EVENT_OBJECT_FOCUS or EVENT_SYSTEM_FOREGROUND the event is triggered before the focus happens. I am looking for something that simulates an EVENT_OBJECT_FOCUSED kind of event. My current workaround is to wait 100 milliseconds before running the action which works but feels very patchy.
Related
C# windows application's GUI halt on re-sizing application and i have to kill the process from task Manager.
I have search for the issue and got a link that point me to background invoker and other point me to userpreferencechange events.
I have check the userpreferencechange event and its fired but don't know how to handle this issue in this event.
The problem is most likely in one of these four:
OnSizeChanged() method
OnResize() method,
SizeChanged event handler, or
ReSize event handler.
They all get fired whenever your gui get's resized. I suspect that in one of these event handlers/methods you have some code that tries to do something fancy that either results in an exception, recursion or an infinite loop.
But, without you providing more detailed code, this is, of course, merely an educated guess.
I've got a form that uses KeyDown. The KeyDown event is long, occupying almost 30k lines, and that brings up a problem. The first time I press down a key when debugging, the form freezes for a minute or two until I think reads all the conditionals of my KeyDown event. Then it works perfect until you close that form and load it again.
Note: This only happens when KeyDown event, KeUp event works normally.
I would put the code but as I said its 30K of lines full of conditionals, so my question is, is there a way to make KeyDown event faster or not to freeze like that, something besides reducing the ammount of lines or conditionals?
This requires psychic debugging, this question you asked is most relevant.
You didn't actually subscribe the Form.KeyDown event. You subscribed another KeyDown event, provided by a library that uses a low-level keyboard hook. Underlying winapi call is SetWindowsHookEx(). So you can detect keystrokes while your form doesn't have the focus.
And yes, that misbehaves exactly like you describe. The operating system called the hook's callback function which triggered the KeyDown event. You set a breakpoint on it, now the callback cannot complete. Windows goes catatonic for a while, it cannot process the next keystroke until the callback is completed.
It doesn't wait forever, after several seconds it decides that your program is misbehaving and it unceremoniously destroys the hook. Pretty important of course. You are noticing this delay.
You are going to have to do this differently if you want to have a shot a debugging this monstrosity. You need to setup another machine and connect to it with the remote debugger. It is not a golden solution, you still get the hook destroyed, but at least you regain control on your own machine a lot quicker. Using a unit test that just emulates the callback event would be very, very wise.
this is my first post. I have a huge problem which make me headaches. I have an app uses WinForms, a TTS (Text-To-Speech) voice and custom-buttons with states.
In my 1st form -main- when I click a button, the app opens a 2nd form above the 1st. Ok.
When I close the 2nd form trough a button, I tell the TTS say something and the form closed itself, viewing again the 1st form. Ok.
The problem starts when I click two times in the button on the 2nd form: the TTS says something, the button closes and the 'second click' is still in the click buffer (or somewhere) and it makes click in the 1st form (which appears 4 seconds later when I hit the button for the first time).
I am using the voice in a Sync mode; if I use the voice in an Async mode, the application ends wit h a nice exception.
If I click three or four times in the 2nd form, the other clicks still remains in buffer and clicks in the 1st form all the times.
I tried to (1) delete the DoubleClick event, (2) delete the event associated to the button and (3) hide the button which is clicked automatically when I return from the 2nd form, (4) hide the 1st form before create the 2nd and restore when it finishes.
Suggestions?
Thanks!
PD: I'm sorry by my English :S
PD2: I've uploaded a very simple example of what happens.
EDIT 2
Having looked at the code I understand the issue you're having now. The reason button clicks are being stacked up is when you call Speak within TTS the application locks up while it waits for the function to finish. Any presses in that time are stacked up until the application is free again to process them, you then close the form instanly before the messages are handled and these are then dealt with in the first form.
I've come up with a few solutions which could work for you:
Use only the SpeakAsync command within your TTS class and introduce a Waiting system where you wait for the speech to finish before doing anything. This will free the application and won't cause the mouse click events to stack up.
After you trigger a Speak command you could access the Windows message list and clear all the mouse click events that occurred before the process finished. Unfortunately, I'm not sure how you'd implement this as I've not done this before. I think you need to overwrite the WndProc function but again I'm not sure. This might be also be a bit dangerous as you may end up clearing a perfectly valid or important system message by mistake. Sorry can't provide any more help on that one.
Implement a background worker in your second form which will process the Speak commands seperately on a background thread. This again will free the application so the mouse click events won't stack up. I've modified your sample project and zipped it up for you to take a look. If you want I can explain further but essentially it does the following:
Form 2 loads and creates a background worker.
Worker_DoWork and Worker_WorkComplete delegates are created and set in the background worker. These functions are called when the worker is started and after the worker has finished.
Form 2 triggers the background worker to start. The background worker then sits in an infinite loop waiting for commands to process.
When the "Hello" button is pressed this sets a SayHello boolean to true, the worker spots this, carrys out the appropriate speak function and then resets the boolean ready for the next press.
When the "Close" button is pressed a CancelASync request is called in the background worker.
CancelASync interupts the BackgroundWorker's main loop (CancellationPending becomes true). The appropriate speak command is sent and the cancel property of the DoWorkEventArgs is set to true before breaking out of the BackgroundWorker's main loop.
Breaking out of the main loop causes Worker_WorkComplete to be called where the form is then closed.
I hope you can follow the example (linked below) and I've explained it well enough here. I prefer this solution as its quite extendable, you can add more conditions within the main worker thread for example.
Like I said, if you have any questions please ask and I'll try help as much as possible.
Hope this helps.
Example Link: http://www.mediafire.com/?2mf1yahto50ljs6
Use a boolean flag to track whether the form is in a state that accepts the click.
IE - when you open the 2nd form, 'boolean canPlaySound = true;' When the button click event fires, only play the sound if canPlaySound is true (and set it to false before playing the sound).
The next click will be ignored because canPlaySound = false. You won't play the sound.
I have a problem similar to this one: How can I execute code after my form starts?
But the solution there won't work for me because I am not running a form, I'm running a single custom control, which is a tray icon that monitors things. (Similar to the Icon Dropbox has, where that is the only interface the user has with the program)
What should I do to run code when the control is created? (which has to be after the message pump starts)
I think you're looking for the Application.Idle event.
Occurs when the application finishes
processing and is about to enter the
idle state.
E.g.
Application.Idle += delegate { Console.WriteLine(Application.MessageLoop); };
// Output: true
Application.Run();
First option would be to post a windows message to yourself. That way it will not be dispatched until your thread starts pumping messages. A second option is to hook into the Application.Idle event which is fired when the message queue is empty. Your third option would be to set and run a Timer for a small duration and hook into the Tick event for when it expires. Fourth and the last for now is to fire a delegate asynchronously as they use the message queue as the mechanism for being fired.
I'm trying to show a loader animation when my application it's blocked for more than 500ms.
I want that to be automatic, I don't want to add any piece of code before every long operation.
I know that in WinForms it was possible (I used this: https://snipplr.com/view/24851/), but It does not work in WPF.
I've found that I can do that with the mouse cursor(display Hourglass when application is busy)
I've tried to launch a window with a spinner.
I've found this answer (https://stackoverflow.com/a/21411656/10820863), that works detecting long operation.
Problem is that if I launch a window from a thread that is not the main one, I got a ThreadException because it's not the main thread. If I use Application.Current.Dispatcher.BeginInvoke
method, the window appears only when UI is not blocked anymore.
So, how can I automatically detect long operation and show a loading window/page/image/whatever if it lasts for more than 500ms?
[EDIT]
I don't want to add code to every long function, evaluating case for case which function can be long.
I'd prefer to have an automatic method that do that for me.