前幾天有朋友問我怎麼在Windows中控制Windows Media Player的播放、停止等功能,可以做到此目的的方法有很多種,其中用Spy++及SendMessage可以輕易達成。我這裡稍微簡述一下方法,詳細流程可以參考[
Interoperating with Windows Media Player using P/Invoke and C# - CodeProject]。
目的
為了方便說明,我改以控制PCMan中我的最愛其中之一的連結來說明。如下圖被框起來的功能表項。
手段
使用SendMessage摸擬功能表項被按下的動作。其中SendMessage的參數如下:
第一個參數可以透過
FindWindow來找到,第二個參數因為是按功能表項所以必定是WM_COMMAND,第三及第四個參數較難取得,但我們可以透過Vistual Studio內附的Spy++來監視PCMan的WM_COMMAND訊息來取得。
首先打開Spy++並按下Ctrl-M,並用下圖紅框1的東東拖到PCMan選到正確視窗,如下圖紅框2。
接著按到訊息的Tab,選WM_COMMAND如下圖。
最後在PCMan內去按下[我的最愛]->[台大批踢踢實業坊],此時在Spy++內便會出現下圖訊息,按下右鍵選[屬性]後便能取得wParam及lParam。
在SendMessage四個參數都備齊後,我寫了一支程式去做SendMessage。底下是程式結果,其中程式的4個參數分別為Program ClassName、Event、wParam和lParam。
執行後ptt便會在PCMan中被打開了。MessageControl的源碼如下:
1 // MessageControl.cpp : 定義主控台應用程式的進入點。 2 // 3 4 #include "stdafx.h" 5 #include <stdlib.h> 6 #include <Windows.h> 7 8 struct EventMappingTable_t {
9 LPCWSTR Name;
10 UINT Code;
11 } g_eventMapping[] = {
12 {
_T(
"WM_COMMNOTIFY"),
0x0044}
13 };
14 15 int _tmain(
int argc, _TCHAR* argv[])
16 {
17 if (argc !=
5) {
18 fprintf(
stderr,
"Usage: %S ClassName Event WPARAM LPARAM\n", argv[
0]);
19 return -
1;
20 }
21 22 HWND hWnd =
FindWindow(argv[
1],
NULL);
23 if (hWnd ==
NULL) {
24 fprintf(
stderr,
"Cannot find window: %S\n", argv[
1]);
25 return -
2;
26 }
27 28 WPARAM wParam;
29 LPARAM lParam;
30 UINT eventID =
0;
31 UINT i;
32 for (i =
0; i <
sizeof(g_eventMapping)/
sizeof(EventMappingTable_t); ++i) {
33 if (
_wcsicmp(g_eventMapping[i].Name, argv[
2]) ==
0) {
34 eventID = g_eventMapping[i].Code;
35 break;
36 }
37 }
38 if (i >=
sizeof(g_eventMapping)/
sizeof(EventMappingTable_t)) {
39 fprintf(
stderr,
"Cannot Event: %S\n", argv[
2]);
40 return -
3;
41 }
42 43 wParam = wcstol(argv[
3],
NULL,
16);
44 lParam = wcstol(argv[
4],
NULL,
16);
45 SendMessage(hWnd, eventID, wParam, lParam);
46 return 0;
47 }
48