Support for showing if app is 32bit vs 64bit, and support for doing message hooks on both
Added support for message hook viewer to hook both 32 and 64 bit applications. Fixed filtering on the msg hook viewer Added custom filtering on msg hook viewer Added Process Id targetting on msg hook viewer Added SetMsgHook.exe command line app as an alternative way of starting msg hook viewer.
This commit is contained in:
@@ -20,12 +20,14 @@ import com.sun.jna.platform.win32.WinDef.*;
|
||||
import com.sun.jna.platform.win32.Advapi32Util;
|
||||
import com.sun.jna.platform.win32.BaseTSD.LONG_PTR;
|
||||
import com.sun.jna.platform.win32.BaseTSD.ULONG_PTR;
|
||||
import com.sun.jna.platform.win32.WinBase.SYSTEM_INFO;
|
||||
import com.sun.jna.platform.win32.WinDef;
|
||||
import com.sun.jna.platform.win32.WinNT.HANDLE;
|
||||
import com.sun.jna.platform.win32.WinReg;
|
||||
import com.sun.jna.platform.win32.WinUser;
|
||||
import com.sun.jna.platform.win32.WinNT.LARGE_INTEGER;
|
||||
import com.sun.jna.platform.win32.WinUser.WNDENUMPROC;
|
||||
import com.sun.jna.ptr.IntByReference;
|
||||
import com.sun.jna.ptr.PointerByReference;
|
||||
import com.sun.jna.win32.StdCallLibrary.StdCallCallback;
|
||||
import com.sun.jna.win32.W32APIOptions;
|
||||
@@ -323,6 +325,9 @@ public class Api {
|
||||
boolean GetDiskFreeSpaceEx(String lpDirectoryName, LARGE_INTEGER.ByReference lpFreeBytesAvailable, LARGE_INTEGER.ByReference lpTotalNumberOfBytes, LARGE_INTEGER.ByReference lpTotalNumberOfFreeBytes);
|
||||
int GetLastError();
|
||||
Pointer OpenProcess(int dwDesiredAccess, boolean bInheritHandle, Pointer pointer);
|
||||
boolean CloseHandle(HANDLE hObject);
|
||||
void GetNativeSystemInfo(SYSTEM_INFO lpSystemInfo);
|
||||
boolean IsWow64Process(HANDLE hProcess, IntByReference Wow64Process);
|
||||
}
|
||||
|
||||
|
||||
@@ -627,6 +632,36 @@ public class Api {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isProcess64bit(int pid)
|
||||
{
|
||||
try {
|
||||
SYSTEM_INFO lpSystemInfo = new SYSTEM_INFO();
|
||||
Kernel32.instance.GetNativeSystemInfo(lpSystemInfo);
|
||||
if (lpSystemInfo.processorArchitecture.dwOemID.intValue() == 0)
|
||||
{
|
||||
System.out.println("intel x86"); //not a 64 bit os
|
||||
return false;
|
||||
}
|
||||
|
||||
Pointer process = Kernel32.instance.OpenProcess(Api.PROCESS_QUERY_INFORMATION | Api.PROCESS_VM_READ, false, new Pointer(pid));
|
||||
IntByReference isWow64 = new IntByReference(0);
|
||||
if (!Kernel32.instance.IsWow64Process(new HANDLE(process), isWow64))
|
||||
{
|
||||
//handle error
|
||||
}
|
||||
//System.out.println("isProcess64bit " + pid + " = " + isWow64.getValue());
|
||||
Kernel32.instance.CloseHandle(new HANDLE(process));
|
||||
if (isWow64.getValue() == 1)
|
||||
return false;
|
||||
return true;
|
||||
//CloseHandle()
|
||||
} catch(Exception ex)
|
||||
{
|
||||
ex.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static HWND FindMainWindowFromPid(final long targetProcessId) {
|
||||
|
||||
final List<HWND> resultList = new ArrayList<HWND>();
|
||||
|
||||
@@ -117,6 +117,9 @@ public class CommandPopupMenu extends JPopupMenu {
|
||||
CommandMenuItem mntmSendCommandMsg = new CommandMenuItem("sendCommandMsg", 4);
|
||||
mnWinMessages.add(mntmSendCommandMsg);
|
||||
|
||||
CommandMenuItem mntmSendMessage = new CommandMenuItem("sendMessage", 5);
|
||||
mnWinMessages.add(mntmSendMessage);
|
||||
|
||||
CommandMenuItem mntmSetcursorposition = new CommandMenuItem("setCursorPosition", 3);
|
||||
mnWinMessages.add(mntmSetcursorposition);
|
||||
|
||||
@@ -232,6 +235,8 @@ public class CommandPopupMenu extends JPopupMenu {
|
||||
actionStr += "with | |";
|
||||
if (paramCount > 3)
|
||||
actionStr += " and | |";
|
||||
if (paramCount > 4)
|
||||
actionStr += " and | |";
|
||||
return actionStr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ public class CommandProcessor implements Runnable{
|
||||
public static boolean DEFAULT_QUIET = false; //by default is quiet enabled
|
||||
|
||||
protected CommandProcessor CommandProcessor = null;
|
||||
public int executeCount = 0;
|
||||
public int executeErrorCount;
|
||||
public String lastError = "";
|
||||
public String currentCommandText = "";
|
||||
@@ -94,6 +95,7 @@ public class CommandProcessor implements Runnable{
|
||||
events.statusChanged("Executing Test Script...");
|
||||
//CommandProcessor cmdProcessor = new CommandProcessor();
|
||||
scriptErrorCount = 0;
|
||||
executeCount = 0;
|
||||
lastError = "";
|
||||
long startTime = System.nanoTime();
|
||||
String[] lines = scriptStr.split("\n");
|
||||
@@ -101,7 +103,7 @@ public class CommandProcessor implements Runnable{
|
||||
|
||||
if (!line.trim().startsWith("|"))
|
||||
continue; //skip if it doesn't start with bar
|
||||
String[] parsed = line.split("\\|");
|
||||
String[] parsed = line.trim().split("\\|");
|
||||
//
|
||||
|
||||
//System.out.println("line: " + line);
|
||||
@@ -117,6 +119,8 @@ public class CommandProcessor implements Runnable{
|
||||
execute(parsed[2].trim(), new String[] {parsed[4].trim(), parsed[6].trim()});
|
||||
if (parsed.length == 9)
|
||||
execute(parsed[2].trim(), new String[] {parsed[4].trim(), parsed[6].trim(), parsed[8].trim()});
|
||||
if (parsed.length == 11)
|
||||
execute(parsed[2].trim(), new String[] {parsed[4].trim(), parsed[6].trim(), parsed[8].trim(), parsed[10].trim()});
|
||||
|
||||
if (executeErrorCount > 0) //check if any errors occurred
|
||||
++scriptErrorCount;
|
||||
@@ -128,7 +132,7 @@ public class CommandProcessor implements Runnable{
|
||||
String forcedStr = "Completed";
|
||||
if (STOP_PROCESSOR.get())
|
||||
forcedStr = "Stopped";
|
||||
events.statusChanged("Script Execution " + forcedStr + " with " + scriptErrorCount + " error(s) in " + new DecimalFormat("#.###").format(seconds) + " seconds");
|
||||
events.statusChanged("Script Execution " + forcedStr + " " + executeCount + " command(s) with " + scriptErrorCount + " error(s) in " + new DecimalFormat("#.###").format(seconds) + " seconds");
|
||||
events.executionCompleted();
|
||||
if (scriptErrorCount > 0 && !isQuiet)
|
||||
{
|
||||
@@ -142,6 +146,7 @@ public class CommandProcessor implements Runnable{
|
||||
}
|
||||
|
||||
public Object execute(String command, String[] args) {
|
||||
++executeCount;
|
||||
executeErrorCount = 0;
|
||||
currentCommandText = command;
|
||||
String joinedArgs = "";
|
||||
@@ -221,6 +226,8 @@ public class CommandProcessor implements Runnable{
|
||||
return win.cmdSelectContextMenuId(args);
|
||||
if (command.equals("sendCommandMsg"))
|
||||
return win.cmdSendCommandMsg(args);
|
||||
if (command.equals("sendMessage"))
|
||||
return win.cmdSendMessage(args);
|
||||
if (command.equals("windowMinimize"))
|
||||
return win.cmdWindowMinimize(args);
|
||||
if (command.equals("windowMaximize"))
|
||||
|
||||
@@ -19,14 +19,23 @@ import javax.swing.JOptionPane;
|
||||
|
||||
public class MsgHook {
|
||||
|
||||
|
||||
public static String targetdllName = "";
|
||||
public static String dll64bitName = "";
|
||||
public static String dll32bitName = "";
|
||||
static
|
||||
{
|
||||
String loadFailedMsg = "Failed to load MsgHook library.\n";
|
||||
//System.out.println("SynthuseDlg.config.disableUiaBridge: " + SynthuseDlg.config.disableUiaBridge);
|
||||
String archDataModel = System.getProperty("sun.arch.data.model");//32 or 64 bit
|
||||
try {
|
||||
loadNativeLibraryFromJar("/MsgHook" + archDataModel + ".dll");
|
||||
targetdllName = "/MsgHook" + archDataModel + ".dll";
|
||||
dll64bitName = SaveNativeLibraryFromJar("/MsgHook64.dll"); //need to save both 32 and 64 bit dlls for hooking both types
|
||||
dll32bitName = SaveNativeLibraryFromJar("/MsgHook32.dll");
|
||||
if (archDataModel.equals("32"))
|
||||
System.load(dll32bitName);
|
||||
else
|
||||
System.load(dll64bitName);
|
||||
|
||||
} catch (Exception ex) {
|
||||
StringWriter sw = new StringWriter();
|
||||
PrintWriter pw = new PrintWriter(sw);
|
||||
@@ -36,7 +45,7 @@ public class MsgHook {
|
||||
}
|
||||
}
|
||||
|
||||
public static void loadNativeLibraryFromJar(String path) {
|
||||
public static String SaveNativeLibraryFromJar(String path) {
|
||||
// Obtain filename from path
|
||||
String[] parts = path.split("/");
|
||||
String filename = (parts.length > 1) ? parts[parts.length - 1] : null;
|
||||
@@ -58,7 +67,7 @@ public class MsgHook {
|
||||
}
|
||||
if (!temp.exists()) { //some reason the temp file wasn't create so abort
|
||||
System.out.println("File " + temp.getAbsolutePath() + " does not exist.");
|
||||
return;
|
||||
return "";
|
||||
}
|
||||
|
||||
// Prepare buffer for data copying
|
||||
@@ -68,7 +77,7 @@ public class MsgHook {
|
||||
InputStream is = MsgHook.class.getResourceAsStream(path);
|
||||
if (is == null) { //check if valid
|
||||
System.out.println("File " + path + " was not found inside JAR.");
|
||||
return;
|
||||
return "";
|
||||
}
|
||||
// Open output stream and copy data between source file in JAR and the temporary file
|
||||
OutputStream os = null;
|
||||
@@ -83,23 +92,25 @@ public class MsgHook {
|
||||
e.printStackTrace();
|
||||
}
|
||||
// Finally, load the library
|
||||
System.load(temp.getAbsolutePath());
|
||||
return temp.getAbsolutePath();
|
||||
}
|
||||
|
||||
//public native boolean initialize(int hwnd);
|
||||
public native boolean initialize(String dll32bitName, String dll64bitName);
|
||||
public native boolean createMsgHookWindow();
|
||||
public native boolean setMsgHookWindowTargetHwnd(int hwnd);
|
||||
public native boolean setMsgHookWindowTargetClass(String classname);
|
||||
public native boolean setMsgHookWindowTargetPid(int pid);
|
||||
public native boolean setMessageHook(int hwnd, int threadId);
|
||||
public native boolean removeMessageHook();
|
||||
//public native boolean shutdown();
|
||||
|
||||
public static Thread createMsgHookWinThread(final long targetHwnd)
|
||||
public static Thread createMsgHookWinThread(final long targetHwnd, final int targetPid)
|
||||
{
|
||||
Thread t = new Thread() {
|
||||
public void run() {
|
||||
MsgHook mh = new MsgHook();
|
||||
mh.setMsgHookWindowTargetClass("");
|
||||
mh.initialize(dll32bitName, dll64bitName);
|
||||
if (targetPid != 0)
|
||||
mh.setMsgHookWindowTargetPid(targetPid);
|
||||
if (targetHwnd != 0)
|
||||
mh.setMsgHookWindowTargetHwnd((int)targetHwnd);
|
||||
mh.createMsgHookWindow();
|
||||
|
||||
@@ -29,6 +29,7 @@ import com.jgoodies.forms.layout.RowSpec;
|
||||
import com.jgoodies.forms.factories.FormFactory;
|
||||
*/
|
||||
import com.sun.jna.platform.win32.WinDef.HWND;
|
||||
import com.sun.jna.ptr.PointerByReference;
|
||||
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.event.ActionListener;
|
||||
@@ -50,7 +51,7 @@ public class SynthuseDlg extends JFrame {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static String VERSION_STR = "1.2.1";
|
||||
public static String VERSION_STR = "1.2.2";
|
||||
|
||||
public static String RES_STR_MAIN_ICON = "/org/synthuse/img/gnome-robots.png";
|
||||
public static String RES_STR_REFRESH_IMG = "/org/synthuse/img/rapidsvn.png";
|
||||
@@ -77,6 +78,7 @@ public class SynthuseDlg extends JFrame {
|
||||
public static Config config = new Config(Config.DEFAULT_PROP_FILENAME);
|
||||
private String dialogResult = "";
|
||||
private String lastDragHwnd = "";
|
||||
private int lastDragPid = 0;
|
||||
private String lastRuntimeId ="";
|
||||
private JComboBox<String> cmbXpath;
|
||||
private JButton btnTestIde;
|
||||
@@ -195,10 +197,10 @@ public class SynthuseDlg extends JFrame {
|
||||
*/
|
||||
long lastHwndLong = 0;
|
||||
try {
|
||||
lastHwndLong = Long.parseLong(lastDragHwnd);
|
||||
//lastHwndLong = Long.parseLong(lastDragHwnd);
|
||||
} catch (Exception ex) {
|
||||
}
|
||||
MsgHook.createMsgHookWinThread(lastHwndLong);
|
||||
MsgHook.createMsgHookWinThread(lastHwndLong, lastDragPid);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -510,6 +512,10 @@ public class SynthuseDlg extends JFrame {
|
||||
String handleStr = Api.GetHandleAsString(hwnd);
|
||||
String classStr = WindowsEnumeratedXml.escapeXmlAttributeValue(Api.getWindowClassName(hwnd));
|
||||
String parentStr = Api.GetHandleAsString(User32.instance.GetParent(hwnd));
|
||||
PointerByReference pointer = new PointerByReference();
|
||||
User32.instance.GetWindowThreadProcessId(hwnd, pointer);
|
||||
int pid = pointer.getPointer().getInt(0);
|
||||
|
||||
String enumProperties = "";
|
||||
if (!SynthuseDlg.config.isUiaBridgeDisabled())
|
||||
enumProperties = uiabridge.getWindowInfo(targetX, targetY, WindowInfo.UIA_PROPERTY_LIST_ADV);
|
||||
@@ -524,6 +530,7 @@ public class SynthuseDlg extends JFrame {
|
||||
}
|
||||
lastDragHwnd = handleStr;
|
||||
lastRuntimeId = runtimeId;
|
||||
lastDragPid = pid;
|
||||
//lastDragHwnd = (hwnd + "");
|
||||
if (framework.equals(UiaBridge.FRAMEWORK_ID_WPF) || framework.equals(UiaBridge.FRAMEWORK_ID_SILVER))
|
||||
{// WPF and Silverlight apps don't expose their child windows boundaries the same as win32 apps
|
||||
|
||||
@@ -12,7 +12,9 @@ import java.awt.BorderLayout;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
import javax.swing.filechooser.FileNameExtensionFilter;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JFileChooser;
|
||||
import javax.swing.JToolBar;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JScrollPane;
|
||||
@@ -26,6 +28,7 @@ import java.awt.event.ActionEvent;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.awt.Toolkit;
|
||||
import java.io.*;
|
||||
|
||||
import javax.swing.JLabel;
|
||||
|
||||
@@ -36,7 +39,8 @@ public class TestIdeFrame extends JFrame {
|
||||
public static String RES_STR_RUN_IMG = "/org/synthuse/img/arrow-right-3.png";
|
||||
public static String RES_STR_CLEAR_IMG = "/org/synthuse/img/user-trash-2.png";
|
||||
public static String RES_STR_COPY_IMG = "/org/synthuse/img/edit-copy-7.png";
|
||||
|
||||
public static String RES_STR_SAVE_IMG = "/org/synthuse/img/document-save-6.png";
|
||||
public static String RES_STR_OPEN_IMG = "/org/synthuse/img/document-open-folder.png";
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@@ -46,6 +50,8 @@ public class TestIdeFrame extends JFrame {
|
||||
private JButton btnRun;
|
||||
private JButton btnClear;
|
||||
private JButton btnCopy;
|
||||
private JButton btnSave;
|
||||
private JButton btnOpen;
|
||||
private JLabel lblStatus;
|
||||
|
||||
/**
|
||||
@@ -68,32 +74,30 @@ public class TestIdeFrame extends JFrame {
|
||||
btnRun = new JButton("Run");
|
||||
btnRun.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent arg0) {
|
||||
if (btnRun.getText().equals("Run")) {
|
||||
btnRun.setText("Stop");
|
||||
btnRun.setIcon(new ImageIcon(SynthuseDlg.class.getResource(RES_STR_STOP_IMG)));
|
||||
CommandProcessor.STOP_PROCESSOR.set(false);
|
||||
CommandProcessor.executeThreaded(txtTest.getText(), new CommandProcessor.Events() {
|
||||
@Override
|
||||
public void statusChanged(String status) {
|
||||
lblStatus.setText(status);
|
||||
}
|
||||
@Override
|
||||
public void executionCompleted() {
|
||||
btnRun.setText("Run");
|
||||
btnRun.setIcon(new ImageIcon(SynthuseDlg.class.getResource(RES_STR_RUN_IMG)));
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
CommandProcessor.STOP_PROCESSOR.set(true);
|
||||
//btnRun.setText("Run");
|
||||
//btnRun.setIcon(new ImageIcon(SynthuseDlg.class.getResource(RES_STR_RUN_IMG)));
|
||||
}
|
||||
runTestScript();
|
||||
}
|
||||
});
|
||||
btnRun.setIcon(new ImageIcon(SynthuseDlg.class.getResource(RES_STR_RUN_IMG)));
|
||||
toolBar.add(btnRun);
|
||||
|
||||
btnSave = new JButton("Save");
|
||||
btnSave.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent arg0) {
|
||||
saveTestScript();
|
||||
}
|
||||
});
|
||||
btnSave.setIcon(new ImageIcon(SynthuseDlg.class.getResource(RES_STR_SAVE_IMG)));
|
||||
toolBar.add(btnSave);
|
||||
|
||||
btnOpen = new JButton("Open");
|
||||
btnOpen.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent arg0) {
|
||||
openTestScript();
|
||||
}
|
||||
});
|
||||
btnOpen.setIcon(new ImageIcon(SynthuseDlg.class.getResource(RES_STR_OPEN_IMG)));
|
||||
toolBar.add(btnOpen);
|
||||
|
||||
btnClear = new JButton("Clear");
|
||||
btnClear.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent arg0) {
|
||||
@@ -135,5 +139,83 @@ public class TestIdeFrame extends JFrame {
|
||||
});
|
||||
super.setAlwaysOnTop(SynthuseDlg.config.isAlwaysOnTop());
|
||||
}
|
||||
|
||||
public void runTestScript()
|
||||
{
|
||||
if (btnRun.getText().equals("Run")) {
|
||||
btnRun.setText("Stop");
|
||||
btnRun.setIcon(new ImageIcon(SynthuseDlg.class.getResource(RES_STR_STOP_IMG)));
|
||||
CommandProcessor.STOP_PROCESSOR.set(false);
|
||||
CommandProcessor.executeThreaded(txtTest.getText(), new CommandProcessor.Events() {
|
||||
@Override
|
||||
public void statusChanged(String status) {
|
||||
lblStatus.setText(status);
|
||||
}
|
||||
@Override
|
||||
public void executionCompleted() {
|
||||
btnRun.setText("Run");
|
||||
btnRun.setIcon(new ImageIcon(SynthuseDlg.class.getResource(RES_STR_RUN_IMG)));
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
CommandProcessor.STOP_PROCESSOR.set(true);
|
||||
//btnRun.setText("Run");
|
||||
//btnRun.setIcon(new ImageIcon(SynthuseDlg.class.getResource(RES_STR_RUN_IMG)));
|
||||
}
|
||||
}
|
||||
|
||||
private void saveTestScript()
|
||||
{
|
||||
JFileChooser fChoose = new JFileChooser();
|
||||
fChoose.setFileFilter(new FileNameExtensionFilter("Text Files", "txt", "text"));
|
||||
int result = fChoose.showSaveDialog(this);
|
||||
if (result == JFileChooser.CANCEL_OPTION)
|
||||
return;
|
||||
File file = fChoose.getSelectedFile();
|
||||
if (fChoose.getFileFilter().getDescription().startsWith("Text") && !file.getAbsolutePath().toLowerCase().endsWith(".txt"))
|
||||
file = new File(file.getAbsolutePath() + ".txt"); //append extension if not already there
|
||||
|
||||
FileWriter fw = null;
|
||||
try {
|
||||
fw = new FileWriter(file);
|
||||
fw.write(txtTest.getText());
|
||||
fw.flush();
|
||||
fw.close();
|
||||
fw = null;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (fw != null)
|
||||
try { fw.close(); } catch (Exception e){ e.printStackTrace(); };
|
||||
lblStatus.setText("Script Saved: " + file.getAbsolutePath());
|
||||
}
|
||||
|
||||
private void openTestScript()
|
||||
{
|
||||
JFileChooser fChoose = new JFileChooser();
|
||||
fChoose.setFileFilter(new FileNameExtensionFilter("Text Files", "txt", "text"));
|
||||
int result = fChoose.showOpenDialog(this);
|
||||
if (result == JFileChooser.CANCEL_OPTION)
|
||||
return;
|
||||
File file = fChoose.getSelectedFile();
|
||||
BufferedReader br = null;
|
||||
try {
|
||||
br = new BufferedReader(new FileReader(file));
|
||||
String line = "";
|
||||
txtTest.setText("");
|
||||
while((line = br.readLine()) != null){
|
||||
txtTest.append(line + System.getProperty("line.separator"));
|
||||
//System.out.println(line);
|
||||
}
|
||||
br.close();
|
||||
br = null;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (br != null)
|
||||
try { br.close(); } catch (Exception e){ e.printStackTrace(); };
|
||||
lblStatus.setText("Script Loaded: " + file.getAbsolutePath());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import com.sun.jna.platform.win32.WinDef.LPARAM;
|
||||
import com.sun.jna.platform.win32.WinDef.LRESULT;
|
||||
import com.sun.jna.platform.win32.WinDef.RECT;
|
||||
import com.sun.jna.platform.win32.WinDef.WPARAM;
|
||||
import com.sun.jna.platform.win32.WinNT.HANDLE;
|
||||
import com.sun.jna.ptr.PointerByReference;
|
||||
|
||||
public class WindowInfo {
|
||||
@@ -50,6 +51,7 @@ public class WindowInfo {
|
||||
public int menus = 0;
|
||||
public HMENU menu = null;
|
||||
public boolean useUiaBridge = false;
|
||||
public boolean is64bit = false;
|
||||
|
||||
public Map<String, String> extra = null;
|
||||
|
||||
@@ -146,13 +148,10 @@ public class WindowInfo {
|
||||
useUiaBridge = true;
|
||||
}
|
||||
else {
|
||||
|
||||
PointerByReference pointer = new PointerByReference();
|
||||
User32.instance.GetWindowThreadProcessId(hWnd, pointer);
|
||||
pid = pointer.getPointer().getInt(0);
|
||||
Pointer process = Kernel32.instance.OpenProcess(Api.PROCESS_QUERY_INFORMATION | Api.PROCESS_VM_READ, false, pointer.getValue());
|
||||
Psapi.instance.GetModuleBaseNameW(process, null, buffer2, 512);
|
||||
processName = Native.toString(buffer2);
|
||||
getProcessInfo();
|
||||
//test to see if uiaBridge should be used on this parent
|
||||
if (this.className.startsWith("HwndWrapper") || this.className.startsWith("WindowsForms"))
|
||||
useUiaBridge = true;
|
||||
@@ -204,6 +203,8 @@ public class WindowInfo {
|
||||
this.hwndStr = "";
|
||||
//if (this.framework == null)
|
||||
// this.framework = "na";
|
||||
if(this.controlType.equals("window"))
|
||||
this.isChild = false;
|
||||
return;
|
||||
}
|
||||
// non-wildcard mode
|
||||
@@ -234,7 +235,9 @@ public class WindowInfo {
|
||||
value = value.substring(0, MAX_TEXT_SIZE);
|
||||
if (this.hwndStr == null)
|
||||
this.hwndStr = "";
|
||||
|
||||
getProcessInfo();
|
||||
if(this.controlType.equals("window"))
|
||||
this.isChild = false;
|
||||
/*
|
||||
this.rect = new RECT();
|
||||
try {
|
||||
@@ -250,6 +253,18 @@ public class WindowInfo {
|
||||
*/
|
||||
}
|
||||
|
||||
private void getProcessInfo()
|
||||
{
|
||||
if (pid == 0)
|
||||
return;
|
||||
char[] buffer = new char[1026];
|
||||
Pointer process = Kernel32.instance.OpenProcess(Api.PROCESS_QUERY_INFORMATION | Api.PROCESS_VM_READ, false, new Pointer(pid));
|
||||
Psapi.instance.GetModuleBaseNameW(process, null, buffer, 512);
|
||||
processName = Native.toString(buffer);
|
||||
Kernel32.instance.CloseHandle(new HANDLE(process));
|
||||
is64bit = Api.isProcess64bit((int)pid);
|
||||
}
|
||||
|
||||
|
||||
public static String getRuntimeIdFromProperties(String enumProperties)
|
||||
{
|
||||
|
||||
@@ -195,6 +195,7 @@ public class WindowsEnumeratedXml implements Runnable{
|
||||
if (!w.controlType.isEmpty())
|
||||
win.setAttribute("type", w.controlType);
|
||||
if (!w.isChild) {
|
||||
//win.setAttribute("parent", "yes");
|
||||
parentCount++;
|
||||
if (w.processName != null && !w.processName.isEmpty()) {
|
||||
if (!processList.containsKey(w.pid+""))
|
||||
@@ -203,11 +204,20 @@ public class WindowsEnumeratedXml implements Runnable{
|
||||
if (w.processName != null)
|
||||
win.setAttribute("PROCESS", w.processName.toUpperCase());
|
||||
}
|
||||
if (w.pid != 0)
|
||||
{
|
||||
if (w.is64bit)
|
||||
win.setAttribute("bits", "64");
|
||||
else
|
||||
win.setAttribute("bits", "32");
|
||||
}
|
||||
}
|
||||
if (w.pid != 0)
|
||||
win.setAttribute("pid", w.pid+"");
|
||||
//else
|
||||
//win.setAttribute("parent", w.parent + ""); // not really needed since child node is append to parent node
|
||||
|
||||
|
||||
if (w.extra != null) {
|
||||
for(String extraName: w.extra.keySet()) {
|
||||
win.setAttribute(extraName, w.extra.get(extraName)+"");
|
||||
|
||||
@@ -176,5 +176,23 @@ public class WindowsCommands extends BaseCommand {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean cmdSendMessage(String[] args) {
|
||||
if (!checkArgumentLength(args, 4))
|
||||
return false;
|
||||
WinPtr handle = findHandleWithXpath(args[0]); //xpath to HWND is first argument
|
||||
if (handle.isEmpty())
|
||||
return false;
|
||||
int msg = Integer.parseInt(args[1]);
|
||||
int id = Integer.parseInt(args[2]); //context menu id is supplied as second argument
|
||||
int idLparam = Integer.parseInt(args[3]); //context menu id is supplied as second argument
|
||||
handle.convertToNativeHwnd();
|
||||
//LRESULT result =
|
||||
//System.out.println("Send Message WM_COMMAND to " + handle.toString() + " PARAMS: " + id + ", " + idLparam);
|
||||
//api.user32.PostMessage(handle.hWnd, Api.WM_COMMAND, new WPARAM(id), new LPARAM(0));
|
||||
api.user32.SendMessage(handle.hWnd, msg, new WPARAM(id), new LPARAM(idLparam));
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BIN
src/org/synthuse/img/document-open-folder.png
Normal file
BIN
src/org/synthuse/img/document-open-folder.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 852 B |
BIN
src/org/synthuse/img/document-save-6.png
Normal file
BIN
src/org/synthuse/img/document-save-6.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.2 KiB |
BIN
src/org/synthuse/test/WpfMockTestAppx64.exe
Normal file
BIN
src/org/synthuse/test/WpfMockTestAppx64.exe
Normal file
Binary file not shown.
Reference in New Issue
Block a user