實作步驟
- 在 ActiveX 專案中(無論 VB、C++、Delphi、C#),使用 IDE 的「加入方法」或「加入屬性」精靈,新增方法,例如
SendKeysToWindow(processName, keys)。
- IDE 會產生空白存根函數,在其中填入邏輯:
核心代碼 (C++/ATL 範例)
STDMETHODIMP CMyCtrl::SendKeysToWindow(BSTR bstrProcess, BSTR bstrKeys) {
// 1. 找進程 ID
DWORD pid = 0;
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
PROCESSENTRY32 pe = { sizeof(pe) };
if (Process32First(hSnap, &pe)) {
do {
if (_wcsicmp(pe.szExeFile, bstrProcess) == 0) { pid = pe.th32ProcessID; break; }
} while (Process32Next(hSnap, &pe));
}
CloseHandle(hSnap);
if (!pid) return E_FAIL;
// 2. 列舉主視窗
HWND hWnd = NULL;
EnumWindows([](HWND hw, LPARAM lp) -> BOOL {
DWORD wPid; GetWindowThreadProcessId(hw, &wPid);
if (wPid == (DWORD)lp && GetWindow(hw, GW_OWNER) == NULL && IsWindowVisible(hw)) {
*(HWND*)lp = hw; return FALSE;
}
return TRUE;
}, (LPARAM)&hWnd);
if (!hWnd) return E_FAIL;
// 3. 激活並發送鍵盤
SetForegroundWindow(hWnd);
// 需將 BSTR 轉為 ANSI/Unicode 字串,逐字元 PostMessage WM_KEYDOWN/WM_CHAR
// 簡化:使用 SendInput 或 keybd_event(需處理焦點)
return S_OK;
}
關鍵點
- 方法位置:放在類別的介面定義(
.idl 或 Class Wizard)中,IDE 自動處理調度。
- 權限:發送輸入需 UI 權限,若控件跑在低完整性程序(如 IE Protected Mode)可能失敗。
- 替代方案:若僅需自動化測試,建議使用 UI Automation / Selenium 等成熟框架,而非自製 ActiveX。