首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> 關於VC++

MFC 修改 QQ 視窗控件實作:禁用輸入與按鈕的技術細節

     編輯:關於VC++

前言

本文記錄一個實際需求:透過 MFC 程式尋找 QQ 聊天視窗(「發送訊息」、「查看訊息」),修改其按鈕、靜態文字、編輯框等控件屬性(如禁用發送按鈕、修改標題文字),並寫入登錄實現開機自啟,以達到「強制戒除 QQ 聊天」的效果。技術涉及視窗枚舉、控件子類化、跨進程視窗操作與登錄操作。

核心技術點解析

1. 視窗尋找與控件枚舉

HWND WndHandle = ::FindWindow(NULL, "查看訊息");
::SetWindowText(WndHandle, "聊天真的很痛苦的呀"); // 修改視窗標題

// 禁用編輯框
HWND WndEdit = ::FindWindowEx(WndHandle, NULL, "Edit", "");
::EnableWindow(WndEdit, FALSE);

2. 批量禁用按鈕控件

char buttoncaption[4][20] = {
    "聊天記錄(&H)", "對話模式(&T)", "取消發送(&C)", "送訊息(&S)"
};
HWND button_c[6];
for (int i = 0; i < 4; i++) {
    button_c[i] = FindWindowEx(WndHandle, NULL, "Button", buttoncaption[i]);
}
for (int i = 0; i < 4; i++) {
    ::EnableWindow(button_c[i], FALSE);
}

3. 靈活枚舉 Static 控件並選擇性修改文字

HWND static_c[11];
static_c[0] = NULL;
for (int i = 1; i < 11; i++) {
    // 關鍵:第二參數傳入上一個找到的 HWND,避免重複返回同一控件
    static_c[i] = FindWindowEx(WndHandle, static_c[i-1], "Static", NULL);
}

int static_index[4], n = 0;
for (int i = 1; i < 11; i++) {
    char caption[100];
    ::GetWindowText(static_c[i], caption, 100);
    // 保留不需修改的標籤:QQ#:、暱稱:、Email:、按ctrl+回車鍵發送訊息
    if (strcmp(caption, "QQ#:") != 0 &&
        strcmp(caption, "暱稱:") != 0 &&
        strcmp(caption, "Email:") != 0 &&
        strcmp(caption, "按ctrl + 回車鍵發送訊息") != 0) {
        static_index[n++] = i;
    }
}
char *s[4] = {"自定義文字1", "自定義文字2", "自定義文字3", "自定義文字4"};
for (int i = 1; i <= 4; i++) {
    int index = static_index[i-1];
    if (index >= 0 && index <= 10) {
        int dlgindex = ::GetDlgCtrlID(static_c[index]);
        ::SetDlgItemText(WndHandle, dlgindex, s[i-1]);
    }
}
::InvalidateRect(WndHandle, NULL, FALSE);
for (int i = 1; i <= 4; i++) {
    ::UpdateWindow(static_c[static_index[i-1]]);
}

4. 登錄寫入實現開機自啟

char path[MAX_PATH];
::GetCurrentDirectory(MAX_PATH, path);
strcat(path, "\\戒掉qq聊天的壞習慣.exe");

LPBYTE path_set = pchar_To_LPBYTE(path);
DWORD type = REG_SZ;
DWORD cbdata = strlen(path) + 1;
HKEY hkey;
LPCTSTR data_set = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run\\";

long ret_0 = ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, data_set, 0, KEY_ALL_ACCESS, &hkey);
long ret_1 = ::RegSetValueEx(hkey, "BadQQ", 0, type, path_set, cbdata);
::RegCloseKey(hkey);

LPBYTE CShitDlg::pchar_To_LPBYTE(char* str) {
    LPBYTE lpb = new BYTE[strlen(str) + 1];
    for (int i = 0; i < strlen(str); i++) lpb[i] = str[i];
    lpb[strlen(str)] = 0;
    return lpb;
}

關鍵技術難點與解決方案

難點解決方案
跨進程操作 QQ 控件使用 FindWindow/FindWindowEx 取得 HWND,直接呼叫 EnableWindow/SetWindowText 等 Win32 API,Windows 允許跨進程視窗操作(受 UIPI 限制,需相同或更高完整性等級)
枚舉同類別名控件避免重複FindWindowEx(hParent, hChildAfter, ...) 第二參數傳入上一次找到的 HWND,實現迭代枚舉
修改對話框模板文字需重繪修改後呼叫 InvalidateRect + UpdateWindow 強制重繪
登錄寫入需管理員權限HKLM 需管理員權限;若無權限可改寫 HKCU\Software\Microsoft\Windows\CurrentVersion\Run

安全與道德提醒

此技術屬於「軟體行為修改/攔截」範疇,實際部署時必須:

  • 取得使用者明確知情同意
  • 提供完整的卸載/恢復機制
  • 不得繞過系統安全機制(如 UAC、UIPI)
  • 企業環境應透過群組原則、EDR 等正規管道管理軟體使用行為

本文僅供技術原理解析,請勿用於未經授權的軟體行為控制。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved