如何以WM_SETTINGCHANGE响应的AutoHotkey的脚本

问题描述:

内(这个问题类似于Delphi: How to respond to WM_SettingChange/WM_WinIniChange?但对于AutoHotKey语言,这是不是从里面的AutoHotkey发送WM_SETTINGCHANGE。)如何以WM_SETTINGCHANGE响应的AutoHotkey的脚本

在另一个Windows进程(“发件人”),我通过修改HK_CURRENT_USER注册表来更改PATH环境变量。然后,我使用SendMessageTimeout API发送/发布WM_SETTINGCHANGE消息。

我同时运行的AutoHotKey脚本(“接收器”),我用作程序启动器,似乎没有意识到这种变化。我想要捕获此消息以刷新脚本的PATH变量的本地副本。可能吗?

例如, “发件人” 可能是System Properties dialog box,或一些another AutoHotKey script

EnvUpdate 

或其他一些方便的第三方Windows二进制像nircmd

nircmd sysrefresh environment 

或一些Ruby code

### This is a -*- ruby -*- script 
require 'Win32API' 

module Windows::EnvByReg 
    def self.envupdate() 
    result = 0 
    wParam_unused = 0 
    timeout_ms = 5000 
    SendMessageTimeout.call(HWND_BROADCAST, WM_SETTINGCHANGE, 
          wParam_unused, 'Environment', 
          SMTO_ABORTIFHUNG, timeout_ms, result) 
    end 
    SendMessageTimeout = Win32API.new('user32', 'SendMessageTimeout', 
            'LLLPLLP', 'L') 
    HWND_BROADCAST = 0xffff 
    WM_SETTINGCHANGE = 0x001A 
    SMTO_ABORTIFHUNG = 2 
end#module 

if __FILE__ == $PROGRAM_NAME 
    Windows::EnvByReg.envupdate 
end 

使用OnMessage函数来响应消息。

以下是一个示例脚本。

;;; This is an AutoHotKey -*- ahk -*- script 
;;; 
;;; ABOUT 
;;; Respond to WM_SETTINGCHANGE messages and update this process's PATH 
;;; environment variable. 
;;; 
;;; USAGE 
;;; Run the script directly (e.g. double-click) or drag and drop onto 
;;; the AutoHotKey application. 
;;; 
;;; DEBUG 
;;; Optionally define a key binding to debug_show_recv_count, e.g.: 
;;; #space:: debug_show_recv_count() 
;;; 
;;; AUTHOR 
;;; piyo @ StackOverflow 
;;; 

;; 
;; Register an AHK function as a callback. 
;; 
OnMessage((WM_SETTINGCHANGE:=0x1A), "recv_WM_SETTINGCHANGE") 

;; 
;; Respond to the WM_SETTINGCHANGE message. 
;; 
recv_WM_SETTINGCHANGE(wParam, lParam, msg, hwnd) 
{ 
    global g_recv_WM_SETTINGCHANGE_count 
    g_recv_WM_SETTINGCHANGE_count := g_recv_WM_SETTINGCHANGE_count + 1 
    ;;debug;; ToolTip Received a WM_SETTINGCHANGE ! 
    reset_env_path_from_registry() 
} 

;; 
;; Import the recently changed Path environment variable from the 
;; Windows Registry. Import from the System and User environments. 
;; 
reset_env_path_from_registry() 
{ 
    sys_path := "" 
    sys_subkey := "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" 
    RegRead, sys_path, HKEY_LOCAL_MACHINE, %sys_subkey%, Path 
    cu_path := "" 
    cu_subkey := "Environment" 
    RegRead, cu_path, HKEY_CURRENT_USER, %cu_subkey%, Path 
    new_path := sys_path . ";" . cu_path 
    ;;debug;; MsgBox,% new_path 
    EnvSet, PATH,% new_path 
} 

;;; 

; Debug var for interactive sanity checking 
g_recv_WM_SETTINGCHANGE_count := 0 

; Debug function for interactive sanity checking 
debug_show_recv_count() { 
    global g_recv_WM_SETTINGCHANGE_count 
    path := "" 
    EnvGet, path, PATH 
    msg := "g_recv_WM_SETTINGCHANGE := " . g_recv_WM_SETTINGCHANGE_count 
    msg := msg . "!`n" . path 
    MsgBox,% msg 
} 

;;; end 

上AutoHotkey的论坛用户NoobSawce张贴了这个function to refresh environment variables

我的AutoHotKey.ahk脚本在每个运行语句之前调用该函数,以便从AutoHotKey启动的任何应用程序获取当前系统环境,而不是AutoHotKey在启动时捕获的环境。

例如:

+#b:: 
RefreshEnvironment() 
run c:\cygwin\bin\run.exe c:\cygwin\bin\rxvt.exe -geometry 80x40 
return 

+#g:: 
RefreshEnvironment() 
run c:\gnu\emacs\bin\runemacs.exe 
return