I want to capture events that close editor window (tab) in Visual Studio 2008 IDE.
When I use
dte2.Application.Events.get_CommandEvents(null, 0).BeforeExecute
I successfully captured such events:
File.Close
File.CloseAllButThis
File.Exit
Window.CloseDocumentWindow
and others.
If code in window is not acceptable, I stop the event (CancelDefault = true).
But if I click "X" button on the right hand side, "Save Changes"; dialog appears, tab with
editor window close and I have no any captured events. In this case I can capture WindowClosing event,
but can not cancel the event.
Is it poosible to handle "x" button click and stop event?
In C# it would be something like this: you add Closing event handler and then
void MyWindow_Closing(object sender, CancelEventArgs e)
{
if(something)
e.Cancel = true; //<- thats the magic part you want
}
I would suggest, check on the lines of handling MDI Child window events!!
The editor tab you are referring is basically an instance of MDI Child Window.
Hope this helps!
If you're willing to use some Windows API code you might be able to set up a hook using the SetWindowsHookEx function to intercept WM_CLOSE, WM_QUIT and WM_DESTROY.
Related
Is it possible to prevent mouse events when a window is activated?
For example, I have a C# window and I change the focus to something else such as a browser. When I reactivate the c# window by clicking on it, I don't want any mouse events to be executed. The first click on the window should just activate it. Mouse Events are only fired if the window is already activated.
An event will be fired then a user clicks on your wpf controll but why don't you just handle the event?
Subscribe to the event and prevent it to bubble up the visual tree:
private void Panel_KeyDown(object sender, KeyEventArgs e)
{
e.Handled = true;
}
Have a look at this link it describes the event bubble and tunneling in WPF.
I am coding a Windows form based application in C#.
When I click on the red cross(x) on the top right corner of the windows it should not stop the execution of the program. It should instead go to next part of the program. What do I need to do in order to have my program behave this way?
You can use the form closing event to cancel the closing of the form. In the designer click the lighting symbol in the properties and double click the form closing entry. This should make the code for you. It should make a function a bit like this:
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
e.Cancel = true;
}
You need to add the e.Cancel that will stop the form closing
Within the application I am writing for testing/learning C#, I use the hidden/visible property to open and close windows.
It is a WPF application.
In the main window, I have a "close" button that triggers this method:
public void buttonQuit_Click(object sender, RoutedEventArgs e)
{
var message = exitmessage;
var title = exitTitle;
var result = MessageBox.Show(
message, // the message to show
title, // the title for the dialog box
MessageBoxButton.YesNo, // show two buttons: Yes and No
MessageBoxImage.Question); // show a question mark icon
// lets see what has been pressed
switch (result)
{
case System.Windows.MessageBoxResult.Yes: // Yes button pressed
CloseAllWindows();
break;
case System.Windows.MessageBoxResult.No: // No button pressed
break;
default: // Neither Yes nor No pressed (just in case)
MessageBox.Show("Oh noes! What did you press?!?!");
break;
}
}
This way I make sure that all windows get closed, including the hidden ones.
But now is the catch; when the user presses (in the main window) the top right red X in toolbar to close, only that main window gets closed, but in the background the hidden ones are still there.
So in fact it is 2 questions:
Is CloseAllWindows(); really sufficient to get the app 100% closed down?
How do I "catch" the event when the user presses that red X in the toolbar, and make this also trigger the right closing event?
You should be handling either the Closing or Closed event for your window(s). The former allows you to cancel the close, while the latter just allows you to perform necessary cleanup in response to the window being closed.
So, in this case, you should place the code from your buttonQuit_Click method into a handler method attached to the Closing event so that it gets triggered regardless of how the window is closed.
Then, your buttonQuit_Click method can simply call the window's Close method. That will close the window, in turn raising the Closing event, and running your code in the attached handler method.
As far as your other question, CloseAllWindows will do exactly what it says: it will close all of the windows that your application has opened. In most cases, that should be sufficient to close the application, but it might not be, especially if you've created non-background threads or depending on the ShutdownMode setting.
App.Current.Shutdown will work unconditionally.
You could use the Closing event of the window for that.
Some more info
http://msdn.microsoft.com/en-us/library/system.windows.window.closing.aspx
How can I capture a mouse click outside of a panel in an Windows Form application?
To capture global mouse and keyboard events you need to capture the windows messages WM_MOUSE_LL and WM_KEYBOARD_LL, not just WM_MOUSE and WM_KEYBOARD. These events can only be captured in NT/2000/XP. In later OS versions this is not possible (for fairly obvious security reasons I assume).
If you are using NT/2000/XP here is some example code:
http://www.codeproject.com/KB/cs/globalhook.aspx
The answer is in your question, set the panel's Capture property to true. All mouse input events are now directed to the panel, even if the mouse is outside of the panel window. This is however a temporary conditions (as it should be), a button click is going to cancel the capture after the click is delivered to the panel. The MouseCaptureChanged event lets you know when that happened. Unconditionally capturing the mouse is not an option, typing Ctrl+Esc for example will always cancel it.
You can handle the MouseClick event of the form itself.
class YourForm : Form
{
protected override void OnMouseClick(MouseEventArgs e)
{
base.OnMouseClick(e);
// Do something.
}
}
I'm writing a Windows application that basically runs in the background with a notification icon to interact with it. The notification icon can do basic things like exit the application or show information about it. It can also launch a modal configuration dialog.
The code that creates the dialog is pretty straightforward:
using(var frmSettings = new SettingsForm(configuration))
{
frmSettings.ConfigurationChanged += ConfigurationChangedHandler;
frmSettings.UnhandledException += UnhandledExceptionHandler;
frmSettings.ShowDialog();
}
The SettingsForm class basically has three GroupBox controls, with a Label and TextBox control in each, and 4 Button controls at the bottom: "Advanced...", "Restore Defaults", "Cancel", and "Apply". Each TextBox has a Validating event handler wired up through the designer. Each button has a Click handler wired up through the designer. Each of them does pretty obvious things: opens another modal dialog with more advanced settings, restores the textboxes to their default values, closes the dialog, or saves the changes, fires the ConfigurationChanged event, and then closes the dialog (but only if all fields are valid!).
When there is a form entry error I cancel the corresponding Validating event by setting ((CancelEventArgs)e).Cancel = true. However, the default behavior of both forms was to prevent the user from changing focus when validation failed. I found this pretty annoying and eventually found the option in the designer to still automatically validate when the user leaves the field, but to allow them to leave even if validation fails: AutoValidate = EnableAllowFocusChange.[1]
My "Apply" button Click handler looks basically like this:
private void btnApply_Click(object sender, EventArgs e)
{
try
{
if(this.ValidateChildren())
{
this.Configuration.Field1 = this.txtField1.Text;
this.Configuration.Field2 = this.txtField2.Text;
this.Configuration.Field3 = this.txtField3.Text;
if(this.Configuration.Changed)
{
this.Configuration.Save();
this.OnConfigurationChanged(new ConfigurationChangedEventArgs(
this.Configuration));
}
this.Close();
}
}
catch(Exception ex)
{
this.OnUnhandledException(new UnhandledExceptionEventArgs(
"Failed To Apply Configuration Settings",
ex));
}
}
I'm currently testing out the code by breaking on the first line and stepping through the method line by line. Essentially, ValidateChildren is returning false as expected and the entire if block, including the this.Close() are skipped. Yet, if I step all the way to the bottom of the method and then step out of it I end up back on the frmSettingsForm.ShowDialog() line and the form is magically closed.
The "Apply" button is set as the form's AcceptButton. I wonder if it's implicitly attached a handler to the button's Click event to automatically close the form when the button is pressed. That doesn't sound like it logically should be assumed, especially considering there doesn't seem to be a way to cancel the Click event, but it's the only explanation that I can come up with. To test that theory, I have tried unsetting the AcceptButton in the designer, but my form still closes when the data is invalid.
What is closing my form and how do I stop it?
[1]: If anybody else has trouble finding it, it's a form property, not a property of each individual control (as I expected it would be).
Do you have the DialogResult of the Button set? If so, when you click the Button, the DialogResult of the Form will be set to that value and the modal Form will close. To prevent this, when validation fails in your Click handler, set the Form's DialogResult to DialogResult.None.
I don't know why that happens, but you could override the event OnFormClosing and check for the value of DialogResult according to your logic.
If (DialogResult != Windows.Forms.DialogResult.Cancel )
e.Cancel = True