??????API?????????????????д?????μ??????????????????????????????????£?
1.import java.util.concurrent.Callable; 
2.import java.util.concurrent.ExecutorService; 
3.import java.util.concurrent.Executors; 
4.import java.util.concurrent.Future; 
5.import java.util.concurrent.TimeUnit; 
6. 
7.import com.sun.jna.Native; 
8.import com.sun.jna.Pointer; 
9.import com.sun.jna.platform.win32.WinDef.HWND; 
10.import com.sun.jna.platform.win32.WinUser.WNDENUMPROC; 
11. 
12./**
13. * Window?????????????
14. * 
15. * @author sunju
16. * 
17. */ 
18.public class Win32Util { 
19. 
20.    private static final int N_MAX_COUNT = 512; 
21. 
22.    private Win32Util() { 
23.    } 
24. 
25.    /**
26.     * ?????濪????????????????????????????Χ??????δ????κ????????????????
27.     * @param className ?????????
28.     * @param timeout ??????
29.     * @param unit ????????λ
30.     * @return ????????????????????????????????????????????????????????δ??????????<code>null</code>
31.     */ 
32.    public static HWND findHandleByClassName(String className?? long timeout?? TimeUnit unit) { 
33.        return findHandleByClassName(USER32EXT.GetDesktopWindow()?? className?? timeout?? unit); 
34.    } 
35. 
36.    /**
37.     * ?????濪?????????????????
38.     * @param className ?????????
39.     * @return ????????????????????????????????????????????????????????δ????κ????????<code>null</code>
40.     */ 
41.    public static HWND findHandleByClassName(String className) { 
42.        return findHandleByClassName(USER32EXT.GetDesktopWindow()?? className); 
43.    } 
44. 
45.    /**
46.     * ?????λ????????????????????
47.     * @param root ????????????λ????????????????<code>null</code>??????濪?????
48.     * @param className ?????????
49.     * @param timeout ??????
50.     * @param unit ????????λ
51.     * @return ????????????????????????????????????????????????????????δ??????????<code>null</code>
52.     */ 
53.    public static HWND findHandleByClassName(HWND root?? String className?? long timeout?? TimeUnit unit) { 
54.        if(null == className || className.length() <= 0) { 
55.            return null; 
56.        } 
57.        long start = System.currentTimeMillis(); 
58.        HWND hwnd = findHandleByClassName(root?? className); 
59.        while(null == hwnd && (System.currentTimeMillis() - start < unit.toMillis(timeout))) { 
60.            hwnd = findHandleByClassName(root?? className); 
61.        } 
62.        return hwnd; 
63.    } 
64. 
65.    /**
66.     * ?????λ????????????????????
67.     * @param root ????????????λ????????????????<code>null</code>??????濪?????
68.     * @param className ?????????
69.     * @return ????????????????????????????????????????????????????????δ????κ????????<code>null</code>
70.     */ 
71.    public static HWND findHandleByClassName(HWND root?? String className) { 
72.        if(null == className || className.length() <= 0) { 
73.            return null; 
74.        } 
75.        HWND[] result = new HWND[1]; 
76.        findHandle(result?? root?? className); 
77.        return result[0]; 
78.    } 
79. 
80.    private static boolean findHandle(final HWND[] target?? HWND root?? final String className) { 
81.        if(null == root) { 
82.            root = USER32EXT.GetDesktopWindow(); 
83.        } 
84.        return USER32EXT.EnumChildWindows(root?? new WNDENUMPROC() { 
85. 
86.            @Override 
87.            public boolean callback(HWND hwnd?? Pointer pointer) { 
88.                char[] winClass = new char[N_MAX_COUNT]; 
89.                USER32EXT.GetClassName(hwnd?? winClass?? N_MAX_COUNT); 
90.                if(USER32EXT.IsWindowVisible(hwnd) && className.equals(Native.toString(winClass))) { 
91.                    target[0] = hwnd; 
92.                    return false; 
93.                } else { 
94.                    return target[0] == null || findHandle(target?? hwnd?? className); 
95.                } 
96.            } 
97. 
98.        }?? Pointer.NULL); 
99.    } 
100. 
101.    /**
102.     * ????????????????????????win32 keybd_event????η???KEYEVENTF_KEYDOWN??KEYEVENTF_KEYUP????????????10???
103.     * @param hwnd ?????????????????
104.     * @param keyCombination ?????????????<a href="http://msdn.microsoft.com/ZH-CN/library/windows/desktop/dd375731.aspx">Virtual-Key Code</a>???????????{@link java.awt.event.KeyEvent}</br>
105.     *                      ???????????е?????????????????????????????????????е?????????????????????????????????
106.     * @return ??????????????windows??????г??????<code>true</code>????????????????windows????????????????<code>false</code>
107.     */ 
108.    public static boolean simulateKeyboardEvent(HWND hwnd?? int[][] keyCombination) { 
109.        if(null == hwnd) { 
110.            return false; 
111.        } 
112.        USER32EXT.SwitchToThisWindow(hwnd?? true); 
113.        USER32EXT.SetFocus(hwnd); 
114.        for(int[] keys : keyCombination) { 
115.            for(int i = 0; i < keys.length; i++) { 
116.                USER32EXT.keybd_event((byte) keys[i]?? (byte) 0?? KEYEVENTF_KEYDOWN?? 0); // key down 
117.            } 
118.            for(int i = keys.length - 1; i >= 0; i--) { 
119.                USER32EXT.keybd_event((byte) keys[i]?? (byte) 0?? KEYEVENTF_KEYUP?? 0); // key up 
120.            } 
121.        } 
122.        return true; 
123.    } 
124. 
125.    /**
126.     * ?????????????????????win32 SendMessage API????WM_CHAR????????10???
127.     * @param hwnd ??????????????????
128.     * @param content ??????????????????????<code>char[]</code>????????????
129.     * @return ????????????????????<code>true</code>?????????????????????????<code>false</code>
130.     */ 
131.    public static boolean simulateCharInput(final HWND hwnd?? final String content) { 
132.        if(null == hwnd) { 
133.            return false; 
134.        } 
135.        try { 
136.            return execute(new Callable<Boolean>() { 
137. 
138.                @Override 
139.                public Boolean call() throws Exception { 
140.                    USER32EXT.SwitchToThisWindow(hwnd?? true); 
141.                    USER32EXT.SetFocus(hwnd); 
142.                    for(char c : content.toCharArray()) { 
143.                        Thread.sleep(5); 
144.                        USER32EXT.SendMessage(hwnd?? WM_CHAR?? (byte) c?? 0); 
145.                    } 
146.                    return true; 
147.                } 
148. 
149.            }); 
150.        } catch(Exception e) { 
151.            return false; 
152.        } 
153.    } 
154.     
155.    public static boolean simulateCharInput(final HWND hwnd?? final String content?? final long sleepMillisPreCharInput) { 
156.        if(null == hwnd) { 
157.            return false; 
158.        } 
159.        try { 
160.            return execute(new Callable<Boolean>() { 
161. 
162.                @Override 
163.                public Boolean call() throws Exception { 
164.                    USER32EXT.SwitchToThisWindow(hwnd?? true); 
165.                    USER32EXT.SetFocus(hwnd); 
166.                    for(char c : content.toCharArray()) { 
167.                        Thread.sleep(sleepMillisPreCharInput); 
168.                        USER32EXT.SendMessage(hwnd?? WM_CHAR?? (byte) c?? 0); 
169.                    } 
170.                    return true; 
171.                } 
172. 
173.            }); 
174.        } catch(Exception e) { 
175.            return false; 
176.        } 
177.    } 
178. 
179.    /**
180.     * ?????????????????????win32 SendMessage API????WM_SETTEXT????????10???
181.     * @param hwnd ??????????????????
182.     * @param content ????????????
183.     * @return ????????????????????<code>true</code>?????????????????????????<code>false</code>
184.     */ 
185.    public static boolean simulateTextInput(final HWND hwnd?? final String content) { 
186.        if(null == hwnd) { 
187.            return false; 
188.        } 
189.        try { 
190.            return execute(new Callable<Boolean>() { 
191. 
192.                @Override 
193.                public Boolean call() throws Exception { 
194.                    USER32EXT.SwitchToThisWindow(hwnd?? true); 
195.                    USER32EXT.SetFocus(hwnd); 
196.                    USER32EXT.SendMessage(hwnd?? WM_SETTEXT?? 0?? content); 
197.                    return true; 
198.                } 
199. 
200.            }); 
201.        } catch(Exception e) { 
202.            return false; 
203.        } 
204.    } 
205. 
206.    /**
207.     * ?????????????????????win32 SendMessage API????BM_CLICK????????10???
208.     * @param hwnd ??????????????
209.     * @return ????????????????<code>true</code>?????????????????????<code>false</code>
210.     */ 
211.    public static boolean simulateClick(final HWND hwnd) { 
212.        if(null == hwnd) { 
213.            return false; 
214.        } 
215.        try { 
216.            return execute(new Callable<Boolean>() { 
217. 
218.                @Override 
219.                public Boolean call() throws Exception { 
220.                    USER32EXT.SwitchToThisWindow(hwnd?? true); 
221.                    USER32EXT.SendMessage(hwnd?? BM_CLICK?? 0?? null); 
222.                    return true; 
223.                } 
224. 
225.            }); 
226.        } catch(Exception e) { 
227.            return false; 
228.        } 
229.    } 
230. 
231.    private static <T> T execute(Callable<T> callable) throws Exception { 
232.        ExecutorService executor = Executors.newSingleThreadExecutor(); 
233.        try { 
234.            Future<T> task = executor.submit(callable); 
235.            return task.get(10?? TimeUnit.SECONDS); 
236.        } finally { 
237.            executor.shutdown(); 
238.        } 
239.    } 
240.}