C++使用 COPYDATASTRUCT 将 SendMessage 转换为 C#

发布于 2024-09-10 15:27:10 字数 2480 浏览 1 评论 0原文

我正在将 C++ 应用程序转换为 C#,这通常相当简单,但现在我正在处理指针并遇到问题。

原始 C++ 代码

  ShockVideoInfo* pVideoInfo = new ShockVideoInfo;
  COPYDATASTRUCT  cd;

  cd.dwData = bSelf ? SHOCK_REQUEST_SELFVIEW_WINDOW : SHOCK_REQUEST_MAINVIEW_WINDOW;
  cd.lpData = pVideoInfo;
  cd.cbData = sizeof(ShockVideoInfo);

  pVideoInfo->dwLeft   = 10;
  pVideoInfo->dwTop    = 10;
  pVideoInfo->dwWidth  = 100;
  pVideoInfo->dwHeight = 100;
  pVideoInfo->dwFlags  = SHVIDSHOW | SHVIDSIZE | SHVIDTOPMOST | SHVIDMOVE | SHVIDSIZABLE;

  if (::SendMessage(m_hShockWnd, WM_COPYDATA, (WPARAM)GetSafeHwnd(), (LPARAM)&cd))
    Log(eResult, _T("Window updated"));
  else
    Log(eError, _T("Window not updated"));

这是带有结构定义的

typedef struct tagShockVideoInfo
{
  DWORD dwLeft;
  DWORD dwTop;
  DWORD dwWidth;
  DWORD dwHeight;
  DWORD dwFlags;

} ShockVideoInfo;

这是我到 C# 的转换,使用编组来处理指针:

ShockVideoInfo videoInfo = new ShockVideoInfo();
COPYDATASTRUCT cd = new COPYDATASTRUCT();

cd.dwData = (IntPtr)_shockRequestMainviewWindow;
cd.lpData = Marshal.AllocCoTaskMem(cd.cbData); // Pointer to videoInfo
Marshal.StructureToPtr(videoInfo, cd.lpData, true);
cd.cbData = Marshal.SizeOf(videoInfo);        

// Set-up video window position
videoInfo.dwFlags = _shvidShow | _shvidSize | _shvidTopmost | _shvidMove | _shvidSizable;
videoInfo.dwTop = 10;
videoInfo.dwLeft = 10;
videoInfo.dwHeight = 100;
videoInfo.dwWidth = 100;

IntPtr cdPointer = Marshal.AllocCoTaskMem(Marshal.SizeOf(videoInfo));
Marshal.StructureToPtr(videoInfo, cdPointer, true);

if ( (int) SendMessage(_hWnd, WM_COPYDATA, _formHandle, cdPointer) == 1 )
{
    Debug.WriteLine("Window updated");
}
else
{
    Debug.WriteLine("Window not updated");
}

Marshal.FreeCoTaskMem(cdPointer);
Marshal.FreeCoTaskMem(cd.lpData);

此外,我在 C# 代码中使用以下内容:

[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);

[StructLayout(LayoutKind.Sequential)]    
struct ShockVideoInfo
{
    public uint dwLeft;
    public uint dwTop;
    public uint dwWidth;
    public uint dwHeight;
    public uint dwFlags;
}

[StructLayout(LayoutKind.Sequential)]
struct COPYDATASTRUCT
{
    public IntPtr dwData;
    public int cbData;
    public IntPtr lpData;
}

我的代码没有得到我想要的响应(正在移动视频窗口),所以我做错了。

有这方面经验的人可以告诉我我做错了什么吗?

I'm converting a C++ application into C# which has generally been fairly straight forward, but now I'm dealing with pointers and running into problems.

