how can I check if BalloonTip attached to NotifyIcon was closed by user clicking "Close" icon or had dissapeared after give timeout? It seems that BalloonTipClosed is fired in both cases, and BaloonTipClicked is fired when user clicks anywhere on appearing tooltip...
I don't think it is possible to determine the close button being clicked over the balloon being clicked.
MSDN! lists the messages sent by the Notify Icon. It would appear from that list that there is no distinction between a user clicking the balloon and the user clicking the close button.
As commented below this blog explains why the clicking of the close button does not raise a separate event.
However, this blog has a comment suggesting that, on Windows XP, NIN_BALLOONTIMEOUT is sent when the user clicks the close button. It would be against best practice to rely on quirks like this to make your program run.
Could you implement your own timer that will close the baloon tip upon completion?
Make sure you set the balloon tip to display for longer than the timer.
Then you can detect whether the timer is still running when the balloon is closed, if not then the timeout closed the balloon, otherwise the user did.
Related
Everyone just want to hide the keyboard, but it closes automatically.
I want to keep the keyboard open and keep the entry focused after the completed event fired on a Xamarin entry control or in other words, I do not want the entry control blurred.
I have a transparent controls and window where I can click through as it would not even exist. My question is: Is it possible to detect whenever click event is fired no matter where on the screen I click, while the wpf applicaton is running?
The reason why I need this is because I'm making an agent that will collect all information about actions made by user. Any suggestions, hacks, tricks will do.
You would need to create an event hook so that you could snoop all system wide messages before they are dispatched to the target window. Check the following link for more information...
Here's the scenario:
Platform: Windows
IDE: Microsoft Visual Studio 2008
Language: C#
.NET framework: 3.5
My application contains 2 buttons - "Load Data" and "Stop Loading Data" and a multi-line textbox. Upon clicking "Load Data" button some data starts getting loaded in the textbox. To prevent the user clicking on the "Load Data" button multiple times, I have disabled that button once it is clicked. When the entire data gets loaded in the textbox then the "Load Data" button gets activated again. On the other hand on clicking "Stop Loading Data" button the loading of data is stopped (if user wishes to stop it before loading the entire content).
As stated earlier, to prevent the user clicking on the "Load Data" button multiple times, I have disabled that button with the intention that user can only click on "Stop Loading Data" button or else wait for the entire data to be loaded in the textbox. I implemented this. At first glance it seemed to work well. But while testing I found that even though the "Load Data" button is disabled, if the user clicks on that button, although nothing happens at that instant but as soon as the entire data gets loaded and the button becomes enabled again, that click made during the disabled state is found to be executed. As if the program was recording the keystrokes and mouse clicks and waiting for the button to become active again. But there are no such keystrokes or mouse-clicks recording facility in my program. What is causing such an activity? How can I prevent such behavior?
Thanks.
One option would be to work with a reentrancy sentinel:
You could define an int field (initialize with 0) and update it via Interlocked.Increment on entering the method and only proceed if it is 1. At the end just do a Interlocked.Decrement.
To make it visible for the user you can disable the button at the beginning of execution and enable it when the execution is finished...
BTW: long-running tasks should be done async (via a separate thread for example)...
if you make your call a synchronous one, it will lock up the entire page until loading finishes.
Otherwise you'd be just doing the method you've already tried, i'd like to see your code for the disabled state, because something tells me you just made it appear to be disabled, and it was still a functional button
Check out this post:
http://www.codeguru.com/forum/showthread.php?t=480279
My first thought was removing the event handler and rebinding it at the end of the click event. This thread suggests using a BackgroundWorker and making it async.
I bet that you can't even move the form until data is loaded, and you also can't stop loading data. The problem is that the whole form freezes until loading is done. You must move the loading part in separate thread.
Well, another silution again:
On begin load simply hide a load button and in place of it (say) show a progress bar. On finish of loading or on stop loading click make load button visible again. In this case you avoid "chain clicks" management you complains about.
Or manage one button. First it is load, on click, instead, becomes stop load. Solution like this you would find often in mobile environment, considering the limited screen space. But I think it can be applied to desktop with great sucess too. Why not?
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'm implementing a Windows 7/Vista-style notification area ('system tray') pop-up application in WPF. I've written about my work so far here (determining the notify icon's position, disabling resize, etc.).
There is one problem that I haven't solved quite to my satisfaction, however: hiding the window when the notify icon is clicked a second time. If you click (for example) the volume icon in Vista/7 to show the volume control, notice that it is hidden again when the icon is clicked a second time.
I handle the window's Deactivated event to hide the window, and the window is indeed deactivated when the notify icon is clicked. However, clicking the notify icon of course shows and activates the window, so what ends up happening is that the window disappears while the mouse is down and re-appears when the mouse is released (completing the mouse click event).
My first thought was that I might use the notify icon's MouseDown event (I'm using a System.Windows.Forms.NotifyIcon) and check whether the window is visible at that time - if it were, I could interpret it as the user clicking the notify icon a second time to hide the window. Unfortunately, the MouseDown event seems not to fire until the mouse has actually been clicked (in other words it works identically to the MouseClick event), by which time the window has already been deactivated and thus hidden. This seems to rule out this solution.
My next idea (and the approach I've ended up using) was to get the cursor position when the window is deactivated (GetCursorPos) and checking whether that point is within the notify icon's bounds. At the same time, I also use GetForegroundWindow to find the currently active window - if the notify icon is indeed to be clicked, it should either be the taskbar (the top-level window with class name Shell_TrayWnd) or the notification area fly-out (top-level window with class name NotifyIconOverflowWindow; Windows 7+ only). In short, if the cursor is over the notify icon and the notification area is active, I assume that the user mouse-downed the notify icon to hide the window. If these conditions are true, then the following MouseClick event will not result in the window being shown/activated.
This solution has at least one problem, though: if the cursor is hovering over the notify icon and the user presses the Windows key to open the start menu (or uses a Windows key + number shortcut to open an application), my program will wrongly interpret that as a mouse-down to the notify icon (because the taskbar is made active by those keyboard shortcuts). This means that the next time the user actually does click the notify icon, the window will not be shown. (Clicking the notify icon once more will show it.)
I hope what I've written makes some sense; if not, I'm happy to try and clarify the situation further.
I'm interested to hear if anyone has any other ideas about how to solve this.
I suspect that it might not be possible: it seems to me that the native Windows 7 notification area pop-up applications themselves use a simple timer implementation. Clicking on (for example) the volume icon when the volume control is open will only close the volume control if the time between the window deactivation and mouse click is less than about 2 seconds. Holding the mouse down on the icon for a longer period of time and then releasing will show the volume control again, even if it was open before the mouse-down.
That's not how the volume control window works. It disappears when you click anywhere, including the notification icon. The icon isn't relevant. This is a standard Win32 trick, it captures the mouse so it can see clicks outside of its window.
Mouse.Capture in WPF. Not nearly as easy to do because it requires an IInputElement instead of a window handle.