レジストリキーの変更を監視          <TOP>


RegOpenKeyEx レジストリのキーのハンドルを確保
RegNotifyChangeKeyValue レジストリキーの変更を通知
CreateEvent イベントオブジェクトを作成
WaitForSingleObject 指定された時間が経過するまでスレッドをスリープ
CloseHandle オープンされているオブジェクトハンドルをクローズ
RegCloseKey レジストリのハンドルを解放


例では、10秒間のタイムアウト時間を設けその間にレジストリに変化があれば即通知、無ければタイムアウトと表示されます。

 

'================================================================
'= レジストリキーの変更を監視
'=    (RegNotifyChangeKeyValue.bas)
'================================================================
#include "Windows.bi"

Type SECURITY_ATTRIBUTES
    nLength              As Long
    lpSecurityDescriptor As Long
    bInheritHandle       As Long
End Type

#define HKEY_CURRENT_USER -2147483647   '現在Windowsにログインしているユーザーの情報
#define REG_NOTIFY_CHANGE_LAST_SET &H4  'キー内のレジストリエントリの変更が発生したとき、呼び出しへの通知

#define KEY_READ &H20019                '((&H20000 Or &H1 Or &H8 Or &H10) And (Not &H100000))
#define KEY_WRITE &H20006               '((&H20000 Or &H2 Or &H4) And (Not &H100000))
#define KEY_ALL_ACCESS &HF003F          '

#define WAIT_ABANDONED &H80             '放棄されたためにミューテックスオブジェクトがシグナル状態になったことを示す
#define WAIT_FAILED &HFFFFFFFF          'エラーが発生したことを示す
#define WAIT_OBJECT_0 &H0               'オブジェクトがシグナル状態になったことを示す
#define WAIT_TIMEOUT &H102              'タイムアウト時間が経過したことを示す
#define vbNullString byval 0            '値0の文字列。値0を持つ文字列。空文字列ではない

' レジストリのキーのハンドルを確保
Declare Function Api_RegOpenKeyEx& Lib "advapi32" Alias "RegOpenKeyExA" (ByVal hKey&, ByVal lpSubKey$, ByVal ulOptions&, ByVal samDesired&, phkResult&)

' レジストリキーの変更を通知
Declare Function Api_RegNotifyChangeKeyValue& Lib "advapi32" Alias "RegNotifyChangeKeyValue" (ByVal hKey&, ByVal bWatchSubtree&, ByVal dwNotifyFilter&, ByVal hEvent&, ByVal fAsynchronous&)

' イベントオブジェクトを作成
Declare Function Api_CreateEvent& Lib "Kernel32" Alias "CreateEventA" (lpEventAttributes As SECURITY_ATTRIBUTES, ByVal bManualReset&, bInitialState&, ByVal lpName$)

' 指定されたカーネルオブジェクトがシグナル状態になるか、指定された時間が経過するまでスレッドをスリープ
Declare Function Api_WaitForSingleObject& Lib "Kernel32" Alias "WaitForSingleObject" (ByVal hHandle&, ByVal dwMilliseconds&)

' オープンされているオブジェクトハンドルをクローズ
Declare Function Api_CloseHandle& Lib "Kernel32" Alias "CloseHandle" (ByVal hObject&)

' レジストリのハンドルを解放
Declare Function Api_RegCloseKey& Lib "advapi32" Alias "RegCloseKey" (ByVal hKey&)

Var Shared text(3) As Object
Var Shared Button1 As Object

For i = 0 To 3
    Text(i).Attach GetDlgItem("Text" & Trim$(Str$(i + 1)))
    Text(i).SetFontSize 14
Next
Button1.Attach GetDlgItem("Button1") : Button1.SetFontSize 14

'================================================================
'=
'================================================================
Declare Sub Button1_on edecl ()
Sub Button1_on()
    Var KeyName As String
    Var hRegistryKey As Long
    Var EventHandle As Long
    Var sa As SECURITY_ATTRIBUTES
    Var Timeout As Long
    Var Ret As Long

    'ラベルをクリア
    Text(3).SetWindowText ""

    'レジストリキーの名前を指定
    KeyName = "gTips"
    Text(2).SetWindowText KeyName

    'レジストリキーをオープン
    Ret = Api_RegOpenKeyEx(HKEY_CURRENT_USER, KeyName, 0, KEY_READ, hRegistryKey)

    'イベントオブジェクトを作成
    EventHandle = Api_CreateEvent(sa, 1, 0, vbNullString)

    'レジストリキーの変更を監視
    Ret = Api_RegNotifyChangeKeyValue(hRegistryKey, 0, REG_NOTIFY_CHANGE_LAST_SET, EventHandle, 1)

    'タイムアウト時間を指定
    Timeout = 10000

    'オブジェクトのシグナル状態を監視
    Ret = Api_WaitForSingleObject(EventHandle, Timeout)

    '制御を戻す原因となったイベントを表示
    Select Case Ret
        Case WAIT_ABANDONED
            Text(3).SetWindowText "未開放ミューテックスオブジェクト"
        Case WAIT_FAILED
            Text(3).SetWindowText  "待機失敗"
        Case WAIT_OBJECT_0
            Text(3).SetWindowText  "変更通知を受信"
        Case WAIT_TIMEOUT
            Text(3).SetWindowText  "タイムアウト"
    End Select

    'イベントオブジェクトを閉じる
    Ret = Api_CloseHandle(EventHandle)

    'レジストリキーをクローズ
    Ret = Api_RegCloseKey(hRegistryKey)
End Sub

'================================================================
'=
'================================================================
While 1
    WaitEvent
Wend
Stop
End