我有一个本机C++应用程序,暂时只需将其命令行字符串和当前鼠标光标坐标发送到WPF应用程序。消息发送和接收很好,但我无法将C#中的IntPtr
实例转换为结构。使用WM_COPYDATA将结构从C++发送到WPF
当我尝试这样做时,应用程序将会毫无例外地崩溃,或者跳过转换它的代码行被跳过,并接收到循环中的下一条消息。这可能意味着有一个本地异常发生,但我不知道为什么。
这是C++程序。目前,我忽略了命令行字符串,并使用伪造的光标坐标来确保工作正常。
#include "stdafx.h"
#include "StackProxy.h"
#include "string"
typedef std::basic_string<WCHAR, std::char_traits<WCHAR>> wstring;
struct StackRecord
{
//wchar_t CommandLine[128];
//LPTSTR CommandLine;
//wstring CommandLine;
__int32 CursorX;
__int32 CursorY;
};
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
COPYDATASTRUCT data;
ZeroMemory(&data, sizeof(COPYDATASTRUCT));
StackRecord* record = new StackRecord();
wstring cmdLine(lpCmdLine);
//record.CommandLine = cmdLine;
record->CursorX = 5;
record->CursorY = 16;
data.dwData = 12;
data.cbData = sizeof(StackRecord);
data.lpData = record;
HWND target = FindWindow(NULL, _T("Window1"));
if(target != NULL)
{
SendMessage(target, WM_COPYDATA, (WPARAM)(HWND) target, (LPARAM)(LPVOID) &data);
}
return 0;
}
这里是接收消息的WPF应用程序的一部分。 IF语句中的第二行会跳过,如果整个事件不会崩溃。
public IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
if (msg == Interop.WM_COPYDATA)
{
var data = (Interop.CopyDataStruct)Marshal.PtrToStructure(lParam, typeof(Interop.CopyDataStruct));
var record = (Interop.StackRecord)Marshal.PtrToStructure(data.lpData, typeof(Interop.StackRecord));
MessageBox.Show(String.Format("X: {0}, Y: {1}", record.CursorX, record.CursorY));
}
return IntPtr.Zero;
}
这里是对结构的C#的定义。我玩弄了无数的编组属性,无处可寻。
internal static class Interop
{
public static readonly int WM_COPYDATA = 0x4A;
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct CopyDataStruct
{
public IntPtr dwData;
public int cbData;
public IntPtr lpData;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto, Pack = 1)]
public struct StackRecord
{
//[MarshalAs(UnmanagedType.ByValTStr)]
//public String CommandLine;
public Int32 CursorX;
public Int32 CursorY;
}
}
任何想法?
我也试过在一个WinForms窗口覆盖的WndProc,行为是一样的。 – 2009-12-13 23:26:06