У меня возникли некоторые проблемы при получении окна уведомлений для правильного поведения в c #.В основном я показываю форму без границ в правой нижней части экрана, которая отображает сообщение в течение нескольких секунд, а затем исчезает.Проблема в том, что мне нужно, чтобы он появлялся поверх других окон, чтобы он не смог украсть фокус.В идеале я хочу, чтобы это был чисто управляемый код, хотя, просматривая похожие примеры, сомневаюсь, что это будет возможно.
В настоящий момент я не даю ему украсть фокус при вызове Form.Show () с переопределением:
protected override bool ShowWithoutActivation // stops the window from stealing focus
{
get { return true; }
}
и последующее игнорирование щелчков мыши с помощью:
private const int WM_MOUSEACTIVATE = 0x0021;
private const int MA_NOACTIVATEANDEAT = 0x0004;
protected override void WndProc(ref Message m)
{
if (m.Msg == WM_MOUSEACTIVATE)
{
m.Result = (IntPtr)MA_NOACTIVATEANDEAT;
return;
}
base.WndProc(ref m);
}
Однако я обнаружил, что если я использую их в сочетании с TopMost = true (что мне нужно), он все равно получает фокуси, если все остальные окна свернуты, он также получает фокус.
Итак, есть ли способ выровнять, чтобы форма не получала фокус (будь то щелчок мыши, alt-tab и т. д.), в то время какпо-прежнему будучи самой верхней / второй по величине формой?Даже простое возвращение фокуса к окну, из которого оно было украдено, сработало бы (хотя и с мерцанием).
Буду очень признателен за любые предложения, я действительно застрял с этим.
РЕДАКТИРОВАТЬ:
Хорошо, так что мне наконец удалось получить эту работу, используя:
protected override bool ShowWithoutActivation // stops the window from stealing focus
{
get { return true; }
}
// and
const int WS_EX_NOACTIVATE = 0x08000000;
const int WS_EX_TOPMOST = 0x00000008;
protected override CreateParams CreateParams
{
get
{
CreateParams param = base.CreateParams;
param.ExStyle |= WS_EX_TOPMOST; // make the form topmost
param.ExStyle |= WS_EX_NOACTIVATE; // prevent the form from being activated
return param;
}
}
// and
[DllImport("user32.dll")]
private extern static IntPtr SetActiveWindow(IntPtr handle);
private const int WM_ACTIVATE = 6;
private const int WA_INACTIVE = 0;
private const int WM_MOUSEACTIVATE = 0x0021;
private const int MA_NOACTIVATEANDEAT = 0x0004;
protected override void WndProc(ref Message m)
{
if (m.Msg == WM_MOUSEACTIVATE)
{
m.Result = (IntPtr)MA_NOACTIVATEANDEAT; // prevent the form from being clicked and gaining focus
return;
}
if (m.Msg == WM_ACTIVATE) // if a message gets through to activate the form somehow
{
if (((int)m.WParam & 0xFFFF) != WA_INACTIVE)
{
if (m.LParam != IntPtr.Zero)
{
SetActiveWindow(m.LParam);
}
else
{
// Could not find sender, just in-activate it.
SetActiveWindow(IntPtr.Zero);
}
}
}
Я также добавил Form.Hide () к событию GotFocus, чтобы дажеесли он каким-то образом получает фокус, он просто закрывается и удаляется от пользователя как можно скорее.
Кроме того, если кому-то интересно, константы для всех стилей окон и т. Д. Можно найти в WINUSER.H, он находится по адресу http://www.woodmann.com/fravia/sources/WINUSER.H, если вы не можете его найти.
Однако, если кто-нибудь увидит более элегантный способ сделать это, это будет оценено.