c# - 使用系统 Windows 自动化发送 WM_COPYDATA 消息
问题描述
我正在使用以下代码将消息/命令发送到另一个窗口/进程。
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 自动机轻松实现。
更新 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;
更新 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;
任何帮助将不胜感激..
解决方案
尝试以下方法传递 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; }
推荐阅读
- r - Ggplot循环遍历组中的唯一变量
- algorithm - 以其他基数表示负数
- sql - 如何从值是字典的表中选择值,并且字典的键是使用 SQL 查询的数字?
- matlab - 在 Matlab 中将 3d 平面转换为 2d 平面
- c++ - C++ Qt:push_back 不能正常工作
- flutter - 颤振轮播重叠
- c# - 记录的动态翻译
- python - 在增加索引号的基础上连接熊猫数据框并在此基础上保留它们的位置
- istio - 如何从 Istio 自定义 AuthorizationPolicy 拒绝的错误代码和响应正文?
- python - 在 matplotlib bar_label 中隐藏小于 n 的条形标签