package me.test;
import com.sun.jna.platform.win32.Kernel32;
import com.sun.jna.platform.win32.User32;
import com.sun.jna.platform.win32.WinBase;
import com.sun.jna.platform.win32.WinBase.SECURITY_ATTRIBUTES;
import com.sun.jna.platform.win32.WinDef.DWORD;
import com.sun.jna.platform.win32.WinDef.HWND;
import com.sun.jna.platform.win32.WinDef.LPARAM;
import com.sun.jna.platform.win32.WinDef.WPARAM;
import com.sun.jna.platform.win32.WinNT.OSVERSIONINFOEX;
// 打开计算器并发送消息
public class Test03 {
public static void main(String[] args) {
System.out.println("============================= CASE 3");
// 打开计算器
Kernel32 kernel32 = Kernel32.INSTANCE;
SECURITY_ATTRIBUTES procSecAttr = new SECURITY_ATTRIBUTES();
SECURITY_ATTRIBUTES threadSecAttr = new SECURITY_ATTRIBUTES();
WinBase.PROCESS_INFORMATION.ByReference byRef = new WinBase.PROCESS_INFORMATION.ByReference();
WinBase.STARTUPINFO startupInfo = new WinBase.STARTUPINFO();
startupInfo = new WinBase.STARTUPINFO();
boolean success = kernel32.CreateProcess(null, "calc.exe", procSecAttr,
threadSecAttr, false, new DWORD(0x00000010), null, null,
startupInfo, byRef);
if (!success) {
System.out.println("计算器打开失败");
System.out.println();
return;
}
// 找到计算器的窗口
// PS:仅仅是为了学习。如果程序是自己打开的,应该使用 startupInfo。
User32 user32 = User32.INSTANCE;
int tryTimes = 0;
boolean found = false;
HWND h1 = null;
while (!found && tryTimes < 3) {
h1 = user32.FindWindow(null, "计算器");
if (h1 == null) {
tryTimes++;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
break;
}
} else {
found = true;
}
}
System.out.println("tryTimes = " + tryTimes);
if (h1 == null) {
System.out.println("找不到计算器");
System.out.println();
return;
}
// 使计算器窗口置前
user32.SetForegroundWindow(h1);
// 找到输入框并设置文本(XP OK,Win7 的计算器已经改变)
OSVERSIONINFOEX osVerInfo = new OSVERSIONINFOEX();
boolean setText = kernel32.GetVersionEx(osVerInfo);
if (setText) {
int major = osVerInfo.dwMajorVersion.intValue();
int minor = osVerInfo.dwMinorVersion.intValue();
if (!(major == 5 && minor == 0) // Windows 2000
&& !(major == 5 && minor == 1) // Windows XP
&& !(major == 5 && minor == 1) // Windows 2003 (R2)
) {
setText = false;
}
}
if (setText) {
MyUser32 myUser32 = MyUser32.INSTANCE;
HWND h2 = myUser32.FindWindowEx(h1, null, "Edit", null); //
final int WM_SETTEXT = 0xC;
myUser32.SendMessage(h2, WM_SETTEXT, new WPARAM(0), "123ABC中文");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
Thread.sleep(10000);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
// 模拟 Esc 按键的 down 与 up,清除设置的不合法输入
for (int i = 0; i < 3; i++) {
//final int VK_ESCAPE = 0x1B;
WPARAM wParam = new WPARAM(8);
int repeatCount = 1;
int scanCode = 0;
int isExtendedKey = 0;
int contextCode = 0;
int preKeyState = 0;
int transitionState = 0;
LPARAM lParam = new LPARAM(repeatCount | scanCode | isExtendedKey
| contextCode | contextCode | preKeyState | transitionState);
user32.PostMessage(h1, User32.WM_KEYDOWN, wParam, lParam);
repeatCount = 1;
scanCode = 0;
isExtendedKey = 0;
contextCode = 0;
preKeyState = 1 << 31;
transitionState = 1 << 31;
user32.PostMessage(h1, User32.WM_KEYUP, wParam, lParam);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try {
System.out.println("文字应当已经被清除,请确认。");
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 调用 PostMessage, 计算 1+2+3+4+5+6+7+8+9=
// FIXME : 区别 SendInput SendMessage PostMessage
for (int i = 0; i < 10; i++) {
user32.PostMessage(h1, User32.WM_CHAR, new WPARAM('0' + i),
new LPARAM(0));
if (i < 9) {
user32.PostMessage(h1, User32.WM_CHAR, new WPARAM('+'),
new LPARAM(0));
} else {
user32.PostMessage(h1, User32.WM_CHAR, new WPARAM('='),
new LPARAM(0));
}
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}