如何检测窗口是否闪烁

2024-03-01

当需要吸引用户注意时,我使用 FlashWindowEx() 来闪烁应用程序窗口。窗口标题和任务栏按钮持续闪烁,直到应用程序获得焦点。如何检查应用程序当前是否正在闪烁(即,自从指示其闪烁以来尚未获得焦点)。


这里有两种可能的解决方案。一种使用 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);
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何检测窗口是否闪烁 的相关文章

  • 秒表有最长运行时间吗?

    多久可以Stopwatch在 NET 中运行 如果达到该限制 它会回绕到负数还是从 0 重新开始 Stopwatch Elapsed返回一个TimeSpan From MSDN https learn microsoft com en us
  • 在哪里可以找到列出 SSE 内在函数操作的官方参考资料?

    是否有官方参考列出了 GCC 的 SSE 内部函数的操作 即 头文件中的函数 除了 Intel 的 vol 2 PDF 手册外 还有一个在线内在指南 https www intel com content www us en docs in
  • 用于检查类是否具有运算符/成员的 C++ 类型特征[重复]

    这个问题在这里已经有答案了 可能的重复 是否可以编写一个 C 模板来检查函数是否存在 https stackoverflow com questions 257288 is it possible to write a c template
  • 使用实体框架模型输入安全密钥

    这是我今天的完美想法 Entity Framework 中的强类型 ID 动机 比较 ModelTypeA ID 和 ModelTypeB ID 总是 至少几乎 错误 为什么编译时不处理它 如果您使用每个请求示例 DbContext 那么很
  • 如何从 appsettings.json 文件中的对象数组读取值

    我的 appsettings json 文件 StudentBirthdays Anne 01 11 2000 Peter 29 07 2001 Jane 15 10 2001 John Not Mentioned 我有一个单独的配置类 p
  • 将多个表映射到实体框架中的单个实体类

    我正在开发一个旧数据库 该数据库有 2 个具有 1 1 关系的表 目前 我为每个定义的表定义了一种类型 1Test 1Result 我想将这些特定的表合并到一个类中 当前的类型如下所示 public class Result public
  • WCF 中 SOAP 消息的数字签名

    我在 4 0 中有一个 WCF 服务 我需要向 SOAP 响应添加数字签名 我不太确定实际上应该如何完成 我相信响应应该类似于下面的链接中显示的内容 https spaces internet2 edu display ISWG Signe
  • 显示UnityWebRequest的进度

    我正在尝试使用下载 assetbundle统一网络请求 https docs unity3d com ScriptReference Networking UnityWebRequest GetAssetBundle html并显示进度 根
  • SolrNet连接说明

    为什么 SolrNet 连接的容器保持静态 这是一个非常大的错误 因为当我们在应用程序中向应用程序发送异步请求时 SolrNet 会表现异常 在 SolrNet 中如何避免这个问题 class P static void M string
  • 转发声明和包含

    在使用库时 无论是我自己的还是外部的 都有很多带有前向声明的类 根据情况 相同的类也包含在内 当我使用某个类时 我需要知道该类使用的某些对象是前向声明的还是 include d 原因是我想知道是否应该包含两个标题还是只包含一个标题 现在我知
  • 控件的命名约定[重复]

    这个问题在这里已经有答案了 Microsoft 在其网站上提供了命名指南 here http msdn microsoft com en us library xzf533w0 VS 71 aspx 我还有 框架设计指南 一书 我找不到有关
  • 如何序列化/反序列化自定义数据集

    我有一个 winforms 应用程序 它使用强类型的自定义数据集来保存数据进行处理 它由数据库中的数据填充 我有一个用户控件 它接受任何自定义数据集并在数据网格中显示内容 这用于测试和调试 为了使控件可重用 我将自定义数据集视为普通的 Sy
  • 如何查看网络连接状态是否发生变化?

    我正在编写一个应用程序 用于检查计算机是否连接到某个特定网络 并为我们的用户带来一些魔力 该应用程序将在后台运行并执行检查是否用户请求 托盘中的菜单 我还希望应用程序能够自动检查用户是否从有线更改为无线 或者断开连接并连接到新网络 并执行魔
  • 链接器错误:已定义

    我尝试在 Microsoft Visual Studio 2012 中编译我的 Visual C 项目 使用 MFC 但出现以下错误 error LNK2005 void cdecl operator new unsigned int 2
  • 混合 ExecutionContext.SuppressFlow 和任务时 AsyncLocal.Value 出现意外值

    在应用程序中 由于 AsyncLocal 的错误 意外值 我遇到了奇怪的行为 尽管我抑制了执行上下文的流程 但 AsyncLocal Value 属性有时不会在新生成的任务的执行范围内重置 下面我创建了一个最小的可重现示例来演示该问题 pr
  • 是否可以在 .NET Core 中将 gRPC 与 HTTP/1.1 结合使用?

    我有两个网络服务 gRPC 客户端和 gRPC 服务器 服务器是用 NET Core编写的 然而 客户端是托管在 IIS 8 5 上的 NET Framework 4 7 2 Web 应用程序 所以它只支持HTTP 1 1 https le
  • C# 模拟VolumeMute按下

    我得到以下代码来模拟音量静音按键 DllImport coredll dll SetLastError true static extern void keybd event byte bVk byte bScan int dwFlags
  • IEnumreable 动态和 lambda

    我想在 a 上使用 lambda 表达式IEnumerable
  • Windows 和 Linux 上的线程

    我在互联网上看到过在 Windows 上使用 C 制作多线程应用程序的教程 以及在 Linux 上执行相同操作的其他教程 但不能同时用于两者 是否存在即使在 Linux 或 Windows 上编译也能工作的函数 您需要使用一个包含两者的实现
  • 如何在文本框中插入图像

    有没有办法在文本框中插入图像 我正在开发一个聊天应用程序 我想用图标图像更改值 等 但我找不到如何在文本框中插入图像 Thanks 如果您使用 RichTextBox 进行聊天 请查看Paste http msdn microsoft co

