C #: выделение «указателя на массив int» из SendMessage () lParam - PullRequest
1 голос
/ 08 января 2010

Я пытаюсь создать подкласс неуправляемого окна строки состояния из моего управляемого COM-сервера, используя класс, унаследованный от NativeWindow, и пытаюсь понять, как правильно распределить содержимое lParam.

http://msdn.microsoft.com/en-us/library/bb760757%28VS.85%29.aspx говорит, что содержимое этого lParam имеет тип (LPARAM)(LPINT) aWidths, и что содержимое этой переменной на самом деле является «указателем на целочисленный массив».

Я не могу придумать, как правильно это упорядочить. Цель состоит в том, чтобы прочитать lParam, добавить наше значение в массив, а затем отправить новое сообщение через base.wndProc(ref m).

Было бы хорошо, если бы я мог просто int[] array = (int[])m.*lParam или что-то подобное, но жизнь не так проста (и я не могу использовать небезопасный код). Я неуклюже пытался заставить маршаллера дать мне что-то через Marshal.PtrToStructure(), но знал, что это было обречено с самого начала, так как C-массив не является структурой, а структура, которую я пытался создать, очевидно, не является blittable.

Прямо сейчас мы позволяем исходному вызову пройти, а затем делаем дополнительные вызовы WinAPI, чтобы получить массив, отформатировать его, а затем повторно отправить его, прежде чем строка состояния сможет перерисоваться. Это работает хорошо, но недостаточно хорошо.

Есть идеи?

Спасибо!

Tom

PS - У меня было много проблем с поиском использования lParams в C #, документация довольно запутанная: - /

1 Ответ

2 голосов
/ 08 января 2010

После комментария "dtb" вы можете позаимствовать некоторый код из этой SO записи .

LPARAM, который вы должны предоставить, является указателем на первый элемент массива. Тогда все, что вам нужно сделать, это:

int[] parts = new int[]{ 1, 2, 3, 4 };
int nParts = parts.Length;
IntPtr pointer = Marshal.AllocHGlobal(nParts * Marshal.SizeOf(typeof(int)));
for (int i = 0; i < nParts; i++) {
    Marshal.WriteInt32(pointer, i * Marshal.SizeOf(typeof(int), parts[i]));
}
// Call SendMessage with WPARAM = nParts and LPARAM = Pointer
Marshal.FreeHGlobal(pointer);
...