Export (0) Print
Expand All

RegistryNotifyCallback (Compact 2013)

3/28/2014

This function registers a transient notification request. It is used to request that the caller be notified by a specified callback when a specified value has been changed.


HRESULT WINAPI RegistryNotifyCallback(
  HKEY hKey,
  LPCTSTR pszSubKey,
  LPCTSTR pszValueName,
  REGISTRYNOTIFYCALLBACK pfnRegistryNotifyCallback,
  DWORD dwUserData,
  NOTIFICATIONCONDITION * pCondition,
  HREGNOTIFY * phNotify
);

hKey

[in] Handle to a currently open key, or a predefined root value.

pszSubKey

[in] The key under which the value is stored. If this value is NULL, pszValueName is assumed to be under hKey.

pszValueName

[in] The name of the value on which change notifications are requested. If this value is NULL, it indicates the default value.

dwUserData

[in] User data that will be passed back to the user with the notification.

pfnRegistryNotifyCallback

[in] A pointer to a function that will be called back when a notification arrives. For a prototype for this function, see REGISTRYNOTIFYCALLBACK.

pCondition

[in] Condition that determines when to send the notification. When the comparison between pCondition and the new registry value is TRUE, then a notification is sent. If this value is NULL, any change results in a notification.

phNotify

[out] Receives the handle to the notification request. This handle should be closed using RegistryCloseNotification when notifications on this key are no longer needed. Resetting the device also stops the notification.

Value

Description

S_OK

Request for change notification is registered.

E_INVALIDARG

Invalid hKey, phNotify, or pfnRegistryNotifyCallback.

An error value returned.

Error value wrapped as a FACILITY_WIN32 HRESULT.

The client will be notified of changes via the callback, which is executed on private thread separate from the thread that called RegistryNotifyCallback.

If the value does not exist at the time of the call to RegistryNotifyCallback, the client will be notified when the value is added.

To stop notification and to close the notification handle, the caller must call RegistryCloseNotification. However, this type of notification is transient. Resetting the device stops the notification.

This function can be used to monitor any registry key in the system. The header file snapi.h contains definitions for the registry keys, paths, values, and bitmasks for all the base notifications that are provided by the system.

If the notification to the callback function fails, the notification will be removed.

If the key specified by hKey and pszSubKey doesn't exist, then hKey is monitored until pszSubKey is created, after which pszSubKey is monitored and changes to the key will trigger notifications as requested. To minimize possible performance degradation stemming from a large nuimber of subkeys being monitored, it is a best practice to pass (as hKey) the handle to a key that's as close as possible to pszSubKey rather than passing a root key. For example, if the client is a game and it is monitoring the key structure HKEY_CURRENT_USER\...\MyCoolGame\Player1 and the game could later create HKEY_CURRENT_USER\...\MyCoolGame\Player2, two possible ways to approach notification of changes to the Player2 key include:

Potential performance degradation

Fewer potential problems

hKey = handle to HKEY_CURRENT_USER andpszSubKey=the full path to Player2

hKey = handle to HKEY_CURRENT_USER\...\MyCoolGame\ andpszSubKey=Player2

The following code example demonstrates how to use RegistryNotifyCallback.

Ee487978.note(en-us,WinEmbedded.80).gifNote:
To make the following code example easier to read, security checking and error handling are not included. This code example should not be used in a release configuration unless it has been modified to include them.
void AdjustPowerConsumption(HREGNOTIFY hNotify, DWORD dwUserData, const PBYTE pData, const UINT cbData);
// Register to be notified of changes to the eighth bit
// in SN_POWERBATTERYSTATE_VALUE. The eighth bit is set to one when 
// the battery is critically low (and set to zero and when it is not).
HRESULT RegistryNotifyCallbackExample()
{
    NOTIFICATIONCONDITION nc;
    HRESULT hr         = S_OK;
    HREGNOTIFY hNotify = NULL;
    // Initialize the notification structure.
    // The mask for the eighth bit.
    nc.dwMask = 0x8;
    // Receive a notification whenever that bit toggles.
    nc.ctComparisonType = REG_CT_ANYCHANGE;
    // dw is ignored for REG_CT_ANYCHANGE.
    nc.TargetValue.dw = 0;
    
    hr = RegistryNotifyCallback(SN_POWERBATTERYSTATE_ROOT, 
                                SN_POWERBATTERYSTATE_PATH, 
                                SN_POWERBATTERYSTATE_VALUE, 
                                AdjustPowerConsumption, 
                                0, 
                                &nc, 
                                &hNotify);
    // Close the notification using RegistryCloseNotification when done.
    // Note that it is alright to call RegistryCloseNotification from the callback function.
    // hr = RegistryCloseNotification(hNotify);
    return hr;
}
// This is the callback function.
void AdjustPowerConsumption(HREGNOTIFY hNotify, DWORD dwUserData, const PBYTE pData, const UINT cbData)
{
    DWORD dwCritical;
    HRESULT hr = S_OK;
    // pData contains the new value for SN_POWERBATTERYSTATE_VALUE.
    dwCritical = (*(DWORD*) pData);
    // Extract the eighth bit.
    dwCritical = dwCritical & 0x8; 
critically low.
    {
 your statements for preserving energy, here.
    }
    // The battery level was critically low, but it is not now.
    else
    {
        // Add your statements for returning to the normal battery state, here.
    }
}

