我需要设置一个WindowLong来覆盖WndProc,我在coredll.dll中使用这个方法:
public interface CoreDll extends StdCallLibrary {
//loads the coredll with unicode options
CoreDll INSTANCE = (CoreDll)Native.loadLibrary("coredll", CoreDll.class,
W32APIOptions.UNICODE_OPTIONS);
//native calls
HMODULE GetModuleHandle(String lpModuleName);
long GetWindowLong(HWND hwnd, int gwlWndproc);
long SetWindowLong(HWND hWnd,int nIndex,Callback dwNewLong);
LRESULT DefWindowProc(HWND hWnd, int uMsg, WPARAM uParam,LPARAM lParam);
}
coredll中的原始方法签名是:
LONG SetWindowLong(
HWND hWnd,
int nIndex,
LONG dwNewLong
);
但是当我使用它时它总是返回0,根据微软“指定的32位整数的前一个值表示成功。零表示失败”。无论如何,我试图以这种方式执行它:
public interface CallbackProc extends Callback, StdCall {
LRESULT callback(HWND hWnd, int uMsg, WPARAM uParam, LPARAM lParam);
}
//Get a handle to the current process
final HWND mainHwnd = CoreDll.INSTANCE.GetModuleHandle(null);
//Get a reference to the current process to send it in the new WndProc
long value=CoreDll.INSTANCE.GetWindowLong(new HWND(mainHwnd.getPointer()), -4);
final LONG_PTR prevWndProc = new LONG_PTR(value);
//Sets the new Method to override WndProc
final RfidCallbackProc ptr=new RfidCallbackProc() {
@Override
public LRESULT callback(HWND hWnd, int uMsg, WPARAM wParam,LPARAM lParam) {
//returns the call to the process
return CoreDll.INSTANCE.CallWindowProc(prevWndProc, hWnd, uMsg, wParam, lParam);
}
};
//Sets the new method to override Windows' WndProc
int num=(int)CoreDll.INSTANCE.SetWindowLong(new HWND(mainHwnd.getPointer()),-4 ,ptr);
//NUM IS ALWAYS 0
如果有人能给我一个提示,我会非常感激,谢谢。
答案 0 :(得分:1)
您正在检索模块句柄(GetModuleHandle),此句柄引用加载到进程空间而不是窗口的可执行文件(exe或dll)。 SetWindowsLong失败,因为传递给它的对象不是窗口。 IIRC你有一个表单/控件的方法来获取本机HWND,这是你应该传递给SetWindowLong的正确类型的对象。 看一下代码,我想你有一个通过windows消息发送代码的RFID库。您可以考虑将此包含一些本机代码包装到一个对象中,然后生成“常规”.NET事件。这会有点复杂,但避免了SetWindowLong可能产生的一些麻烦(例如:如果窗口仍然有效时,wndproc的对象被破坏)。
答案 1 :(得分:1)
您需要获取正确的HWND
值才能传递给GetWindowLong()
。如果它是Java窗口,您可以在其上使用Native.getWindowHandle()
。否则,您必须找到某种方法来获取您所定位的窗口的HWND
。
完成后,您需要将回调对象作为dwNewLong
参数传递。您应该为SetWindowLong()
定义新映射,其中第三个参数与您的回调类型相同。
您还应该避免使用Java long
。这是一个64位值,当您确定相应的本机变量也是64位时,应该只使用 。使用int
表示32位,NativeLong
表示原生类型为[unsigned] long
(或LONG
表示w32)。