/* * Copyright 2014, Synthuse.org * Released under the Apache Version 2.0 License. * * last modified by ejakubowski7@gmail.com */ // This class is not actually used and is only here as a reference package org.synthuse; import javax.swing.JFrame; import javax.swing.JToolBar; import java.awt.BorderLayout; import javax.swing.JTextArea; import javax.swing.JScrollPane; import javax.swing.JButton; import javax.swing.WindowConstants; import com.sun.jna.Native; import com.sun.jna.Pointer; import com.sun.jna.Structure; import com.sun.jna.platform.win32.User32; import com.sun.jna.platform.win32.WinDef.*; import com.sun.jna.platform.win32.BaseTSD.LONG_PTR; import com.sun.jna.ptr.IntByReference; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import javax.swing.JLabel; import javax.swing.JTextField; import java.awt.Dimension; import java.awt.Component; import java.util.Arrays; import java.util.List; import javax.swing.Box; public class MessageHookFrame extends JFrame { private static final long serialVersionUID = -5863279004595502801L; public static final String newLine = System.getProperty("line.separator"); public static final int WH_CALLWNDPROC = 4; public static final int WH_GETMESSAGE = 3; public static final int WH_KEYBOARD_LL = 13; public static final int WM_COPYDATA = 74; public static final int GWLP_WNDPROC = -4; private JTextArea textArea; private JButton btnSave; private JButton btnStartMsgHook; private JButton btnPause; private JButton btnClear; private LONG_PTR oldWndProc; private MsgHook msgHook = null; public static volatile boolean quit = false; private JLabel lblTargetHwnd; public JTextField txtTarget; private Component horizontalStrut; public MessageHookFrame() { setTitle("Message Hook"); setBounds(100, 100, 700, 367); JToolBar toolBar = new JToolBar(); getContentPane().add(toolBar, BorderLayout.NORTH); btnStartMsgHook = new JButton("Start Hook"); btnStartMsgHook.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { if (btnStartMsgHook.getText().equals("Start Hook")) { //start Message Hook btnStartMsgHook.setText("Stop Hook"); createMessageHook(); } else { //stop message hook btnStartMsgHook.setText("Start Hook"); stopMessageHook(); } } }); lblTargetHwnd = new JLabel("Target HWND: "); toolBar.add(lblTargetHwnd); txtTarget = new JTextField(); txtTarget.setMaximumSize(new Dimension(70, 2147483647)); txtTarget.setText("0"); toolBar.add(txtTarget); txtTarget.setColumns(10); horizontalStrut = Box.createHorizontalStrut(20); toolBar.add(horizontalStrut); toolBar.add(btnStartMsgHook); btnPause = new JButton("Pause"); btnPause.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { final HWND myHwnd = new HWND(Native.getWindowPointer(MessageHookFrame.this)); oldWndProc = User32.INSTANCE.GetWindowLongPtr(myHwnd, GWLP_WNDPROC); Api.WNDPROC wndProc = new Api.WNDPROC() { public LRESULT callback(HWND hWnd, int uMsg, WPARAM wParam, LPARAM lParam) { if (uMsg == WM_COPYDATA){ System.out.println("WM_COPYDATA"); //handle the window message here } else System.out.println("MESSAGE: " + uMsg); return Api.User32Ex.instance.CallWindowProc(oldWndProc, hWnd, uMsg, wParam, lParam); //return new LRESULT(0); //return User32.INSTANCE.DefWindowProc(hWnd, uMsg, wParam, lParam); } }; Api.User32Ex.instance.SetWindowLongPtr(myHwnd, GWLP_WNDPROC, wndProc); } }); toolBar.add(btnPause); btnSave = new JButton("Save"); btnSave.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { } }); toolBar.add(btnSave); btnClear = new JButton("Clear"); btnClear.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) { textArea.setText(""); } }); toolBar.add(btnClear); JScrollPane scrollPane = new JScrollPane(); getContentPane().add(scrollPane, BorderLayout.CENTER); textArea = new JTextArea(); scrollPane.setViewportView(textArea); this.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); this.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { //TestIdeFrame.this.setVisible(false); MessageHookFrame.this.dispose(); } }); super.setAlwaysOnTop(SynthuseDlg.config.isAlwaysOnTop()); } /* typedef struct { HWND hWnd; int nCode; DWORD dwHookType; WPARAM wParam; LPARAM lParam; TCHAR wParamStr[25]; TCHAR lParamStr[25]; }HEVENT; */ public static class HEVENT extends Structure { //The by-reference version of this structure. public static class ByReference extends HEVENT implements Structure.ByReference { } public HEVENT() { } //Instantiates a new COPYDATASTRUCT with existing data given the address of that data. public HEVENT(final long pointer) { this(new Pointer(pointer)); } //Instantiates a new COPYDATASTRUCT with existing data given a pointer to that data. public HEVENT(final Pointer memory) { super(memory); read(); } public WORD hWnd; public WORD nCode; public DWORD dwHookType; public DWORD wParam; public DWORD lParam; //public TCHAR wParamStr[25]; //public TCHAR lParamStr[25]; @SuppressWarnings("rawtypes") @Override protected final List getFieldOrder() { return Arrays.asList(new String[] {"hWnd", "nCode", "dwHookType", "wParam", "lParam" }); } } public void createMessageHook() { quit = false; //don't quit //find the HWND and current WNDPROC on this java window final HWND myHwnd = new HWND(Native.getWindowPointer(MessageHookFrame.this)); oldWndProc = User32.INSTANCE.GetWindowLongPtr(myHwnd, GWLP_WNDPROC); Api.WNDPROC wndProc = new Api.WNDPROC() { public LRESULT callback(HWND hWnd, int uMsg, WPARAM wParam, LPARAM lParam) { if (uMsg == WM_COPYDATA){ //(COPYDATASTRUCT *) lParam //if( pCopyDataStruct->cbData == sizeof(HEVENT)) { // HEVENT Event; // memcpy(&Event, (HEVENT*)pCopyDataStruct->lpData, sizeof(HEVENT)); // transfer data to internal variable //} Api.WinDefEx.COPYDATASTRUCT cds = new Api.WinDefEx.COPYDATASTRUCT(lParam.longValue()); HEVENT he = new HEVENT(cds.lpData); appendLine("msg: WM_COPYDATA" + cds.cbData); appendLine("hwnd: " + he.hWnd + ", msg: " + he.nCode + ", wParam: " + he.wParam + ", lParam: " + he.lParam); //System.out.println("WM_COPYDATA"); //handle the window message here } //else // System.out.println("MESSAGE: " + uMsg); return Api.User32Ex.instance.CallWindowProc(oldWndProc, hWnd, uMsg, wParam, lParam); //return User32.INSTANCE.DefWindowProc(hWnd, uMsg, wParam, lParam); } }; //Set the wndproc callback on this MessageHookFrame so we can process Windows Messages Api.User32Ex.instance.SetWindowLongPtr(myHwnd, GWLP_WNDPROC, wndProc); IntByReference intByRef = new IntByReference(0); final int threadId = User32.INSTANCE.GetWindowThreadProcessId(Api.GetHandleFromString(txtTarget.getText()), intByRef); //int myPid = Kernel32.INSTANCE.GetCurrentProcessId(); //HWND myHwnd = Api.FindMainWindowFromPid(myPid); final long myHwndLong = Api.GetHandleAsLong(myHwnd); //System.out.println("Starting Msg Hook for " + myHwndLong + " on id " + threadId); if (threadId == 0 ) // don't allow global { System.out.println("Not allowing global message hook " + threadId); User32.INSTANCE.SetWindowLongPtr(myHwnd, GWLP_WNDPROC, oldWndProc); //restore default WNDPROC quit = true; return; } msgHook = new MsgHook(); if (!msgHook.setMessageHook((int) myHwndLong, threadId)) appendLine("Error setting message hook"); else appendLine("Message hook started"); } public void unhook(MsgHook msgHook) { msgHook.removeMessageHook(); } //stops Keyboard hook and causes the unhook command to be called public void stopMessageHook() { //if (!quit) //if not hooked skip // return; quit = true; appendLine("Message hook stopped"); final HWND myHwnd = new HWND(Native.getWindowPointer(MessageHookFrame.this)); User32.INSTANCE.SetWindowLongPtr(myHwnd, GWLP_WNDPROC, oldWndProc); //restore default WNDPROC unhook(msgHook); } public void appendLine(String txt) { textArea.append(txt + newLine); textArea.setCaretPosition(textArea.getDocument().getLength()); } }