Pregunta

Estoy tratando de llamar a SendMessage con un parámetro uint de Java, pero no puedo convertir int a uint. No puedo cambiar el parámetro uint en SendMessage porque es una función de Windows. ¿Hay alguna forma de hacer esto?

Antecedentes: En realidad estoy usando Processing y sigo los siguientes tutoriales para acceder a user32.dll: http: / /processing.org/hacks/hacks:jnative

y http://jnative.free. fr / SPIP-v1-8-3 / article.php3? id_article = 8

Y estoy siguiendo esto para llamar a SendMessage http://www.codeproject.com/KB/cs/Monitor_management_guide.aspx

Aquí está mi código, GetActiveWindow funciona bien, es del segundo enlace de arriba.

 int SC_MONITORPOWER = 0xF170;
 int WM_SYSCOMMAND = 0x0112;
 int MONITOR_ON = -1;
 int MONITOR_OFF = 2;
 int MONITOR_STANDBY = 1;

HWND ValidHWND = org.xvolks.jnative.util.User32.GetActiveWindow(); 
org.xvolks.jnative.util.User32.SendMessage(ValidHWND, (UINT)WM_SYSCOMMAND, 
          (WPARAM)SC_MONITORPOWER, (LPARAM)MONITOR_STANDBY);

última línea es donde ocurre el error, dice que la UINT esperada en el tipo Usuario32 no es aplicable a la LARGA que proporcioné. No puedo modificar SendMessage tampoco

Aquí está el archivo java correspondiente que invoca la llamada anterior, la parte GetActiveWindow funciona bien ya que es de un tutorial. Estoy tratando de adaptar Sendmessage para seguirlo, pero aún no lo he descubierto todo. Sin embargo, no creo que sea importante para el error que estoy recibiendo, ya que cambiar los parámetros a SendMessage aquí no cambia lo que el compilador espera. Intenté cambiar int Msg a uint Msg a long Msg, el compilador todavía espera uint del código anterior.

public class Paul_s_User32 extends User32 {
public HANDLE GetActiveWindow() {
    JNative GetActiveWindow = new JNative(DLL_NAME, "GetActiveWindow");
    GetActiveWindow.setRetVal(Type.INT);
    GetActiveWindow.invoke();
    HWND handle = new HWND(GetActiveWindow.getRetValAsInt());
    GetActiveWindow.dispose();
    return handle;
}
public IntPtr SendMessage(IntPtr hWnd, int Msg, 
          IntPtr wParam, IntPtr lParam) {
    JNative SendMessage = new JNative(DLL_NAME, "SendMessage");
    //SendMessage.setRetVal(Type.long);
    SendMessage.invoke();

    SendMessage(ValidHWND, WM_SYSCOMMAND, SC_MONITORPOWER, MONITOR_STANDBY);
}
¿Fue útil?

Solución

Si está utilizando el paquete org.xvolks.jnative, todos los parámetros (HWND, UINT, WPARAM y LPARAM) son clases en org.xvolks.jnative.misc.basicStructures. Por lo tanto, debería poder hacer algo como esto (código no probado):

import org.xvolks.jnative.misc.basicStructures.*;
...

User32.SendMessage(
    new HWND(ValidHWND),
    new UINT(WM_SYSCOMMAND), 
    new WPARAM(SC_MONITORPOWER),
    new LPARAM(MONITOR_STANDBY);

Para su referencia, aquí está la implementación de SendMessage en org.xvolks.jnative.util.User32. Como puede ver, al código jnative no le importan los signos firmados y no firmados. Puede que le resulte útil obtener el código fuente jnative .

public static LRESULT SendMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) throws NativeException, IllegalAccessException
{
    JNative SendMessage = new JNative(DLL_NAME, "SendMessageA");
    SendMessage.setRetVal(Type.INT);
    int pos = 0;
    SendMessage.setParameter(pos++, hWnd.getValue());
    SendMessage.setParameter(pos++, Msg.getValue());
    SendMessage.setParameter(pos++, wParam.getValue());
    SendMessage.setParameter(pos++, lParam.getValue());
    SendMessage.invoke();
    pos = SendMessage.getRetValAsInt();
    SendMessage.dispose();
    return new LRESULT(pos);
}

Y si decides que no te gusta JNative, puedes echar un vistazo a Java Native Access ( JNA) .

Otros consejos

Desde una perspectiva de datos, un uint y un int son lo mismo: un valor de 32 bits. La única diferencia es cómo los códigos de operación interpretan el bit superior. Al pasar entre Java y C, solo pasa 32 bits, por lo que el signo no es relevante. La solución es declarar el parámetro uint como int.

Por cierto, el problema de no firmado / firmado no es significativo aquí porque el valor de uMsg para SendMessage es positivo para todos los mensajes de Microsoft, y para el caso, es más que positivo para cualquier otra cosa que pueda encontrar.

Dado que Java no tiene la noción de tipos sin signo, debe usar un largo para representar un int sin signo. Consulte este sitio para ver ejemplos de cómo hacerlo.

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