Как отправить экземпляры объекта в WndProc

Я использую свой собственный класс, который описывает некоторые состояния и значения:

  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 я мог использовать его для нужд логики. Возможно?


person DreadAngel    schedule 28.06.2011    source источник
comment
Не надо; это плохая идея. Зачем вам это нужно?   -  person SLaks    schedule 28.06.2011


Ответы (1)


Вы не сможете этого сделать. Указатели в управляемом языке ничего не значат, их часто перемещают и убивают, когда на них больше не ссылаются. Ну, может быть, вы сможете добиться чего-то, что работает таким образом (в процессе), с небезопасным кодом и закрепленными указателями, но это будет ваша гибель.

Если вам нужна только внутрипроцессная связь, остерегайтесь последствий межпоточной связи.

Если вам нужна межпроцессная связь, см. этот поток: Механизмы IPC в С# - Использование и рекомендации

Изменить:

Отправка uniqueID через SendMessage для получения сериализованного объекта. Я не советую это делать, так как это подвержено взлому и ошибкам, но вы просили:

при отправке сообщения:

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");
}

Извините за опечатки в коде, я пишу это специально и не могу проверить...

person Marino Šimić    schedule 28.06.2011
comment
Приложение должно запускаться более одного экземпляра, но должен оставаться только один экземпляр - каждый новый экземпляр добавляет новые данные. Для выполнения логики с одним экземпляром используется класс Mutex - если логика обнаружит, что экземпляр уже запущен - он отправит сообщение с помощью SendMessage/PostMessage, где дополнительно должны быть отправлены и новые данные - в моем случае эти данные завернуты в экземпляре класса. Вопрос - как отправить этот экземпляр класса для обработки в форме WndProc? Или не могли бы Вы предложить другой способ. - person DreadAngel; 28.06.2011
comment
Если я правильно понял, я не могу помочь вам с этим. Кажется, ужасный дизайн. Такого рода требования подходят для клиент-серверного приложения. Это, вероятно, бесполезно для вас, поскольку у вас уже есть что расширять. - person Marino Šimić; 28.06.2011
comment
Возможно, вы можете где-нибудь сериализовать этот объект и сохранить этот кэшированный объект с заранее определенным индексом. Затем отправьте этот индекс вместо указателя, извлеките объект из хранилища с индексом, который вы получили из Param, и десериализуйте его. - person Marino Šimić; 28.06.2011
comment
Хорошо, я признаю, что могу сериализовать - и получить строку... Не могли бы вы предоставить фрагмент кода, отражающий это? И SendMessage(..), и Wndroc блокируют блокировку? - person DreadAngel; 28.06.2011