C # PostMessage - Как предотвратить потерю данных? - PullRequest
0 голосов
/ 02 января 2012

У меня есть приложение, которое сформирует пакет и отправит данные пакета во внешнюю программу для отправки. У меня все работает, но мой единственный известный мне метод, который не требует, чтобы окно было главным, - это 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);  

1 Ответ

1 голос
/ 02 января 2012

Тот факт, что вы находите TEdit и TButton, заставляет меня думать, что целевое приложение было написано на Delphi.Если это так, в зависимости от версии Delphi это может быть или не быть приложением Unicode.Вы вызываете PostMessageA вместо PostMessageW, что означает, что он отправляет однобайтовый символ Ansi вместо 16-разрядного символа Unicode из приложения c #.

У вас есть источник для целевого приложения?Заполнение данных в поле редактирования и нажатие кнопки кажется немного хрупким.Если вы можете изменить целевое приложение, безусловно, есть и другие варианты, кроме отправки по одному символу за раз.

...