Java中如何传递uint?

发布于 2024-07-20 05:36:58 字数 2052 浏览 7 评论 0原文

我尝试使用 Java 中的 uint 参数调用 SendMessage,但无法将 int 转换为 uint。 我无法更改 SendMessage 中的 uint 参数,因为它是一个 Windows 函数。 有什么方法可以做到这一点吗?

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

I'm trying to call SendMessage with an uint parameter from Java, but I can't convert int to uint. I can't change the uint parameter in SendMessage because it is a windows function. Is there some way of doing this?

Background:
I'm actually using Processing, and I'm following the following tutorials to access user32.dll: http://processing.org/hacks/hacks:jnative

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

And I'm following this to call SendMessage
http://www.codeproject.com/KB/cs/Monitor_management_guide.aspx

Here's my code, GetActiveWindow works fine, it's from the second link above.

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

last line is where the error happens, it says the expected UINT in type User32 is not applicable to the LONG I provided. I can't modify SendMessage either

Here's the corresponding java file the call above invokes, the GetActiveWindow part works fine since it's from a tutorial. I'm trying to tailor Sendmessage to follow it, but I haven't figured it all out yet. However, I don't think it matters to the error I'm getting, since changing the parameters to SendMessage here doesn't change what the compiler expects. I've tried changing int Msg to uint Msg to long Msg, the compiler still expects uint from the code above.

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

小镇女孩 2024-07-27 05:36:58

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

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

From a data perspective, a uint and an int are the same thing -- a 32 bit value. The only difference is how opcodes interpret the uppermost bit. When passing between Java and C, you're just passing 32 bits, so the sign is not relevant. The solution is to just declare the uint parameter as an int.

BTW, the issue of unsigned/signed is not significant here because the uMsg value for SendMessage is positive for all Microsoft messages, and for that matter, is more than likely positive for anything else you're likely to encounter.

隐诗 2024-07-27 05:36:58

如果您使用 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)< /a>.

If you are using the org.xvolks.jnative package, all of the parameters (HWND, UINT, WPARAM, and LPARAM) are classes in org.xvolks.jnative.misc.basicStructures. So you should be able to do something like this (untested code):

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

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

For your reference, here's the implementation of SendMessage in org.xvolks.jnative.util.User32. As you can see, the jnative code does not care at all about signed and unsigned. You might find it useful to grab the 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);
}

And if you decide that you don't like JNative, you could take a look at Java Native Access (JNA).

戏舞 2024-07-27 05:36:58

由于Java没有无符号类型的概念,因此必须使用long来表示无符号int。 请查看此网站了解如何执行此操作的示例。

Since Java does not have the notion of unsigned types, you have to use a long to represent an unsigned int. Check this site for examples on how to do this.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文