C# 获得另一个窗体句柄并发送消息(使用windows API)

2023-05-16

复制代码


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.IO;
 
namespace findWindowTest
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
 
        // Find Window
        // 查找窗体
        // @para1: 窗体的类名 例如对话框类是"#32770"
        // @para2: 窗体的标题 例如打开记事本 标题是"无标题 - 记事本" 注意 - 号两侧的空格
        // return: 窗体的句柄
        [DllImport("User32.dll", EntryPoint = "FindWindow")]
        public static extern IntPtr FindWindow(string className, string windowName);
       
       
       
       
       
        // Find Window Ex
        // 查找窗体的子窗体
        // @para1: 父窗体的句柄 如果为null,则函数以桌面窗口为父窗口,查找桌面窗口的所有子窗口
        // @para2: 子窗体的句柄 如果为null,从@para1的直接子窗口的第一个开始查找
        // @para3: 子窗体的类名 为""表示所有类
        // @para4: 子窗体的标题 为""表示要查找的窗体无标题 如空白的textBox控件
        // return: 子窗体的句柄
        [DllImport("user32.dll", EntryPoint = "FindWindowEx")]
        private static extern IntPtr FindWindowEx(
            IntPtr hwndParent,
            IntPtr hwndChildAfter,
            string lpszClass,
            string lpszWindow);
 
        // SendMessage
        // 向窗体发送消息
        // @para1: 窗体句柄
        // @para2: 消息类型
        // @para3: 附加的消息信息
        // @para4: 附加的消息信息
        [DllImport("User32.dll", EntryPoint = "SendMessage")]
        private static extern int SendMessage(
            IntPtr hWnd,
            int Msg,
            IntPtr wParam,
            string lParam);
 
        // 消息类型(部分)
        const int WM_GETTEXT     = 0x000D;  // 获得窗体文本 如获得对话框标题
        const int WM_SETTEXT     = 0x000C;  // 设置窗体文本 如设置文本框内容
        const int WM_CLICK       = 0x00F5;  // 发送点击消息如调用该窗体(按钮)的"button1_Click();"
 
        // 本程序针对指定的另一程序窗体因此声名了如下变量
        IntPtr Wnd  = new IntPtr(0);// 一卡通注册程序主窗体
        IntPtr sWnd = new IntPtr(0);// GroupBox控件 此为“一卡通注册程序”主窗体的子窗体
        IntPtr txt  = new IntPtr(0);// 文本框
        IntPtr btn1 = new IntPtr(0);// 查询按钮
        IntPtr btn2 = new IntPtr(0);// 注册按钮 这三个窗体又为“GroupBox控件”的子窗体
        //IntPtr popW = new IntPtr(0);// 弹出对话框
        //IntPtr popB = new IntPtr(0);// 弹出对话框确定按钮
 
        // 文件操作
        private String filename = string.Empty;
        private StreamReader reader = null;
 
        // 从“打开文件”对话框打开txt文件 同时获得需要的窗口句柄
        private void button2_Click(object sender, EventArgs e)
        {
            label2.Text = "";
            openFileDialog1.DefaultExt = "txt";
            openFileDialog1.Filter = "文本文件|*.txt";
            openFileDialog1.RestoreDirectory = true;
            openFileDialog1.FilterIndex = 1;
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                filename = openFileDialog1.FileName;
            }
 
            // 获得窗口句柄
            Wnd  = FindWindowEx((IntPtr)0, (IntPtr)0, null, "读者一卡通注册");// 一个注册程序的窗体
            sWnd = FindWindowEx(Wnd,  (IntPtr)0, null, "条件"); // 窗体上的一个GroupBox控件
            txt  = FindWindowEx(sWnd, (IntPtr)0, null, "");     // GroupBox内的textBox控件
            btn1 = FindWindowEx(sWnd, (IntPtr)0, null, "查询"); // GroupBox内的查询按钮
            btn2 = FindWindowEx(sWnd, (IntPtr)0, null, "注册"); // GroupBox内的注册按钮
        }
 
        // 重复地把文件内读取的行
        // 将该行发送给注册程序窗体上的文本框中
        // 并“点击”查询按钮和注册按钮
        // 直到文件读取完毕
        private void button3_Click(object sender, EventArgs e)
        {
            //计数
            int count = 0;
 
            //读取文件
            if (filename == string.Empty)
            {
                button2.Focus();
                return;
            }
 
            reader = new StreamReader(filename);
            if (reader.EndOfStream)
            {
                return;
            }
 
            string str = string.Empty;
 
            do
            {
                //读取学号 保存在变量str中
                str = reader.ReadLine();
 
                //设置学号
                SendMessage(txt, WM_SETTEXT, (IntPtr)0, str);
 
                //点击查询按钮
                SendMessage(btn1, WM_CLICK, (IntPtr)0, "");
 
                //点击注册按钮
                SendMessage(btn2, WM_CLICK, (IntPtr)0, "");
 
                count++;
            }
            while(!reader.EndOfStream);
 
            reader.Close();
            filename = string.Empty;
            label1.Text = "注册人数:";
            label2.Text = Convert.ToString(count);
        }
    }
}  