随机推荐

  • Wordpress 开发插件时出错 - “您没有足够的权限访问此页面。”

    我刚刚开始学习 WordPress 插件开发 当我从管理员访问我的插件菜单时出现此错误 这是代码 importer php Admin function function oscimp admin include importer admi
  • 如何检查 GTK+3.0 中小部件的类型?

    I saw this https stackoverflow com questions 60112777 find type of gtk widgets帖子 但它是针对 Python 的 所以这对我没有太大帮助 我正在使用 C 进行编程
  • 如何避免 gen_l10n/app_localizations.dart 的 lint 问题“依赖于引用的包”[关闭]

    Closed 这个问题需要调试细节 help minimal reproducible example 目前不接受答案 在我的 Flutter 应用程序上 我遇到了 lint 规则的问题 依赖于引用的包 https dart lang gi
  • Intel TBB 可以在 AMD 处理器上运行吗? [复制]

    这个问题在这里已经有答案了 可能的重复 AMD多核编程 https stackoverflow com questions 1623975 amd multi core programming Is 英特尔TBB http threadin
  • C#:从锁定块调用事件

    我通常听说在调用事件侦听器之前解锁所有锁以避免死锁是一个好主意 然而 自从lock 块可以由 C 中的同一线程重入 是否可以从锁定块调用事件 或者我是否需要复制相关状态数据并在锁定块外部调用事件 如果没有 请举例说明何时从某个对象内调用事件
  • “MutationObserver”上的“观察”:参数 1 不是“Node”类型

    我正在创建一个 Chrome 扩展程序 并尝试在 gMail 撰写框的 发送 按钮旁边包含一个小文本 我正在使用 MutationObserver 来了解撰写框窗口何时出现 我通过观察带有类的元素来做到这一点no因为撰写框元素是作为该元素的
  • 在函数参数之前使用 & 的目的是什么?

    我看到一些函数声明是这样的 function boo var 什么是 性格呢 这是通过引用传递 函数内的变量 指向 与调用上下文中的变量相同的数据 function foo bar bar 1 x 0 foo x echo x 1
  • Codeigniter REST CSV 导入到 mysql

    我想使用 API 在我的控制器上发布 csv 文件 我正在使用 phil sturgeon 的 Codeigniter REST 库 如何在客户端实现将 CSV 导入到我的 REST 服务器 我只是想问一下 因为我找不到任何有关它的文档 这
  • var FOO = FOO || 如何实现Javascript 中的 {} 习惯用法?

    从这个问题来看 var FOO FOO 将变量或空对象分配给该变量 在 Javascript 中意味着什么 https stackoverflow com questions 6439579 what does var foo foo as
  • 如何用单引号插入文本sql server 2005

    我想插入带单引号的文本 例如 john 到 sql server 2005 数据库中的表 正如 Kirtan 指出的那样 使用附加单引号来转义单引号如果您尝试通过 sp executesql 执行动态 sql 这首先不是一个好主意 那么下面
  • 如何从 UITableView 中获取选定的行?

    因此 我编写了这段代码 在我想要选择的行旁边打上复选标记 因为我想要多个选定的行 UITableViewCell cell tableView cellForRowAtIndexPath path if cell accessoryType
  • 为什么 const 左值引用可以引用可变右值引用?

    在 C 11 中 可以使用可变右值引用来初始化 const 左值引用 然后 右值引用的值可以发生变化 产生 const 左值引用的可见突变 这是一个例子 int rval 3 const int lval rval cout lt lt l
  • DbSet 在 EF7 中没有 Find 方法

    我正在尝试创建一个通用存储库来访问我的数据库 在 EF6 中 我能够这样做以获得特定的实体 protected IDbSet
  • R:合并具有相同ID的行[重复]

    这个问题在这里已经有答案了 Edit 我将 Var4 更改为字符串值 因为我的问题对我的数据不够精确 因此由于类型无效 答案失败 对此感到抱歉 这是我的第一个问题 我希望有人可以帮助我 我有以下数据集 ID Date N Date Var1
  • 在列表中查找一个值[重复]

    这个问题在这里已经有答案了 我使用以下命令来检查是否item is in my list if item in my list print Desired item is in list Is if item in my list 在列表中
  • 与 Vuex-ORM 的两种方式数据绑定

    有谁知道使用时在表单中实现双向数据绑定的库或已经描述的模式Vuex ORM https vuex orm github io vuex orm 我找到了几个可以帮助解决 Vuex 问题的库 但还没有专门针对 Vuex ORM 的库 vuex
  • 如何在 Java 中使用 servlet 过滤器来更改传入的 servlet 请求 url?

    如何使用 servlet 过滤器更改传入的 servlet 请求 url http nm java appspot com Check License Dir My App Dir ABC My Obj 123 to http nm jav
  • 使用spring-amqp和rabbitmq实现带退避的非阻塞重试

    我正在寻找一种使用 spring amqp 和 Rabbit MQ 的退避策略来实现重试的好方法 但要求是侦听器不应被阻止 因此可以自由地处理其他消息 我在这里看到了类似的问题 但它不包括 后退 的解决方案 RabbitMQ 和 Sprin
  • Kohana 3 分页

    我真的不知道 Kohana 3 中的分页是如何工作的 Kohana 3 中是否有一个很好的分页示例 Get the total count of articles count this gt profil gt articles gt co
  • 如何检测窗口是否闪烁

    当需要吸引用户注意时 我使用 FlashWindowEx 来闪烁应用程序窗口 窗口标题和任务栏按钮持续闪烁 直到应用程序获得焦点 如何检查应用程序当前是否正在闪烁 即 自从指示其闪烁以来尚未获得焦点 这里有两种可能的解决方案 一种使用 WH