Java 中使用 UTF-8 的 User32 GetWindowTextA?
User32 GetWindowTextA with UTF-8 in Java?
以下是为了尝试获取活动window的标题并存储到title
。
byte[] buffer = new byte[1024];
User32.instance.GetWindowTextA(hWnd, buffer, buffer.length);
String title = Native.toString(buffer);
在title
中应该存储类似于"猫の動画 - YouTube - Google Chrome"
的内容;因为假设我在 Chrome 浏览器上打开了一个 YouTube 标签,它的标题有 non-alphabetical 个字符但兼容 UTF-8。
然而,出乎我意料的是,title
居然有类似于"??????? - YouTube - Google Chrome"
的东西。
我还尝试了一些变体,例如以下;但是他们并没有解决乱码问题
String title = new String( buffer, java.nio.charset.StandardCharsets.UTF_8 );
我该如何解决这个问题?谢谢。
补充信息
以下是整个Java脚本:
package Main;
import java.awt.AWTException;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import javax.imageio.ImageIO;
import com.sun.jna.Native;
import com.sun.jna.Structure;
import com.sun.jna.win32.StdCallLibrary;
public class windowcapture {
public static void main(String[] args) throws AWTException, IOException {
int hWnd = User32.instance.GetForegroundWindow();
WindowInfo window = getWindowInfo(hWnd);
}
public static WindowInfo getWindowInfo(int hWnd) {
RECT r = new RECT();
User32.instance.GetWindowRect(hWnd, r);
byte[] buffer = new byte[1024];
User32.instance.GetWindowTextA(hWnd, buffer, buffer.length);
String title = Native.toString(buffer);
WindowInfo info = new WindowInfo(hWnd, r, title);
return info;
}
public static interface WndEnumProc extends StdCallLibrary.StdCallCallback {
boolean callback(int hWnd, int lParam);
}
public static interface User32 extends StdCallLibrary {
public static final String SHELL_TRAY_WND = "Shell_TrayWnd";
public static final int WM_COMMAND = 0x111;
public static final int MIN_ALL = 0x1a3;
public static final int MIN_ALL_UNDO = 0x1a0;
final User32 instance = (User32) Native.loadLibrary("user32", User32.class);
boolean EnumWindows(WndEnumProc wndenumproc, int lParam);
boolean IsWindowVisible(int hWnd);
int GetWindowRect(int hWnd, RECT r);
void GetWindowTextA(int hWnd, byte[] buffer, int buflen);
int GetTopWindow(int hWnd);
int GetWindow(int hWnd, int flag);
boolean ShowWindow(int hWnd);
boolean BringWindowToTop(int hWnd);
int GetActiveWindow();
boolean SetForegroundWindow(int hWnd);
// HWND GetForegroundWindow();
int GetForegroundWindow();
int FindWindowA(String winClass, String title);
long SendMessageA(int hWnd, int msg, int num1, int num2);
final int GW_HWNDNEXT = 2;
}
public static class RECT extends Structure {
public int left, top, right, bottom;
@Override
protected List<String> getFieldOrder() {
List<String> order = new ArrayList<>();
order.add("left");
order.add("top");
order.add("right");
order.add("bottom");
return order;
}
}
public static class WindowInfo {
int hwnd;
RECT rect;
String title;
public WindowInfo(int hwnd, RECT rect, String title) {
this.hwnd = hwnd;
this.rect = rect;
this.title = title;
}
public String toString() {
return String.format("(%d,%d)-(%d,%d) : \"%s\"", rect.left, rect.top, rect.right, rect.bottom, title);
}
}
}
最新(当前)版本
package Main;
import java.awt.AWTException;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import javax.imageio.ImageIO;
import com.sun.jna.Native;
import com.sun.jna.Structure;
import com.sun.jna.win32.StdCallLibrary;
public class windowcapture {
public static void main(String[] args) throws AWTException, IOException {
int hWnd = User32.instance.GetForegroundWindow();
WindowInfo window = getWindowInfo(hWnd);
}
public static WindowInfo getWindowInfo(int hWnd) {
RECT r = new RECT();
User32.instance.GetWindowRect(hWnd, r);
byte[] buffer = new byte[1024];
// User32.instance.GetWindowTextA(hWnd, buffer, buffer.length);
User32.instance.GetWindowTextW(hWnd, buffer, buffer.length);
// FileOutputStream fos = null;
// try {
// fos = new FileOutputStream(new File("./out/hoge.txt"), true);
// fos.write(buffer);
// fos.flush();
// System.out.println("File Written Successfully");
// } catch (IOException ioe) {
// ioe.printStackTrace();
// } finally {
// try {
// if (fos != null) {
// fos.close();
// }
// } catch (IOException ioe) {
// System.out.println("Error in closing the Stream");
// }
// }
String title = Native.toString(buffer);
// String title = new String( buffer, Charset.forName("x-MS950-HKSCS") );
// String title = new String( buffer, Charset.forName("UTF_16BE") );
// String title = new String( buffer, Charset.forName("UTF-8") );
// String title = Native.toString(buffer, StandardCharsets.UTF_16BE);
WindowInfo info = new WindowInfo(hWnd, r, title);
return info;
}
public static interface WndEnumProc extends StdCallLibrary.StdCallCallback {
boolean callback(int hWnd, int lParam);
}
public static interface User32 extends StdCallLibrary {
public static final String SHELL_TRAY_WND = "Shell_TrayWnd";
public static final int WM_COMMAND = 0x111;
public static final int MIN_ALL = 0x1a3;
public static final int MIN_ALL_UNDO = 0x1a0;
final User32 instance = (User32) Native.loadLibrary("user32", User32.class);
boolean EnumWindows(WndEnumProc wndenumproc, int lParam);
boolean IsWindowVisible(int hWnd);
int GetWindowRect(int hWnd, RECT r);
void GetWindowTextA(int hWnd, byte[] buffer, int buflen);
void GetWindowTextW(int hWnd, byte[] buffer, int buflen);
int GetTopWindow(int hWnd);
int GetWindow(int hWnd, int flag);
boolean ShowWindow(int hWnd);
boolean BringWindowToTop(int hWnd);
int GetActiveWindow();
boolean SetForegroundWindow(int hWnd);
// HWND GetForegroundWindow();
int GetForegroundWindow();
int FindWindowA(String winClass, String title);
long SendMessageA(int hWnd, int msg, int num1, int num2);
final int GW_HWNDNEXT = 2;
}
public static class RECT extends Structure {
public int left, top, right, bottom;
@Override
protected List<String> getFieldOrder() {
List<String> order = new ArrayList<>();
order.add("left");
order.add("top");
order.add("right");
order.add("bottom");
return order;
}
}
public static class WindowInfo {
int hwnd;
RECT rect;
String title;
public WindowInfo(int hwnd, RECT rect, String title) {
this.hwnd = hwnd;
this.rect = rect;
this.title = title;
}
public String toString() {
return String.format("(%d,%d)-(%d,%d) : \"%s\"", rect.left, rect.top, rect.right, rect.bottom, title);
}
}
}
GetWindowTextA
中的“A”代表 ANSI,对吗? ANSI 没有这些字符,因此 GetWindowTextA
不可能在这里给你你想要的东西,因此再多的 java 代码也无法解决这个问题。
你想要GetWindowTextW
。我认为可能 return UTF16LE,你可能需要尝试不同的编码,但至少你从 windows 得到的数据仍然有你想要的(与 A
它已经删除了汉字,因为 ANSI 不支持它们。
以下是为了尝试获取活动window的标题并存储到title
。
byte[] buffer = new byte[1024];
User32.instance.GetWindowTextA(hWnd, buffer, buffer.length);
String title = Native.toString(buffer);
在title
中应该存储类似于"猫の動画 - YouTube - Google Chrome"
的内容;因为假设我在 Chrome 浏览器上打开了一个 YouTube 标签,它的标题有 non-alphabetical 个字符但兼容 UTF-8。
然而,出乎我意料的是,title
居然有类似于"??????? - YouTube - Google Chrome"
的东西。
我还尝试了一些变体,例如以下;但是他们并没有解决乱码问题
String title = new String( buffer, java.nio.charset.StandardCharsets.UTF_8 );
我该如何解决这个问题?谢谢。
补充信息
以下是整个Java脚本:
package Main;
import java.awt.AWTException;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import javax.imageio.ImageIO;
import com.sun.jna.Native;
import com.sun.jna.Structure;
import com.sun.jna.win32.StdCallLibrary;
public class windowcapture {
public static void main(String[] args) throws AWTException, IOException {
int hWnd = User32.instance.GetForegroundWindow();
WindowInfo window = getWindowInfo(hWnd);
}
public static WindowInfo getWindowInfo(int hWnd) {
RECT r = new RECT();
User32.instance.GetWindowRect(hWnd, r);
byte[] buffer = new byte[1024];
User32.instance.GetWindowTextA(hWnd, buffer, buffer.length);
String title = Native.toString(buffer);
WindowInfo info = new WindowInfo(hWnd, r, title);
return info;
}
public static interface WndEnumProc extends StdCallLibrary.StdCallCallback {
boolean callback(int hWnd, int lParam);
}
public static interface User32 extends StdCallLibrary {
public static final String SHELL_TRAY_WND = "Shell_TrayWnd";
public static final int WM_COMMAND = 0x111;
public static final int MIN_ALL = 0x1a3;
public static final int MIN_ALL_UNDO = 0x1a0;
final User32 instance = (User32) Native.loadLibrary("user32", User32.class);
boolean EnumWindows(WndEnumProc wndenumproc, int lParam);
boolean IsWindowVisible(int hWnd);
int GetWindowRect(int hWnd, RECT r);
void GetWindowTextA(int hWnd, byte[] buffer, int buflen);
int GetTopWindow(int hWnd);
int GetWindow(int hWnd, int flag);
boolean ShowWindow(int hWnd);
boolean BringWindowToTop(int hWnd);
int GetActiveWindow();
boolean SetForegroundWindow(int hWnd);
// HWND GetForegroundWindow();
int GetForegroundWindow();
int FindWindowA(String winClass, String title);
long SendMessageA(int hWnd, int msg, int num1, int num2);
final int GW_HWNDNEXT = 2;
}
public static class RECT extends Structure {
public int left, top, right, bottom;
@Override
protected List<String> getFieldOrder() {
List<String> order = new ArrayList<>();
order.add("left");
order.add("top");
order.add("right");
order.add("bottom");
return order;
}
}
public static class WindowInfo {
int hwnd;
RECT rect;
String title;
public WindowInfo(int hwnd, RECT rect, String title) {
this.hwnd = hwnd;
this.rect = rect;
this.title = title;
}
public String toString() {
return String.format("(%d,%d)-(%d,%d) : \"%s\"", rect.left, rect.top, rect.right, rect.bottom, title);
}
}
}
最新(当前)版本
package Main;
import java.awt.AWTException;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import javax.imageio.ImageIO;
import com.sun.jna.Native;
import com.sun.jna.Structure;
import com.sun.jna.win32.StdCallLibrary;
public class windowcapture {
public static void main(String[] args) throws AWTException, IOException {
int hWnd = User32.instance.GetForegroundWindow();
WindowInfo window = getWindowInfo(hWnd);
}
public static WindowInfo getWindowInfo(int hWnd) {
RECT r = new RECT();
User32.instance.GetWindowRect(hWnd, r);
byte[] buffer = new byte[1024];
// User32.instance.GetWindowTextA(hWnd, buffer, buffer.length);
User32.instance.GetWindowTextW(hWnd, buffer, buffer.length);
// FileOutputStream fos = null;
// try {
// fos = new FileOutputStream(new File("./out/hoge.txt"), true);
// fos.write(buffer);
// fos.flush();
// System.out.println("File Written Successfully");
// } catch (IOException ioe) {
// ioe.printStackTrace();
// } finally {
// try {
// if (fos != null) {
// fos.close();
// }
// } catch (IOException ioe) {
// System.out.println("Error in closing the Stream");
// }
// }
String title = Native.toString(buffer);
// String title = new String( buffer, Charset.forName("x-MS950-HKSCS") );
// String title = new String( buffer, Charset.forName("UTF_16BE") );
// String title = new String( buffer, Charset.forName("UTF-8") );
// String title = Native.toString(buffer, StandardCharsets.UTF_16BE);
WindowInfo info = new WindowInfo(hWnd, r, title);
return info;
}
public static interface WndEnumProc extends StdCallLibrary.StdCallCallback {
boolean callback(int hWnd, int lParam);
}
public static interface User32 extends StdCallLibrary {
public static final String SHELL_TRAY_WND = "Shell_TrayWnd";
public static final int WM_COMMAND = 0x111;
public static final int MIN_ALL = 0x1a3;
public static final int MIN_ALL_UNDO = 0x1a0;
final User32 instance = (User32) Native.loadLibrary("user32", User32.class);
boolean EnumWindows(WndEnumProc wndenumproc, int lParam);
boolean IsWindowVisible(int hWnd);
int GetWindowRect(int hWnd, RECT r);
void GetWindowTextA(int hWnd, byte[] buffer, int buflen);
void GetWindowTextW(int hWnd, byte[] buffer, int buflen);
int GetTopWindow(int hWnd);
int GetWindow(int hWnd, int flag);
boolean ShowWindow(int hWnd);
boolean BringWindowToTop(int hWnd);
int GetActiveWindow();
boolean SetForegroundWindow(int hWnd);
// HWND GetForegroundWindow();
int GetForegroundWindow();
int FindWindowA(String winClass, String title);
long SendMessageA(int hWnd, int msg, int num1, int num2);
final int GW_HWNDNEXT = 2;
}
public static class RECT extends Structure {
public int left, top, right, bottom;
@Override
protected List<String> getFieldOrder() {
List<String> order = new ArrayList<>();
order.add("left");
order.add("top");
order.add("right");
order.add("bottom");
return order;
}
}
public static class WindowInfo {
int hwnd;
RECT rect;
String title;
public WindowInfo(int hwnd, RECT rect, String title) {
this.hwnd = hwnd;
this.rect = rect;
this.title = title;
}
public String toString() {
return String.format("(%d,%d)-(%d,%d) : \"%s\"", rect.left, rect.top, rect.right, rect.bottom, title);
}
}
}
GetWindowTextA
中的“A”代表 ANSI,对吗? ANSI 没有这些字符,因此 GetWindowTextA
不可能在这里给你你想要的东西,因此再多的 java 代码也无法解决这个问题。
你想要GetWindowTextW
。我认为可能 return UTF16LE,你可能需要尝试不同的编码,但至少你从 windows 得到的数据仍然有你想要的(与 A
它已经删除了汉字,因为 ANSI 不支持它们。