复制代码

//*********

      在项目中有这样的需求,在主窗体隐藏时或者主进程运行时对其它窗体的控件或者事件进行控制,而且其它窗体是处于活动状态,而主窗体或者主进程是隐藏在后面的。这个时候使用句柄和消息来处理就比较好解决这些问题了,当然了也可以使用其它方法。比如将其它窗体在主窗体中申明并且定义,使之和主窗体一样一直存在于内存中,在各个窗体中申明公共方法,在主进程需要调用时直接调用即可,但是这样耗费了大量的系统资源。现在使用消息来解决这个问题。下面提供一个小程序,在主窗体中通过句柄和消息来控制子窗体中Label上文字变化和颜色,代码如下:

 

Windowns的API类

using System;
using System.Runtime.InteropServices;

namespace TestHwnd
{
    public class Win32API
    {
         [DllImport("user32.dll ", CharSet = CharSet.Unicode)]
        public static extern IntPtr PostMessage(IntPtr hwnd, int wMsg, string wParam, string lParam);

    }

}

 

主窗体程序(发送消息):

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace TestHwnd
{
    public partial class Main : Form
    {

        //定义了一个子窗体的句柄
        public IntPtr hwndfrmTest;
        

        public Main()
        {
            InitializeComponent();
        }

     

        private void timer1_Tick(object sender, EventArgs e)
        {

            if(hwndfrmTest!=(IntPtr)0)
            {
                if(DateTime.Now.Second % 3 == 0)
                {
                    Win32API.PostMessage(hwndfrmTest, 0x60, "", "");
                }
                
                if(DateTime.Now.Second % 5 == 0)
                {
                    Win32API.PostMessage(hwndfrmTest, 0x61, "", "");
                }
                
            }
            
        }


        void Button2Click(object sender, EventArgs e)
        {
            frmTest frm=new frmTest();
            frm.Show(this);
        }
    }

子窗体程序(接收消息)

using System;
using System.Drawing;
using System.Windows.Forms;

namespace TestHwnd
{
     ///  <summary>
     ///  Description of frmTest.
     ///  </summary>
     public  partial  class frmTest : Form
    {
        Main main;
         public  frmTest()
        {
             //
             // The InitializeComponent() call is required for Windows Forms designer support.
             //
             InitializeComponent();
            
             //
             // TODO: Add constructor code after the InitializeComponent() call.
             //
        }
        
         void  FrmTest_Load( object sender, EventArgs e)
        {

            main = this.Owner as Main;

             //初始化该窗体的句柄

            main.hwndfrmTest =  this.Handle;
        }
        
         /// 重写窗体的消息处理函数DefWndProc,从中加入自己定义消息 MYMESSAGE 的检测的处理入口
         protected  override  void  DefWndProc( ref Message m)
        {
             switch (m.Msg)
            {
                 case  0x60:
                    {
                        label1.ForeColor=Color.Red;
                        label1.Text = DateTime.Now. ToString() +  "-" +  "测试成功。。。。,呵呵,变红了";
                    }
                     break;
                 case  0x61:
                    {
                        label1.ForeColor=Color.Blue;
                        label1.Text = DateTime.Now. ToString() +  "-" +  "测试成功。。。。,呵呵,变蓝了";
                    }
                     break;
                 default:
                     base. DefWndProc( ref m);
                     break;
            }
        }
        
        
        
         void  Button1Click( object sender, EventArgs e)
        {
                main.hwndfrmTest = (IntPtr) ( 0);
             this. Close();
        }
    }
}

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C# 获得另一个窗体句柄并发送消息(使用windows API) 的相关文章

  • 在新窗口中打开 SAS 程序

    目前 当您在 Windows 中双击 SAS 文件时 它将在您已打开的现有 SAS 会话中打开它 有没有办法让它在窗口中单击时会启动一个新的 SAS 窗口 据我所知 SAS 是一个所谓的 单实例 应用程序 因此它的默认行为是在现有会话中打开
  • 在 Android SDK 中设置 JAVA_HOME

    我和对方有一些冲突JAVA HOME配置 当我使用以下代码时 System out println System getenv JAVA HOME I get C jdk1 6 0 23这是正确的地方 但是 当我在 Android buil
  • 如何在 NERDTree 中显示隐藏文件(以句点开头)?

    我怎样才能使NERDTree https github com scrooloose nerdtree显示以 a 开头的文件 时期 我有一个名为 hgignore在项目目录中 如果我使用 NERDTree 浏览到该目录 该文件不会显示在树中
  • 如何在 Swift 4 中传递 Encodable 或 Decodable 作为参数?

    我正在学习 JSONParsing 我遵循了教程 得到的是这样的 guard let url URL string http localhost test api public api register else return var re
  • 如何在 PowerShell 中键入 TAB 字符?

    Task 默认情况下 在 Windows 命令提示符中按 TAB 键将输出文件名 而在 PowerShell 中则不会执行任何操作 我希望能够在交互模式下键入 TAB 字符 而不是通过脚本 Research 我在这个网站上和通过谷歌搜索发现
  • Python 可执行文件:py2exe 还是 PyInstaller?

    要创建可执行文件 Windows 我假设我们应该使用其中之一 Py2exe 或 PyInstaller 它们之间有什么区别 Py2exe 和 PyInstaller 都是包装器 但我注意到以下几点差异 Py2exe 与 python2 4
  • 使用curl登录并获取会话

    你好 我需要以某种方式获得最高区域的兴趣和随着时间的推移的兴趣 或更好 所以我发现我们必须登录才能导出数据有人可以给我一个使用我们的谷歌用户名和密码执行此操作的示例吗 也许使用curl来导出数据 或者是其他东西 感谢您的关注 亚当 拉马丹
  • 如何让脚本执行结束后自动删除?

    是否可以制作一个Python脚本 在Windows中执行结束时删除 py文件 自删除 这种方式使您的程序不依赖于操作系统 from os import remove from sys import argv remove argv 0 奖励
  • .wav 文件长度/持续时间,无需读入文件

    有没有办法提取有关 wav 文件长度 持续时间的信息 而无需在 R 中读取文件 我有数千个这样的文件 如果我必须阅读每个文件才能找到其持续时间 那将需要很长时间 Windows 文件资源管理器为您提供了打开 长度 字段的选项 并且您可以查看
  • Windows Workflow Foundation 4 (WF4) 延迟

    我正在与 Visual Studio 2010 的候选版本一起使用 Wf4 编写一个用于批准资源请求的新工作流程 在我的工作流程中 如果请求未获得批准 我希望请求在几天后过期 我们在 WF 3 5 Visual Studio 2008 中通
  • 如何更改选项卡控件的名称

    我在 C WinForms 应用程序中使用选项卡控件 我想更改选项卡的标题 默认情况下它们是 tabPage1 tabPage2 等 一种无需代码即可实现的懒惰方法 选择选项卡控件 Go to properties use F4 to do
  • 在OpenCV中将YUV转换为BGR或RGB

    我有一个电视采集卡 其输入内容为 YUV 格式 我在这里看到了与此问题类似的其他帖子 并尝试尝试所述的所有可能的方法 但它们都没有提供清晰的图像 目前最好的结果是 OpenCVcvCvtColor scr dst CV YUV2BGR 函数
  • Swagger 生成 javascript-closure-angular-client

    我是 swagger 的新手 我从 swagger 的在线编辑器生成了一个 javascript 闭包角度客户端 它给了我一个 DefaultAPI js 和其他与我的对象定义匹配的 JS 文件 我在 swagger 文档和网上搜索了一种在
  • 嵌入清单文件以要求具有 mingw32 的管理员执行级别

    我正在 ubuntu 下使用 i586 mingw32msvc 交叉编译应用程序 我很难理解如何嵌入清单文件以要求 mingw32 具有管理员执行级别 对于我的例子 我使用了这个hello c int main return 0 这个资源文
  • 移动/调整窗口大小时闪烁

    我开发了一个显示 jpeg 图像的应用程序 它可以显示 4 个图像 屏幕的每个象限各一个 为此 它使用了 4 个窗口 窗口没有边框 框架 也没有标题栏 当加载新图像时 窗口大小会根据新图像进行调整 然后显示该图像 尤其是当窗户做得较大时 经
  • Facebook 通过 API“Boost Post”?

    我一直在浏览文档 发现可以通过 Facebook 广告 API 实现 Boost Post 功能 但是 我在查找 Boost Post 到底有什么作用时遇到了一些困难 即 API 的哪一部分对应 Facebook UI 的 Boost Po
  • Qt(在 Windows 上)将权限级别设置为“requireAdministrator”

    我正在使用 Qt Creator 并努力制作 exe文件默认以管理员身份运行 在线阅读所有解决方案我试图将这一行放入我的 pro file QMAKE LFLAGS MANIFESTUAC level requireAdministrato
  • 本地推送通知到在应用程序内运行 JS 代码的 Win8 Live Tile

    我正在尝试将更新发送到我的应用程序的磁贴 当应用程序运行时 这可以正常工作 例如 当用户单击按钮时 我可以轻松地将磁贴更新通知发送到磁贴 我无法解决的是当应用程序无法运行时如何更新磁贴 我找到的唯一选择是使用以下命令从远程 Web 服务器拉
  • 如何使用来自 Microsoft-Windows-NDIS-PacketCapture 提供程序的实时 ETW 事件?

    更大的问题是一般如何使用实时 ETW 网络堆栈事件 但我特别感兴趣Microsoft Windows NDIS PacketCapture 提供程序 所有其他网络堆栈提供程序都部分工作 但 NDIS PacketCapture NDIS P
  • 如何将 GIT 调用的输出获取到批处理脚本中的变量中?

    我有一个 git 命令来获取当前存储库的最新 SHA 如下所示 git log pretty format H n 1 我有一个 Windows 批处理脚本 我想按如下方式使用它 SET CURRENT SHA 但我不知道如何将从 git

随机推荐