

![]() | Start a set with this search |
![]() | Include this search in one of my sets |
![]() | Exclude this search from one of my sets |
![]() | Permalink to these results Paste this link in email or IM: |
| Atom feed for tracking future search results Paste this URL into your reader: |
5 messages in net.java.dev.jna.usersRe: [jna-users] Intercepting Win32 Me...| From | Sent On | Attachments |
|---|---|---|
| sam west | Dec 2, 2008 9:42 pm | |
| Daniel Kaufmann | Dec 3, 2008 3:39 am | |
| Timothy Wall | Dec 3, 2008 3:43 am | |
| sam west | Dec 4, 2008 3:00 pm | |
| Timothy Wall | Dec 4, 2008 4:33 pm |

![]() | Permalink for this message Paste this link in email or IM: |
![]() | Permalink for this thread Paste this link in email or IM: |
| Atom feed for this thread Paste this URL into your reader: |
| Subject: | Re: [jna-users] Intercepting Win32 Messages | Actions... |
|---|---|---|
| From: | Daniel Kaufmann (dani...@gmail.com) | |
| Date: | Dec 3, 2008 3:39:27 am | |
| List: | net.java.dev.jna.users | |
Regarding the subclassing code, make sure you keeping a reference to the WndProcCallbackListener object (not sure if you are already doing so, since you didn't submitted the whole code, but from your description of the problem it looks like this might be the problem). You can overrite the finalize method and print/log when it is called to check if this is happening. From jna home page: "If your callback needs to live beyond the method invocation where it is used, make sure you keep a reference to it or the native code will call back to an empty stub after the callback object is garbage collected." Regards, Daniel On Wed, Dec 3, 2008 at 2:43 AM, sam west <samw...@gmail.com> wrote:
G'Day,
I'm trying to intercept WM_POWERBROADCAST and WTS_SESSION_CHANGE mesages from a Java app. I'd prefer to do this using a hook, but I'd settle for subclassing WndProc() and processing messages if necessary.
I've had some success with the latter, using the code snippet below (my WTSAPI dll JNA interface omitted for brevity). And this approach seems to work fine until you lock/unlock or sleep/restart a few times, after which the window hangs. Spy++ shows a whole bunch of WM_PAINT messages getting sent to my JFrame that apparently don't get processed. Any idea what I'm doing wrong?
this.hwnd = new HWND(); hwnd.setPointer(Native.getWindowPointer(window));
/* * Now we're going to change the window's message processing function to our own function, * but make our function call the previous one whenever it receives messages. This is so that * the normal window functions get performed, as well as ours. */ final LONG_PTR prevWndProc = new LONG_PTR(User32.INSTANCE.GetWindowLong(hwnd, User32.GWL_WNDPROC)); wndProcCallbackListener = new WndProcCallbackListener() { public LRESULT callback(HWND hWnd, int uMsg, WPARAM uParam, LPARAM lParam) { if (uMsg == WTSAPI.WM_POWERBROADCAST) { System.out.println("WM_POWERBROADCAST Event: hWnd="+hwnd+", uMsg="+uMsg+", uParam="+uParam+", lParam="+lParam); } else if (uMsg == WTSAPI.WTS_SESSION_CHANGE) { System.out.println("WTS_SESSION_CHANGE Event: hWnd="+hwnd+", uMsg="+uMsg+", uParam="+uParam+", lParam="+lParam); }
//Call the window's actual WndProc so the events get processed. return User32.INSTANCE.CallWindowProc(prevWndProc, hWnd, uMsg, uParam, lParam); } };
//Set the WndProc function to use our callback listener instead of the window's one. int result = User32.INSTANCE.SetWindowLong(hwnd, User32.GWL_WNDPROC, wndProcCallbackListener);
boolean success = WTSAPI.INSTANCE.WTSRegisterSessionNotification(hwnd, WTSAPI.NOTIFY_FOR_THIS_SESSION);
My second attempt was using a thread-local WH_CALLWNDPROCRET hook, based on the global hooking code in KeyHook in the CVS contrib directory. This would seem like the better way to do things, but I can't actually manage to receive any messages using the code below. I've tried the same thing in C# and it appears to work there, but this code just gives me a hook that never receives anything, despite it apparently setting the hook successfully. I *have* gotten this code to receive messages when I change it to a system-wide global hook, but it tends to either crash the app, or, amusingly, causes a blue screen of death (presumably because hooking EVERY message in the system is a Really Bad Idea. Any thoughts why my local hook isn't working here?
final User32 lib = User32.INSTANCE; HMODULE hMod = Kernel32.INSTANCE.GetModuleHandle(null); msgHook = new User32.CallWndRetProc() { public LRESULT callback(int nCode, WPARAM wParam, CWPRETSTRUCT info) {
if (nCode >= 0) { System.out.println("Got Message callback!"); } return lib.CallNextHookEx(hhk, nCode, wParam, info.getPointer()); } };
JFrame f = new JFrame(); f.pack(); f.setSize(100,100); f.setVisible(true);
swingThreadID = getSwingThreadID(); HINSTANCE threadLocalhMod = null; mhk = lib.SetWindowsHookEx(User32.WH_CALLWNDPROCRET, msgHook, threadLocalhMod, swingThreadID);
A few questions on hooking:
1. I suspect I'm using the wrong ThreadID (i've tried obtaining an ID from the Main thread and from the Swing worker thread, but neither work). Which Java thread receives the actual win32 Messages and how do I get its Thread ID?
2. The KeyHook example code starts a dummy messaging loop at the end to ensure it receives low level keyboard messages. If I start a JFrame in the same process, is this still necessary?
3. On SetWindowsHookEX and thread-local hooks, MSDN says "*hMod [in]: Handle to the DLL containing the hook procedure pointed to by the lpfn parameter. The hMod parameter must be set to NULL if the dwThreadId parameter specifies a thread created by the current process and if the hook procedure is within the code associated with the current process. *". Is setting the third parameter in my call to a java null sufficient to achieve this?
Thanks in advance, Sam.
Oh yeah, and JNA rocks.







