2009-05-09 2 views
2

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

фона: Я на самом деле с помощью обработки, и я отслеживаю следующие обучающие программы, чтобы получить доступ к user32.dll: http://processing.org/hacks/hacks:jnative

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

И я после этого вызвать SendMessage http://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 на длинный 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); 
} 

ответ

1

Если вы используете пакет 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 code вообще не заботится о подписанных и unsigned. Вам может показаться полезным захватить jnative source code.

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 Native Access (JNA).

+0

Ничего себе, спасибо! Мое высшее образование в CompE состояло только из программирования на C, поэтому весь этот материал ООП меня смущает. Но даже в этом случае проблема заключалась в том, что я использовал '(UINT) WM_SYSCOMMAND' вместо 'new UINT (WM_SYSCOMMAND);' что имело значение. Я все еще изучаю разницу между ними, но еще раз спасибо! Если позволите, я бы дважды проголосовал бы за вас. Но пока у меня только 11 очков, я даже не могу голосовать за вас. – omikun

+0

Рад, что вы нашли это полезным. Вы можете отметить это как ответ, и это тоже стоит того. BTW, не совсем уверен, что я назвал бы это проблемой ООП. Между Java и C существует несоответствие, и автор JNative попытался придумать умный способ справиться с этой разницей. – jdigital

-1

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

+0

Спасибо, но как долго пропустить, когда SendMessage ожидает uint? Я все еще не могу напечатать преобразование его в uint после его изменения до длинного. Извините, если сайт ответил на него, я не могу найти его нигде. Еще раз спасибо. – omikun

+0

О, уточните, я не пишу SendMessage, это часть user32.dll. Есть ли способ заставить SendMessage принять длинный вместо uint? – omikun

+0

Вы не пропустите длинный, вы и (&) его с 0xFFFFFFFF в конце, чтобы он стал 4-байтным uint в конце, пожалуйста, внимательно прочитайте сайт. – ismail

3

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

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

+0

Это правда, насколько это возможно. Но для «настройки» неподписанного int вам нужно сыграть трюки, например: int foo = (int) 4294967295L; или int foo = 0xFF << 24 | 0xFF << 16 | 0xFF << 8 | 0xFF; (что более удобно, зависит от фактического значения битовой последовательности). Вы не можете просто сделать: int foo = 4294967295 И, конечно, Java по-прежнему будет думать, что foo означает ссылку на -1. Связанный с ним сайт Cartman объясняет это более подробно. –

+0

Проблема SendMessage - это не функция, которой я управляю. В user32.dll это часть Windows. – omikun