The following code example demonstrates how to register transient notification requests for phone StatStore values.

Ee487978.note(en-us,WinEmbedded.80).gifNote:
To make the following code example easier to read, security checking and error handling are not included. This code example should not be used in a release configuration unless it has been modified to include them.
#include <regext.h>
#include "snapi.h"
const TCHAR c_szPhoneRegistryRootkey[]      = TEXT("System\\State");
const TCHAR c_szPhoneRegistrySubkey[]       = TEXT("Phone");
const TCHAR c_szPhoneSignalStrength[]       = TEXT("Signal Strength");
const TCHAR c_szPhoneIncomingCallerNumber[] = TEXT("Incoming Caller Number");
const TCHAR c_szPhoneStatus[]               = TEXT("Status");
#define MAX_NOTIF 3
enum NotifType
{
      SignalStrength = 0,
      IncomingCallerNumber,
      PhoneRoaming
};
HREGNOTIFY g_hRegNotify[ MAX_NOTIF ] ;
// The call-back function for Registry Notifications.
void RegistryNotifyCallbackFunc(HREGNOTIFY hNotify, DWORD dwUserData, const PBYTE pData, const UINT cbData)
{
    TCHAR szOutput[MAX_PATH];
    // Identify the Notification received, based upon the User Data passed in, while registering for the notification.
    switch( dwUserData )
    {
        case SignalStrength:
            StringCchPrintf(szOutput, MAX_PATH, _T("The Signal Strength is %d"), (DWORD) *pData);
            break;
        case IncomingCallerNumber:
            StringCchPrintf(szOutput, MAX_PATH, _T("The Incoming Caller Number is %s"), (TCHAR*)pData);
            break;
        case PhoneRoaming:
            {
                  DWORD dw = 0;
                  // Copy the data sent to us into a local buffer.
                  memcpy(&dw, pData, cbData);
                  // Find out if the roaming status has been set by logically ANDing the data with the value 512 (the bitmask for roaming).
                  StringCchPrintf(szOutput, MAX_PATH, _T("The Roam Status of the Phone is %s"), ( dw & SN_PHONEROAMING_BITMASK ) == SN_PHONEROAMING_BITMASK  ? _T("TRUE") : _T("FALSE")  );
            }
            break;
        default :
            break;
    }
    OutputDebugString( szOutput );
    return;
}
void RegisterForPhoneNotifications()
{
    HKEY hKey;
    // Let us open the registry to get a handle to the Phone Registry key.
    if (S_OK == RegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szPhoneRegistryRootkey, 0,  KEY_QUERY_VALUE, &hKey))
    {
    // Since we are registering for multiple notifications, let's pass some unique User Data for each notification ( 5th param ), 
    // which will help us identify the notification in the Call Back.
     // Let us register for Signal strength notifications.
     HRESULT hr = RegistryNotifyCallback(hKey, 
                                         c_szPhoneRegistrySubkey,
                                         c_szPhoneSignalStrength,
                                         RegistryNotifyCallbackFunc,
                                         SignalStrength,
                                         NULL,
                                         &g_hRegNotify[ SignalStrength ] );
        
    // Let us register for Incoming Caller Number notifications.
            hr = RegistryNotifyCallback(hKey, 
                                        c_szPhoneRegistrySubkey,
                                        c_szPhoneIncomingCallerNumber,
                                        RegistryNotifyCallbackFunc,
                                        IncomingCallerNumber,
                                        NULL,
                                        &g_hRegNotify [ IncomingCallerNumber ] );
    //  Let us register for Roaming status change notifications.
            hr = RegistryNotifyCallback(hKey, 
                                        c_szPhoneRegistrySubkey,
                                        c_szPhoneStatus,
                                        RegistryNotifyCallbackFunc,
                                        PhoneRoaming,
                                        NULL,
                                        &g_hRegNotify [ PhoneRoaming ] );
        RegCloseKey(hKey);
      
    }
}
void  CloseAllNotifications ()
{
     for (int i = 0; i < MAX_NOTIF; i++)
    {
            RegistryCloseNotification(g_hRegNotify[i]);
    }
}

Header

regext.h

Library

coredll.lib

Show:
© 2014 Microsoft