Name of closing button on Windows Forms - winforms

What's the name of the default red button with an X in the middle at the top right?
EDIT: I want to get the event associated with clicking that button.

You cannot disable the close box on its own using in properties window like you can with the minimize and maximize boxes. You can however disable the control box which contains them all.
Setting ControlBox to false will remove the minimize, maximize and close buttons.
You might want to consider why you are doing this though, as it's generally a good idea to let users quit out of windows using the close button (think of it as a cancel button).
EDIT:
You can handle when the user clicks on that close button using either the Closing or the Closed events of the Form. The difference between the two is that the Closing event fires before the form has closed (meaning that you can veto the closure by setting the Cancel property of the FormClosingEventArgs to true), whereas the Closed event fires after the form has actually closed.

it is possible to hook all messages goes to a form by implementing ImessageFilter interface
this link can be use full Using IMessageFilter to create a generic filter for operating system events

You can disable it by setting the ControlBox to false in the form properties, or in code like the following:
this.ControlBox = false;
Setting this will also hide the minimize and maximize buttons if that is OK. If not, the solution is a bit more elaborate.

Related

Show Winforms Contextmenu over ChromiumWebBrowser

I'm working on a Winforms project that uses CefSharp as a Gui. For several reasons I would like to implement a custom context menu using the Winforms ContextMenu class; rendering the menu in Html or customizing the ChromiumWebBrowser's context menu (using CefSharp.IContextMenuHandler) are not an option.
The context menu it triggered by Javascript code that calls a method on a .net object I passed to RegisterAsyncJsObject; the default context menu is prevented using Javascript. I'm invoking the method call on the Gui thread, because the call over the "javascript bridge" to the registered object comes from a different thread.
My problem: when manually showing the Winforms context menu over the CefSharp.WinForms.ChromiumWebBrowser the context menu does not get the keyboard focus (e.g. selecting items with the arrow key doesn't work nor can I close the contextmenu using Esc); instead the keyboard focus remains with the ChromiumWebBrowser control. And, if I click on the ChromiumWebBrowser's control area the context menu doesn't close either. I can only close the context menu by selecting an item with the mouse or clicking on another control within the form (in which the ChromiumWebBrowser is contained) or somewhere completely else (e.g. desktop or another application).
If I trigger the context menu from elsewhere in my code - ultimately using the same method that calls myContextMenu.Show() - the context menu gets the keyboard focus as desired. But one problem still remains: it doesn't close when I click within the ChromiumWebBrowser control.
I haven't used IFocusHander, IContextMenuHandler, IKeyboardHandler - should I?
I'm using CEF 3.2454.1344.g2782fb8, Chromium 45.0.2454.101 and .net 4.5.1.
Unfortunately extracting demo code isn't reasonably possible.
Anyone any ideas?
EDIT1:
After reading the comments, I decided to describe the code flow more precisely:
When right clicking Javascript sends a message to the registered .net object, containing the mouse coordinates. The default context menu is prevented by setting preventDefault on the MouseEvent arguments of the ContextMenu event.
The registered .net object receives the messages and calls windowForm.Invoke(Sub() ... ), because the message is not received on the Main/Gui thread, but must be processed there for the context menu to appear correctly.
The contextmenu is created and assigned to the ContextMenuStrip property of the UserControl that contains the actual ChromiumWebBrowser control.
It is displayed using ContextMenuStrip.Show(location) method.
Issues:
The context menu has no keyboard-focus.
All mouse events appear to be "swallowed" by the ChromiumWebBrowser: clicking there does not close the context menu.
Opening the context menu identically except for using a different "trigger" works fine, except for the 2nd issue.
In the end the solution is simple; everything works as implemented and desired, if the following steps are added:
Before showing the context menu disable the UserControl with the ChromiumWebBrowser and set the focus to the owning form; something like this:
Private Sub showContextMenu(position As Point)
Me.ctrlCefBrowser.Enabled = False
Me.Focus()
myContextMenu.Show(position)
End Sub
That takes the focus away from the ChromiumWebBrowser, giving the context menu a chance to respond to the keyboard inputs. And also, by disabling the control, the mouse events are not "swallowed" anymore so clicking on the browser area causes the context menu to go away again.
Then, finally, add an event handler to the context menu to re-enable the browser control again:
Private Sub myContextMenu_Closed(sender As Object, e As ToolStripDropDownClosedEventArgs) Handles myContextMenu.Closed
Me.ctrlCefBrowser.Enabled = True
Me.ctrlCefBrowser.Focus()
End Sub
That did the trick for me, now I have a fully customizable Gdi context menu for my webbrowser control :o)
Note:
A similar problem arises when using other menus as well, e.g. in a main menu or tool bar: clicking on the ChromiumWebBrowser control will not close the menu (because the mouse event is also "swallowed"). The same solution can be applied: when opening a drop down menu deactivate (Enabled = False) the web browser control. And when it closes, reactivate it. For my menus I used a derived class (Inherits ToolStripMenuItem) that adds listeners to the according events. That takes care of the problem in a global and simple way.
EDIT:
The proposed solution above left the problem that the click on the disabled browser control closed the menu as intended, but got lost, i.e. the browser couldn't process it. My current workaround now is:
Do not disable the browser control.
Using the openening events of menu items and context menus, keep track of which menu is currently open.
When the browser receives the focus (obtainable by intercepting WndProc messages) close the opened menu.
Implementing the actual solution caused some headaches in the details, but maybe that helps someone along anyhow...

