【问题标题】:How to send object instances to WndProc如何将对象实例发送到 WndProc
【发布时间】:2011-06-28 15:05:51
【问题描述】:

我正在使用描述一些状态和值的自定义类:

  class MyClass
    {
        int State;
        String Message;
        IList<string> Values;
    }

由于应用程序架构,表单交互使用消息及其基础结构(SendMessage/PostMessage,WndProc)。 问题是 - 如何使用 SendMessage/PostMessage 将 MyClass 的实例发送到 WndProc? 在我的代码中,PostMessage 的定义方式如下:

[DllImport("user32.dll", SetLastError = true)]
public static extern bool PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);

所以,我需要在我的自定义消息编号下方以某种方式发送和一个 MyClass 实例,所以在 WndProc 中我可以将它用于逻辑需求。 有可能吗?

【问题讨论】:

  • 不要;这是个坏主意。为什么需要这样做?

标签: c# sendmessage wndproc postmessage


【解决方案1】:

您将无法做到这一点。 托管语言中的指针毫无意义,当不再引用它们时,它们通常会被重新定位并杀死。 好吧,也许您可​​以使用不安全的代码和固定指针来实现某种工作方式(正在进行中),但这将是您的厄运。

如果您只想进行进程内通信,请注意跨线程通信的影响。

如果您需要跨进程通信,请参阅此线程: IPC Mechanisms in C# - Usage and Best Practices

编辑:

通过 SendMessage 发送 uniqueID 以获取序列化对象。 我不建议这样做,因为它容易被黑客攻击和出错,但您要求:

发送消息时:

IFormatter formatter = new BinaryFormatter();
string filename = GetUniqueFilenameNumberInFolder(@"c:\storage"); // seek a freee filename number -> if 123.dump is free return 123 > delete those when not needed anymore
using (FileStream stream = new FileStream(@"c:\storage\" + filename + ".dump", FileMode.Create))
{
   formatter.Serialize(stream, myClass);
}
PostMessage(_window, MSG_SENDING_OBJECT, IntPtr.Zero, new IntPtr(int.Parse(filename)));

在 WndProc 中接收时:

if (msg == MSG_SENDING_OBJECT)
{
    IFormatter formatter = new BinaryFormatter();
    MyClass myClass;
    using (FileStream stream = new FileStream(@"c:\storage\" + lParam.ToInt32().ToString() + ".dump", FileMode.Open))
    {
        myClass = (MyClass)formatter.Deserialize(stream);
    }
    File.Delete(@"c:\storage\" + lParam.ToInt32().ToString() + ".dump");
}

抱歉,代码中有错别字,我正在编写此临时文件,无法测试...

【讨论】:

  • 应用程序必须运行不止一次实例,但它应该只保留一个实例 - 每个新实例“添加”一些新数据。为了完成单实例逻辑,使用了 Mutex 类——如果逻辑检测到一个实例已经在运行——它将使用 SendMessage/PostMessage 发送一条消息,其中还应该发送新数据——在我的情况下,数据被包装在一个类实例中。问题 - 如何发送要在表单的 WndProc 中处理的类实例?或者你可以提出另一种方式。
  • 如果我理解正确,我无法帮助您。看起来很糟糕的设计。这种要求适合客户端-服务器应用程序。这可能对你没有用,因为你已经有一些东西要扩展了。
  • 也许您可以在某处序列化该对象并使用预定索引存储该缓存对象。然后发送这个索引而不是指针,使用从 Param 获得的索引从存储中获取对象,并反序列化它。
  • 好的 - 我承认我可以序列化 - 并有一个字符串......你能提供一段反映这一点的代码吗? SendMessage(..) 和 Wndroc 都捕获块?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-02
  • 1970-01-01
  • 2020-09-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多