2015-02-11 24 views
2

我需要設置一個WindowLong覆蓋的WndProc,我使用的是從coredll.dll中此方法:使用SetWindowLong函數重載的WndProc

public interface CoreDll extends StdCallLibrary { 
 
\t //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,根據Microsoft「指定的32位整數的前一個值表示成功。零表示失敗」無論如何,我試圖執行這樣說:

public interface CallbackProc extends Callback, StdCall { 
 
\t 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() { 
 
\t @Override 
 
    \t 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

如果有人可以給我一個提示,我將非常感激,感謝

回答

1

你。正在檢索模塊句柄(GetModuleHandle),這個句柄引用一個可執行文件(exe或dll)加載到進程空間而不是窗口。SetWindowsLong失敗,因爲你傳遞給它的對象不是一個窗口。 IIRC你有一個方法在窗體/控件上獲取本機HWND,這是正確的對象,你應該傳遞給SetWindowLong。 看看代碼,我想你有一個通過Windows消息發送代碼的RFID庫。你可以考慮用一些本地代碼包裝這個對象,然後生成「常規」的.NET事件。這會稍微複雜一些,但是可以避免SetWindowLong可能產生的一些令人頭痛的問題(例如:當窗口仍然有效時,帶有wndproc的對象被銷燬)。

+0

準確地說,我正在寫這個來閱讀通過窗口消息發送的代碼,但我很難與此,我已經跟着這個代碼,最後我得到了正確的SetWindowLong [鏈接](https:// github .com/pke/clipboard.monitor/blob/master/clipboard.monitor.windows/src/clipboard/monitor/windows/AbstractWindowsClipboardMonitor.java),但無論如何我無法讀取dll發送的消息。我能夠在PeekMessage循環中只讀取1條消息,然後嘗試調用TranslateMessage(msg); DispatchMessage函數(MSG);但它不是調用WndProc我已經定義 – pppnk 2015-02-12 19:46:44

+0

如果你可以在這裏看看我會非常感激它,我已經發布了一個新的問題,我的新代碼[鏈接](http://stackoverflow.com/questions/28487457/java-jna-read-codes-sent-via-window-messages) – pppnk 2015-02-12 20:49:41

1

您需要獲取正確的HWND值才能傳遞給GetWindowLong()。如果它是Java窗口,則可以使用Native.getWindowHandle()。否則,你必須找出一些方法來獲得你所定位窗口的HWND

一旦你有了,你需要傳入你的回調對象作爲dwNewLong參數。您應該爲SetWindowLong()定義一個新映射,其中第三個參數的類型與您的回調類型相同。您應該避免使用Java long。這是一個64位值,只有當您確定相應的本地變量也是64位時,才應該使用。當本機類型爲[unsigned] long(或用於w32的LONG)時,對於32位使用int,對於32位使用NativeLong

+0

謝謝這是有幫助的 – pppnk 2015-02-12 19:48:22