Вопрос

Я пытаюсь вызвать SendMessage с параметром uint из Java, но не могу преобразовать int в uint.Я не могу изменить параметр uint в SendMessage, потому что это функция Windows.Есть ли какой-нибудь способ сделать это?

Фон:На самом деле я использую обработку и следую следующим руководствам для доступа к user32.dll: http://processing.org/hacks/hacks:jnative

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

И я следую этому, чтобы вызвать SendMessagehttp://www.codeproject.com/KB/cs/Monitor_management_guide.aspx

Вот мой код, GetActiveWindow работает нормально, это из второй ссылки выше.

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

В последней строке возникает ошибка: в ней говорится, что ожидаемый UINT типа User32 неприменим к предоставленному мной LONG.Я тоже не могу изменить SendMessage

Вот соответствующий Java-файл, который вызывает вызов выше. Часть GetActiveWindow работает нормально, поскольку она взята из руководства.Я пытаюсь адаптировать Sendmessage под него, но еще не во всем разобрался.Однако я не думаю, что это имеет значение для ошибки, которую я получаю, поскольку изменение здесь параметров на SendMessage не меняет того, что ожидает компилятор.Я попытался изменить int Msg на uint Msg на long Msg, компилятор по-прежнему ожидает uint из приведенного выше кода.

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);
}
Это было полезно?

Решение

Если вы используете пакет org.xvolks.jnative, все параметры (HWND, UINT, WPARAM и LPARAM) являются классами в org.xvolks.jnative.misc.basicStructures.Итак, вы сможете сделать что-то вроде этого (непроверенный код):

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

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

Для справки, вот реализация SendMessage в org.xvolks.jnative.util.User32.Как видите, код 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);
}

И если вы решите, что вам не нравится JNative, вы можете взглянуть на Собственный доступ к Java (JNA).

Другие советы

С точки зрения данных, uint и int — это одно и то же — 32-битное значение.Единственная разница заключается в том, как коды операций интерпретируют самый старший бит.При передаче между Java и C вы передаете только 32 бита, поэтому знак не имеет значения.Решение состоит в том, чтобы просто объявить параметр uint как int.

Кстати, проблема неподписанного/подписанного здесь не имеет большого значения, поскольку значение uMsg для SendMessage является положительным для всех сообщений Microsoft, и в этом отношении более чем вероятно положительно для всего остального, с чем вы, вероятно, столкнетесь.

Поскольку в Java нет понятия беззнаковых типов, вам нужно использовать long для представления беззнакового целого числа.Проверять этот сайт примеры того, как это сделать.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top