Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/eclipse/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何检测窗口是否闪烁_C#_.net_Windows 7_Pinvoke_Flashwindowex - Fatal编程技术网

C# 如何检测窗口是否闪烁

C# 如何检测窗口是否闪烁,c#,.net,windows-7,pinvoke,flashwindowex,C#,.net,Windows 7,Pinvoke,Flashwindowex,我正在使用FlashWindowEx()在需要吸引用户注意时刷新应用程序窗口。窗口标题和任务栏按钮持续闪烁,直到应用程序收到焦点。如何检查应用程序当前是否正在闪烁(即,自指示闪烁后未收到焦点)。以下是两种可能的解决方案。一个使用WH_SHELL,另一个使用NativeWindow。您必须提供自己的扩展方法(FlashWindow())来启动闪烁 // base class. Two different forms subclass this form to illustrate two //

我正在使用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);
}
//基类。两个不同的表单将此表单子类化以说明两个
//不同的解决方案。
公共类FormFlash:Form{
受保护标签lb=新标签{Text=“不闪烁”,Dock=DockStyle.Top};
公共FormFlash(){
控件。添加(lb);
线程t=新线程(()=>{
睡眠(3000);
if(Form.ActiveForm==此)
SetForegroundWindow(GetDesktopWindow());//通过将桌面设置为前台窗口来停用当前窗体
this.FlashWindow();//调用扩展方法到flash窗口
lb.BeginInvoke((操作)委托{
lb.Text=“闪烁”;
});
});
t、 IsBackground=true;
t、 Start();
}
[DllImport(“user32.dll”)]
私有静态外部bool setforegroundindow(IntPtr hWnd);
[DllImport(“user32.dll”)]
私有静态外部IntPtr GetDesktopWindow();
}
//这个解决方案简单一点。依赖于程序员知道
//闪动开始了。使用NativeWindow检测WM_何时激活EAPP
//消息发生,表示闪烁结束。
FormFlashNW类:FormFlash{
NW=null;
公共表单FlashNW(){
}
已创建受保护的重写无效OnHandleCreated(EventArgs e){
碱基。根据HandleCreated(e);
nw=新的nw(此手柄,磅);
}
受保护的覆盖无效OnHandleDestroyed(事件参数e){
碱基。经处理的雌雄同体(e);
nw.释放手柄();
}
NW类:本机窗口{
标签lb=null;
公共NW(IntPtr手柄,标签lb){
把手;
这1.lb=lb;
}
受保护的覆盖无效WndProc(参考消息m){
基准WndProc(参考m);
常数int WM_ACTIVATEAPP=0x1C;
如果(m.Msg==WM_ACTIVATEAPP){
lb.BeginInvoke((操作)委托{
lb.Text=“不闪烁”;
});
}
}
}
}
//这个解决方案更复杂。依赖于设置钩子进程。
//“Isflash”布尔在闪烁时交替激发真与假
//它是活动的。
公共类FormShellHook:FormFlash{
public FormShellHook(){
FlashWindowExListener.Register(此);
FlashWindowExListener.FlashVent+=FlashXLListener\u FlashVent;
}
无效FlashXListener\u FlashVent(表格f,bool isFlashing){
如果(f==这个){
lb.Text=DateTime.Now.ToLongTimeString()+“正在闪烁:”+正在闪烁;
}
}
}
公共类FlashWindowExListener{
私有委托IntPtr CallShellProc(intncode、IntPtr wParam、IntPtr lParam);
私有静态CallShellProc procShell=newcallshellproc(ShellProc);
私有静态字典表单=新字典();
私有静态IntPtr hHook=IntPtr.Zero;
公共静态事件FlashWindowExEventHandler FlashEvent=委托{};
公共代表无效FlashWindowExEventHandler(表格f,bool正在闪烁);
静态FlashWindowExListener(){
int processID=GetCurrentThreadId();
//我们有兴趣听WH_SHELL事件,主要是HSHELL_REDRAW事件。
hHook=SetWindowsHookEx(WH_SHELL、procShell、IntPtr.Zero、processID);
System.Windows.Forms.Application.ApplicationExit+=委托{
脱钩(hHook);
};
}
公众静态无效登记册(表格f){
如果(f.IsDisposed)
抛出新ArgumentException(“无法使用已处置的表单”);
if(f.Handle==IntPtr.Zero){
f、 HandleCreated+=委托{
表格[f.Handle]=f;
};
}
其他的
表格[f.Handle]=f;
f、 HandleDestroyed+=委托{
注销(f);
};
}
公共静态无效注销(表格f){
形式。移除(f.手柄);
}
专用静态IntPtr ShellProc(int nCode、IntPtr wParam、IntPtr lParam){
if(nCode==HSHELL\u重绘){
形式f=空;
//看起来没问题,不用打电话给f.BeginInvoke
if(forms.TryGetValue(wParam,out f))
flashvent(f,(int)lParam==1);
}
返回CallNextHookEx(hHook、nCode、wParam、lParam);
}
私有常量int WH_SHELL=10;
私家律师事务所律师事务所律师事务所律师事务所律师事务所律师事务所律师事务所律师事务所律师事务所律师事务所律师事务所律师事务所律师事务所律师事务所律师事务所律师事务所律师事务所律师事务所律师事务所律师事务所律师事务所律师事务所律师事务所律师事务所律师事务所律师事务所律师事务所律师事务所;
[DllImport(“user32.dll”)]
私有静态外部程序int unhookwindowshookx(IntPtr idHook);
[DllImport(“user32.dll”)]
私有静态外部IntPtr setwindowshhookx(intidhook、CallShellProc lpfn、IntPtr hInstance、intthreadid);
[DllImport(“kernel32.dll”)]
私有静态外部int GetCurrentThreadId();
[DllImport(“user32.dll”)]
私有静态外部IntPtr CallNextHookEx(IntPtr idHook、intncode、IntPtr wParam、IntPtr lParam);
}
说你可以通过WH_SHELL钩子来检测它。直到应用程序接收到焦点-当使用
FlashWindowEx()开始闪烁时,你可以一起设置
bool isflash=true
,当接收到焦点事件(
已激活
?)时,可以一起重置(
isflash=false
)。这样,通过简单读取
isflash
的值,您就可以知道它是否在闪烁。