c# 我无法让 SendMessage 向记事本窗口发送消息 [英] c# i'm unable to get SendMessage to send a message to a notepad window

查看:22
本文介绍了c# 我无法让 SendMessage 向记事本窗口发送消息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我看过这个问答

已添加

基于 Remy 建议的新代码

使用系统;使用 System.Windows.Forms;使用 System.Runtime.InteropServices;使用 System.Diagnostics;命名空间测试发送消息{公共部分类 Form1 :表单{[DllImport("user32.dll", EntryPoint = "FindWindowEx")]public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);[DllImport("User32.dll", CharSet = CharSet.Unicode, EntryPoint = "SendMessageW")]公共静态外部 IntPtr SendMessageWStr(IntPtr hWnd, uint uMsg, IntPtr wParam, string lParam);const uint WM_SETTEXT = 0x000C;公共 Form1(){初始化组件();}private void Form1_Load(对象发送者,EventArgs e){}private void button1_Click(object sender, EventArgs e){Process[] notepads = Process.GetProcessesByName("notepadd");if (notepads.Length == 0) 返回;如果(记事本[0] != null){IntPtr child = FindWindowEx(notepads[0].MainWindowHandle, new IntPtr(0), "Edit", null);SendMessageWStr(child, WM_SETTEXT, IntPtr.Zero, "abcd");}}}}

但我仍然遇到同样的问题,即在单击按钮之前记事本窗口是空白的,之后也是空白的.它不会将文本发送到记事本窗口.尽管它已经到达了将文本发送给它的那行代码.

进一步补充.

当前代码,

我已将 FindWindowEx 更改为 FindWindowExW,并将 new IntPtr(0) 更改为 IntPtr.Zero,但它仍然没有响应.

我已经从 cmd 打开了 notepadd.exe,我看到了那里的窗口.当然还有任务管理器中的 notepadd.exe,但是单击我的应用程序中的按钮不会在该窗口中写入任何文本.

使用系统;使用 System.Windows.Forms;使用 System.Runtime.InteropServices;使用 System.Diagnostics;命名空间测试发送消息{公共部分类 Form1 :表单{[DllImport("user32.dll", EntryPoint = "FindWindowExW")]public static extern IntPtr FindWindowExW(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);[DllImport("User32.dll", CharSet = CharSet.Unicode, EntryPoint = "SendMessageW")]公共静态外部 IntPtr SendMessageWStr(IntPtr hWnd, uint uMsg, IntPtr wParam, string lParam);const uint WM_SETTEXT = 0x000C;公共 Form1(){初始化组件();}private void Form1_Load(对象发送者,EventArgs e){}private void button1_Click(object sender, EventArgs e){Process[] notepads = Process.GetProcessesByName("notepadd");if (notepads.Length == 0) 返回;如果(记事本[0] != null){IntPtr child = FindWindowExW(notepads[0].MainWindowHandle, IntPtr.Zero, "Edit", null);SendMessageWStr(child, WM_SETTEXT, IntPtr.Zero, "abcd");}}}}

解决方案

非常感谢 Remy.经过一些故障排除后,我最终发现代码有效,所以我发现它无效的原因是个谜.

一个很好的故障排除步骤是尝试使用 nircmd 移动窗口,这样您就知道自己掌握了控制权.

要获取窗口句柄,可以使用nirsoft winlister,或者winspector

您可以使用 nircmd 命令,例如 nircmd win close handle 0x00230632 将 0x00230632 更改为您找到的任何句柄.或者最好不要关闭它(否则你必须重新打开它并且新窗口会有一个新的句柄),所以像 nircmd win move handle 0x00B917AE 80 10 100 100 这样的命令你知道不管代码有什么问题,句柄都是正确的.

Winspector 还显示记事本窗口的子窗口

回到 C# 代码,你可以

跳过孩子并尝试写入父级,它应该写入窗口的标题

尝试使用 SendMessage 直接指定窗口.你用十进制而不是十六进制写句柄.例如如果句柄是 3479948 那么

例如SendMessage(new IntPtr(3479948), WM_SETTEXT, IntPtr.Zero, "abcdee");

您还可以检查 notepads[0].MainWindowHandle 是否选择了正确的值.. winspector 中显示的句柄.

您可以查看 IntPtr child = FindWindowEx(...) 行,确保 'child' 正在拿起子句柄.

您可以尝试使用 SendMessage 直接写信给那个人.例如SendMessage(new IntPtr(1234567), WM_SETTEXT, IntPtr.Zero, "abcdee");//(如果 winspector 将子窗口显示为该句柄).

I have looked at this question and answer

How to send text to Notepad in C#/Win32?

A slight variation that I think shouldn't matter.. Is that I have a bunch of notepad windows.. So to test this I copied notepad.exe to be notepadd.exe and opened notepadd.exe, so only one of my notepad windows is the notepadd.exe process.

I have this code

using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Diagnostics;

namespace testsendmessage
{

