Domanda

Sto provando a chiamare SendMessage con un parametro uint da Java, ma non riesco a convertire int in uint. Non riesco a modificare il parametro uint in SendMessage perché è una funzione di Windows. C'è un modo per farlo?

Sfondo: Attualmente sto utilizzando Elaborazione e sto seguendo i seguenti tutorial per accedere a user32.dll: http: / /processing.org/hacks/hacks:jnative

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

E sto seguendo questo per chiamare SendMessage http://www.codeproject.com/KB/cs/Monitor_management_guide.aspx

Ecco il mio codice, GetActiveWindow funziona bene, è dal secondo link sopra.

 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);

l'ultima riga è dove si verifica l'errore, dice che l'UINT previsto nel tipo User32 non è applicabile al LONG che ho fornito. Nemmeno io posso modificare SendMessage

Ecco il corrispondente file java che la chiamata sopra richiama, la parte GetActiveWindow funziona bene poiché proviene da un tutorial. Sto cercando di personalizzare Sendmessage per seguirlo, ma non ho ancora capito tutto. Tuttavia, non penso che sia importante l'errore che sto ricevendo, poiché la modifica dei parametri in SendMessage qui non cambia ciò che il compilatore si aspetta. Ho provato a cambiare int Msg in Ust Msg in Msg lungo, il compilatore si aspetta ancora dal codice sopra.

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);
}
È stato utile?

Soluzione

Se si utilizza il pacchetto org.xvolks.jnative, tutti i parametri (HWND, UINT, WPARAM e LPARAM) sono classi in org.xvolks.jnative.misc.basicStructures. Quindi dovresti essere in grado di fare qualcosa del genere (codice non testato):

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

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

Per riferimento, ecco l'implementazione di SendMessage in org.xvolks.jnative.util.User32. Come puoi vedere, il codice jnative non si preoccupa affatto di firmato e non firmato. Potresti trovare utile prendere il codice sorgente 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);
}

E se decidi che non ti piace JNative, puoi dare un'occhiata a Java Native Access ( JNA) .

Altri suggerimenti

Dal punto di vista dei dati, un uint e un int sono la stessa cosa: un valore a 32 bit. L'unica differenza è il modo in cui i codici operativi interpretano il bit più in alto. Quando si passa tra Java e C, si passano solo 32 bit, quindi il segno non è rilevante. La soluzione è dichiarare semplicemente il parametro uint come int.

A proposito, il problema di unsigned / signed non è significativo qui perché il valore uMsg per SendMessage è positivo per tutti i messaggi Microsoft e, del resto, è più che probabile positivo per qualsiasi altra cosa che potresti incontrare.

Dato che Java non ha la nozione di tipi senza segno, devi usare un long per rappresentare un int senza segno. Controlla questo sito per esempi su come farlo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top