|
31 | 31 | import org.junit.Test;
|
32 | 32 | import org.junit.runner.JUnitCore;
|
33 | 33 |
|
| 34 | +import com.sun.jna.CallbackReference; |
34 | 35 | import com.sun.jna.Native;
|
35 | 36 | import com.sun.jna.Pointer;
|
36 | 37 | import com.sun.jna.Structure;
|
@@ -106,6 +107,24 @@ public void testWindowMesssages() {
|
106 | 107 | log("User Message sent to hooked proc " + hwndPing + ", result = " + result);
|
107 | 108 | assertEquals(0, result.intValue());
|
108 | 109 |
|
| 110 | + // DEMO 4 : subclass the window to return a different value when receiving MSG_SIMPLE_CODE |
| 111 | + // First make sure we remove the hook |
| 112 | + User32.INSTANCE.UnhookWindowsHookEx(hook); |
| 113 | + hook = null; |
| 114 | + |
| 115 | + subclassProc(hwndPing); |
| 116 | + result = User32.INSTANCE.SendMessage(hwndPing, WinUser.WM_USER, new WPARAM(MSG_SIMPLE_CODE), |
| 117 | + new LPARAM(MSG_SIMPLE_VAL)); |
| 118 | + log("User Message sent to subclassed " + hwndPing + ", result = " + result); |
| 119 | + assertEquals(0xC0FE, result.intValue()); |
| 120 | + |
| 121 | + // Then we check if this still works with a hooked proc as well |
| 122 | + hook = hookwinProc(hwndPing); |
| 123 | + result = User32.INSTANCE.SendMessage(hwndPing, WinUser.WM_USER, new WPARAM(MSG_HOOKED_CODE), |
| 124 | + new LPARAM(MSG_HOOKED_VAL)); |
| 125 | + log("User Message sent to hooked and subclassed proc " + hwndPing + ", result = " + result); |
| 126 | + assertEquals(0, result.intValue()); |
| 127 | + |
109 | 128 | // Waits e few moment before shutdown message.
|
110 | 129 | sleepCurrThread(3000);
|
111 | 130 |
|
@@ -395,6 +414,38 @@ public LRESULT callback(int nCode, WPARAM wParam, LPARAM lParam) {
|
395 | 414 | return User32.INSTANCE.SetWindowsHookEx(WinUser.WH_CALLWNDPROC, hookProc, hInst, threadtoHook);
|
396 | 415 | }
|
397 | 416 |
|
| 417 | + private void subclassProc(HWND hwndToSubclass) { |
| 418 | + class SubClassedWindowProc implements WindowProc { |
| 419 | + private Pointer oldWindowProc; |
| 420 | + |
| 421 | + @Override |
| 422 | + public LRESULT callback(HWND hwnd, int uMsg, WPARAM wParam, LPARAM lParam) { |
| 423 | + if (uMsg == WinUser.WM_USER) { |
| 424 | + log(hwnd + " - subclass received a WM_USER message with code : '" + wParam + "' and value : '" + lParam |
| 425 | + + "'"); |
| 426 | + |
| 427 | + if (wParam.intValue() == MSG_SIMPLE_CODE) { |
| 428 | + // We also want to be sure the value is still the same passed |
| 429 | + assertEqualsForCallbackExecution(MSG_SIMPLE_VAL, lParam.intValue()); |
| 430 | + |
| 431 | + return new LRESULT(0xC0FE); |
| 432 | + } |
| 433 | + } |
| 434 | + if (this.oldWindowProc != null) { |
| 435 | + return User32.INSTANCE.CallWindowProc(this.oldWindowProc, hwnd, uMsg, wParam, lParam); |
| 436 | + } else { |
| 437 | + // In case the old pointer has not yet been set due to for example a race condition, |
| 438 | + // send the message to the default handler instead |
| 439 | + return User32.INSTANCE.DefWindowProc(hwnd, uMsg, wParam, lParam); |
| 440 | + } |
| 441 | + } |
| 442 | + } |
| 443 | + |
| 444 | + SubClassedWindowProc subclass = new SubClassedWindowProc(); |
| 445 | + subclass.oldWindowProc = User32.INSTANCE.SetWindowLongPtr(hwndToSubclass, WinUser.GWL_WNDPROC, |
| 446 | + CallbackReference.getFunctionPointer(subclass)); |
| 447 | + } |
| 448 | + |
398 | 449 | /**
|
399 | 450 | * Gets the last error.
|
400 | 451 | *
|
|
0 commit comments