2

我正在尝试使用 Java 中的 uint 参数调用 SendMessage,但我无法将 int 转换为 uint。我无法更改 SendMessage 中的 uint 参数,因为它是一个 windows 函数。有没有办法做到这一点?

背景:我实际上正在使用处理,我正在按照以下教程访问 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);

最后一行是发生错误的地方,它表示 User32 类型的预期 UINT 不适用于我提供的 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);
}
4

3 回答 3

3

从数据的角度来看,一个 uint 和一个 int 是同一个东西——一个 32 位的值。唯一的区别是操作码如何解释最高位。在 Java 和 C 之间传递时,您只是传递 32 位,因此符号无关紧要。解决方案是将 uint 参数声明为 int。

顺便说一句,未签名/已签名的问题在这里并不重要,因为 SendMessage 的 uMsg 值对于所有 Microsoft 消息都是正数,就此而言,对于您可能遇到的其他任何事情,很可能是正数。

于 2009-05-09T21:48:19.420 回答
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);

供您参考,这里是 org.xvolks.jnative.util.User32 中 SendMessage 的实现。如您所见,jnative 代码根本不关心有符号和无符号。您可能会发现获取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 Native Access (JNA)

于 2009-05-10T01:25:37.683 回答
-1

由于 Java 没有无符号类型的概念,因此您必须使用 long 来表示无符号 int。检查此站点以获取有关如何执行此操作的示例。

于 2009-05-09T21:02:58.390 回答