zoukankan      html  css  js  c++  java
  • 利用Delphi监视注册表的变化

    转帖:利用Delphi监视注册表的变化 2009-12-23 11:53:51

    分类:

    利用Delphi监视注册表的变化
     
        我们在编写软件的时候,常常需要把一些信息保存到系统的注册表中。如果用户更改了注册表的信息,我们如何及时知道,并做相应的处理呢?通过研究,我们发现 在Win98以上操作系统中,微软在SDK函数库中增加了RegNotifyChangeKeyValue函数,用于监视注册表特定键值的变化。下面我们 就怎样用Delphi编一个注册表监视器,做详细地探讨。
     
    关于注册表监视函数
       下面是注册表监视函数地声明:
    function RegNotifyChangeKeyValue(
       hKey : HKEY,             // 需要监视地注册表键
       bWatchSubtree : LongBool,  // 是否监视其子键
       dwNotifyFilter : Cardinal,   //  监视键变化的类型  
       hEvent : Cardinal,               // 当有变化时所触发的通知事件句柄
       fAsynchronous : LongBool  // 异步通知事件标志
       ) : integer;
        根据MSDN中对该函数的描述,我们对其参数做一下描述:
        hKey --我们所要监视的目标键值句柄,它必须是已经被打开的。要打开一个注册表键可以利用Tregistry 中的OpenKeyReadOnly函数。
        dwNotifyFilter ――是一组标志集合,用于标识我们需要监视的变化类型,它们包括: 
        REG_NOTIFY_CHANGE_NAME – 增加或删除了子键
        REG_NOTIFY_CHANGE_ATTRIBUTES – 改变了键的属性
        REG_NOTIFY_CHANGE_LAST_SET – 键值发生了改变
        REG_NOTIFY_CHANGE_SECURITY -键的安全属性发生了改变
        hEvent ――当有变化时所触发的通知事件句柄。我们可以利用SDK函数CreateEvent来创建一个事件。
        fAsynchronous ――以异步方式触发事件标志。
       
    现在我们已经对如何利用该函数有了大体的了解:
    1.打开需要监视的注册表键
    2.创建触发事件
    3.调用注册表监视函数,等待事件触发。
      如果等待事件触发在主界面中实现,就会造成界面堵塞。一个解决办法就是,等待事件触发在线程中实现。
     
    在线程中实现注册表的监视
        在Delphi下进行多现成程序设计并不需要去学习庞大的Win32 API函数,我们可以利用Delphi标准的多线程类Tthread来完成我们的工作。
        Tthread是一个抽象类――一个带有虚拟抽象方法的类,不能直接使用它。要做的是把Tthread作为基类,用继承的形式来生成子类。实际上,根据TThread来写线程应用是非常容易的。
        1.  无论何时创建一个TThread对象,首先要创建它的派生类。
        2.  每次创建一个TThread对象的派生类的时候,都要重载Execute方法。
        我们可以利用Delphi的向导,来生成创建TThread派生类的代码:
    选择Delphi的File菜单下的New选项,再选择“TThread Object”项目,Delphi就会构造基本的程序模块,然后我们再根据需要做相应修改。如下图我们构建了一个注册表监视线程:
     
        下面我们看看该线程是如何实现对注册表的监视的:
     
    procedure TRegMonitorThread.Execute;
    begin
      InitThread;   // 打开注册表键,创建通知事件
      while not Terminated do
      begin
        if WaitForSingleObject(FEvent, INFINITE) = WAIT_OBJECT_0 then
        begin
          fChangeData.RootKey := RootKey;
          fChangeData.Key := Key;
          SendMessage(Wnd, WM_REGCHANGE,
                      RootKey, LongInt(PChar(Key)));
          ResetEvent(FEvent);   // Fevent对象复位,等待再次被触发
         RegNotifyChangeKeyValue(FReg.CurrentKey, 1, Filter, FEvent, 1);
        end;
      end;
    end;
        我们可以看到,Execute 过程实际上是一个循环,结束的条件是进程退出。在循环中,调用WaitForSingleObject API函数进入等待状态,直到FEvent 对象变为有信号状态。可以看出我们所等待的Fevent ,RegNotifyChangeKeyValue  曾经调用。
        注意,Fevent 被触发后,我们用SendMessage 发送消息到主窗口,下面我们对此做详细讨论。
    利用自定义消息传递监视信息

    利用自定义消息传递监视信息
        消息是Windows发出的一个通知,它告诉应用程序某个事件发生了。在Delphi中,大多数情况下Windows的消息被封装在VCL的事件中,我们 只需处理相应的VCL事件就可以了,但如果我们需要利用自己定义的消息实现某些功能,再Delphi中是如何实现的呢?下面我们看看是如何利用自定义消息 传递监视信息的:
        1.  首先定义自定义休息WM_REGCHANGE:
    WM_REGCHANGE  = WM_USER + 1973;
        2.  声明主窗体中消息响应应函数:
    procedure WMREGCHANGE(var Msg : TMessage); message WM_REGCHANGE;
        3.  实现消息响应函数:
     
    procedure TForm1.WMREGCHANGE(var Msg: TMessage);
    begin
     with Memo1.Lines  do
     begin
      Add('-----------------------------------');
      Add('Registry change at ' + DateTimeToStr(Now));
      Add(IntToStr(RegMonitorThread.ChangeData.RootKey) +
          ' - ' + RegMonitorThread.ChangeData.Key);
     end;
    end;
        我们在主界面上放了一个TMemo控件,用于显示注册表监视信息,在消息响应函数中,监视信息在TMemo控件中的显示。

    本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/oury/archive/2005/04/12/343722.aspx
  • 相关阅读:
    面试题--十进制转换成2进制
    c++基础--如何将函数作为参数传递
    面试题--完全二叉树的的最后一层的最右节点
    数据库原理--故障恢复
    数据库原理--事务并发控制
    数据库原理--事务(一)
    数据库原理--1nf 2nf 3nf
    数据库原理--外键和主键
    数据库原理--函数依赖和范式
    人人都有极客精神
  • 原文地址:https://www.cnblogs.com/edwardsun/p/3506583.html
Copyright © 2011-2022 走看看