O Gerenciador de tarefas Fechar não é detectado pela segunda vez em um aplicativo Winforms
-
23-09-2019 - |
Pergunta
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (e.CloseReason == CloseReason.UserClosing)
{
if (MessageBox.Show(this, "Do you really want to close?", "Close?",
MessageBoxButtons.YesNo) == DialogResult.No)
{
e.Cancel = true;
}
}
}
Então, quando eu quero fechar o aplicativo clicando no botão Fechar, a caixa de mensagem é mostrada como deveria, então eu escolhi não. Em seguida, a linha e.cancel = true é executada e o formulário não está fechado.
Agora, a coisa é que, depois disso, se eu fechar o aplicativo do gerente de tarefas, o motivo próximo é UserClosing !!! Por quê? Não deveria ser o TaskManagerclosing?
Solução
Achei um fio com uma resposta por nossa própria Nobugz:
Os formulários do Windows não podem detectar que o motivo próximo veio do gerenciador de tarefas. Por isso traduz automaticamente o ClosEROUNH.NONE para Closteron.TaskManagerClosing. O problema é que, uma vez que você tentou fechar com o "X", a Closerason está definida como UserClosing e não é redefinida de volta a ninguém se você cancelar o fechamento. Desleixado.
E ao lado, uma explicação de outro usuário sobre como alterar o valor de E.Closerason para nenhum usando a reflexão (pois é somente leitura), para trabalhar com esse problema (isso deve ser aplicado ao definir e. :
FieldInfo fi = typeof(Form).GetField("closeReason", BindingFlags.Instance | BindingFlags.NonPublic);
fi.SetValue(this, CloseReason.None);
Outras dicas
Veja o responda a esta pergunta que usa CloseReason.TaskManagerClosing
para pegar o mesmo.
Apenas a tradução de você code em VB:
Imports System.Reflection
Private Sub ResetCloseReason()
Dim myFieldInfo As FieldInfo
Dim myType As Type = GetType(Form)
myFieldInfo = myType.GetField("closeReason", BindingFlags.NonPublic Or _
BindingFlags.Instance Or BindingFlags.Public)
myFieldInfo.SetValue(Me, CloseReason.None)
End Sub