私はそれが(Win32 APIへの呼び出し:データを保持するために、WM_COPYDATAとCOPYDATASTRUCTでSendMessage)を働かせるために多くの苦労しています、そして、今私のWindows 7コンピュータで動作するように、私のソリューションの副作用がない場合は?ここでJNA:COPYDATASTRUCTの正しいマッピングですか?
は私のコードです:
/**
* For usage with WM_COPYDATA
* cf : https://msdn.microsoft.com/en-us/library/windows/desktop/ms649010(v=vs.85).aspx
*/
long SendMessage(HWND hWnd, int msg, WPARAM wParam, COPYDATASTRUCT.ByReference lParam);
int WM_COPYDATA = 0x004A;
//cf : https://msdn.microsoft.com/en-us/library/windows/desktop/ms649010(v=vs.85).aspx
class COPYDATASTRUCT extends Structure {
public static class ByReference extends COPYDATASTRUCT implements Structure.ByReference {
}
public COPYDATASTRUCT() {
super();
}
public int dwData;
public long cbData;
public Pointer lpData;
protected List<String> getFieldOrder() {
return Arrays.asList(new String[] { "dwData", "cbData", "lpData" });
}
}
そして2例と呼び出しコード:
User32Extension.COPYDATASTRUCT.ByReference dataStruct = new User32Extension.COPYDATASTRUCT.ByReference();
String message = "Hello ! :-) !";
Memory m = new Memory(message.length() + 1);
m.setString(0, message);
dataStruct.dwData = 10;
dataStruct.cbData = message.length() + 1;
dataStruct.lpData = m;
dataStruct.write(); // writes to native memory the structure.
result = user32.SendMessage(hwndTarget, // target hwnd.
User32Extension.WM_COPYDATA, // copy data message.
wparam, // current hwnd
dataStruct // data by reference here
);
User32Extension.COPYDATASTRUCT.ByReference myDataStruct = new User32Extension.COPYDATASTRUCT.ByReference();
User32Extension.TEST_STRUCT myStruct = new User32Extension.TEST_STRUCT();
//simple C structure here with 4 fields of C types int, char, char and long.
myStruct.iNumber = 677;
myStruct.cCode = 'E';
myStruct.cCode2 = 'T';
myStruct.lLong1 = new NativeLong(123456789L);
myStruct.write();
LOGGER.trace("myStruct (size=" + myStruct.size() + ")=" + myStruct.toString(true));
myDataStruct.dwData = 11;
myDataStruct.cbData = myStruct.size();
myDataStruct.lpData = myStruct.getPointer();
myDataStruct.write(); // writes to native memory the structure.
result = user32.SendMessage(hwndTarget, // target hwnd.
User32Extension.WM_COPYDATA, // copy data message.
wparam, // current hwnd
myDataStruct // data
);
重要なのは、私がネット上で見つけたすべてのものに比べて、このコードで、そのCOPYDATASTRUCTです属性cbDataの型がlongです。 intに設定すると動作しません(レガシーCアプリケーションのWndProcでデータが正しく受信されません)。 DWORDを長いjava型にマップするのは正しいですか? NativeLongの方が良いでしょうか?
もう1つ注目すべきことは、すべてのインスタンス化された構造体(myStructおよびmyDataStruct)のStructure.write()を明示的に呼び出すことです。 SendMessage APIを呼び出す前に空のメモリを持たないことが必要です。 それは正常だと思いますか?またはSendMessageを呼び出す前にjnaが自動的に呼び出す必要がありますか?
ありがとうございます。
JNAは、 'DWORD'と他のウィンドウタイプの定義を提供します。ネイティブの 'long'型の使用は、JNAの' NativeLong'型で表現されるべきです。 'Structure.write()'は構造体引数を持つネイティブ関数呼び出しの前にJNAによって自動的に呼び出されます。 – technomage
@technomage、書き込みのために、別のテストを行った:正しい動作のために必要ではない。 'Structure.toString(true)'を呼び出すことでデバッグのために追加しました。 DWORDタイプの場合、私が使用すると、メッセージはプログラムと呼ばれるCに到着しません。 – cnico7
ここでは、情報のために、トレースのメモリダンプ(Hello文字列を使ったテスト用): DWORDのメモリダンプ [0a000000] [00000000] [0e000000] [00000000] [306eda58] [00000000:CBDATA:CBDATAのために長いと [0a000000] [0e000000] [00c2d058] [00000000] メモリダンプ] – cnico7