This is the original C++ code

  ShockVideoInfo* pVideoInfo = new ShockVideoInfo;
  COPYDATASTRUCT  cd;

  cd.dwData = bSelf ? SHOCK_REQUEST_SELFVIEW_WINDOW : SHOCK_REQUEST_MAINVIEW_WINDOW;
  cd.lpData = pVideoInfo;
  cd.cbData = sizeof(ShockVideoInfo);

  pVideoInfo->dwLeft   = 10;
  pVideoInfo->dwTop    = 10;
  pVideoInfo->dwWidth  = 100;
  pVideoInfo->dwHeight = 100;
  pVideoInfo->dwFlags  = SHVIDSHOW | SHVIDSIZE | SHVIDTOPMOST | SHVIDMOVE | SHVIDSIZABLE;

  if (::SendMessage(m_hShockWnd, WM_COPYDATA, (WPARAM)GetSafeHwnd(), (LPARAM)&cd))
    Log(eResult, _T("Window updated"));
  else
    Log(eError, _T("Window not updated"));

with the structure definition

typedef struct tagShockVideoInfo
{
  DWORD dwLeft;
  DWORD dwTop;
  DWORD dwWidth;
  DWORD dwHeight;
  DWORD dwFlags;

} ShockVideoInfo;

Here's my conversion to C#, using Marshalling to handle the pointers:

ShockVideoInfo videoInfo = new ShockVideoInfo();
COPYDATASTRUCT cd = new COPYDATASTRUCT();

cd.dwData = (IntPtr)_shockRequestMainviewWindow;
cd.lpData = Marshal.AllocCoTaskMem(cd.cbData); // Pointer to videoInfo
Marshal.StructureToPtr(videoInfo, cd.lpData, true);
cd.cbData = Marshal.SizeOf(videoInfo);        

// Set-up video window position
videoInfo.dwFlags = _shvidShow | _shvidSize | _shvidTopmost | _shvidMove | _shvidSizable;
videoInfo.dwTop = 10;
videoInfo.dwLeft = 10;
videoInfo.dwHeight = 100;
videoInfo.dwWidth = 100;

IntPtr cdPointer = Marshal.AllocCoTaskMem(Marshal.SizeOf(videoInfo));
Marshal.StructureToPtr(videoInfo, cdPointer, true);

if ( (int) SendMessage(_hWnd, WM_COPYDATA, _formHandle, cdPointer) == 1 )
{
    Debug.WriteLine("Window updated");
}
else
{
    Debug.WriteLine("Window not updated");
}

Marshal.FreeCoTaskMem(cdPointer);
Marshal.FreeCoTaskMem(cd.lpData);

In addition I'm using the following in my C# code:

[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);

[StructLayout(LayoutKind.Sequential)]    
struct ShockVideoInfo
{
    public uint dwLeft;
    public uint dwTop;
    public uint dwWidth;
    public uint dwHeight;
    public uint dwFlags;
}

[StructLayout(LayoutKind.Sequential)]
struct COPYDATASTRUCT
{
    public IntPtr dwData;
    public int cbData;
    public IntPtr lpData;
}

My code isn't getting the response I want (which is moving a video window), so I've done something wrong.

Can anyone with experience in this area please show me what I'm doing wrong?

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

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

发布评论

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

评论(1

孤芳又自赏 2024-09-17 15:27:10

我想我已经找到了我的问题:

IntPtr cdPointer = Marshal.AllocCoTaskMem(Marshal.SizeOf(videoInfo));
Marshal.StructureToPtr(videoInfo, cdPointer, true);

应该是:

IntPtr cdPointer = Marshal.AllocCoTaskMem(Marshal.SizeOf(cd));
Marshal.StructureToPtr(cd, cdPointer, false);

换句话说,我没有将指针传递给 videoInfo 结构!这有帮助:)

I think I've found my issue:

IntPtr cdPointer = Marshal.AllocCoTaskMem(Marshal.SizeOf(videoInfo));
Marshal.StructureToPtr(videoInfo, cdPointer, true);

Should have been:

IntPtr cdPointer = Marshal.AllocCoTaskMem(Marshal.SizeOf(cd));
Marshal.StructureToPtr(cd, cdPointer, false);

In other words, I wasn't passing the pointer to the videoInfo structure! Which helps :)

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