¿Cuál es la firma P/Invoke para enviar el mensaje MCM_GETSELRANGE a un MonthCalendar?

StackOverflow https://stackoverflow.com/questions/5863393

  •  28-10-2019
  •  | 
  •  

Pregunta

Estoy tratando de enviar el MCM_GETSELRANGE Mensaje de Windows a un MonthCalendar estándar. Según la documentación, he probado lo siguiente sin suerte (las fechas vuelven como nada [ya que no están establecidas en nada más que cero], sin embargo, obtengo un valor de retorno distinto de cero que parece indicar que ha tenido éxito ?):

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 no parece tener ninguna sugerencia sobre cómo se debe llamar a esto.

Gracias

¿Fue útil?

Solución

Claramente, está enviando esto a una ventana que pertenece a otro proceso. Eso no puede funcionar así, la matriz SystemTime solo es válida en su proceso, no en el otro. Esto complica considerablemente el código, debe asignar memoria en el proceso de destino.

Describiré brevemente el PinVoke requerido, no debe tener problemas para buscar en Google el código de muestra de los nombres de funciones API. Primero necesita GetWindowThreadProcessID () para obtener la identificación del proceso que posee la ventana. OpenProcess () para abrirle un mango. VirtualallOcex () para asignar la memoria.

SendMessage () para enviar el mensaje como lo hizo antes, pasando el puntero que obtuvo de VirtualallOcex (). ReadProcessMemory () para leer el contenido de la matriz fuera del proceso. Limpie con VirtualFreeEx () y CloseHandle (). No es poco probable que estén luchando contra los problemas de seguridad, por cierto, estas son funciones privilegiadas.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top