    public partial class Form1 : Form
    {
        [DllImport("user32.dll", EntryPoint = "FindWindowEx")]
        public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
        [DllImport("User32.dll")]
        public static extern int SendMessage(IntPtr hWnd, int uMsg, int wParam, string lParam);

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

         private void button1_Click(object sender, EventArgs e)
        {
            Process[] notepads = Process.GetProcessesByName("notepadd");
            if (notepads.Length == 0) return;
            if (notepads[0] != null)
            {
                IntPtr child = FindWindowEx(notepads[0].MainWindowHandle, new IntPtr(0), "Edit", null);
                SendMessage(child, 0x000C, 0, "abcd");
            }
        }
    }
}

It's not touching the notepad window though.

I tried debugging and I see that the notepads array has one item, which is certainly correct.

And it gets within the 'if' and it runs SendMessage(child, 0x000C, 0, "abcd");

But I see nothing appearing in the notepad window

I'm not getting an error from the code it's just nothing appearing in the notepad window.. And I don't really understand winapi stuff much, so i'm not sure how to proceed in trying to solve it?

As you can see it reaches that line, and I can use the watch window to look at the notepads Process array, and at 'child' but I don't know what I should be looking at to determine why it's not sending to the window

Added

New code based on Remy's suggestion

using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Diagnostics;

namespace testsendmessage
{

    public partial class Form1 : Form
    {
        [DllImport("user32.dll", EntryPoint = "FindWindowEx")]
        public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);

        [DllImport("User32.dll", CharSet = CharSet.Unicode, EntryPoint = "SendMessageW")]
        public static extern IntPtr SendMessageWStr(IntPtr hWnd, uint uMsg, IntPtr wParam, string lParam);

        const uint WM_SETTEXT = 0x000C;
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

         private void button1_Click(object sender, EventArgs e)
        {
            Process[] notepads = Process.GetProcessesByName("notepadd");
            if (notepads.Length == 0) return;
            if (notepads[0] != null)
            {
                IntPtr child = FindWindowEx(notepads[0].MainWindowHandle, new IntPtr(0), "Edit", null);
                SendMessageWStr(child, WM_SETTEXT, IntPtr.Zero, "abcd");
            }

        }
    }
}

But I still get the same issue that the notepad window was blank before clicking button and is blank after too. It's not sending the text to the notepadd window. Despite the fact that it is reaching that line of code that is meant to send the text to it.

Further addition.

Current code,

I've changed FindWindowEx to FindWindowExW and i've changed new IntPtr(0) to IntPtr.Zero and it still is unresponsive.

I've opened up notepadd.exe from cmd, I see the window there. And of course notepadd.exe in task manger, But clicking the button in my application is not writing any text into that window.

using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Diagnostics;

namespace testsendmessage
{

    public partial class Form1 : Form
    {
        [DllImport("user32.dll", EntryPoint = "FindWindowExW")]

        public static extern IntPtr FindWindowExW(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);

        [DllImport("User32.dll", CharSet = CharSet.Unicode, EntryPoint = "SendMessageW")]
        public static extern IntPtr SendMessageWStr(IntPtr hWnd, uint uMsg, IntPtr wParam, string lParam);

        const uint WM_SETTEXT = 0x000C;
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

         private void button1_Click(object sender, EventArgs e)
        {
            Process[] notepads = Process.GetProcessesByName("notepadd");
            if (notepads.Length == 0) return;
            if (notepads[0] != null)
            {
                IntPtr child = FindWindowExW(notepads[0].MainWindowHandle, IntPtr.Zero, "Edit", null);
                SendMessageWStr(child, WM_SETTEXT, IntPtr.Zero, "abcd");
            }

        }
    }
}

解决方案

Much credit to Remy. After some troubleshooting I ended up finding the code worked so it's a mystery why I was finding it didn't.

A good troubleshooting step is to try moving the window around with nircmd, so you know you have the handle.

To get the handle of the window, you can use nirsoft winlister, or winspector

You can use nircmd commands like nircmd win close handle 0x00230632 change that 0x00230632 to whatever you find the handle to be. Or better don't close it(otherwise you'll have to reopen it and the new window will have a new handle), so a command like nircmd win move handle 0x00B917AE 80 10 100 100 So you know the handle is right, regardless of any issue with the code.

Winspector also shows the child of the notepad window

Going back to the C# code, you can

skip the child and try writing into the parent, it should write into the title of the window

Try using SendMessage to specify a window directly. You write the handle in decimal rather than hex. e.g. if the handle is 3479948 then

e.g. SendMessage(new IntPtr(3479948), WM_SETTEXT, IntPtr.Zero, "abcdee");

You can also check that notepads[0].MainWindowHandle is picking up the correct value.. the handle shown in winspector.

You can look at the IntPtr child = FindWindowEx(...) line, make sure the 'child' is picking up the child handle.

You can try writing to that one directly with SendMessage. e.g. SendMessage(new IntPtr(1234567), WM_SETTEXT, IntPtr.Zero, "abcdee"); // (if winspector shows the child window to be that handle).

这篇关于c# 我无法让 SendMessage 向记事本窗口发送消息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