Question

J'essaie d'appeler SendMessage avec un paramètre uint à partir de Java, mais je ne peux pas convertir int en uint. Je ne peux pas modifier le paramètre uint dans SendMessage car il s'agit d'une fonction Windows. Y a-t-il un moyen de le faire?

Contexte: J'utilise actuellement Processing et je suis les tutoriels suivants pour accéder à user32.dll: http: / /processing.org/hacks/hacks:jnative

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

Et je suis ceci pour appeler SendMessage http://www.codeproject.com/KB/cs/Monitor_management_guide.aspx

Voici mon code, GetActiveWindow fonctionne bien, c'est à partir du deuxième lien ci-dessus.

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

La dernière ligne est l'endroit où l'erreur se produit, elle indique que le UINT attendu dans le type User32 n'est pas applicable au LONG que j'ai fourni. Je ne peux pas non plus modifier SendMessage

Voici le fichier Java correspondant appelé par l'appel ci-dessus. La partie GetActiveWindow fonctionne correctement car elle provient d'un didacticiel. J'essaie d'adapter Sendmessage pour le suivre, mais je n'ai pas encore tout compris. Cependant, je ne pense pas que l'erreur que je reçois ait d'importance, car le fait de modifier les paramètres en SendMessage ici ne change pas les attentes du compilateur. J'ai essayé de changer int Msg en uint Msg en long Msg, le compilateur attend toujours l'uint du code ci-dessus.

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);
}
Était-ce utile?

La solution

Si vous utilisez le package org.xvolks.jnative, tous les paramètres (HWND, UINT, WPARAM et LPARAM) sont des classes de org.xvolks.jnative.misc.basicStructures. Vous devriez donc pouvoir faire quelque chose comme ceci (code non testé):

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

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

Pour votre information, voici l'implémentation de SendMessage dans org.xvolks.jnative.util.User32. Comme vous pouvez le constater, le code nominatif ne s’intéresse pas du tout aux signatures et non signés. Vous trouverez peut-être utile de récupérer le code source nominatif .

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

Et si vous décidez que vous n'aimez pas JNative, vous pouvez consulter Accès natif Java ( JNA) .

Autres conseils

Du point de vue des données, un uint et un int sont la même chose - une valeur de 32 bits. La seule différence est la façon dont les opcodes interprètent le bit le plus haut. Lorsque vous passez entre Java et C, vous ne faites que transmettre 32 bits, le signe n'est donc pas pertinent. La solution consiste simplement à déclarer le paramètre uint en tant qu'int.

BTW, la question de la signature non signée / signée n’a pas d’importance, car la valeur uMsg de SendMessage est positive pour tous les messages de Microsoft et, de ce fait, probablement pour toute autre chose que vous êtes susceptible de rencontrer.

Puisque Java n’a pas la notion de types non signés, vous devez utiliser un long pour représenter un entier non signé. Consultez ce site pour des exemples de mise en oeuvre.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top