Send a WM_SETTINGCHANGE Broadcast to all Windows

    Args:

        message (str):
            A string value representing the portion of the system that has been
            updated and needs to be refreshed. Default is ``Environment``. These
            are some common values:

            - "Environment" : to effect a change in the environment variables
            - "intl" : to effect a change in locale settings
            - "Policy" : to effect a change in Group Policy Settings
            - a leaf node in the registry
            - the name of a section in the ``Win.ini`` file

            See lParam within msdn docs for
            `WM_SETTINGCHANGE <https://msdn.microsoft.com/en-us/library/ms725497%28VS.85%29.aspx>`_
            for more information on Broadcasting Messages.

            See GWL_WNDPROC within msdn docs for
            `SetWindowLong <https://msdn.microsoft.com/en-us/library/windows/desktop/ms633591(v=vs.85).aspx>`_
            for information on how to retrieve those messages.

    .. note::
        This will only affect new processes that aren't launched by services. To
        apply changes to the path or registry to services, the host must be
        restarted. The ``salt-minion``, if running as a service, will not see
        changes to the environment until the system is restarted. Services
        inherit their environment from ``services.exe`` which does not respond
        to messaging events. See
        `MSDN Documentation <https://support.microsoft.com/en-us/help/821761/changes-that-you-make-to-environment-variables-do-not-affect-services>`_
        for more information.

    CLI Example:

    ... code-block:: python

        import salt.utils.win_functions
        salt.utils.win_functions.broadcast_setting_change('Environment')

def broadcast_setting_change(message='Environment'):
    '''
    Send a WM_SETTINGCHANGE Broadcast to all Windows

    Args:

        message (str):
            A string value representing the portion of the system that has been
            updated and needs to be refreshed. Default is ``Environment``. These
            are some common values:

            - "Environment" : to effect a change in the environment variables
            - "intl" : to effect a change in locale settings
            - "Policy" : to effect a change in Group Policy Settings
            - a leaf node in the registry
            - the name of a section in the ``Win.ini`` file

            See lParam within msdn docs for
            `WM_SETTINGCHANGE <https://msdn.microsoft.com/en-us/library/ms725497%28VS.85%29.aspx>`_
            for more information on Broadcasting Messages.

            See GWL_WNDPROC within msdn docs for
            `SetWindowLong <https://msdn.microsoft.com/en-us/library/windows/desktop/ms633591(v=vs.85).aspx>`_
            for information on how to retrieve those messages.

    .. note::
        This will only affect new processes that aren't launched by services. To
        apply changes to the path or registry to services, the host must be
        restarted. The ``salt-minion``, if running as a service, will not see
        changes to the environment until the system is restarted. Services
        inherit their environment from ``services.exe`` which does not respond
        to messaging events. See
        `MSDN Documentation <https://support.microsoft.com/en-us/help/821761/changes-that-you-make-to-environment-variables-do-not-affect-services>`_
        for more information.

    CLI Example:

    ... code-block:: python

        import salt.utils.win_functions
        salt.utils.win_functions.broadcast_setting_change('Environment')
    '''
    # Listen for messages sent by this would involve working with the
    # SetWindowLong function. This can be accessed via win32gui or through
    # ctypes. You can find examples on how to do this by searching for
    # `Accessing WGL_WNDPROC` on the internet. Here are some examples of how
    # this might work:
    #
    # # using win32gui
    # import win32con
    # import win32gui
    # old_function = win32gui.SetWindowLong(window_handle, win32con.GWL_WNDPROC, new_function)
    #
    # # using ctypes
    # import ctypes
    # import win32con
    # from ctypes import c_long, c_int
    # user32 = ctypes.WinDLL('user32', use_last_error=True)
    # WndProcType = ctypes.WINFUNCTYPE(c_int, c_long, c_int, c_int)
    # new_function = WndProcType
    # old_function = user32.SetWindowLongW(window_handle, win32con.GWL_WNDPROC, new_function)
    broadcast_message = ctypes.create_unicode_buffer(message)
    user32 = ctypes.WinDLL('user32', use_last_error=True)
    result = user32.SendMessageTimeoutW(HWND_BROADCAST, WM_SETTINGCHANGE, 0,
                                        broadcast_message, SMTO_ABORTIFHUNG,
                                        5000, 0)
    return result == 1