Updated Synthuse to list WPF and Silverlight Windows

The WpfBridge native library can now enumerate all WPF and Silverlight
Windows and list them in Synthuse.  Still need to add a method to
connect the Drag Target to locate the WPF window.
This commit is contained in:
Edward Jakubowski
2014-04-05 17:24:08 -04:00
parent d92f85e1b8
commit 1809e2ad55
14 changed files with 297 additions and 79 deletions

View File

@@ -11,6 +11,7 @@ public class Config extends PropertiesSerializer {
public static String DEFAULT_PROP_FILENAME = "synthuse.properties";
public String disableWpf = "false";
public String urlList = "";
public String xpathList = "";
public String xpathHightlight = ".*process=\"([^\"]*)\".*";

View File

@@ -162,9 +162,9 @@ public class SynthuseDlg extends JFrame {
btnRefresh.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
//lblStatus.setText("Loading Windows Enumerated Xml...");
//WindowsEnumeratedXml wex = new WindowsEnumeratedXml(textPane, lblStatus);
//wex.run();
WindowsEnumeratedXml.getXmlThreaded(textPane, lblStatus);
//appendToPane(WindowsEnumeratedXml.getXml());
//lblStatus.setText("Windows Enumerated Xml loaded");
}
});
btnRefresh.setIcon(new ImageIcon(SynthuseDlg.class.getResource(RES_STR_REFRESH_IMG)));

View File

