Отправить сообщение WM_COPYDATA с помощью системы Windows Automation - PullRequest
0 голосов
/ 08 января 2019

Я использую следующий код для отправки сообщения / команды в другое окно / процесс.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.InteropServices;
using System.Diagnostics;

namespace AvroSwitch
{
    public class clsSwitch
    {
        [DllImport("User32.dll")]
        private static extern int RegisterWindowMessage(string lpString);

        [DllImport("User32.dll", EntryPoint = "FindWindow")]
        public static extern Int32 FindWindow(String lpClassName, String lpWindowName);

        //For use with WM_COPYDATA and COPYDATASTRUCT
        [DllImport("User32.dll", EntryPoint = "SendMessage")]
        public static extern int SendMessage(int hWnd, int Msg, int wParam, ref COPYDATASTRUCT lParam);

        public const int WM_COPYDATA = 0x4A;

        //Used for WM_COPYDATA for string messages
        public struct COPYDATASTRUCT
        {
            public IntPtr dwData;
            public int cbData;
            [MarshalAs(UnmanagedType.LPStr)]
            public string lpData;
        }

        private static int sendWindowsStringMessage(int hWnd, int wParam, string msg)
        {
            int result = -1;

            if (hWnd > 0)
            {
                byte[] sarr = System.Text.Encoding.Unicode.GetBytes(msg);
                sarr = System.Text.Encoding.Convert(ASCIIEncoding.ASCII, UnicodeEncoding.Unicode, sarr);
                int len = sarr.Length;
                COPYDATASTRUCT cds;
                cds.dwData = (IntPtr)0;
                cds.lpData = System.Text.Encoding.Unicode.GetString(sarr);
                cds.cbData = len + 1;
                result = SendMessage(hWnd, WM_COPYDATA, wParam, ref cds);
            }

            return result;
        }

        private static int getWindowId(string className, string windowName)
        {
            return FindWindow(className, windowName);
        }

        public static int toBangla()
        {
            return sendWindowsStringMessage(getWindowId("TAvroMainForm1", null), 0, "bn");
        }

        public static int toEnglish()
        {
            return sendWindowsStringMessage(getWindowId("TAvroMainForm1", null), 0, "sys");
        }
    }
}

Я использую 2 функции toBangle () и toEnglish (), но ни одна из них не работает.

но приведенный выше код не работает. и я думаю, что это может быть легко достигнуто с помощью системного автомата Windows.

Update-1:

это код из стороннего приложения в Delphi для точной отправки команды в главное приложение / окно.

Function SendCommand(cmd: String): boolean;
Var
     copyDataStruct           : TCopyDataStruct;
     receiverHandle           : THandle;
Begin
     result := false;
     copyDataStruct.dwData := 0;        //0=string
     copyDataStruct.cbData := 1 + Length(cmd);
     copyDataStruct.lpData := PChar(cmd);

     receiverHandle := FindWindow(PChar('TAvroMainForm1'), Nil);
     If receiverHandle = 0 Then
          Exit;


     SendMessage(receiverHandle, WM_COPYDATA, 0, Integer(@copyDataStruct));
     Result := True;
End;

Update-2:

И это главное окно / приложение формы кода, которое обрабатывает команду wm:

Procedure TAvroMainForm1.WMCopyData(Var Msg: TWMCopyData);
Var
         cmd: String;
Begin
         cmd := PChar(Msg.CopyDataStruct.lpData);
         cmd := Lowercase(cmd);

         If cmd = 'bn' Then Begin
                    KeyLayout.BanglaMode;
                    // Send something back
                    Msg.result := 21;
         End;

         If cmd = 'sys' Then Begin
                    KeyLayout.SysMode;

                    // Send something back
                    Msg.result := 21;
         End;
End;

любая помощь будет принята с благодарностью ..

1 Ответ

0 голосов
/ 24 января 2019

Попробуйте передать текст ANSI

string msg = "bn"; //or "sys"
COPYDATASTRUCT cds;
cds.dwData = (IntPtr)0;
cds.lpData = msg;
cds.cbData = Encoding.Default.GetBytes(msg).Length;
SendMessage(hwnd, WM_COPYDATA, wParam, ref cds);

Это должно работать, поскольку lpData уже маршалируется

public struct COPYDATASTRUCT
{
    public IntPtr dwData;
    public int cbData;
    [MarshalAs(UnmanagedType.LPStr)]
    public string lpData;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...