C# PostMessage - 如何防止数据丢失?

发布于 12-24 00:53 字数 1693 浏览 4 评论 0原文

我有一个应用程序,它将形成一个数据包并将数据包数据发送到外部程序来发送。我一切正常,但我知道唯一不需要窗口位于最前面的方法是 PostMessage。然而,它似乎总是在消息的开头丢失 0-2 个字符。有什么办法可以进行支票以防止损失吗?我尝试过循环 GetLastError() 并在它为 0 时重新发送它,但这没有任何帮助。这是到目前为止我得到的代码:

    public void SendPacket(string packet)
    {
        //Get window name
        IntPtr hWnd = Window.FindWindow(null, "???????????");
        //Get the first edit box handle
        IntPtr edithWnd = Window.FindWindowEx(hWnd, IntPtr.Zero, "TEdit", "");
        //Get the handle for the send button
        IntPtr buttonhWnd = Window.FindWindowEx(hWnd, IntPtr.Zero, "TButton", "SEND");
        //Iterate twice to get the edit box I need
        edithWnd = Window.FindWindowEx(hWnd, edithWnd, "TEdit", "");
        edithWnd = Window.FindWindowEx(hWnd, edithWnd, "TEdit", "");
        foreach (Char c in packet)
        {
            SendCheck(c, edithWnd);
        }
        //Press button
        TextSend.PostMessageA(buttonhWnd, 0x00F5, 0, 0);
        //Clear the edit box
        TextSend.SendMessage(edithWnd, 0x000C, IntPtr.Zero, "");
    }

    public void SendCheck(char c, IntPtr handle)
    {
        //Send the character
        TextSend.PostMessageA(handle, 0x102, c, 1);
        //If error code is 0 (failure), resend that character
        if (TextSend.GetLastError() == 0)
            SendCheck(c, handle);
        return;
    }

以下是 TextSend 类中的定义:

        [DllImport("Kernel32.dll")]
        public static extern int GetLastError();
        [return: MarshalAs(UnmanagedType.Bool)]
        [DllImport("user32.dll", SetLastError = true)]
        public static extern bool SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, string s);  

I have an application that will form a packet and send the packet data to an external program to send. I have everything working, but my only method I know that doesn't require the window to be the foremost is PostMessage. However, it seems to always lose 0-2 characters at the beginning of the message. Is there a way I can make a check to prevent the loss? I've tried looping GetLastError() and re-sending it if it's 0, but it doesn't help any. Here's the code I've gotten so far:

    public void SendPacket(string packet)
    {
        //Get window name
        IntPtr hWnd = Window.FindWindow(null, "???????????");
        //Get the first edit box handle
        IntPtr edithWnd = Window.FindWindowEx(hWnd, IntPtr.Zero, "TEdit", "");
        //Get the handle for the send button
        IntPtr buttonhWnd = Window.FindWindowEx(hWnd, IntPtr.Zero, "TButton", "SEND");
        //Iterate twice to get the edit box I need
        edithWnd = Window.FindWindowEx(hWnd, edithWnd, "TEdit", "");
        edithWnd = Window.FindWindowEx(hWnd, edithWnd, "TEdit", "");
        foreach (Char c in packet)
        {
            SendCheck(c, edithWnd);
        }
        //Press button
        TextSend.PostMessageA(buttonhWnd, 0x00F5, 0, 0);
        //Clear the edit box
        TextSend.SendMessage(edithWnd, 0x000C, IntPtr.Zero, "");
    }

    public void SendCheck(char c, IntPtr handle)
    {
        //Send the character
        TextSend.PostMessageA(handle, 0x102, c, 1);
        //If error code is 0 (failure), resend that character
        if (TextSend.GetLastError() == 0)
            SendCheck(c, handle);
        return;
    }

And here are the definitions in TextSend class:

        [DllImport("Kernel32.dll")]
        public static extern int GetLastError();
        [return: MarshalAs(UnmanagedType.Bool)]
        [DllImport("user32.dll", SetLastError = true)]
        public static extern bool SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, string s);  

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

岁月静好2024-12-31 00:53:24

事实上,您找到了 TEdit 和 TButton,这让我认为目标应用程序是用 Delphi 编写的。如果是这样,根据 Delphi 的版本,它可能是也可能不是 Unicode 应用程序。您正在调用 PostMessageA 而不是 PostMessageW,这意味着它从 c# 应用程序发送单字节 Ansi 字符而不是 16 位 Unicode 字符。

您有目标应用程序的源代码吗?将数据填充到编辑框中并单击按钮似乎有点脆弱。如果您可以修改目标应用程序,那么除了一次发送一个字符之外,肯定还有其他选项可用。

The fact that you're finding a TEdit and a TButton makes me think that the target application was written in Delphi. If so, depending on the version of Delphi it may or may not be a Unicode application. You're calling PostMessageA instead of PostMessageW which means it's sending a single-byte Ansi char instead of a 16-bit Unicode char from the c# application.

Do you have source to the target application? Stuffing data in an edit box and clicking a button seems a bit fragile. If you can modify the target application there are certainly other options available than to send one character at a time.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文