WPF menu and multitouch

I have a menu that is implemented in a way that when a menu item is pressed, a popup containing it's sub-items is open.
When running with touch screen, occasionally user touches 2 menu items at the same time with his fingers - and this leads to one of the menuitems have a touch capture which is not released until another window gets focus, making the app seem stuck.
How can I prevent such a case?
thanks
You could use a queue that contains delegates:
When triggering a command, add the delegate to the queue.
Then grab the first delegate of the queue and flush it afterwards.
Now you only have 1 "command".
I found the cause for the problem: the popup used to display submenu items had StaysOpen set to false.
This causes the Popup to capture input so it can know when to close itself once a click was made outside its boundaries.
Setting its StaysOpen property to True fixed the issue.

Silverlight click event registered a second time before first event completed

I have a button which launches a "modal dialog" - it just creates a transparent grid covering everything, with the "dialog" created on top of that.
However I have a strange issue - if I double/triple click the button really fast (or add some delay in the event code), the button click event is executed multiple times, creating multiple overlapping modal dialogs. If the first action in my event is to disable the button (IsEnabled=false) it seems to prevent this.
My guess is that Silverlight is being multithreaded with input - it is not only recording the second click in another thread (while the button's click event is running), but it is jumping the gun by evaluating which control should be the target before the previous event has finished executing. Even though that event alters what control is at those mouse coordinates, it doesn't matter.
Does anyone know anything about this behavoir, or a way around it? If I have something like a save window, where the user clicks a save button, a blocking grid ("Saving...") is placed up while it saves, and then the whole "window" is closed, I'd like to avoid the user being able to queue up multiple save event clicks (this could lead to unpredictable program behavoir).
If you've ever worked with WinForms or WPF, this is expected behavior. Your button is broadcasting its Click event until your modal dialog covers it up. Unfortunately, there is some amount of time between your first click and when the modal dialog covers the button which allows multiple clicks to the original button.
You have two solution choices:
Disable the button after the first click and then re-enable after the modal dialog returns. You've already mentioned that this works.
Write code in the Event Handler of the button to determine if a modal dialog is already being displayed. This way, you're putting the responsibility in one location rather than splitting it up (disabling and re-enabling the button). This would be my preferred solution.
I think what you're seeing is the behaviour of Silverlight's routed events.
You can set the Handled property of the event arguments to true to prevent the event from bubbling.

WinForms Accept Button Annoyance

I have a base panel class that has (among other things) three buttons. I use subclasses of this base class in two different config dialogues. Both dialogues have an OK button set as the accept button.
In one of the dialogues, if I click one of the buttons in the base class, focus immediately returns to the OK button, so pressing the enter key works as expected.
In the other dialogue, focus remains wth the button in the base class that was clicked if it is enabled, or moves to the next button if the clicked button is no longer enabled.
There is no code that handles the base class button click events in either of the derived classes.
Ideas anyone?
I'm not sure what's going on in your first dialog because it doesn't seem to be operating the way I would expect it to. The second dialog sounds more like the standard behavior.
In Windows Forms, the AcceptButton property only comes into play when pressing Enter doesn't otherwise cause any actions. In both of your examples, clicking on a button should move the focus to that button, and subsequently pressing Enter would cause another click on that button.
In any event, I think it's generally preferable to stick with the Windows user interface guidelines and not automatically change the input focus back to the OK button. If the user clicks on one of the other buttons, the focus should stay there until they move it.
i don't know what language you are using, but the button class should have a focus method that will highlite it for enter pressing. in the click method, or when you open the dialog you can call this method to make the button you want get the form's focus
c#
myButton.Focus();

Making the window [X] button close instead of minimise on Windows Moblie

The [x] button in the top bar of a window that normally closes the window in standard Windows, appears to do a minimise instead on Windows Compact.
How do it make it close instead? I need to also be able to raise an event when this happens as I want to preform some logic on window close.
Set the Form.MinimizeBox property to false. This will change the [X] to [ok], and close your form instead of minimizing it when clicked.
Edit: The event you want is either Closing or Closed.
I'm not sure how this relates to the .NET forum support but you need to use the Native API SHDoneButton.
By default it's set to "SHDB_HIDE" which then shows the "Windows Mobile" "X" button (or any application that overrides X button like LGE's 'X' button application, or the HTC one).
If you set it to "SHDB_SHOW" it will show a "ok" button which sends a IDOK to the window if pressed.
If you set it to "SHDB_SHOWCANCEL" it will show a "x" button which sends a IDCANCEL to the window if pressed. SHDB_SHOWCANCEL is not documented by MSDN but it's in the header file (aygshell.h).

Resources