C#Winform程序判断是不是有全屏窗口程序正在运行

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C#Winform程序判断是不是有全屏窗口程序正在运行相关的知识,希望对你有一定的参考价值。

修改启动文件Program.cs
static class Program
    
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main()
        
            Process instance = RunningInstance();
            if (instance == null)
            
                //没有实例在运行
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                Application.Run(new Form1());
            
            else
            
                //已经有一个实例在运行
                HandleRunningInstance(instance);
            
        
 
         private static Process RunningInstance()
         
             Process current = Process.GetCurrentProcess();
             Process[] processes = Process.GetProcessesByName(current.ProcessName);
             //遍历与当前进程名称相同的进程列表  
             foreach (Process process in processes)
             
                 //如果实例已经存在则忽略当前进程  
                 if (process.Id != current.Id)
                 
                     //保证要打开的进程同已经存在的进程来自同一文件路径
                     if (Assembly.GetExecutingAssembly().Location.Replace("/", "\\\\") == current.MainModule.FileName)
                     
                         //返回已经存在的进程
                         return process;
                          
                     
                 
             
             return null;
         
 
         public static void HandleRunningInstance(Process instance)
         
             ShowWindowAsync(instance.MainWindowHandle, WS_SHOWNORMAL);
             SetForegroundWindow(instance.MainWindowHandle);
         
         [DllImport("User32.dll")]
         private static extern bool ShowWindowAsync(IntPtr hWnd, int cmdShow);
         [DllImport("User32.dll")]
         private static extern bool SetForegroundWindow(IntPtr hWnd);
         private const int WS_SHOWNORMAL = 1;
    

参考技术A 注册一个AppBar(什么是AppBar?Using Application Desktop Toolbars),通过SHAppBarMessage向系统注册AppBar,这样,当有程序全屏运行时系统会向我们的程序发送消息,在窗体WndProc中处理即可。

声明要使用到的API和常量:
public class APIWrapper

[DllImport("SHELL32", CallingConvention = CallingConvention.StdCall)]
public static extern uint SHAppBarMessage(int dwMessage, ref APPBARDATA pData);

[DllImport("User32.dll", CharSet = CharSet.Auto)]
public static extern int RegisterWindowMessage(string msg);



[StructLayout(LayoutKind.Sequential)]
public struct APPBARDATA

public int cbSize;
public IntPtr hWnd;
public int uCallbackMessage;
public int uEdge;
public RECT rc;
public IntPtr lParam;


public enum ABMsg : int

ABM_NEW = 0,
ABM_REMOVE,
ABM_QUERYPOS,
ABM_SETPOS,
ABM_GETSTATE,
ABM_GETTASKBARPOS,
ABM_ACTIVATE,
ABM_GETAUTOHIDEBAR,
ABM_SETAUTOHIDEBAR,
ABM_WINDOWPOSCHANGED,
ABM_SETSTATE


public enum ABNotify : int

ABN_STATECHANGE = 0,
ABN_POSCHANGED,
ABN_FULLSCREENAPP,
ABN_WINDOWARRANGE


public enum ABEdge : int

ABE_LEFT = 0,
ABE_TOP,
ABE_RIGHT,
ABE_BOTTOM


[StructLayout(LayoutKind.Sequential)]
public struct RECT

public int left;
public int top;
public int right;
public int bottom;

public override string ToString()

return "left=" + left.ToString() + ", " + "top=" + top.ToString() + ", " +
"right=" + right.ToString() + ", " + "bottom=" + bottom.ToString() + "";


重载窗口消息处理函数:
protected override void WndProc(ref System.Windows.Forms.Message m)

if (m.Msg == uCallBackMsg)

switch (m.WParam.ToInt32())

case (int)ABNotify.ABN_FULLSCREENAPP:

if ((int)m.LParam == 1)
this.RunningFullScreenApp = true;
else
this.RunningFullScreenApp = false;
break;

default:
break;



base.WndProc(ref m);

在程序退出时,不要忘了Unregister我们注册的AppBar:this.RegisterAppBar(true);
以上介绍的是C# Winform程序判断是否有全屏窗口程序正在运行,希望队你有所帮助。本回答被提问者和网友采纳

C++ 获取全屏窗口的设备上下文

【中文标题】C++ 获取全屏窗口的设备上下文【英文标题】:C++ Getting the Device Context of Fullscreen Window 【发布时间】:2013-12-02 07:07:04 【问题描述】:

我正在尝试获取窗口处理程序的设备上下文。

IntPtr dc = GetWindowDC(WHandle);

但我无法获取实际应用程序的处理程序。它正在获取整个桌面屏幕。

如何获取全屏应用的设备上下文?

【问题讨论】:

所以它是一个“全屏” 应用程序,而您获得了“整个桌面” 的句柄?这当然是有道理的,不是吗?还是我错过了什么? 是的。 @罗杰罗兰。我使用该处理程序捕获了图像。它给出了桌面屏幕的图像。它没有给出实际的全屏应用程序截图。请提供任何建议。 您无法通过其底层窗口的 DC 捕获 DirectX 应用程序的内容。 【参考方案1】:

也许(我没有 Windows 8 可以尝试)这会有所帮助。来自msdn:

GetDC函数

GetDC 函数检索设备上下文 (DC) 的句柄 指定窗口或整个屏幕的客户区

【讨论】:

我尝试了 GetDC 功能。由于我的应用程序是一个游戏,它总是以全屏模式运行。但是我无法使用 GetDC 或 GetWindowDC 获取该游戏应用程序的处理程序和设备上下文。 游戏不是我的领域。所以,不确定,this 可以帮忙吗?【参考方案2】:

如果你只是想给你的游戏截图,你可以试试 DirectX 功能:GetFrontBufferData,小心,这个功能很慢。但是,如果您的游戏使用 Overlay 表面,那么除了挂钩 DirectX 之外,没有其他方法可以捕获它。

【讨论】:

以上是关于C#Winform程序判断是不是有全屏窗口程序正在运行的主要内容,如果未能解决你的问题,请参考以下文章

c# winform程序,判断是不是打开同一个窗口的问题。

C#winform判断子窗口是不是已关闭或在关闭的时候触发事件

winform 窗口加载时候屏幕闪动

C# - 为啥全屏 Winform 应用程序不总是覆盖任务栏?

C++ 获取全屏窗口的设备上下文

C ++ glfw3:全屏模式下的一个(两个)窗口不是真正的全屏(Mac Os)