I'm creating a simple clipboard manager application. It monitors the content of a clipboard. When a change occurs (throu the win api message loop) it fires up a method to capture current content of clipboard and creates new object called clipboarditem. Next its building a ContextMeuStrip which consits of several clipboarditems created previously. The items menu is accessed by a hotkey. It shows up this menu on certain position of the screen itemsMenu.Show(caretPosition);, with .Focus(), I want it to make it disappear after it loses the focus (eg. clicking somehwere else on the screen or switch applications by alt-tab). Found an event OnLoseFocus but I dont think its working properly because the menu wont even show up.
How to make ContextMenuStrip disappear after loosing focus and how to prevent from showing ContextMenuStrip in taskabr ?
Sorry for my language skills :)
From a very quick look at the events that ContextMenuStrip contains, have you tried the "MouseCaptureChanged" event? It may help you with the losing focus issue.
For the showing in the taskbar issue, have you set "ShowInTaskbar" to false on the form you have your ContextMenuStrip (if you have it on a form)?
Related
This question already has answers here:
Tray icon does not disappear on killing process
(8 answers)
Closed 9 months ago.
After I send a TB_DELETEBUTTON message to delete a button (of a external application) in the system-tray toolbar, it remains a blank/empty rectangle from that deleted button, and the toolbar does not remove this empty rectangle until I do left or right click on some other icon, then finally the toolbar window gets redrawn and the empty rectangle from he button that I deleted disappears.
This is an aesthetic issue that I would like to avoid. I just would like to programatically update/redraw the toolbar window after I send the TB_DELETEBUTTON message, however after I call the UpdateWindow, UpdateLayeredWindow or RedrawWindow, the empty rectangle of the deleted button remains there.
The flags cobmination that I tried to use with RedrawWindow are: RDW_FRAME, RDW_ALLCHILDREN, RDW_UPDATENOW and RDW_INVALIDATE, all together.
The window handle that I'm passing to these functions is the window with class name: "ToolbarWindow32" (on which reside the system-tray buttons/icons of the applications), a example for getting this window handle can be found here.
My question is: how can I properly update/redraw this window?.
After calling the InvalidateRect function I noticed that the notification area window is redrawn (because the window flicks for a moment), so redrawing the window seems not a valid solution to solve this issue...
However, in the next thread I found a solution:
https://forum.lazarus.freepascal.org/index.php?topic=14847.0
The thing is that in order to "properly" refresh the size of the notification area to remove any empty space from previously deleted buttons, I just need to send WM_LBUTTONDOWN and WM_LBUTTONUP messages through the SendMessage function.
These window messages must be sent two times (at least for Windows 10) to the ToolbarWindow32 window following the next order: WM_LBUTTONDOWN, WM_LBUTTONUP, WM_LBUTTONDOWN, WM_LBUTTONUP. This is to reproduce two single clicks (not a double click) in the first button inside the system-tray, which is what I manually needed to do before applying this automated solution. After sending the messages, the window becomes "auto-sized" properly.
The only aesthetic problem would be if the first button is a button from an application that performs some undesired action when doing a single click on its button, but this is not typical to see. Typically the user only can do a double-click to restore the window from the button on system-tray, or do right click to open its context menu, but nothing should happens for doing a single click on a button... if the developer didn't programmed anything to happen.
Note that this methodology also works when there is the up arrow that contains "hidden" buttons.
I have a winform with a toolstriptextbox where users can write some stuff. The problem is that the textbox does not release the focus using the following code:
this.ActiveControl = otherControl;
OR
otherControl.Focus();
It is very strange because I can still see the text cursor blinking in the toolstriptextbox (if I press some other key it will appear in it).
Does any one know how to remove the cursor of toolstriptextbox?
PD. The toolstriptextbox is the only textbox inside the form.
Regarding to the comments...
In fact there are not several controls in the form. Some buttons in the toolstrip, a splitterPanel and a couple of picture boxes. I tried to focus the picture boxes and the toolstrip but sometimes the form loses its handlers of events and the only way to solve this is to open or to focus any other app and go back(this restores the handlers). So far the only way to avoid that is to focus the splitterPanel. I do understand that theoretically the splitterPanel is not focusable, but that is the only workaround I have found.
Finaly when the splitterPanel is focused the initial behaviour occurs.
Thanks for your comments.
The following answer helpme to solve this problem: https://stackoverflow.com/a/1140277/2835505
What I did was to add an invisible label in the form. After the user is done updating the toolstriptextbox. I just focus on the new auxiliary label and it is done.
Thanks to all people who commented
I am making a game, and to open up and close the store, you press S. While in the store, you have six different choices to buy from, but they are all buttons.
However, once you buy something, the focus is no longer on the form, but on the button, and the key down event is part of the form, therefore, because the focus gets switched from the form to the button, the key down event no longer works, and disables you from closing the store and continuing on with the game.
My question is how to set the focus back to a form once a button is press? I started out with visual basic, and the code would be something along the lines of form1.setfocus, but its totally different in c#.
I have tried Activating the form, .focus, a lot, and nothing seems to be setting the focus back to the form. Help would be greatly appreciated.
Form1.focus();
But I think, to get keyboard events on Form itself, you need KeyPreview set to true for the Form so that Form gets Keys first and then other controls.
Try:
form.Focus();
MSDN:
The Focus method returns true if the control successfully received input focus. The control can have the input focus while not displaying any visual cues of having the focus. This behavior is primarily observed by the nonselectable controls listed below, or any controls derived from them.
Tell me more
You can add the key down event to the buttons too.
The WinRT TextBox control has a delete button that shows up when the control has focus and there is text in it.
When the control loses focus by tapping outside of it or tabbing outside of it, the delete button disappears.
When the control loses focus by tapping in a different app (two apps are up in splitscreen), the delete button doesn't disappear.
Is there a way to detect the different lost focus events? Nothing from the sender or RoutedEventArgs is different in the two cases where the control loses focus.
You can handle Window.Activated to check if the whole app has lost focus:
This event occurs when a Window has been activated or deactivated by
the system. An app can determine what the status of the Window
activation is by checking the
WindowActivatedEventArgs.WindowActivationState property. A Window
could be visible on screen but not be active (for example, in snapped
apps). Additionally, if any other parts of the system takes focus away
from the window, this event will occur. This could happen as a result
of user interaction or code, and the WindowActivationState will
indicate which action has taken place.
http://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.xaml.window.activated.aspx
On my main form, there is another (floatable) window. This floatable window works sort of like a popupwindow in that it will close when the user clicks somewhere else outside of this window. This is handled by the Deactivate event. But what I want to do is, if the user clicks on a different control (say a button), I want to both close this float window and then activate that button with just one click. Currently, the user has to click twice (one to deactivate the window and once more to activate the desired button). Is there a way to do this with just one click?
foreach(Control c in parentForm.Controls)
{
c.Click += delegate(object sender, EventArgs e)
{
if(floatyWindow != null && floatyWindow.IsFloating)
{
floatyWindow.Close();
}
};
}
And then add your handlers as normal. This additional handler can close the floaty window.
Make sure you floaty window isn't a dialog too as this will not allow your parent form's controls to be clicked.
I had a slightly hacky solution. In your Deactivate event, fire another custom event to your main form. Then when you main form is handling the custom event, enumerate through your control(this.Controls) and locate the control under the mouse by checking all their bound then call Focus(). You might need to sort by the one with the smallest surface area, or you can have a separate list of "focus-able" control like button just for this purpose.
Another way might be to switch focus to your main form immediately after OnMouseLeave of the floatable window, or OnMouseHover of your main window, but keep the floatable windows on top, just no focus. Handle the global mouse down of your main form, and close the floatable window by then.
These are just theories, not tested.
I had an issue like this once too, when a customer wanted "floaty" windows all over there application. I used used an approach similar to the one described in this article:
http://www.vbaccelerator.com/home/NET/Code/Controls/Popup_Windows/Popup_Windows/article.asp
Code sample available here:
http://www.vbaccelerator.com/home/NET/Code/Controls/Popup_Windows/Popup_Windows/Popup_Form_Demonstration.asp
By extending this a bit we created "floaty" windows similar to the ones VS uses when you get a runtime error while debugging code.
At the very least reading the code may give you some insight, however, quarrelsome's response may be the more simple solution.