自動登錄本質是 跨進程窗口操作:找到目標窗口 → 獲取控件句柄 → 發送消息模擬用戶輸入 → 觸發登錄動作。關鍵工具:Spy++ 獲取窗口類名、標題、控件 ID。
CWnd* pWnd = FindWindow(_T("#32770"), _T("QQ用戶登錄"));
if (!pWnd) {
PROCESS_INFORMATION pi;
STARTUPINFO si = { sizeof(STARTUPINFO) };
si.dwFlags = STARTF_FORCEOFFFEEDBACK;
CreateProcess(_T("D:\\Tencent\\qq\\CoralQQ.exe"), NULL, NULL, NULL, FALSE,
NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi);
// 實際應加等待窗口創建邏輯
}
CComboBox* pCob = (CComboBox*)pWnd->GetDlgItem(138); // Spy++ 獲取的 ID
if (pCob) {
m_edtCode.SetSel(0, -1); m_edtCode.Copy(); // 本程序編輯框複製賬號
pCob->SetCurSel(0); pCob->DeleteString(0); // 清空原有
pCob->SendMessage(WM_PASTE, 0, 0); // 粘貼
}
QQ 密碼框使用鍵盤加密保護,禁止 WM_PASTE,必須逐字符發送 WM_CHAR:
// 遍歷子窗口查找密碼框(ID=16038)
CWnd* pCwnd = pWnd->GetNextWindow(GW_CHILD);
pCwnd = pCwnd->GetNextWindow(GW_HWNDNEXT);
while (pCwnd) {
CEdit* pPwd = (CEdit*)pCwnd->GetDlgItem(16038);
if (pPwd) {
// Unicode 轉 ANSI(視項目編碼而定)
char buf[20] = {0};
WideCharToMultiByte(CP_ACP, 0, m_strPassword, -1, buf, 20, NULL, NULL);
pPwd->SetSel(0, -1); pPwd->Clear(); // 清空
for (int i = 0; buf[i]; ++i) {
pPwd->SendMessage(WM_CHAR, (WPARAM)buf[i], 0); // 逐字符發送
}
break;
}
pCwnd = pCwnd->GetNextWindow(GW_HWNDNEXT);
}
CButton* pbtnLogin = (CButton*)pWnd->GetDlgItem(16032);
if (pbtnLogin) {
pbtnLogin->PostMessage(WM_LBUTTONDOWN, 0, 0);
pbtnLogin->PostMessage(WM_LBUTTONUP, 0, 0);
}
設置 WM_TIMER 定期檢查登錄狀態,未登錄則執行上述流程。
| 技術點 | API/方法 | 注意事項 |
|---|---|---|
| 查找主窗口 | FindWindow | 類名 #32770 為對話框通用類 |
| 啟動進程 | CreateProcess | 需正確路徑、STARTUPINFO 初始化 |
| 獲取控件 | GetDlgItem / GetNextWindow | 子窗口需層層查找 |
| 文本輸入 | WM_PASTE / WM_CHAR | 密碼框常禁用粘貼,需模擬鍵盤 |
| 按鈕點擊 | PostMessage(WM_LBUTTONDOWN/UP) | PostMessage 異步,SendMessage 同步 |
| 編碼轉換 | WideCharToMultiByte | Unicode 項目操作 ANSI 控件必須轉換 |
同樣原理可應用於:
WM_HIDE)WM_COPYDATA、共享內存)跨進程窗口操作是 Windows 系統編程的進階技能。掌握 Spy++ 使用、消息機制、窗口層級遍歷、編碼處理,能解決大量自動化、集成類需求。但請始終遵循軟件授權協議與安全規範。