Я использую FlashWindowEx() для запуска окна приложения, когда ему нужно привлечь внимание пользователя. Кнопка заголовка окна и кнопки панели задач непрерывно мигает, пока приложение не получит фокус. Как я могу проверить, мигает ли приложение (т. Е. Не получил фокус, так как ему было предложено мигать).Как обнаружить, что окно мигает
1
A
ответ
1
Вот два возможных решения. Один использует WH_SHELL, и один использует NativeWindow. Вам нужно будет предоставить свой собственный метод расширения (FlashWindow()
), чтобы начать мигать.
// base class. Two different forms subclass this form to illustrate two
// different solutions.
public class FormFlash : Form {
protected Label lb = new Label { Text = "Not flashing", Dock = DockStyle.Top };
public FormFlash() {
Controls.Add(lb);
Thread t = new Thread(() => {
Thread.Sleep(3000);
if (Form.ActiveForm == this)
SetForegroundWindow(GetDesktopWindow()); // deactivate the current form by setting the desktop as the foreground window
this.FlashWindow(); // call extension method to flash window
lb.BeginInvoke((Action) delegate {
lb.Text = "Flashing";
});
});
t.IsBackground = true;
t.Start();
}
[DllImport("user32.dll")]
private static extern bool SetForegroundWindow(IntPtr hWnd);
[DllImport("user32.dll")]
private static extern IntPtr GetDesktopWindow();
}
// this solution is a bit simpler. Relies on the programmer knowing when the
// flashing started. Uses a NativeWindow to detect when a WM_ACTIVATEAPP
// message happens, that signals the end of the flashing.
class FormFlashNW : FormFlash {
NW nw = null;
public FormFlashNW() {
}
protected override void OnHandleCreated(EventArgs e) {
base.OnHandleCreated(e);
nw = new NW(this.Handle, lb);
}
protected override void OnHandleDestroyed(EventArgs e) {
base.OnHandleDestroyed(e);
nw.ReleaseHandle();
}
class NW : NativeWindow {
Label lb = null;
public NW(IntPtr handle, Label lb) {
AssignHandle(handle);
this.lb = lb;
}
protected override void WndProc(ref Message m) {
base.WndProc(ref m);
const int WM_ACTIVATEAPP = 0x1C;
if (m.Msg == WM_ACTIVATEAPP) {
lb.BeginInvoke((Action) delegate {
lb.Text = "Not flashing";
});
}
}
}
}
// this solution is more complicated. Relies on setting up the hook proc.
// The 'isFlashing' bool fires true and false alternating while the flashing
// is active.
public class FormShellHook : FormFlash {
public FormShellHook() {
FlashWindowExListener.Register(this);
FlashWindowExListener.FlashEvent += FlashExListener_FlashEvent;
}
void FlashExListener_FlashEvent(Form f, bool isFlashing) {
if (f == this) {
lb.Text = DateTime.Now.ToLongTimeString() + " is flashing: " + isFlashing;
}
}
}
public class FlashWindowExListener {
private delegate IntPtr CallShellProc(int nCode, IntPtr wParam, IntPtr lParam);
private static CallShellProc procShell = new CallShellProc(ShellProc);
private static Dictionary<IntPtr,Form> forms = new Dictionary<IntPtr,Form>();
private static IntPtr hHook = IntPtr.Zero;
public static event FlashWindowExEventHandler FlashEvent = delegate {};
public delegate void FlashWindowExEventHandler(Form f, bool isFlashing);
static FlashWindowExListener() {
int processID = GetCurrentThreadId();
// we are interested in listening to WH_SHELL events, mainly the HSHELL_REDRAW event.
hHook = SetWindowsHookEx(WH_SHELL, procShell, IntPtr.Zero, processID);
System.Windows.Forms.Application.ApplicationExit += delegate {
UnhookWindowsHookEx(hHook);
};
}
public static void Register(Form f) {
if (f.IsDisposed)
throw new ArgumentException("Cannot use disposed form.");
if (f.Handle == IntPtr.Zero) {
f.HandleCreated += delegate {
forms[f.Handle] = f;
};
}
else
forms[f.Handle] = f;
f.HandleDestroyed += delegate {
Unregister(f);
};
}
public static void Unregister(Form f) {
forms.Remove(f.Handle);
}
private static IntPtr ShellProc(int nCode, IntPtr wParam, IntPtr lParam) {
if (nCode == HSHELL_REDRAW) {
Form f = null;
// seems OK not having to call f.BeginInvoke
if (forms.TryGetValue(wParam, out f))
FlashEvent(f, (int) lParam == 1);
}
return CallNextHookEx(hHook, nCode, wParam, lParam);
}
private const int WH_SHELL = 10;
private const int HSHELL_REDRAW = 6;
[DllImport("user32.dll")]
private static extern int UnhookWindowsHookEx(IntPtr idHook);
[DllImport("user32.dll")]
private static extern IntPtr SetWindowsHookEx(int idHook, CallShellProc lpfn, IntPtr hInstance, int threadId);
[DllImport("kernel32.dll")]
private static extern int GetCurrentThreadId();
[DllImport("user32.dll")]
private static extern IntPtr CallNextHookEx(IntPtr idHook, int nCode, IntPtr wParam, IntPtr lParam);
}
Смежные вопросы
- 1. Окно Pycharm «мигает»
- 2. дочернее окно мигает
- 3. Как обнаружить, что окно не сфокусировано?
- 4. Как обнаружить, что Окно израсходовало вызов «ShowDialog»
- 5. сумасшедший мигает окно OpenGL GLFW
- 6. Щелкать бутстрапом модальное окно мигает
- 7. Как обнаружить окно внешнего окна
- 8. Как обнаружить, что одно окно поворота выше другого
- 9. как обнаружить, что всплывающее окно службы местоположения было ранее показано
- 10. Как обнаружить, что окно WPF было вставлено в Windows 7
- 11. Как можно обнаружить, что вспышка кинопроектор активно окно
- 12. Как обнаружить, что окно функции больше не существует
- 13. обнаружить окно загрузки закрыть jquery
- 14. Как обнаружить, если окно браузера активен
- 15. нажав на ссылку мигает/мигает
- 16. Как обнаружить окно было изменено на Windows7
- 17. Как обнаружить окно браузера/вкладку Close Event?
- 18. Webdriverio - Как обнаружить закрытое окно браузера
- 19. Могу ли я обнаружить, что окно частично скрыто?
- 20. Как обнаружить, что активирован ViewController?
- 21. Как обнаружить, что марионетка завершена
- 22. Как обнаружить, что файл игнорируется?
- 23. Как обнаружить, что что-то будет удалено
- 24. Мигает UILabel как
- 25. Окно GUI в Python (PyQT) мгновенно мигает и закрывается?
- 26. Обнаружить, что SKShapedNode закрыт
- 27. Обнаружить, что вызывает исключение
- 28. Мигает окном
- 29. Окно мигает с рендерингом OpenGL на графической карте NVIDIA
- 30. LibGDX мигает
[Эта статья] (http://stackoverflow.com/questions/7785334) сообщила, что вы можете обнаружить ее через крюк WH_SHELL. – yukitos
* пока приложение не получит фокус * - вы можете установить 'bool IsFlashing = true' вместе при запуске мигания с помощью' FlashWindowEx() 'и сбросить (' IsFlashing = false') при получении фокусного события ('Activated'?). Таким образом, вы узнаете, мигает ли оно или нет, простым значением чтения 'IsFlashing'. – Sinatr