@@ -17,6 +17,8 @@ import com.sun.jna.ptr.PointerByReference;
public class WindowInfo {
public static String WPF_PROPERTY_LIST = "RuntimeIdProperty,ParentRuntimeIdProperty,ProcessIdProperty,FrameworkIdProperty,ClassNameProperty,NameProperty";
public HWND hwnd;
public String hwndStr = "";
public HWND parent = null;
@@ -28,8 +30,12 @@ public class WindowInfo {
public String processName = "";
public long pid = 0;
public Object xmlObj = null;
public String framework = "win32";//default as win32
public String runtimeId = "";
//Default Win32 support
public WindowInfo(HWND hWnd, boolean isChild) {
this.framework = "win32";
byte[] buffer = new byte[1024];
User32.instance.GetWindowTextA(hWnd, buffer, buffer.length);
text = Native.toString(buffer);
@@ -61,7 +67,39 @@ public class WindowInfo {
}
this.hwnd = hWnd;
hwndStr = Api.GetHandleAsString(hWnd);
}
//support for WPF and Silverlight
public WindowInfo(String enumProperties, boolean isChild) {
//WPF_PROPERTY_LIST = "RuntimeIdProperty,ParentRuntimeIdProperty,ProcessIdProperty,FrameworkIdProperty,ClassNameProperty,NameProperty";
String[] spltProperties = enumProperties.split(",");
if (spltProperties.length > 0)
this.runtimeId = spltProperties[0];
this.hwndStr = this.runtimeId;
if (spltProperties.length > 1 && isChild)
this.parentStr = spltProperties[1];
this.isChild = isChild;
if (spltProperties.length > 2)
this.pid = Long.parseLong(spltProperties[2]);
if (spltProperties.length > 3)
this.framework = spltProperties[3];
if (spltProperties.length > 4)
this.className = spltProperties[4];
if (spltProperties.length > 5)
this.text = spltProperties[5];
/*
this.rect = new RECT();
try {
String rectStr = wb.getProperty("BoundingRectangleProperty", runtimeId);
String[] rectSplt = rectStr.split(",");
this.rect.right = Integer.parseInt(rectSplt[0]);
this.rect.bottom = Integer.parseInt(rectSplt[1]);
this.rect.left = Integer.parseInt(rectSplt[2]);
this.rect.top = Integer.parseInt(rectSplt[3]);
} catch (Exception e) {
e.printStackTrace();
}
*/
}
public String toString() {

View File

@@ -12,6 +12,7 @@ import java.io.StringWriter;
import java.sql.Timestamp;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
@@ -91,6 +92,10 @@ public class WindowsEnumeratedXml implements Runnable{
}
}
Api.User32.instance.EnumWindows(new ParentWindowCallback(), 0);
//Enumerate WPF windows and add to list
if (!SynthuseDlg.config.disableWpf.equals("true"))
infoList.putAll(EnumerateWindowsWithWpfBridge("WPF"));
// convert window info list to xml dom
try {
@@ -108,22 +113,30 @@ public class WindowsEnumeratedXml implements Runnable{
WindowInfo w = infoList.get(handle);
//System.out.println(w);
// create new win xml element
Element win = doc.createElement("win");
Element win = null;
if (w.framework.equals("win32"))
win = doc.createElement("win");
else
win = doc.createElement("wpf");
win.setAttribute("hwnd", w.hwndStr);
win.setAttribute("text", w.text);
win.setAttribute("TEXT", w.text.toUpperCase());
if (w.text != null)
win.setAttribute("TEXT", w.text.toUpperCase());
win.setAttribute("class", w.className);
win.setAttribute("CLASS", w.className.toUpperCase());
if (w.className != null)
win.setAttribute("CLASS", w.className.toUpperCase());
if (!w.isChild) {
parentCount++;
if (w.processName != null && !w.processName.isEmpty()) {
if (!processList.containsKey(w.pid+""))
processList.put(w.pid+"", w.hwndStr);
win.setAttribute("process", w.processName);
win.setAttribute("PROCESS", w.processName.toUpperCase());
win.setAttribute("pid", w.pid+"");
if (w.processName != null)
win.setAttribute("PROCESS", w.processName.toUpperCase());
}
}
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
@@ -159,6 +172,28 @@ public class WindowsEnumeratedXml implements Runnable{
return "";
}
public static Map<String, WindowInfo> EnumerateWindowsWithWpfBridge(String frameworkType) {
final Map<String, WindowInfo> infoList = new LinkedHashMap<String, WindowInfo>();
WpfBridge wb = new WpfBridge();
wb.setFrameworkId(frameworkType);
List<String> parentIds = new ArrayList<String>(Arrays.asList(wb.enumChildrenWindowIds("")));
//System.out.println("enumChildrenWindowIds");
String[] allIds = wb.enumDescendantWindowInfo("", WindowInfo.WPF_PROPERTY_LIST);
//System.out.println("enumDescendantWindowIds " + allIds.length);
for(String runtimeIdAndInfo : allIds) {
//System.out.println("getting window info for: " + runtimeIdAndInfo);
String onlyRuntimeId = runtimeIdAndInfo;
if (runtimeIdAndInfo.contains(","))
onlyRuntimeId = runtimeIdAndInfo.substring(0, runtimeIdAndInfo.indexOf(","));
//System.out.println("is parent? " + onlyRuntimeId);
if (parentIds.contains(onlyRuntimeId)) //is Parent?
infoList.put(onlyRuntimeId, new WindowInfo(runtimeIdAndInfo, false));
else// must be child
infoList.put(onlyRuntimeId, new WindowInfo(runtimeIdAndInfo, true));
}
return infoList;
}
public static String escapeXmlAttributeValue(String unescapedStr) {
String result = "";
try {

View File

@@ -69,22 +69,24 @@ public class WpfBridge {
System.load(temp.getAbsolutePath());
}
native void SetFrameworkId(String propertyValue); //default is WPF, but also accepts Silverlight, Win32
native void setFrameworkId(String propertyValue); //default is WPF, but also accepts Silverlight, Win32
//Descendants will walk the full tree of windows, NOT just one level of children
native int CountDescendantWindows();
native int CountDescendantWindows(String runtimeIdValue);
native int countDescendantWindows();
native int countDescendantWindows(String runtimeIdValue);
native int CountChildrenWindows();
native int CountChildrenWindows(String runtimeIdValue);
native int countChildrenWindows();
native int countChildrenWindows(String runtimeIdValue);
native String[] EnumChildrenWindowIds(String runtimeIdValue); //if runtimeIdValue is null will start at desktop
native String[] EnumDescendantWindowIds(String runtimeIdValue); //if runtimeIdValue is null will start at desktop
native String[] EnumDescendantWindowIds(long processId);
native String[] EnumDescendantWindowIdsFromHandle(long windowHandle);
native String[] enumChildrenWindowIds(String runtimeIdValue); //if runtimeIdValue is null will start at desktop
native String[] enumDescendantWindowIds(String runtimeIdValue); //if runtimeIdValue is null will start at desktop
native String[] enumDescendantWindowIds(long processId);
native String[] enumDescendantWindowIdsFromHandle(long windowHandle);
//In all the above Enumerate methods will return a list of Runtime Ids for all related windows.
native String[] enumDescendantWindowInfo(String runtimeIdValue, String properties); //returns properties comma separated
native String GetProperty(String propertyName, String runtimeIdValue);
native String[] GetProperties(String runtimeIdValue);
native String[] GetPropertiesAndValues(String runtimeIdValue);
native String getParentRuntimeId(String runtimeIdValue);
native String getProperty(String propertyName, String runtimeIdValue);
native String[] getProperties(String runtimeIdValue);
native String[] getPropertiesAndValues(String runtimeIdValue);
}