首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用SetWindowLong覆盖WndProc

使用SetWindowLong覆盖WndProc
EN

Stack Overflow用户
提问于 2015-02-11 15:37:12
回答 2查看 799关注 0票数 2

我需要设置一个WindowLong来覆盖WndProc,我正在使用来自coredll.dll的以下方法:

代码语言:javascript
复制
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中的原始方法签名是:

代码语言:javascript
复制
LONG SetWindowLong( 
  HWND hWnd, 
  int nIndex, 
  LONG dwNewLong
); 

但是当我使用它时,它总是返回0,根据微软的说法,“指定的32位整数的前一个值表示成功,零表示失败”。不管怎么说,我正试着这么做:

代码语言:javascript
复制
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

如果有人能给我个提示,我会很感激的,谢谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-02-12 07:37:55

您正在检索模块句柄(GetModuleHandle),此句柄引用加载到进程空间中的可执行文件(exe或dll),而不是窗口。SetWindowsLong失败,因为您传递给它的对象不是窗口。IIRC在窗体/控件上有一个获取本机HWND的方法,这是应该传递给SetWindowLong的正确对象。看一下代码,我想您有一个RFID库,它通过windows消息发送代码。您可以考虑将其与一些本机代码包装到一个对象中,然后生成“常规”.NET事件。这会稍微复杂一些,但避免了SetWindowLong可能产生的一些麻烦(例如:如果窗口仍然有效时,wndproc的对象被销毁了)。

票数 1
EN

Stack Overflow用户

发布于 2015-02-12 10:14:56

您需要获得传递给GetWindowLong()的正确的GetWindowLong()值。如果它是Java窗口,则可以在其上使用Native.getWindowHandle()。否则,您将不得不想出一些方法来获取您要针对的窗口的HWND

一旦实现了这个功能,就需要将回调对象作为dwNewLong参数传递。您应该为SetWindowLong()定义一个新的映射,其中第三个参数具有与回调相同的类型。

您还应该避免使用Java long。这是一个64位的值,只有当您确定相应的本机变量也是64位时才应该使用。32位使用int,本机类型为[unsigned] long (或LONG表示w32)时使用NativeLong .

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28458297

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档