elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Trabajando con las ramas de git (tercera parte)


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación General
| | |-+  .NET (C#, VB.NET, ASP) (Moderador: kub0x)
| | | |-+  Problema con PostMessage y SendMessage
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Problema con PostMessage y SendMessage  (Leído 1,093 veces)
SrTrp


Desconectado Desconectado

Mensajes: 325


Script/C#


Ver Perfil
Problema con PostMessage y SendMessage
« en: 12 Abril 2024, 04:01 am »

Hola que tal, les platico quiero hacer click en ciertas partes especificas de las ventanas, pero tengo un problema con SendMessage de plano no me ha funcionado nada de click solo la instrucción de cerrar, en cuanto a postmessage a veces me funciona pero como que solo lee una coordenada y si es por como mando el dato pero igual sigue funcionar como quiero así tengo mi código
ACTUALIZO ESTUVE INVESTIGANDO E HICE UNAS PRUENAS CON 1 COORDENA 500 500 Y USANDO EL METODO MakeLParam pero ahora solo me da clicks ahi aun que cambie las cordenadas cerrelas ventanas y el proyecto lo volvi a depurar y sigue solo dando click ahi

Código
  1. [DllImport("user32.dll", CharSet = CharSet.Auto)]
  2. public static extern IntPtr SendMessage(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);
  3. [DllImport("user32.dll")]
  4. static extern bool PostMessage(IntPtr hWnd, uint Msg, int wParam, int lParam);//Aqui igual forma ya intente usar IntPtr en wParam y lParam y nada
  5. const int WM_LBUTTONDOWN = 0x0201;
  6. const int WM_LBUTTONUP = 0x0202;
  7.  
  8. //Este lo use para intentar mandar coordenadas para postmessage pero aquí si no hace nada cuando uso este metodo
  9. private int MakeLParam(int x, int y)
  10. {
  11.    return ((y << 16) | (x & 0xFFFF));
  12. }
  13. private void button1_Click(object sender, EventArgs e)
  14. {
  15.    SendMessageClick(int.Parse(textBox1.Text), int.Parse(textBox2.Text));
  16. }
  17. private void SendMessageClick(int x, int y)
  18. {
  19.    int selectedIndex = cbxWindows.SelectedIndex;
  20.    IntPtr hWnd = GetOpenWindows()[selectedIndex].hWnd;
  21.  
  22.    if (hWnd != IntPtr.Zero)
  23.    {
  24.        IntPtr lParam = (IntPtr)((y << 16) | x);
  25.        PostMessage(hWnd, WM_LBUTTONDOWN, 1, x);
  26.        PostMessage(hWnd, WM_LBUTTONUP, 0, y);
  27.      /*  SendMessage(hWnd, WM_LBUTTONDOWN, IntPtr.Zero, lParam);
  28.         SendMessage(hWnd, WM_LBUTTONUP, IntPtr.Zero, lParam);*/
  29.    }
  30. }
  31.  


« Última modificación: 12 Abril 2024, 04:16 am por SrTrp » En línea

MCKSys Argentina
Moderador Global
***
Desconectado Desconectado

Mensajes: 5.471


Diviértete crackeando, que para eso estamos!


Ver Perfil
Re: Problema con PostMessage y SendMessage
« Respuesta #1 en: 12 Abril 2024, 15:22 pm »

Hola!

Parece que es un problema de larga data en VS, pero que tiene solución: https://forums.codeguru.com/showthread.php?500671-RESOLVED-PostMessage-amp-SendMessage-Problem

Saludos!


En línea

MCKSys Argentina

"Si piensas que algo está bien sólo porque todo el mundo lo cree, no estás pensando."

Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.821



Ver Perfil
Re: Problema con PostMessage y SendMessage
« Respuesta #2 en: 13 Abril 2024, 11:17 am »

Claves para entender el manejo de mensajes de ventana y sus parámetros

1. La diferencia entre las funciones SendMessage y PostMessage es que la primera es sincrónica, y la otra es asincrónica. Es decir, SendMessage encola un mensaje en la cola de mensajes de la ventana objetivo, y no retorna hasta que la ventana haya terminado de procesar el mensaje. Por otro lado, PostMessage retorna inmediatamente tras haber encolado el mensaje, y esto significa que el mensaje de ventana puede no ser procesado de inmediato después de haber retornado.

2. El valor de retorno de las funciones SendMessage y PostMessage son muy distintos, puesto que el propósito de estas funciones es igual de distinto, como ya expliqué en el punto anterior. La función SendMessage devuelve un valor específico que depende del mensaje de ventana enviado, mientras que la función PostMessage devuelve un valor booleano indicando si el mensaje de ventana se encoló de forma satisfactoria. El valor de retorno de la función PostMessage no indica el éxito del mensaje procesado, de hecho, no está asegurado que el mensaje sea procesado.

Esa es su principal diferencia, y ello deriva en que algunas personas - sin suficiente entendimiento - acaben experimentando y utilizando PostMessage de forma incorrecta, esperando resultados que no van a obtener, para acabar concluyendo, de forma equivocada, que PostMessage no funciona como debería.

3. Las coordenadas que estás utilizando son relativas al área cliente de la ventana objetivo, no a la pantalla del monitor. Es decir, las coordenadas 0,0 (x,y) hacen referencia a la esquina superior izquierda del área cliente de la ventana objetivo. Del mismo, modo, la distancia de las coordenadas 500,500 que pusiste como ejemplo, se miden desde la esquina superior izquierda (coordenadas 0,0) de la ventana objetivo.

4. La función MakeLParam de la que hablaste, es una implementación de la macro MAKELPARAM para C++, que toma como parámetros dos valores (en este caso, dos coordenadas, x e y) para combinarlos en un único valor de 32 bits, definido como "LPARAM"; y este valor "LPARAM" (combinación de las coordenadas x e y) es el que hay que utilizar en el parámetro lParam de las funciones Sendmessage y PostMessage (entre otras varias funciones) al usar los mensajes de ventana para simular las pulsaciones de los botones del ratón WM_LBUTTONDOWN, WM_LBUTTONUP, etc.

5. El tipo de valores que se deben utilizar en los parámetros lParam y wParam de las funciones SendMessage y PostMessage siempre dependerá del mensaje de ventana en cuestión.

En el sitio web de Microsoft siempre podrás encontrar a tu disposición la documentación necesaria para entender como se debe utilizar cada mensaje de ventana, donde se especificará el tipo de valor que se debe utilizar para los parámetros lParam y wParam en caso de que se deban usar para ese mensaje.

Te invito a que leas la documentación de los mensajes de ventana WM_LBUTTONDOWN y WM_LBUTTONUP:


CONTINÚO EN EL SIGUIENTE POST, POR QUE EL FORO TIENE UN LÍMITE DE CARACTERES, ASÍ QUE NO ME CABE TODA LA RESPUESTA EN ESTE POST.  :rolleyes:
« Última modificación: 13 Abril 2024, 11:39 am por Eleкtro » En línea

Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.821



Ver Perfil
Re: Problema con PostMessage y SendMessage
« Respuesta #3 en: 13 Abril 2024, 11:23 am »

Solución al problema

El siguiente código fuente está elaborado mediante porciones de código que he extraído y posteriormente los he combinado, de un proyecto mucho más amplio (una librería de clases comercial que tengo a la venta, por lo que no puedo compartirlo todo), y originalmente escrito en VB.NET, por lo que he tenido que convertido a C#.

Aqui está todo lo necesario para que puedas simular una pulsación o 'click' del ratón, mediante una de las siguientes funciones:

  • SimulateMouseButtonAction (que internamente llamará a la función SendMessage)
  • SimulateMouseButtonActionAsync (que internamente llamará a la función PostMessage)

Al final de este post comparto un ejemplo de como utilizar el código. Es bien sencillo.

Cabe mencionar que todo esto también podrías llevarlo a cabo utilizando la función SendInput:


De hecho, esa sería la forma óptima.

Para poder utilizar la función SendInput es necesario implementar ciertas estructuras y enumeraciones (INPUT, MOUSEINPUT, etc). Yo lo tengo todo implementado en mi librería de clases comercial, si necesitas puedo extraerlo, adaptarlo, y convertirlo a C#, pero me llevaría otro rato.

De todas formas creo que con el siguiente código es más que suficiente, ya que te debería funcionar de igual forma.

(EL SIGUIENTE CÓDIGO HA SIDO REFACTORIZADO Y PUBLICADO A LAS 16:35 HORA ESPAÑOLA, SIMPLIFICANDO Y MEJORANDO VARIOS ASPECTOS GENERALES. HE TENIDO QUE LIMITAR BASTANTE LA DOCUMENTACIÓN Y LOS ENLACES EXTERNOS, POR QUE NO CABE TODO EL CÓDIGO DEBIDO AL LÍMITE DE CARACTERES)

DevCase.cs
Código
  1. using System;
  2. using System.ComponentModel;
  3. using System.Diagnostics;
  4. using System.Drawing;
  5. using System.Linq;
  6. using System.Runtime.InteropServices;
  7. using System.Security;
  8. using System.Threading;
  9. using System.Windows.Forms;
  10.  
  11. using DevCase.Win32;
  12. using DevCase.Win32.Enums;
  13.  
  14. namespace DevCase {
  15.  
  16.    namespace Core.IO.Devices.Input {
  17.  
  18.        /// <summary>
  19.        /// Provides mouse interaction related utilities.
  20.        /// </summary>
  21.        internal sealed class UtilMouse {
  22.  
  23.            /// <summary>
  24.            /// Prevents a default instance of the <see cref="UtilMouse"/> class from being created.
  25.            /// </summary>
  26.            [DebuggerNonUserCode]
  27.            private UtilMouse() { }
  28.  
  29.            /// <summary>
  30.            /// Defines a button message to send to a window.
  31.            /// </summary>
  32.            internal enum MouseButtonMessage : int {
  33.  
  34.                /// <summary>
  35.                /// Hold down the left mouse button.
  36.                /// </summary>
  37.                LeftDown = WindowMessages.WM_LButtonDown,
  38.  
  39.                /// <summary>
  40.                /// Release up the left mouse button.
  41.                /// </summary>
  42.                LeftUp = WindowMessages.WM_LButtonUp,
  43.  
  44.                /// <summary>
  45.                /// Hold down the right mouse button.
  46.                /// </summary>
  47.                RightDown = WindowMessages.WM_RButtonDown,
  48.  
  49.                /// <summary>
  50.                /// Release up the right mouse button.
  51.                /// </summary>
  52.                RightUp = WindowMessages.WM_RButtonUp,
  53.  
  54.                /// <summary>
  55.                /// Hold down the middle mouse button.
  56.                /// </summary>
  57.                MiddleDown = WindowMessages.WM_MButtonDown,
  58.  
  59.                /// <summary>
  60.                /// Release up the middle mouse button.
  61.                /// </summary>
  62.                MiddleUp = WindowMessages.WM_MButtonUp,
  63.  
  64.                /// <summary>
  65.                /// Move down the mouse wheel.
  66.                /// </summary>
  67.                WheelDown,
  68.  
  69.                /// <summary>
  70.                /// Move up the mouse wheel.
  71.                /// </summary>
  72.                WheelUp,
  73.  
  74.                /// <summary>
  75.                /// Tilt horizontal mouse wheel to left.
  76.                /// </summary>
  77.                WheelLeft,
  78.  
  79.                /// <summary>
  80.                /// Tilt horizontal mouse wheel to right.
  81.                /// </summary>
  82.                WheelRight
  83.  
  84.            }
  85.  
  86.            /// <summary>
  87.            /// Defines a click of a mouse button.
  88.            /// </summary>
  89.            internal enum MouseButtonClick : int {
  90.  
  91.                /// <summary>
  92.                /// Left mouse button click.
  93.                /// </summary>
  94.                LeftButton,
  95.  
  96.                /// <summary>
  97.                /// Right mouse button click.
  98.                /// </summary>
  99.                RightButton,
  100.  
  101.                /// <summary>
  102.                /// Middle mouse button click.
  103.                /// </summary>
  104.                MiddleButton
  105.            }
  106.  
  107.            /// <summary>
  108.            /// Sends a mouse button message to the specified window,
  109.            /// on the specified coordinates relative to its client-area,
  110.            /// by calling <see cref="Win32.NativeMethods.SendMessage"/> function.
  111.            /// </summary>
  112.            ///
  113.            /// <param name="hWnd">
  114.            /// A handle to the target window.
  115.            /// </param>
  116.            ///
  117.            /// <param name="button">
  118.            /// The mouse button message to send.
  119.            /// </param>
  120.            ///
  121.            /// <param name="pt">
  122.            /// The coordinates within the client area of the window,
  123.            /// where to send the mouse button message.
  124.            /// </param>
  125.            ///
  126.            /// <returns>
  127.            /// <see langword="True"/> if the function succeeds; otherwise, <see langword="False"/>.
  128.            /// </returns>
  129.            [DebuggerStepThrough]
  130.            internal static bool SendMouseButtonMessage(IntPtr hWnd, MouseButtonMessage button, Point pt) {
  131.                return UtilMouse.SendMouseButtonMessage_Internal(hWnd, button, pt, async: false);
  132.            }
  133.  
  134.            /// <summary>
  135.            /// Asynchronouslly sends a mouse button message to the specified window,
  136.            /// on the specified coordinates relative to its client-area,
  137.            /// by calling <see cref="Win32.NativeMethods.PostMessage"/> function.
  138.            /// </summary>
  139.            ///
  140.            /// <param name="hWnd">
  141.            /// A handle to the target window.
  142.            /// </param>
  143.            ///
  144.            /// <param name="button">
  145.            /// The mouse button message to send.
  146.            /// </param>
  147.            ///
  148.            /// <param name="pt">
  149.            /// The coordinates within the client area of the window,
  150.            /// where to send the mouse button message.
  151.            /// </param>
  152.            ///
  153.            /// <returns>
  154.            /// <see langword="True"/> if the function succeeds; otherwise, <see langword="False"/>.
  155.            /// </returns>
  156.            [DebuggerStepThrough]
  157.            internal static bool SendMouseButtonMessageAsync(IntPtr hWnd, MouseButtonMessage button, Point pt) {
  158.                return UtilMouse.SendMouseButtonMessage_Internal(hWnd, button, pt, async: true);
  159.            }
  160.  
  161.            /// <summary>
  162.            /// Sends a mouse button click to the specified window,
  163.            /// on the specified coordinates relative to its client-area,
  164.            /// by calling <see cref="Win32.NativeMethods.SendMessage"/> function.
  165.            /// </summary>
  166.            ///
  167.            /// <param name="hWnd">
  168.            /// A handle to the target window.
  169.            /// </param>
  170.            ///
  171.            /// <param name="button">
  172.            /// The mouse button click to send.
  173.            /// </param>
  174.            ///
  175.            /// <param name="pt">
  176.            /// The coordinates within the client area of the window,
  177.            /// where to send the mouse button click.
  178.            /// </param>
  179.            ///
  180.            /// <returns>
  181.            /// <see langword="True"/> if the function succeeds; otherwise, <see langword="False"/>.
  182.            /// </returns>
  183.            [DebuggerStepThrough]
  184.            internal static bool SendMouseButtonClick(IntPtr hWnd, MouseButtonClick button, Point pt) {
  185.                return UtilMouse.SendMouseButtonClick_Internal(hWnd, button, pt, async: false);
  186.            }
  187.  
  188.            /// <summary>
  189.            /// Asynchronouslly sends a mouse button click to the specified window,
  190.            /// on the specified coordinates relative to its client-area,
  191.            /// by calling <see cref="Win32.NativeMethods.PostMessage"/> function.
  192.            /// </summary>
  193.            ///
  194.            /// <param name="hWnd">
  195.            /// A handle to the target window.
  196.            /// </param>
  197.            ///
  198.            /// <param name="button">
  199.            /// The mouse button click to send.
  200.            /// </param>
  201.            ///
  202.            /// <param name="pt">
  203.            /// The coordinates within the client area of the window,
  204.            /// where to send the mouse button click.
  205.            /// </param>
  206.            ///
  207.            /// <returns>
  208.            /// <see langword="True"/> if the function succeeds; otherwise, <see langword="False"/>.
  209.            /// </returns>
  210.            [DebuggerStepThrough]
  211.            internal static bool SendMouseButtonClickAsync(IntPtr hWnd, MouseButtonClick button, Point pt) {
  212.                return UtilMouse.SendMouseButtonClick_Internal(hWnd, button, pt, async: true);
  213.            }
  214.  
  215.            /// <summary>
  216.            /// *** FOR INTERNAL USE ONLY ***
  217.            /// <para></para>
  218.            /// Sends a mouse button message to the specified window,
  219.            /// on the specified coordinates relative to its client-area.
  220.            /// </summary>
  221.            ///
  222.            /// <param name="hWnd">
  223.            /// A handle to the target window.
  224.            /// </param>
  225.            ///
  226.            /// <param name="button">
  227.            /// The mouse button message to send.
  228.            /// </param>
  229.            ///
  230.            /// <param name="pt">
  231.            /// The coordinates within the client area of the window,
  232.            /// where to send the mouse button message.
  233.            /// </param>
  234.            ///
  235.            /// <param name="async">
  236.            /// If <see langword="True"/>, calls PostMessage function rather than SendMessage.
  237.            /// </param>
  238.            ///
  239.            /// <returns>
  240.            /// <see langword="True"/> if the function succeeds; otherwise, <see langword="False"/>.
  241.            /// </returns>
  242.            private static bool SendMouseButtonMessage_Internal(IntPtr hWnd, MouseButtonMessage button, Point pt, bool async) {
  243.  
  244.                if (pt == null) {
  245.                    pt = Point.Empty;
  246.                }
  247.  
  248.                Delegate msgFunc = async ?
  249.                    (Delegate)(new Func<IntPtr, WindowMessages, IntPtr, IntPtr, bool>(NativeMethods.PostMessage)) :
  250.                    (Delegate)(new Func<IntPtr, WindowMessages, IntPtr, IntPtr, IntPtr>(NativeMethods.SendMessage));
  251.  
  252.                WindowMessages msg = (WindowMessages)button;
  253.                IntPtr lParam = UtilWin32.MakeLParam(pt.X, pt.Y);
  254.                IntPtr wParam = System.IntPtr.Zero;
  255.  
  256.                switch (button) {
  257.                    case MouseButtonMessage.LeftUp:
  258.                    case MouseButtonMessage.RightUp:
  259.                    case MouseButtonMessage.MiddleUp:
  260.                        wParam = IntPtr.Zero;
  261.                        break;
  262.  
  263.                    case MouseButtonMessage.LeftDown:
  264.                        wParam = new IntPtr((int)WParams.MK_LButton);
  265.                        break;
  266.  
  267.                    case MouseButtonMessage.RightDown:
  268.                        wParam = new IntPtr((int)WParams.MK_RButton);
  269.                        break;
  270.  
  271.                    case MouseButtonMessage.MiddleDown:
  272.                        wParam = new IntPtr((int)WParams.MK_MButton);
  273.                        break;
  274.  
  275.                    case MouseButtonMessage.WheelDown:
  276.                        msg = WindowMessages.WM_MouseWheel;
  277.                        wParam = UtilWin32.MakeLParam(0, -120);
  278.                        break;
  279.  
  280.                    case MouseButtonMessage.WheelUp:
  281.                        msg = WindowMessages.WM_MouseWheel;
  282.                        wParam = UtilWin32.MakeLParam(0, 120);
  283.                        break;
  284.  
  285.                    case MouseButtonMessage.WheelLeft:
  286.                        msg = WindowMessages.WM_MouseHWheel;
  287.                        wParam = UtilWin32.MakeLParam(0, -120);
  288.                        break;
  289.  
  290.                    case MouseButtonMessage.WheelRight:
  291.                        msg = WindowMessages.WM_MouseHWheel;
  292.                        wParam = UtilWin32.MakeLParam(0, 120);
  293.                        break;
  294.  
  295.                    default:
  296.                        throw new InvalidEnumArgumentException(nameof(button), (int)button, typeof(MouseButtonMessage));
  297.                }
  298.  
  299.                // Ensures the target window has focus.
  300.                NativeMethods.SetFocus(hWnd);
  301.  
  302.                object success = msgFunc.DynamicInvoke(hWnd, msg, wParam, lParam);
  303.                return (async ? (bool)success : (IntPtr)success == IntPtr.Zero);
  304.            }
  305.  
  306.            /// <summary>
  307.            /// *** FOR INTERNAL USE ONLY ***
  308.            /// <para></para>
  309.            /// Sends a mouse button click to the specified window,
  310.            /// on the specified coordinates relative to its client-area.
  311.            /// </summary>
  312.            ///
  313.            /// <param name="hWnd">
  314.            /// A handle to the target window.
  315.            /// </param>
  316.            ///
  317.            /// <param name="button">
  318.            /// The mouse button click to send.
  319.            /// </param>
  320.            ///
  321.            /// <param name="pt">
  322.            /// The coordinates within the client area of the window,
  323.            /// where to send the mouse button click.
  324.            /// </param>
  325.            ///
  326.            /// <param name="async">
  327.            /// If <see langword="True"/>, calls PostMessage function rather than SendMessage.
  328.            /// </param>
  329.            ///
  330.            /// <returns>
  331.            /// <see langword="True"/> if the function succeeds; otherwise, <see langword="False"/>.
  332.            /// </returns>
  333.            private static bool SendMouseButtonClick_Internal(IntPtr hWnd, MouseButtonClick button, Point pt, bool async) {
  334.  
  335.                MouseButtonMessage msgButtonDown;
  336.                MouseButtonMessage msgButtonUp;
  337.  
  338.                switch (button) {
  339.                    case MouseButtonClick.LeftButton:
  340.                        msgButtonDown = MouseButtonMessage.LeftDown;
  341.                        msgButtonUp = MouseButtonMessage.LeftUp;
  342.                        break;
  343.  
  344.                    case MouseButtonClick.RightButton:
  345.                        msgButtonDown = MouseButtonMessage.RightDown;
  346.                        msgButtonUp = MouseButtonMessage.RightUp;
  347.                        break;
  348.  
  349.                    case MouseButtonClick.MiddleButton:
  350.                        msgButtonDown = MouseButtonMessage.MiddleDown;
  351.                        msgButtonUp = MouseButtonMessage.MiddleUp;
  352.                        break;
  353.  
  354.                    default:
  355.                        throw new InvalidEnumArgumentException(nameof(button), (int)button, typeof(MouseButtonClick));
  356.                }
  357.  
  358.                // Milliseconds to wait between sequentially sendig WM_#BUTTON_DOWN + WM_#BUTTON_UP message combination.
  359.                const int msgIntervalMs = 100;
  360.  
  361.                bool successButtonDown = UtilMouse.SendMouseButtonMessage_Internal(hWnd, msgButtonDown, pt, async);
  362.                Thread.Sleep(msgIntervalMs);
  363.                bool successButtonUp = UtilMouse.SendMouseButtonMessage_Internal(hWnd, msgButtonUp, pt, async);
  364.  
  365.                return successButtonDown & successButtonUp;
  366.            }
  367.  
  368.        }
  369.  
  370.    }
  371.  
  372.    namespace Win32 {
  373.  
  374.        /// <summary>
  375.        /// Platform Invocation (P/Invoke) methods, access unmanaged code.
  376.        /// </summary>
  377.        [SuppressUnmanagedCodeSecurity]
  378.        internal sealed class NativeMethods {
  379.  
  380.            /// <summary>
  381.            /// Prevents a default instance of the <see cref="NativeMethods"/> class from being created.
  382.            /// </summary>
  383.            [DebuggerNonUserCode]
  384.            private NativeMethods() { }
  385.  
  386.            #region  User32.dll
  387.  
  388.            /// <summary>
  389.            /// Sets the keyboard focus to the specified window.
  390.            /// <para></para>
  391.            /// The window must be attached to the calling thread's message queue.
  392.            /// </summary>
  393.            ///
  394.            /// <param name="hWnd">
  395.            /// A handle to the window that will receive the keyboard input.
  396.            /// <para></para>
  397.            /// If this parameter is <see cref="IntPtr.Zero"/>, keystrokes are ignored.
  398.            /// </param>
  399.            ///
  400.            /// <returns>
  401.            /// If the function succeeds, the return value is the handle to the window that previously had the keyboard focus.
  402.            /// <para></para>
  403.            /// If the <paramref name="hWnd"/> parameter is invalid or
  404.            /// the window is not attached to the calling thread's message queue,
  405.            /// the return value is <see cref="IntPtr.Zero"/>.
  406.            /// <para></para>
  407.            /// To get extended error information, call <see cref="Marshal.GetLastWin32Error"/>.
  408.            /// </returns>
  409.            [DllImport("User32.dll", SetLastError = true)]
  410.            internal static extern IntPtr SetFocus([In, Optional] IntPtr hWnd);
  411.  
  412.            /// <summary>
  413.            /// Sends the specified message to a window or windows.
  414.            /// <para></para>
  415.            /// The SendMessage function calls the window procedure for the specified window
  416.            /// and does not return until the window procedure has processed the message.
  417.            /// </summary>
  418.            ///
  419.            /// <param name="hWnd">
  420.            /// A handle to the window whose window procedure will receive the message.
  421.            /// </param>
  422.            ///
  423.            /// <param name="msg">
  424.            /// The message to be sent.
  425.            /// </param>
  426.            ///
  427.            /// <param name="wParam">
  428.            /// Additional message-specific information.
  429.            /// </param>
  430.            ///
  431.            /// <param name="lParam">
  432.            /// Additional message-specific information.
  433.            /// </param>
  434.            ///
  435.            /// <returns>
  436.            /// The return value specifies the result of the message processing; it depends on the message sent.
  437.            /// </returns>
  438.            [DllImport("User32.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Auto, SetLastError = true)]
  439.            [return: MarshalAs(UnmanagedType.SysInt)]
  440.            internal static extern IntPtr SendMessage([In, MarshalAs(UnmanagedType.SysInt)] IntPtr hWnd,
  441.                                                      [In, MarshalAs(UnmanagedType.I4)] WindowMessages msg,
  442.                                                      [In, MarshalAs(UnmanagedType.SysInt)] IntPtr wParam,
  443.                                                      [In, MarshalAs(UnmanagedType.SysInt)] IntPtr lParam);
  444.  
  445.            /// <summary>
  446.            /// Places (posts) a message in the message queue associated with the thread that created
  447.            /// the specified window and returns without waiting for the thread to process the message.
  448.            /// </summary>
  449.            ///
  450.            /// <param name="hWnd">
  451.            /// Handle to the window whose window procedure will receive the message.
  452.            /// <para></para>
  453.            /// If this parameter is WindowMessages.HWND_Broadcast,
  454.            /// the message is sent to all top-level windows in the system,
  455.            /// including disabled or invisible unowned windows, overlapped windows, and pop-up windows;
  456.            /// but the message is not sent to child windows.
  457.            /// </param>
  458.            ///
  459.            /// <param name="msg">
  460.            /// The message to be sent.
  461.            /// </param>
  462.            ///
  463.            /// <param name="wparam">
  464.            /// Additional message-specific information.
  465.            /// </param>
  466.            ///
  467.            /// <param name="lparam">
  468.            /// Additional message-specific information.
  469.            /// </param>
  470.            ///
  471.            /// <returns>
  472.            /// If the function succeeds, the return value is <see langword="true"/>.
  473.            /// <para></para>
  474.            /// If the function fails, the return value is <see langword="false"/>.
  475.            /// <para></para>
  476.            /// To get extended error information, call <see cref="Marshal.GetLastWin32Error"/>.
  477.            /// </returns>
  478.            [DllImport("User32.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Auto, SetLastError = true)]
  479.            [return: MarshalAs(UnmanagedType.Bool)]
  480.            internal static extern bool PostMessage([In, Optional, MarshalAs(UnmanagedType.SysInt)] IntPtr hWnd,
  481.                                                    [In, MarshalAs(UnmanagedType.I4)] WindowMessages msg,
  482.                                                    [In, MarshalAs(UnmanagedType.SysInt)] IntPtr wparam,
  483.                                                    [In, MarshalAs(UnmanagedType.SysInt)] IntPtr lparam);
  484.  
  485.            #endregion
  486.        }
  487.  
  488.        /// <summary>
  489.        /// Provides Windows API related utilites.
  490.        /// </summary>
  491.        internal sealed class UtilWin32 {
  492.  
  493.            /// <summary>
  494.            /// Prevents a default instance of the <see cref="UtilWin32"/> class from being created.
  495.            /// </summary>
  496.            [DebuggerNonUserCode]
  497.            private UtilWin32() { }
  498.  
  499.            /// <summary>
  500.            /// Creates a LONG Param (LParam) value for a window message, from two <see cref="Integer"/> values.
  501.            /// <para></para>
  502.            /// You must call this method if you need to use negative values.
  503.            /// <para></para>
  504.            /// <seealso cref="Message.LParam"/>
  505.            /// </summary>
  506.            ///
  507.            /// <remarks>
  508.            /// <see href="https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-makelparam"/>
  509.            /// </remarks>
  510.            ///
  511.            /// <example> This is a code example.
  512.            /// <code language="VB.NET">
  513.            /// Dim lParam as IntPtr = MakeLParam(Integer.MaxValue, Integer.MaxValue)
  514.            /// </code>
  515.            /// </example>
  516.            ///
  517.            /// <param name="lo">
  518.            /// The low-order <see cref="Integer"/> value.
  519.            /// </param>
  520.            ///
  521.            /// <param name="hi">
  522.            /// The high-order <see cref="Integer"/> value.
  523.            /// </param>
  524.            ///
  525.            /// <returns>
  526.            /// The resulting LParam value.
  527.            /// </returns>
  528.            [DebuggerStepThrough]
  529.            internal static IntPtr MakeLParam(int lo, int hi) {
  530.                byte[] loBytes = { BitConverter.GetBytes(lo)[0], BitConverter.GetBytes(lo)[1] };
  531.                byte[] hiBytes = { BitConverter.GetBytes(hi)[0], BitConverter.GetBytes(hi)[1] };
  532.                byte[] combined = loBytes.Concat(hiBytes).ToArray();
  533.  
  534.                return new IntPtr(BitConverter.ToInt32(combined, 0));
  535.            }
  536.  
  537.            /// <summary>
  538.            /// Creates a LONG Param (LParam) value for a window message, from two <see cref="UShort"/> values.
  539.            /// <para></para>
  540.            /// <seealso cref="Message.LParam"/>
  541.            /// </summary>
  542.            ///
  543.            /// <remarks>
  544.            /// <see href="https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-makelparam"/>
  545.            /// </remarks>
  546.            ///
  547.            /// <example> This is a code example.
  548.            /// <code language="VB.NET">
  549.            /// Dim lParam as IntPtr = MakeLParam(UShort.MaxValue, UShort.MaxValue)
  550.            /// </code>
  551.            /// </example>
  552.            ///
  553.            /// <param name="loWord">
  554.            /// The low-order WORD value.
  555.            /// </param>
  556.            ///
  557.            /// <param name="hiWord">
  558.            /// The high-order WORD value.
  559.            /// </param>
  560.            ///
  561.            /// <returns>
  562.            /// The resulting LParam value.
  563.            /// </returns>
  564.            [DebuggerStepThrough]
  565.            internal static IntPtr MakeLParam(ushort loWord, ushort hiWord) {
  566.                return new IntPtr(UtilWin32.MakeDWord(loWord, hiWord));
  567.            }
  568.  
  569.            /// <summary>
  570.            /// Creates a Double WORD (DWORD, 32-Bit Unsigned Integer) value from a LOWORD and a HIWORD value.
  571.            /// </summary>
  572.            ///
  573.            /// <example> This is a code example.
  574.            /// <code language="VB.NET">
  575.            /// Dim value as UInteger = MakeDWord(UShort.MaxValue, UShort.MaxValue)
  576.            /// </code>
  577.            /// </example>
  578.            ///
  579.            /// <param name="loWord">
  580.            /// The low-order WORD.
  581.            /// </param>
  582.            ///
  583.            /// <param name="hiWord">
  584.            /// The high-order WORD.
  585.            /// </param>
  586.            ///
  587.            /// <returns>
  588.            /// The resulting DWORD value.
  589.            /// </returns>
  590.            [DebuggerStepThrough]
  591.            internal static uint MakeDWord(ushort loWord, ushort hiWord) {
  592.                byte[] loBytes = BitConverter.GetBytes(loWord);
  593.                byte[] hiBytes = BitConverter.GetBytes(hiWord);
  594.                byte[] combined = loBytes.Concat(hiBytes).ToArray();
  595.  
  596.                return BitConverter.ToUInt32(combined, 0);
  597.            }
  598.        }
  599.    }
  600.  
  601.    namespace Win32.Enums {
  602.  
  603.        /// <summary>
  604.        /// Defines additional message-specific information for the WORD Param (WParam) value of window messages.
  605.        /// </summary>
  606.        ///
  607.        /// <remarks>
  608.        /// <see href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms644927%28v=vs.85%29.aspx#system_defined"/>
  609.        /// </remarks>
  610.        internal enum WParams : int {
  611.            /// <summary>
  612.            /// A null WParam.
  613.            /// </summary>
  614.            Null = 0x0,
  615.  
  616.            /// <summary>
  617.            /// The left mouse button is down.
  618.            /// <para></para>
  619.            /// wParam to use with <see cref="WindowMessages.WM_LButtonDown"/> message.
  620.            /// </summary>
  621.            MK_LButton = 0x1,
  622.  
  623.            /// <summary>
  624.            /// The middle mouse button is down.
  625.            /// <para></para>
  626.            /// wParam to use with <see cref="WindowMessages.WM_LButtonDown"/> and <see cref="WindowMessages.WM_LButtonUp"/> messages.
  627.            /// </summary>
  628.            MK_MButton = 0x10,
  629.  
  630.            /// <summary>
  631.            /// The right mouse button is down.
  632.            /// <para></para>
  633.            /// wParam to use with <see cref="WindowMessages.WM_LButtonDown"/> and <see cref="WindowMessages.WM_LButtonUp"/> messages.
  634.            /// </summary>
  635.            MK_RButton = 0x2
  636.        }
  637.  
  638.        /// <summary>
  639.        /// Defines window messages.
  640.        /// <para></para>
  641.        /// The system sends or posts a system-defined message when it communicates with an application.
  642.        /// <para></para>
  643.        /// It uses these messages to control the operations of applications and to provide input and other information for applications to process.
  644.        /// <para></para>
  645.        /// An application can also send or post system-defined messages.
  646.        /// <para></para>
  647.        /// Applications generally use these messages to control the operation of control windows created by using preregistered window classes.
  648.        /// </summary>
  649.        ///
  650.        /// <remarks>
  651.        /// <see href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms644927%28v=vs.85%29.aspx"/>
  652.        /// </remarks>
  653.        internal enum WindowMessages : int {
  654.  
  655.            /// <summary>
  656.            /// The message is posted when the user presses the left mouse button while the cursor is in the
  657.            /// client area of a window.
  658.            /// <para></para>
  659.            /// If the mouse is not captured the message is posted to the window beneath the cursor.
  660.            /// <para></para>
  661.            /// Otherwise the message is posted to the window that has captured the mouse.
  662.            /// </summary>
  663.            WM_LButtonDown = 0x201,
  664.  
  665.            /// <summary>
  666.            /// The message is posted when the user releases the left mouse button while the cursor is in the
  667.            /// client area of a window.
  668.            /// <para></para>
  669.            /// If the mouse is not captured the message is posted to the window beneath the cursor.
  670.            /// <para></para>
  671.            /// Otherwise the message is posted to the window that has captured the mouse.
  672.            /// </summary>
  673.            WM_LButtonUp = 0x202,
  674.  
  675.            /// <summary>
  676.            /// The message is posted when the user presses the middle mouse button while the cursor is in the
  677.            /// client area of a window.
  678.            /// <para></para>
  679.            /// If the mouse is not captured the message is posted to the window beneath the cursor.
  680.            /// <para></para>
  681.            /// Otherwise the message is posted to the window that has captured the mouse.
  682.            /// </summary>
  683.            WM_MButtonDown = 0x207,
  684.  
  685.            /// <summary>
  686.            /// The message is posted when the user releases the middle mouse button while the cursor is in the
  687.            /// client area of a window.
  688.            /// <para></para>
  689.            /// If the mouse is not captured the message is posted to the window beneath the cursor.
  690.            /// <para></para>
  691.            /// Otherwise the message is posted to the window that has captured the mouse.
  692.            /// </summary>
  693.            WM_MButtonUp = 0x208,
  694.  
  695.            /// <summary>
  696.            /// The message is posted when the user presses the right mouse button while the cursor is in the
  697.            /// client area of a window.
  698.            /// <para></para>
  699.            /// If the mouse is not captured the message is posted to the window beneath the cursor.
  700.            /// <para></para>
  701.            /// Otherwise the message is posted to the window that has captured the mouse.
  702.            /// </summary>
  703.            WM_RButtonDown = 0x204,
  704.  
  705.            /// <summary>
  706.            /// The message is posted when the user releases the right mouse button while the cursor is in the
  707.            /// client area of a window.
  708.            /// <para></para>
  709.            /// If the mouse is not captured the message is posted to the window beneath the cursor.
  710.            /// <para></para>
  711.            /// Otherwise the message is posted to the window that has captured the mouse.
  712.            /// </summary>
  713.            WM_RButtonUp = 0x205,
  714.  
  715.            /// <summary>
  716.            /// Posted when the user presses the first or second X button while the cursor is in the client area of a window.
  717.            /// <para></para>
  718.            /// If the mouse is not captured, the message is posted to the window beneath the cursor.
  719.            /// <para></para>
  720.            /// Otherwise, the message is posted to the window that has captured the mouse.
  721.            /// </summary>
  722.            WM_XButtonDown = 0x20B,
  723.  
  724.            /// <summary>
  725.            /// Posted when the user releases the first or second X button while the cursor is in the client area of a window.
  726.            /// <para></para>
  727.            /// If the mouse is not captured, the message is posted to the window beneath the cursor.
  728.            /// <para></para>
  729.            /// Otherwise, the message is posted to the window that has captured the mouse.
  730.            /// </summary>
  731.            WM_XButtonUp = 0x20C,
  732.  
  733.            /// <summary>
  734.            /// The message is sent to the focus window when the mouse wheel is rotated.
  735.            /// <para></para>
  736.            /// The <c>DefWindowProc</c> function propagates the message to the window's parent.
  737.            /// <para></para>
  738.            /// There should be no internal forwarding of the message since <c>DefWindowProc</c> propagates it up the
  739.            /// parent chain until it finds a window that processes it.
  740.            /// </summary>
  741.            WM_MouseWheel = 0x20A,
  742.  
  743.            /// <summary>
  744.            /// The message is sent to the focus window when the mouse's horizontal scroll wheel is tilted or rotated.
  745.            /// <para></para>
  746.            /// The <c>DefWindowProc</c> function propagates the message to the window's parent.
  747.            /// <para></para>
  748.            /// There should be no internal forwarding of the message since <c>DefWindowProc</c> propagates it up
  749.            /// the parent chain until it finds a window that processes it.
  750.            /// </summary>
  751.            WM_MouseHWheel = 0x20E
  752.  
  753.        }
  754.  
  755.    }
  756.  
  757. }



Ejemplo de uso:

Código
  1. using System;
  2. using System.Drawing;
  3. using System.Windows.Forms;
  4.  
  5. using DevCase.Core.IO.Devices.Input;
  6.  
  7. namespace WindowsFormsApp1 {
  8.  
  9.    public partial class Form1 : Form {
  10.        public Form1() {
  11.            this.InitializeComponent();
  12.        }
  13.  
  14.        private void Button1_Click(object sender, EventArgs e) {
  15.            IntPtr hWnd = this.button2.Handle;
  16.            Point pt = Point.Empty;
  17.            bool success = UtilMouse.SendMouseButtonClick(hWnd, MouseButtonClick.LeftButton, pt);
  18.  
  19.            // O también:
  20.            // bool success =
  21.            //     UtilMouse.SendMouseButtonMessage(hWnd, MouseButtonMessage.LeftDown, point) &
  22.            //     UtilMouse.SendMouseButtonMessage(hWnd, MouseButtonMessage.LeftUp, point);
  23.  
  24.            Console.WriteLine($"{nameof(success)}: {success}");
  25.        }
  26.  
  27.        private void Button2_Click(object sender, EventArgs e) {
  28.            MessageBox.Show("Button Clicked!");
  29.        }
  30.    }
  31. }

Aténtamente,
Elektro.
« Última modificación: 13 Abril 2024, 16:49 pm por Eleкtro » En línea

Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.821



Ver Perfil
Re: Problema con PostMessage y SendMessage
« Respuesta #4 en: 13 Abril 2024, 12:59 pm »

Comparto el código fuente anterior, pero con documentación reducida, por si alguien lo prefiere así sin tanto texto adicional.

(EL SIGUIENTE CÓDIGO HA SIDO REFACTORIZADO Y PUBLICADO A LAS 16:35 HORA ESPAÑOLA, SIMPLIFICANDO Y MEJORANDO VARIOS ASPECTOS GENERALES.)

Son 280 líneas, en comparación con las 694 del post anterior.
Son 328 líneas, en comparación con las 757 del post anterior.

DevCase.cs
Código
  1. using System;
  2. using System.ComponentModel;
  3. using System.Diagnostics;
  4. using System.Drawing;
  5. using System.Linq;
  6. using System.Runtime.InteropServices;
  7. using System.Security;
  8. using System.Threading;
  9.  
  10. using DevCase.Win32;
  11. using DevCase.Win32.Enums;
  12.  
  13. namespace DevCase {
  14.  
  15.    namespace Core.IO.Devices.Input {
  16.  
  17.        /// <summary>
  18.        /// Provides mouse interaction related utilities.
  19.        /// </summary>
  20.        internal sealed class UtilMouse {
  21.  
  22.            [DebuggerNonUserCode]
  23.            private UtilMouse() { }
  24.  
  25.            /// <summary>
  26.            /// Defines a button message to send to a window.
  27.            /// </summary>
  28.            internal enum MouseButtonMessage : int {
  29.                LeftDown = WindowMessages.WM_LButtonDown,
  30.                LeftUp = WindowMessages.WM_LButtonUp,
  31.                RightDown = WindowMessages.WM_RButtonDown,
  32.                RightUp = WindowMessages.WM_RButtonUp,
  33.                MiddleDown = WindowMessages.WM_MButtonDown,
  34.                MiddleUp = WindowMessages.WM_MButtonUp,
  35.                WheelDown,
  36.                WheelUp,
  37.                WheelLeft,
  38.                WheelRight
  39.  
  40.            }
  41.  
  42.            /// <summary>
  43.            /// Defines a click of a mouse button.
  44.            /// </summary>
  45.            internal enum MouseButtonClick : int {
  46.                LeftButton,
  47.                RightButton,
  48.                MiddleButton
  49.            }
  50.  
  51.            /// <summary>
  52.            /// Sends a mouse button message to the specified window,
  53.            /// on the specified coordinates relative to its client-area,
  54.            /// by calling <see cref="Win32.NativeMethods.SendMessage"/> function.
  55.            /// </summary>
  56.            [DebuggerStepThrough]
  57.            internal static bool SendMouseButtonMessage(IntPtr hWnd, MouseButtonMessage button, Point pt) {
  58.                return UtilMouse.SendMouseButtonMessage_Internal(hWnd, button, pt, async: false);
  59.            }
  60.  
  61.            /// <summary>
  62.            /// Asynchronouslly sends a mouse button message to the specified window,
  63.            /// on the specified coordinates relative to its client-area,
  64.            /// by calling <see cref="Win32.NativeMethods.PostMessage"/> function.
  65.            /// </summary>
  66.            [DebuggerStepThrough]
  67.            internal static bool SendMouseButtonMessageAsync(IntPtr hWnd, MouseButtonMessage button, Point pt) {
  68.                return UtilMouse.SendMouseButtonMessage_Internal(hWnd, button, pt, async: true);
  69.            }
  70.  
  71.            /// <summary>
  72.            /// Sends a mouse button click to the specified window,
  73.            /// on the specified coordinates relative to its client-area,
  74.            /// by calling <see cref="Win32.NativeMethods.SendMessage"/> function.
  75.            /// </summary>
  76.            [DebuggerStepThrough]
  77.            internal static bool SendMouseButtonClick(IntPtr hWnd, MouseButtonClick button, Point pt) {
  78.                return UtilMouse.SendMouseButtonClick_Internal(hWnd, button, pt, async: false);
  79.            }
  80.  
  81.            /// <summary>
  82.            /// Asynchronouslly sends a mouse button click to the specified window,
  83.            /// on the specified coordinates relative to its client-area,
  84.            /// by calling <see cref="Win32.NativeMethods.PostMessage"/> function.
  85.            /// </summary>
  86.            [DebuggerStepThrough]
  87.            internal static bool SendMouseButtonClickAsync(IntPtr hWnd, MouseButtonClick button, Point pt) {
  88.                return UtilMouse.SendMouseButtonClick_Internal(hWnd, button, pt, async: true);
  89.            }
  90.  
  91.            /// <summary>
  92.            /// *** FOR INTERNAL USE ONLY ***
  93.            /// <para></para>
  94.            /// Sends a mouse button message to the specified window,
  95.            /// on the specified coordinates relative to its client-area.
  96.            /// </summary>
  97.            private static bool SendMouseButtonMessage_Internal(IntPtr hWnd, MouseButtonMessage button, Point pt, bool async) {
  98.  
  99.                if (pt == null) {
  100.                    pt = Point.Empty;
  101.                }
  102.  
  103.                Delegate msgFunc = async ?
  104.                    (Delegate)(new Func<IntPtr, WindowMessages, IntPtr, IntPtr, bool>(NativeMethods.PostMessage)) :
  105.                    (Delegate)(new Func<IntPtr, WindowMessages, IntPtr, IntPtr, IntPtr>(NativeMethods.SendMessage));
  106.  
  107.                WindowMessages msg = (WindowMessages)button;
  108.                IntPtr lParam = UtilWin32.MakeLParam(pt.X, pt.Y);
  109.                IntPtr wParam = System.IntPtr.Zero;
  110.  
  111.                switch (button) {
  112.                    case MouseButtonMessage.LeftUp:
  113.                    case MouseButtonMessage.RightUp:
  114.                    case MouseButtonMessage.MiddleUp:
  115.                        wParam = IntPtr.Zero;
  116.                        break;
  117.  
  118.                    case MouseButtonMessage.LeftDown:
  119.                        wParam = new IntPtr((int)WParams.MK_LButton);
  120.                        break;
  121.  
  122.                    case MouseButtonMessage.RightDown:
  123.                        wParam = new IntPtr((int)WParams.MK_RButton);
  124.                        break;
  125.  
  126.                    case MouseButtonMessage.MiddleDown:
  127.                        wParam = new IntPtr((int)WParams.MK_MButton);
  128.                        break;
  129.  
  130.                    case MouseButtonMessage.WheelDown:
  131.                        msg = WindowMessages.WM_MouseWheel;
  132.                        wParam = UtilWin32.MakeLParam(0, -120);
  133.                        break;
  134.  
  135.                    case MouseButtonMessage.WheelUp:
  136.                        msg = WindowMessages.WM_MouseWheel;
  137.                        wParam = UtilWin32.MakeLParam(0, 120);
  138.                        break;
  139.  
  140.                    case MouseButtonMessage.WheelLeft:
  141.                        msg = WindowMessages.WM_MouseHWheel;
  142.                        wParam = UtilWin32.MakeLParam(0, -120);
  143.                        break;
  144.  
  145.                    case MouseButtonMessage.WheelRight:
  146.                        msg = WindowMessages.WM_MouseHWheel;
  147.                        wParam = UtilWin32.MakeLParam(0, 120);
  148.                        break;
  149.  
  150.                    default:
  151.                        throw new InvalidEnumArgumentException(nameof(button), (int)button, typeof(MouseButtonMessage));
  152.                }
  153.  
  154.                // Ensures the target window has focus.
  155.                NativeMethods.SetFocus(hWnd);
  156.  
  157.                object success = msgFunc.DynamicInvoke(hWnd, msg, wParam, lParam);
  158.                return (async ? (bool)success : (IntPtr)success == IntPtr.Zero);
  159.            }
  160.  
  161.            /// <summary>
  162.            /// *** FOR INTERNAL USE ONLY ***
  163.            /// <para></para>
  164.            /// Sends a mouse button click to the specified window,
  165.            /// on the specified coordinates relative to its client-area.
  166.            /// </summary>
  167.            private static bool SendMouseButtonClick_Internal(IntPtr hWnd, MouseButtonClick button, Point pt, bool async) {
  168.  
  169.                MouseButtonMessage msgButtonDown;
  170.                MouseButtonMessage msgButtonUp;
  171.  
  172.                switch (button) {
  173.                    case MouseButtonClick.LeftButton:
  174.                        msgButtonDown = MouseButtonMessage.LeftDown;
  175.                        msgButtonUp = MouseButtonMessage.LeftUp;
  176.                        break;
  177.  
  178.                    case MouseButtonClick.RightButton:
  179.                        msgButtonDown = MouseButtonMessage.RightDown;
  180.                        msgButtonUp = MouseButtonMessage.RightUp;
  181.                        break;
  182.  
  183.                    case MouseButtonClick.MiddleButton:
  184.                        msgButtonDown = MouseButtonMessage.MiddleDown;
  185.                        msgButtonUp = MouseButtonMessage.MiddleUp;
  186.                        break;
  187.  
  188.                    default:
  189.                        throw new InvalidEnumArgumentException(nameof(button), (int)button, typeof(MouseButtonClick));
  190.                }
  191.  
  192.                // Milliseconds to wait between sequentially sendig WM_#BUTTON_DOWN + WM_#BUTTON_UP message combination.
  193.                const int msgIntervalMs = 100;
  194.  
  195.                bool successButtonDown = UtilMouse.SendMouseButtonMessage_Internal(hWnd, msgButtonDown, pt, async);
  196.                Thread.Sleep(msgIntervalMs);
  197.                bool successButtonUp = UtilMouse.SendMouseButtonMessage_Internal(hWnd, msgButtonUp, pt, async);
  198.  
  199.                return successButtonDown & successButtonUp;
  200.            }
  201.  
  202.        }
  203.  
  204.    }
  205.  
  206.    namespace Win32 {
  207.  
  208.        /// <summary>
  209.        /// Platform Invocation (P/Invoke) methods, access unmanaged code.
  210.        /// </summary>
  211.        [SuppressUnmanagedCodeSecurity]
  212.        internal sealed class NativeMethods {
  213.  
  214.            [DebuggerNonUserCode]
  215.            private NativeMethods() { }
  216.  
  217.            #region  User32.dll
  218.  
  219.            /// <summary>
  220.            /// Sets the keyboard focus to the specified window.
  221.            /// <para></para>
  222.            /// The window must be attached to the calling thread's message queue.
  223.            /// </summary>
  224.            [DllImport("User32.dll", SetLastError = true)]
  225.            internal static extern IntPtr SetFocus([In, Optional] IntPtr hWnd);
  226.  
  227.            /// <summary>
  228.            /// Sends the specified message to a window or windows.
  229.            /// <para></para>
  230.            /// The SendMessage function calls the window procedure for the specified window
  231.            /// and does not return until the window procedure has processed the message.
  232.            /// </summary>
  233.            [DllImport("User32.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Auto, SetLastError = true)]
  234.            [return: MarshalAs(UnmanagedType.SysInt)]
  235.            internal static extern IntPtr SendMessage([In, MarshalAs(UnmanagedType.SysInt)] IntPtr hWnd,
  236.                                                      [In, MarshalAs(UnmanagedType.I4)] WindowMessages msg,
  237.                                                      [In, MarshalAs(UnmanagedType.SysInt)] IntPtr wParam,
  238.                                                      [In, MarshalAs(UnmanagedType.SysInt)] IntPtr lParam);
  239.  
  240.            /// <summary>
  241.            /// Places (posts) a message in the message queue associated with the thread that created
  242.            /// the specified window and returns without waiting for the thread to process the message.
  243.            /// </summary>
  244.            [DllImport("User32.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Auto, SetLastError = true)]
  245.            [return: MarshalAs(UnmanagedType.Bool)]
  246.            internal static extern bool PostMessage([In, Optional, MarshalAs(UnmanagedType.SysInt)] IntPtr hWnd,
  247.                                                    [In, MarshalAs(UnmanagedType.I4)] WindowMessages msg,
  248.                                                    [In, MarshalAs(UnmanagedType.SysInt)] IntPtr wparam,
  249.                                                    [In, MarshalAs(UnmanagedType.SysInt)] IntPtr lparam);
  250.  
  251.            #endregion
  252.        }
  253.  
  254.        /// <summary>
  255.        /// Provides Windows API related utilites.
  256.        /// </summary>
  257.        internal sealed class UtilWin32 {
  258.  
  259.            [DebuggerNonUserCode]
  260.            private UtilWin32() { }
  261.  
  262.            /// <summary>
  263.            /// Creates a LONG Param (LParam) value for a window message, from two <see cref="Integer"/> values.
  264.            /// <para></para>
  265.            /// You must call this method if you need to use negative values.
  266.            /// </summary>
  267.            [DebuggerStepThrough]
  268.            internal static IntPtr MakeLParam(int lo, int hi) {
  269.                byte[] loBytes = { BitConverter.GetBytes(lo)[0], BitConverter.GetBytes(lo)[1] };
  270.                byte[] hiBytes = { BitConverter.GetBytes(hi)[0], BitConverter.GetBytes(hi)[1] };
  271.                byte[] combined = loBytes.Concat(hiBytes).ToArray();
  272.  
  273.                return new IntPtr(BitConverter.ToInt32(combined, 0));
  274.            }
  275.  
  276.            /// <summary>
  277.            /// Creates a LONG Param (LParam) value for a window message, from two <see cref="UShort"/> values.
  278.            /// </summary>
  279.            [DebuggerStepThrough]
  280.            internal static IntPtr MakeLParam(ushort loWord, ushort hiWord) {
  281.                return new IntPtr(UtilWin32.MakeDWord(loWord, hiWord));
  282.            }
  283.  
  284.            /// <summary>
  285.            /// Creates a Double WORD (DWORD, 32-Bit Unsigned Integer) value from a LOWORD and a HIWORD value.
  286.            /// </summary>
  287.            [DebuggerStepThrough]
  288.            internal static uint MakeDWord(ushort loWord, ushort hiWord) {
  289.                byte[] loBytes = BitConverter.GetBytes(loWord);
  290.                byte[] hiBytes = BitConverter.GetBytes(hiWord);
  291.                byte[] combined = loBytes.Concat(hiBytes).ToArray();
  292.  
  293.                return BitConverter.ToUInt32(combined, 0);
  294.            }
  295.        }
  296.    }
  297.  
  298.    namespace Win32.Enums {
  299.  
  300.        /// <summary>
  301.        /// Defines additional message-specific information for the WORD Param (WParam) value of window messages.
  302.        /// </summary>
  303.        internal enum WParams : int {
  304.            Null = 0x0,
  305.            MK_LButton = 0x1,
  306.            MK_MButton = 0x10,
  307.            MK_RButton = 0x2
  308.        }
  309.  
  310.        /// <summary>
  311.        /// Defines window messages.
  312.        /// </summary>
  313.        internal enum WindowMessages : int {
  314.            WM_LButtonDown = 0x201,
  315.            WM_LButtonUp = 0x202,
  316.            WM_MButtonDown = 0x207,
  317.            WM_MButtonUp = 0x208,
  318.            WM_RButtonDown = 0x204,
  319.            WM_RButtonUp = 0x205,
  320.            WM_XButtonDown = 0x20B,
  321.            WM_XButtonUp = 0x20C,
  322.            WM_MouseWheel = 0x20A,
  323.            WM_MouseHWheel = 0x20E
  324.        }
  325.  
  326.    }
  327.  
  328. }

Aténtamente,
Elektro.
« Última modificación: 13 Abril 2024, 16:49 pm por Eleкtro » En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Problema con SendMessage [AYUDA]
Programación Visual Basic
Psyke1 2 1,861 Último mensaje 10 Junio 2010, 18:09 pm
por Psyke1
SendMessage
Programación Visual Basic
calk9 6 2,591 Último mensaje 20 Septiembre 2011, 00:53 am
por calk9
ayuda de PostMessage
Programación C/C++
franfis 1 1,709 Último mensaje 17 Abril 2013, 18:47 pm
por x64core
¿Cómo usar Postmessage y Sendmessage?
.NET (C#, VB.NET, ASP)
Crazy.sx 2 5,449 Último mensaje 14 Septiembre 2013, 08:52 am
por Crazy.sx
Problema al enviar combinación de teclas con PostMessage
Programación C/C++
ramiro069 0 1,542 Último mensaje 12 Octubre 2016, 16:19 pm
por ramiro069
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines