2

Java から uint パラメーターを指定して SendMessage を呼び出そうとしていますが、int を uint に変換できません。Windows 関数であるため、SendMessage の uint パラメータを変更できません。これを行う方法はありますか?

背景: 私は実際に 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 は正常に動作します。上記の 2 番目のリンクからのものです。

 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 メッセージに対して正であり、さらに言えば、遭遇する可能性が高い他のすべてに対して正である可能性が高いため、ここでは unsigned/signed の問題は重要ではありません。

于 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 には unsigned 型の概念がないため、unsigned int を表すには long を使用する必要があります。これを行う方法の例については、このサイトを確認してください。

于 2009-05-09T21:02:58.390 に答える