MFC 注册表编程
记录点滴。
对话框部分程序:
1 // RegeditDlg.h : 头文件 2 // 3 4 #pragma once 5 #include "afxwin.h" 6 7 // 注册表监控线程函数 8 static DWORD WINAPI ThreadFunc(); 9 10 // CRegeditDlg 对话框 11 class CRegeditDlg : public CDialogEx 12 { 13 // 构造 14 public: 15 CRegeditDlg(CWnd* pParent = NULL); // 标准构造函数 16 17 // 对话框数据 18 enum { IDD = IDD_REGEDIT_DIALOG }; 19 20 protected: 21 virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 22 23 24 // 实现 25 protected: 26 HICON m_hIcon; 27 28 // 生成的消息映射函数 29 virtual BOOL OnInitDialog(); 30 afx_msg void OnSysCommand(UINT nID, LPARAM lParam); 31 afx_msg void OnPaint(); 32 afx_msg HCURSOR OnQueryDragIcon(); 33 DECLARE_MESSAGE_MAP() 34 public: 35 CString Reg_add; 36 // CString Reg_change; 37 afx_msg void OnBnClickedButton1(); 38 afx_msg void OnBnClickedButton2(); 39 afx_msg void OnBnClickedButton3(); 40 afx_msg void OnLbnSelchangeList1(); 41 afx_msg void OnCbnSelchangeCombo1(); 42 afx_msg void OnBnClickedButton4(); 43 CString ValueName; 44 CString ValueData; 45 CComboBox m_COMBOX; 46 CString ValueSearch; 47 afx_msg void OnBnClickedButton5(); 48 CString MainPage; 49 afx_msg void OnBnClickedButton7(); 50 afx_msg void OnBnClickedButton6(); 51 afx_msg void OnBnClickedButton9(); 52 afx_msg void OnBnClickedButton10(); 53 };
1 /* 2 2015.5 HT 3 注册表编程 4 5 基于: 6 HKEY_CURRENT_CONFIG\Regedit 7 8 */ 9 10 // RegeditDlg.cpp : 实现文件 11 // 12 13 #include "stdafx.h" 14 #include "Regedit.h" 15 #include "RegeditDlg.h" 16 #include "afxdialogex.h" 17 18 #ifdef _DEBUG 19 #define new DEBUG_NEW 20 #endif 21 22 23 // 用于应用程序“关于”菜单项的 CAboutDlg 对话框 24 25 class CAboutDlg : public CDialogEx 26 { 27 public: 28 CAboutDlg(); 29 30 // 对话框数据 31 enum { IDD = IDD_ABOUTBOX }; 32 33 protected: 34 virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 35 36 // 实现 37 protected: 38 DECLARE_MESSAGE_MAP() 39 }; 40 41 CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD) 42 { 43 } 44 45 void CAboutDlg::DoDataExchange(CDataExchange* pDX) 46 { 47 CDialogEx::DoDataExchange(pDX); 48 } 49 50 BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx) 51 END_MESSAGE_MAP() 52 53 54 // CRegeditDlg 对话框 55 56 57 58 CRegeditDlg::CRegeditDlg(CWnd* pParent /*=NULL*/) 59 : CDialogEx(CRegeditDlg::IDD, pParent) 60 , Reg_add(_T("")) 61 , ValueName(_T("")) 62 , ValueData(_T("")) 63 , ValueSearch(_T("")) 64 , MainPage(_T("")) 65 { 66 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); 67 } 68 69 void CRegeditDlg::DoDataExchange(CDataExchange* pDX) 70 { 71 CDialogEx::DoDataExchange(pDX); 72 DDX_Text(pDX, IDC_EDIT1, Reg_add); 73 // DDX_Text(pDX, IDC_EDIT2, Reg_change); 74 DDX_Text(pDX, IDC_EDIT3, ValueName); 75 DDX_Text(pDX, IDC_EDIT4, ValueData); 76 DDX_Control(pDX, IDC_COMBO1, m_COMBOX); 77 DDX_Text(pDX, IDC_EDIT2, ValueSearch); 78 DDX_Text(pDX, IDC_EDIT5, MainPage); 79 } 80 81 BEGIN_MESSAGE_MAP(CRegeditDlg, CDialogEx) 82 ON_WM_SYSCOMMAND() 83 ON_WM_PAINT() 84 ON_WM_QUERYDRAGICON() 85 ON_BN_CLICKED(IDC_BUTTON1, &CRegeditDlg::OnBnClickedButton1) 86 ON_BN_CLICKED(IDC_BUTTON2, &CRegeditDlg::OnBnClickedButton2) 87 ON_BN_CLICKED(IDC_BUTTON3, &CRegeditDlg::OnBnClickedButton3) 88 ON_CBN_SELCHANGE(IDC_COMBO1, &CRegeditDlg::OnCbnSelchangeCombo1) 89 ON_BN_CLICKED(IDC_BUTTON4, &CRegeditDlg::OnBnClickedButton4) 90 ON_BN_CLICKED(IDC_BUTTON5, &CRegeditDlg::OnBnClickedButton5) 91 ON_BN_CLICKED(IDC_BUTTON7, &CRegeditDlg::OnBnClickedButton7) 92 ON_BN_CLICKED(IDC_BUTTON6, &CRegeditDlg::OnBnClickedButton6) 93 ON_BN_CLICKED(IDC_BUTTON9, &CRegeditDlg::OnBnClickedButton9) 94 ON_BN_CLICKED(IDC_BUTTON10, &CRegeditDlg::OnBnClickedButton10) 95 END_MESSAGE_MAP() 96 97 98 // CRegeditDlg 消息处理程序 99 100 BOOL CRegeditDlg::OnInitDialog() 101 { 102 CDialogEx::OnInitDialog(); 103 104 // 将“关于...”菜单项添加到系统菜单中。 105 106 // IDM_ABOUTBOX 必须在系统命令范围内。 107 ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); 108 ASSERT(IDM_ABOUTBOX < 0xF000); 109 110 CMenu* pSysMenu = GetSystemMenu(FALSE); 111 if (pSysMenu != NULL) 112 { 113 BOOL bNameValid; 114 CString strAboutMenu; 115 bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX); 116 ASSERT(bNameValid); 117 if (!strAboutMenu.IsEmpty()) 118 { 119 pSysMenu->AppendMenu(MF_SEPARATOR); 120 pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); 121 } 122 } 123 124 // 设置此对话框的图标。 当应用程序主窗口不是对话框时,框架将自动 125 // 执行此操作 126 SetIcon(m_hIcon, TRUE); // 设置大图标 127 SetIcon(m_hIcon, FALSE); // 设置小图标 128 129 // TODO: 在此添加额外的初始化代码 130 131 return TRUE; // 除非将焦点设置到控件,否则返回 TRUE 132 } 133 134 void CRegeditDlg::OnSysCommand(UINT nID, LPARAM lParam) 135 { 136 if ((nID & 0xFFF0) == IDM_ABOUTBOX) 137 { 138 CAboutDlg dlgAbout; 139 dlgAbout.DoModal(); 140 } 141 else 142 { 143 CDialogEx::OnSysCommand(nID, lParam); 144 } 145 } 146 147 // 如果向对话框添加最小化按钮,则需要下面的代码 148 // 来绘制该图标。 对于使用文档/视图模型的 MFC 应用程序, 149 // 这将由框架自动完成。 150 151 void CRegeditDlg::OnPaint() 152 { 153 if (IsIconic()) 154 { 155 CPaintDC dc(this); // 用于绘制的设备上下文 156 157 SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0); 158 159 // 使图标在工作区矩形中居中 160 int cxIcon = GetSystemMetrics(SM_CXICON); 161 int cyIcon = GetSystemMetrics(SM_CYICON); 162 CRect rect; 163 GetClientRect(&rect); 164 int x = (rect.Width() - cxIcon + 1) / 2; 165 int y = (rect.Height() - cyIcon + 1) / 2; 166 167 // 绘制图标 168 dc.DrawIcon(x, y, m_hIcon); 169 } 170 else 171 { 172 CDialogEx::OnPaint(); 173 } 174 } 175 176 //当用户拖动最小化窗口时系统调用此函数取得光标 177 //显示。 178 HCURSOR CRegeditDlg::OnQueryDragIcon() 179 { 180 return static_cast<HCURSOR>(m_hIcon); 181 } 182 183 184 185 void CRegeditDlg::OnBnClickedButton1() 186 { 187 // 添加项 188 189 UpdateData(TRUE); 190 191 HKEY KEY = NULL; 192 DWORD dw; 193 CString data_add = TEXT("Regedit\\"); 194 if (Reg_add.GetLength() == 0) 195 { 196 MessageBox(_T("不能空,输入项名")); 197 return; 198 } 199 data_add += Reg_add; 200 201 if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_CONFIG, 202 data_add, 0, KEY_ALL_ACCESS, &KEY)) 203 { 204 MessageBox(_T("该项已存在!")); 205 return; 206 } 207 208 if (ERROR_SUCCESS == RegCreateKeyEx(HKEY_CURRENT_CONFIG, data_add, 0, NULL, REG_OPTION_NON_VOLATILE, 209 KEY_ALL_ACCESS, NULL, &KEY, &dw)) 210 { 211 MessageBox(_T("添加项成功!")); 212 } 213 else 214 { 215 MessageBox(_T("添加项失败!")); 216 } 217 218 UpdateData(FALSE); 219 } 220 221 void CRegeditDlg::OnBnClickedButton3() 222 { 223 // 删除项 224 UpdateData(TRUE); 225 226 CString data_add = TEXT("Regedit\\"); 227 if (Reg_add.GetLength() == 0) 228 { 229 MessageBox(_T("不能空,输入项名")); 230 return; 231 } 232 data_add += Reg_add; 233 234 if (ERROR_SUCCESS == RegDeleteKey(HKEY_CURRENT_CONFIG, data_add)) 235 MessageBox(_T("删除项成功!")); 236 237 UpdateData(FALSE); 238 } 239 240 void CRegeditDlg::OnBnClickedButton4() 241 { 242 //新建键值 243 UpdateData(TRUE); 244 245 HKEY KEY; 246 unsigned char *pData = (unsigned char*)ValueData.GetBuffer(ValueData.GetLength()); 247 /* 248 类型: 249 DWORD REG_DWORD 250 QWORD REG_QWORD 251 多字符串值 REG_MULTI_SZ 252 二进制值 REG_BINARY 253 可扩充字符串值 REG_EXPAND_SZ 254 字符串值(默认) REG_SZ 255 */ 256 DWORD nType = REG_SZ; 257 int TypeSelect; 258 TypeSelect = m_COMBOX.GetCurSel(); 259 /*测试用 260 CString STemp; 261 STemp.Format(_T("%d"), TypeSelect); 262 MessageBox(STemp);*/ 263 264 switch (TypeSelect) 265 { 266 case 0: nType = REG_DWORD; break; 267 case 1: nType = REG_QWORD; break; 268 case 2: nType = REG_MULTI_SZ; break; 269 case 3: nType = REG_BINARY; break; 270 case 4: nType = REG_EXPAND_SZ; break; 271 case 5: nType = REG_SZ; break; 272 default: 273 break; 274 } 275 CString data_add = TEXT("Regedit\\"); 276 if (Reg_add.GetLength() == 0) 277 { 278 MessageBox(_T("先选择项名")); 279 return; 280 } 281 data_add += Reg_add; 282 283 if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_CONFIG, 284 data_add, 0, KEY_ALL_ACCESS, &KEY)) 285 { 286 if (ERROR_SUCCESS == RegSetValueEx(KEY, ValueName, 0, nType, 287 pData, (DWORD)ValueData.GetLength()*2)) 288 { 289 MessageBox(_T("新建键值成功!")); 290 } 291 } 292 RegCloseKey(KEY); 293 294 UpdateData(FALSE); 295 } 296 297 void CRegeditDlg::OnBnClickedButton2() 298 { 299 // 删除键值 300 UpdateData(TRUE); 301 302 HKEY KEY; 303 CString data_add = TEXT("Regedit\\"); 304 if (Reg_add.GetLength() == 0) 305 { 306 MessageBox(_T("先选择项名")); 307 return; 308 } 309 data_add += Reg_add; 310 311 if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_CONFIG, 312 data_add, 0, KEY_ALL_ACCESS, &KEY)) 313 { 314 if (ERROR_SUCCESS == RegDeleteValue(KEY, (LPCTSTR)ValueName)) 315 { 316 MessageBox(_T("删除键值成功!")); 317 } 318 else 319 { 320 MessageBox(_T("删除失败,该值可能不存在")); 321 } 322 } 323 RegCloseKey(KEY); 324 325 UpdateData(FALSE); 326 } 327 328 void CRegeditDlg::OnBnClickedButton5() 329 { 330 // 键值查询 331 UpdateData(TRUE); 332 333 HKEY KEY; 334 unsigned char pValue[100]; 335 DWORD len = 100; 336 CString data_add = TEXT("Regedit\\"); 337 if (Reg_add.GetLength() == 0) 338 { 339 MessageBox(_T("先选择项名")); 340 return; 341 } 342 data_add += Reg_add; 343 344 if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_CONFIG, 345 data_add, 0, KEY_ALL_ACCESS, &KEY)) 346 { 347 // 不关心值项类型,设为NULL 348 if (ERROR_SUCCESS == RegQueryValueEx(KEY, (LPCTSTR)ValueSearch, 0, NULL, 349 (LPBYTE)pValue, &len)) 350 { 351 MessageBox(_T("OK,该键值存在")); 352 } 353 else 354 { 355 MessageBox(_T("键值不存在")); 356 } 357 } 358 RegCloseKey(KEY); 359 360 } 361 362 363 void CRegeditDlg::OnBnClickedButton7() 364 { 365 // 修改IE主页 366 UpdateData(TRUE); 367 HKEY KEY; 368 unsigned char* pData = (unsigned char*)MainPage.GetBuffer(); 369 370 if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("Software\\Microsoft\\Internet Explorer\\Main\\"), 371 0, KEY_ALL_ACCESS, &KEY)) 372 { 373 RegSetValueEx(KEY, TEXT("Search Page"), 0, REG_SZ, 374 (const BYTE*)pData, MainPage.GetLength() * 2); 375 RegSetValueEx(KEY, TEXT("Start Page"), 0, REG_SZ, 376 (const BYTE*)pData, MainPage.GetLength()*2); 377 RegSetValueEx(KEY, TEXT("Start Page Redirect Cache"), 0, REG_SZ, 378 (const BYTE*)pData, MainPage.GetLength() * 2); 379 } 380 else 381 { 382 MessageBox(_T("修改IE主页失败!")); 383 return; 384 } 385 386 if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("Software\\Microsoft\\Internet Explorer\\Main\\"), 387 0, KEY_ALL_ACCESS, &KEY)) 388 { 389 RegSetValueEx(KEY, TEXT("Search Page"), 0, REG_SZ, 390 (const BYTE*)pData, MainPage.GetLength() * 2); 391 RegSetValueEx(KEY, TEXT("Start Page"), 0, REG_SZ, 392 (const BYTE*)pData, MainPage.GetLength() * 2); 393 } 394 else 395 { 396 MessageBox(_T("修改IE主页失败!")); 397 return; 398 } 399 RegCloseKey(KEY); 400 401 MessageBox(_T("修改IE主页成功!")); 402 403 } 404 405 void CRegeditDlg::OnCbnSelchangeCombo1() 406 { 407 // TODO: 在此添加控件通知处理程序代码 408 } 409 410 void CRegeditDlg::OnBnClickedButton6() 411 { 412 // 注册表禁止访问 413 HKEY KEY; 414 DWORD Value = 1; 415 //HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\System 416 if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER, 417 TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System\\"), 418 0, KEY_ALL_ACCESS, &KEY)) 419 { 420 RegSetValueEx(KEY, TEXT("Disableregistrytools"), 0, REG_DWORD, (LPBYTE)&Value, sizeof(DWORD)); 421 MessageBox(_T("禁用注册表成功!")); 422 } 423 424 } 425 426 427 void CRegeditDlg::OnBnClickedButton9() 428 { 429 // 注册表允许访问 430 HKEY KEY; 431 DWORD Value = 0; 432 if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER, 433 TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System\\"), 434 0, KEY_ALL_ACCESS, &KEY)) 435 { 436 RegSetValueEx(KEY, TEXT("Disableregistrytools"), 0, REG_DWORD, (LPBYTE)&Value, sizeof(DWORD)); 437 MessageBox(_T("启用注册表成功!")); 438 } 439 } 440 441 /* 442 线程函数不能退出 443 不能独占cpu 444 */ 445 // 注册表监控线程函数 446 // 经过测试还不是很完善,有些 HKEY 项无法受到监控 447 static DWORD WINAPI ThreadFunc() 448 { 449 HANDLE hNotify[5]; 450 HKEY hKEY1, hKEY2, hKEY3, hKEY4, hKEY5; 451 DWORD ret; 452 453 if (ERROR_SUCCESS == 454 (RegOpenKeyEx(HKEY_CLASSES_ROOT, NULL, 455 0, KEY_NOTIFY, &hKEY1) || 456 RegOpenKeyEx(HKEY_CURRENT_USER, NULL, 457 0, KEY_NOTIFY, &hKEY2) || 458 RegOpenKeyEx(HKEY_LOCAL_MACHINE, NULL, 459 0, KEY_NOTIFY, &hKEY3) || 460 RegOpenKeyEx(HKEY_USERS, NULL, 461 0, KEY_NOTIFY, &hKEY4) || 462 RegOpenKeyEx(HKEY_CURRENT_CONFIG, NULL, 463 0, KEY_NOTIFY, &hKEY5)) 464 ); 465 else 466 { 467 AfxMessageBox(_T("RegOpenKeyEx 失败")); 468 return 0; 469 } 470 471 472 // 安全属性 是否手动重置 初始化状态 名称 473 hNotify[0] = CreateEvent(NULL, FALSE, FALSE, TEXT("RegistryNotify")); 474 hNotify[1] = CreateEvent(NULL, FALSE, FALSE, TEXT("RegistryNotify")); 475 hNotify[2] = CreateEvent(NULL, FALSE, FALSE, TEXT("RegistryNotify")); 476 hNotify[3] = CreateEvent(NULL, FALSE, FALSE, TEXT("RegistryNotify")); 477 hNotify[4] = CreateEvent(NULL, FALSE, FALSE, TEXT("RegistryNotify")); 478 if (hNotify[4] == 0) 479 { 480 AfxMessageBox(_T("CreateEvent 失败")); 481 return 0; 482 } 483 484 while (1) 485 { 486 /* 487 监听到指定注册表项变化,hEvent参数指定的事件会被触发为有信号状态 488 监听到变化该函数则自动结束退出 489 */ 490 RegNotifyChangeKeyValue(hKEY1, TRUE, 491 REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_LAST_SET, hNotify[0], TRUE); 492 RegNotifyChangeKeyValue(hKEY2, TRUE, 493 REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_LAST_SET, hNotify[1], TRUE); 494 RegNotifyChangeKeyValue(hKEY3, TRUE, 495 REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_LAST_SET, hNotify[2], TRUE); 496 RegNotifyChangeKeyValue(hKEY4, TRUE, 497 REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_LAST_SET, hNotify[3], TRUE); 498 RegNotifyChangeKeyValue(hKEY5, TRUE, 499 REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_LAST_SET, hNotify[4], TRUE); 500 501 ret = WaitForMultipleObjects(5, hNotify, NULL, INFINITE); 502 if (ret == WAIT_OBJECT_0 || (WAIT_OBJECT_0 + 1) || (WAIT_OBJECT_0 + 2) 503 || (WAIT_OBJECT_0 + 3) || (WAIT_OBJECT_0 + 4)) 504 { 505 AfxMessageBox(_T("!!有程序正在修改注册表")); 506 } 507 508 //// 监听单个事件 509 //if (WaitForSingleObject(hNotify1, INFINITE) == WAIT_OBJECT_0 || 510 // WaitForSingleObject(hNotify2, INFINITE) == WAIT_OBJECT_0 || 511 // WaitForSingleObject(hNotify3, INFINITE) == WAIT_OBJECT_0 || 512 // WaitForSingleObject(hNotify4, INFINITE) == WAIT_OBJECT_0 || 513 // WaitForSingleObject(hNotify5, INFINITE) == WAIT_OBJECT_0 514 // ) 515 //{ 516 // AfxMessageBox(_T("!!有程序正在修改注册表")); 517 //} 518 } 519 520 CloseHandle(hNotify[0]); 521 CloseHandle(hNotify[1]); 522 CloseHandle(hNotify[2]); 523 CloseHandle(hNotify[3]); 524 CloseHandle(hNotify[4]); 525 RegCloseKey(hKEY1); 526 RegCloseKey(hKEY2); 527 RegCloseKey(hKEY3); 528 RegCloseKey(hKEY4); 529 RegCloseKey(hKEY5); 530 return 0; 531 } 532 533 void CRegeditDlg::OnBnClickedButton10() 534 { 535 // 注册表监控进程 536 537 /* 538 第一个参数表示线程内核对象的安全属性,一般传入NULL表示使用默认设置 539 第二个参数表示线程栈空间大小,传入0表示使用默认大小(1MB) 540 第三个参数表示新线程所执行的线程函数地址,多个线程可以使用同一个函数地址 541 第四个参数是传给线程函数的参数 542 第五个参数指定额外的标志来控制线程的创建,为0表示线程创建之后立即就可以进行调度, 543 如果为CREATE_SUSPENDED则表示线程创建后暂停运行,这样它就无法调度,直到调用ResumeThread() 544 第六个参数将返回线程的ID号,传入NULL表示不需要返回该线程ID号 545 函数返回值: 546 成功返回新线程的句柄,失败返回NULL 547 548 线程函数需要静态成员函数或全局函数 549 */ 550 HANDLE hThread = CreateThread(NULL, 0, 551 (LPTHREAD_START_ROUTINE)ThreadFunc, 552 NULL, 0, NULL); 553 MessageBox(_T("注册表监控已打开!")); 554 555 CloseHandle(hThread); 556 }