Fixed WindowInfo class to work properly in Windows 32 bit OS

Fixed WindowInfo class to work properly in Windows 32 bit OS.
Added more unit tests.
About dialog shows system information
This commit is contained in:
Edward Jakubowski
2014-04-10 21:48:28 -04:00
parent be44a8e38b
commit dcae627527
7 changed files with 248 additions and 9 deletions

View File

@@ -147,6 +147,8 @@ public class Api {
int GetClassName(HWND hWnd, char[] buffer2, int i); int GetClassName(HWND hWnd, char[] buffer2, int i);
int GetWindowModuleFileName(HWND hWnd, char[] buffer2, int i); int GetWindowModuleFileName(HWND hWnd, char[] buffer2, int i);
int GetWindowThreadProcessId(HWND hWnd, PointerByReference pref); int GetWindowThreadProcessId(HWND hWnd, PointerByReference pref);
//int GetWindowThreadProcessId(HWND hWnd, IntByReference lpdwProcessId);
boolean GetCursorPos(long[] lpPoint); //use macros POINT_X() and POINT_Y() on long lpPoint[0] boolean GetCursorPos(long[] lpPoint); //use macros POINT_X() and POINT_Y() on long lpPoint[0]

View File

@@ -163,7 +163,6 @@ public class SynthuseDlg extends JFrame {
btnRefresh = new JButton(" Refresh "); btnRefresh = new JButton(" Refresh ");
btnRefresh.addActionListener(new ActionListener() { btnRefresh.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) { public void actionPerformed(ActionEvent arg0) {
//lblStatus.setText("Loading Windows Enumerated Xml...");
//WindowsEnumeratedXml wex = new WindowsEnumeratedXml(textPane, lblStatus); //WindowsEnumeratedXml wex = new WindowsEnumeratedXml(textPane, lblStatus);
//wex.run(); //wex.run();
WindowsEnumeratedXml.getXmlThreaded(textPane, lblStatus); WindowsEnumeratedXml.getXmlThreaded(textPane, lblStatus);
@@ -199,7 +198,20 @@ public class SynthuseDlg extends JFrame {
helpBtn.setIcon(new ImageIcon(SynthuseDlg.class.getResource(RES_STR_HELP_IMG))); helpBtn.setIcon(new ImageIcon(SynthuseDlg.class.getResource(RES_STR_HELP_IMG)));
helpBtn.addActionListener(new ActionListener() { helpBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) { public void actionPerformed(ActionEvent arg0) {
JOptionPane.showMessageDialog(null, "Version " + VERSION_STR + " create by Edward Jakubowski ejakubowski7@gmail.com", "About", JOptionPane.QUESTION_MESSAGE); String about = "";
about += "Synthuse Version " + VERSION_STR + " create by Edward Jakubowski ejakubowski7@gmail.com\n\n";
about += "System information: \n";
about += " Java version - " + System.getProperty("java.version") + "\n";
about += " Java home - " + System.getProperty("java.home") + "\n";
about += " OS Name - " + System.getProperty("os.name") + "\n";
about += " OS Arch - " + System.getProperty("os.arch") + "\n";
String jclasspath = System.getProperty("java.class.path");
jclasspath = jclasspath.replaceAll(";", ";\n ");
if (!System.getProperty("os.name").startsWith("Windows"))
jclasspath = jclasspath.replaceAll(":", ":\n ");
about += " Java class path - " + jclasspath + "\n\n";
JOptionPane.showMessageDialog(null, about , "About", JOptionPane.QUESTION_MESSAGE);
} }
}); });
toolBar.add(helpBtn); toolBar.add(helpBtn);

View File

@@ -56,15 +56,14 @@ public class WindowInfo {
parentStr = Api.GetHandleAsString(parent); parentStr = Api.GetHandleAsString(parent);
} }
else { else {
//User32.instance.GetWindowModuleFileName(hWnd, path, 512);
PointerByReference pointer = new PointerByReference(); PointerByReference pointer = new PointerByReference();
User32.instance.GetWindowThreadProcessId(hWnd, pointer); User32.instance.GetWindowThreadProcessId(hWnd, pointer);
Pointer p = pointer.getPointer(); pid = pointer.getPointer().getInt(0);
pid = p.getLong(0);
Pointer process = Kernel32.instance.OpenProcess(Api.PROCESS_QUERY_INFORMATION | Api.PROCESS_VM_READ, false, pointer.getValue()); Pointer process = Kernel32.instance.OpenProcess(Api.PROCESS_QUERY_INFORMATION | Api.PROCESS_VM_READ, false, pointer.getValue());
Psapi.instance.GetModuleBaseNameW(process, null, buffer2, 512); Psapi.instance.GetModuleBaseNameW(process, null, buffer2, 512);
processName = Native.toString(buffer2); processName = Native.toString(buffer2);
//processName = Native.toString(path);
} }
this.hwnd = hWnd; this.hwnd = hWnd;
hwndStr = Api.GetHandleAsString(hWnd); hwndStr = Api.GetHandleAsString(hWnd);

View File

@@ -0,0 +1,138 @@
package org.synthuse.test;
import java.util.LinkedHashMap;
import java.util.Map;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;
import org.synthuse.Api;
import org.synthuse.WindowInfo;
import org.synthuse.WindowsEnumeratedXml;
import org.synthuse.Api.Kernel32;
import org.synthuse.Api.Psapi;
import org.synthuse.Api.User32;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.WinUser;
import com.sun.jna.platform.win32.WinDef.HWND;
import com.sun.jna.platform.win32.WinDef.RECT;
import com.sun.jna.ptr.PointerByReference;
public class WinApiTest {
@Before
public void setUp() throws Exception {
}
@After
public void tearDown() throws Exception {
}
public static void output(String val) {
System.out.println(val);
}
//copied and modified slightly from WindowInfo class
public String getWindow32Information(HWND hWnd, boolean isChild) {
String hwndStr = "";
HWND parent = null;
String parentStr = "";
RECT rect;
String text;
String className = "";
String processName = "";
long pid = 0;
byte[] buffer = new byte[1024];
output("Calling GetWindowTextA");
User32.instance.GetWindowTextA(hWnd, buffer, buffer.length);
text = Native.toString(buffer);
output("GetWindowTextA returned: " + text);
if (text.isEmpty()) {
output("Calling sendWmGetText");
text = new Api().sendWmGetText(hWnd);
output("sendWmGetText returned: " + text);
}
char[] buffer2 = new char[1026];
output("Calling GetClassName");
User32.instance.GetClassName(hWnd, buffer2, 1026);
className = Native.toString(buffer2);
output("GetClassName returned: " + className);
rect = new RECT();
output("Calling GetWindowRect");
User32.instance.GetWindowRect(hWnd, rect);
output("GetWindowRect returned: " + rect.toString());
if (isChild) {
output("Calling GetParent");
parent = User32.instance.GetParent(hWnd);
parentStr = Api.GetHandleAsString(parent);
output("GetParent returned: " + parentStr);
}
else {
//User32.instance.GetWindowModuleFileName(hWnd, path, 512);
//IntByReference pointer = new IntByReference();
PointerByReference pointer = new PointerByReference();
output("Calling GetWindowThreadProcessId");
User32.instance.GetWindowThreadProcessId(hWnd, pointer);
pid = pointer.getPointer().getInt(0);
output("GetWindowThreadProcessId returned: " + pid);
Pointer process = Kernel32.instance.OpenProcess(Api.PROCESS_QUERY_INFORMATION | Api.PROCESS_VM_READ, false, pointer.getPointer());
//output("OpenProcess returned: " + process.getLong(0));
output("Calling GetModuleBaseNameW");
Psapi.instance.GetModuleBaseNameW(process, null, buffer2, 512);
processName = Native.toString(buffer2);
output("GetModuleBaseNameW returned: " + processName);
//processName = Native.toString(path);
}
hwndStr = Api.GetHandleAsString(hWnd);
output("GetHandleAsString returned: " + hwndStr);
return hwndStr;
}
@Test
public void enumerateParentWindowsTest() {
final Map<String, WindowInfo> infoList = new LinkedHashMap<String, WindowInfo>();
class ParentWindowCallback implements WinUser.WNDENUMPROC {
@Override
public boolean callback(HWND hWnd, Pointer lParam) {
output("Getting window info " + Api.GetHandleAsString(hWnd));
//WindowInfo wi = new WindowInfo(hWnd, false);
infoList.put(getWindow32Information(hWnd, false), null);
//Api.User32.instance.EnumChildWindows(hWnd, new ChildWindowCallback(), new Pointer(0));
return true;
}
}
Api.User32.instance.EnumWindows(new ParentWindowCallback(), 0);
output("enumerateParentWindowsTest size: " + infoList.size());
assertTrue(infoList.size() > 0);
}
@Test
public void getXmlTest() {
String xml = WindowsEnumeratedXml.getXml();
output("getXmlTest len: " + xml.length());
assertTrue(xml.length() > 500);
}
public static void main(String[] args) {
output("WinApiTest");
WinApiTest wat = new WinApiTest();
wat.enumerateParentWindowsTest();
wat.getXmlTest();
output("done.");
}
}

Binary file not shown.

View File

@@ -1,16 +1,48 @@
package org.synthuse.test; package org.synthuse.test;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.junit.After; import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before; import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
import org.synthuse.*; import org.synthuse.*;
public class WpfBridgeTest { public class WpfBridgeTest {
static Process mockApp = null;
public static void RunMockWpfApp() {
String tempFilename = ExtractFileFromJar("/org/synthuse/test/WpfMockTestApp.exe");
Runtime runtime = Runtime.getRuntime();
try {
mockApp = runtime.exec(tempFilename);
} catch (IOException e) {
e.printStackTrace();
}
}
@BeforeClass
public static void setUpBeforeClass() {
//this runs only once for this class
RunMockWpfApp();
}
@AfterClass
public static void tearDownAfterClass() {
//this runs only once for this class
if (mockApp != null)
mockApp.destroy();
}
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
} }
@After @After
@@ -41,7 +73,7 @@ public class WpfBridgeTest {
System.out.println("wpf unfiltered countChildrenWindows: " + wb.countChildrenWindows()); System.out.println("wpf unfiltered countChildrenWindows: " + wb.countChildrenWindows());
} }
@Test //@Test
public void countDescendantsWin32() { public void countDescendantsWin32() {
WpfBridge wb = new WpfBridge(); WpfBridge wb = new WpfBridge();
wb.setFrameworkId("Win32");//We should find some Win32 windows, maybe not WPF wb.setFrameworkId("Win32");//We should find some Win32 windows, maybe not WPF
@@ -54,7 +86,7 @@ public class WpfBridgeTest {
assertTrue(ufwin32Cnt >= win32Cnt); assertTrue(ufwin32Cnt >= win32Cnt);
} }
@Test //@Test
public void countDescendantsWpf() { public void countDescendantsWpf() {
WpfBridge wb = new WpfBridge(); WpfBridge wb = new WpfBridge();
wb.setFrameworkId("WPF");// maybe not WPF wb.setFrameworkId("WPF");// maybe not WPF
@@ -72,6 +104,9 @@ public class WpfBridgeTest {
wb.setFrameworkId("WPF"); wb.setFrameworkId("WPF");
WinPtr wp = new WinPtr(api.user32.FindWindow(null, "MainWindow"));//find WpfMockTestApp.exe WinPtr wp = new WinPtr(api.user32.FindWindow(null, "MainWindow"));//find WpfMockTestApp.exe
long handle = Long.parseLong(wp.hWndStr); long handle = Long.parseLong(wp.hWndStr);
if (handle == 0)
return;
System.out.println("calling getRuntimeIdFromHandle: " + handle);
String rid = wb.getRuntimeIdFromHandle(handle); String rid = wb.getRuntimeIdFromHandle(handle);
System.out.println(wp.hWndStr + " getRuntimeIdFromHandle: " + rid); System.out.println(wp.hWndStr + " getRuntimeIdFromHandle: " + rid);
assertTrue(rid != null); assertTrue(rid != null);
@@ -91,6 +126,8 @@ public class WpfBridgeTest {
wb.setTouchableOnly(false); wb.setTouchableOnly(false);
WinPtr wp = new WinPtr(api.user32.FindWindow(null, "MainWindow"));//find WpfMockTestApp.exe WinPtr wp = new WinPtr(api.user32.FindWindow(null, "MainWindow"));//find WpfMockTestApp.exe
long handle = Long.parseLong(wp.hWndStr); long handle = Long.parseLong(wp.hWndStr);
if (handle == 0)
return;
String rid = wb.getRuntimeIdFromHandle(handle); String rid = wb.getRuntimeIdFromHandle(handle);
System.out.println(wp.hWndStr + " getRuntimeIdFromHandle: " + rid); System.out.println(wp.hWndStr + " getRuntimeIdFromHandle: " + rid);
if (rid == null) if (rid == null)
@@ -101,4 +138,55 @@ public class WpfBridgeTest {
for(String w : wInfo) for(String w : wInfo)
System.out.println(w); System.out.println(w);
} }
public static String ExtractFileFromJar(String path) {
// Obtain filename from path
String[] parts = path.split("/");
String filename = (parts.length > 1) ? parts[parts.length - 1] : null;
// Split filename to prexif and suffix (extension)
String prefix = "";
String suffix = null;
if (filename != null) {
parts = filename.split("\\.", 2);
prefix = parts[0];
suffix = (parts.length > 1) ? "."+parts[parts.length - 1] : null;
}
File temp = null;
try {
// Prepare temporary file
temp = File.createTempFile(prefix, suffix);
temp.deleteOnExit();
} catch(Exception e) {
e.printStackTrace();
}
if (!temp.exists()) { //some reason the temp file wasn't create so abort
System.out.println("File " + temp.getAbsolutePath() + " does not exist.");
return null;
}
// Prepare buffer for data copying
byte[] buffer = new byte[1024];
int readBytes;
// Open and check input stream
InputStream is = WpfBridgeTest.class.getResourceAsStream(path);
if (is == null) { //check if valid
System.out.println("File " + path + " was not found inside JAR.");
return null;
}
// Open output stream and copy data between source file in JAR and the temporary file
OutputStream os = null;
try {
os = new FileOutputStream(temp);
while ((readBytes = is.read(buffer)) != -1) {
os.write(buffer, 0, readBytes);
}
os.close();
is.close();
} catch(Exception e) {
e.printStackTrace();
}
return temp.getAbsolutePath();
// Finally, load the library
//System.load(temp.getAbsolutePath());
}
} }