Что такое подпись P / Invoke для отправки сообщения MCM_GETSELRANGE в MonthCalendar? - PullRequest
1 голос
/ 03 мая 2011

Я пытаюсь отправить сообщение MCM_GETSELRANGE windows в стандартный MonthCalendar. Основываясь на документации, я безуспешно попробовал следующее (даты возвращаются как ничто [так как в них не установлено ничего, кроме нуля), однако я получаю ненулевое возвращаемое значение, которое, кажется, указывает, что оно успешно ?):

using System;
using System.Runtime.InteropServices;

namespace GetSelRange
{
    class Program
    {
        static void Main(string[] args)
        {
            IntPtr targetWindowHandle = new IntPtr(68684130);
            SYSTEMTIME[] dateRange = new SYSTEMTIME[2];
            IntPtr success = SendMessage(targetWindowHandle, MCM_GETSELRANGE, IntPtr.Zero, dateRange);
        }

        #region Win32API

        const uint MCM_FIRST = 0x1000;
        const uint MCM_GETSELRANGE = MCM_FIRST + 5;

        [StructLayout(LayoutKind.Sequential)]
        private struct SYSTEMTIME
        {
            [MarshalAs(UnmanagedType.U2)]
            public ushort Year;
            [MarshalAs(UnmanagedType.U2)]
            public ushort Month;
            [MarshalAs(UnmanagedType.U2)]
            public ushort DayOfWeek;
            [MarshalAs(UnmanagedType.U2)]
            public ushort Day;
            [MarshalAs(UnmanagedType.U2)]
            public ushort Hour;
            [MarshalAs(UnmanagedType.U2)]
            public ushort Minute;
            [MarshalAs(UnmanagedType.U2)]
            public ushort Second;
            [MarshalAs(UnmanagedType.U2)]
            public ushort Milliseconds;
        }

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

        #endregion
    }
}

У pinvoke.net, похоже, нет никаких предложений относительно того, как это следует называть.

Спасибо

1 Ответ

2 голосов
/ 03 мая 2011

Очевидно, что вы отправляете это в окно, которое принадлежит другому процессу.Это не может работать так: массив SYSTEMTIME действителен только в вашем процессе, но не в другом.Это значительно усложняет код, вам нужно выделить память в целевом процессе.

Я кратко опишу требуемый пинвоук, у вас не должно возникнуть проблем с поиском примера кода из имен функций API.Сначала вам нужно GetWindowThreadProcessId (), чтобы получить идентификатор процесса, которому принадлежит окно.OpenProcess (), чтобы открыть дескриптор к нему.VirtualAllocEx () для выделения памяти.

SendMessage () для отправки сообщения, как вы делали раньше, передавая указатель, полученный из VirtualAllocEx ().ReadProcessMemory () для чтения содержимого массива из процесса.Очистить с помощью VirtualFreeEx () и CloseHandle ().Вполне вероятно, что вы будете бороться с проблемами безопасности, это привилегированные функции.

...