• C# WPF 无窗体传递消息


    WPF如果存在窗体(或至少,在任务栏有图标显示),互相传递消息是很容易的。

    寻找目标窗体句柄->WindowsAPI SendMessage/PostMessage->目标窗体AddHook。参见:C# WPF 窗体传递消息

    但是,如果窗体不存在,比如说,最小化的时候仅显示一个tray icon,连任务栏的图标都不能用,这个流程就不管用了。因为此时无法获取到目标窗体的句柄。

    到达到这个要求,还有几种不同的方法:

    1.管道。因为就在本机传递消息,所以匿名管道/命名管道都可以满足要求;

    2.TCP/UDP 如果仅仅是传递一些特定的约定好的少数信息的话,这有点杀鸡用牛刀的感觉;

    3.Windows API: PostThreadMessage

    本文介绍第三种方法:

    示例目标:程序只能运行一个实例,当程序再次被启动,就通知已经运行的实例并且关闭自身进程

    1.判断/获取已经运行的实例

    跟上一篇博文一样的代码一样……

    2.注册WindowsAPI

            [return: MarshalAs(UnmanagedType.Bool)]
            [DllImport("user32.dll", SetLastError = true)]
            public static extern bool PostThreadMessage(int threadId, uint msg, IntPtr wParam, IntPtr lParam);

    3.修改App.OnStartup方法

            public const uint WM_APP = 0x9112;//0x8001~0xBFFF;
    
            protected override void OnStartup(StartupEventArgs e)
            {
                base.OnStartup(e);
    
                Process targetProcess = GetCurrentExeProcess();
    
                if (targetProcess!=null)//Software has been running...
                {
                    if (targetProcess.Threads.Count > 0)
                    {
                        int targetMainThreadID=targetProcess.Threads[0].Id;
    
                        bool result=SingleExeHelper.PostThreadMessage(targetMainThreadID, WM_APP, IntPtr.Zero, IntPtr.Zero);
                    }
                    
                    Environment.Exit(0);//Software has been running, close this
                }
                else
                {
                    ComponentDispatcher.ThreadPreprocessMessage += ComponentDispatcher_ThreadPreprocessMessage;
                }
            }
    
            private void ComponentDispatcher_ThreadPreprocessMessage(ref MSG msg, ref bool handled)
            {
                int m = (int)App.WM_APP;
                if (msg.message == m)
                {
                    System.Windows.MessageBox.Show("收到信息啦!!!!");
                }
            }

    因为没有窗体了,所以在App.OnStartup方法注册收到消息的处理方法。

    参考文章:

    WPF中的Windows消息 . 

    How can I register a global hot key to say CTRL+SHIFT+(LETTER) using WPF and .NET 3.5?

    C#向无窗口的进程发送消息

  • 相关阅读:
    js -- 判断数组是否为空?
    vue 初始化高德地图
    git .gitignore 忽略规则的匹配语法
    vue 人脸识别 demo
    vue音乐app——VSCODE中设置vue文件模板
    vue音乐项目——解析stylus中的 &.router-link-active
    十月训练记录
    概率与期望 学习笔记
    山东省队集训整理
    APIO2020 简要题解
  • 原文地址:https://www.cnblogs.com/AlvinLiang/p/6184182.html
Copyright © 2020-2023  润新知