Invalid callback function When convert v1 script into v2

Get help with using AutoHotkey (v2 or newer) and its commands and hotkeys
reborn
Posts: 10
Joined: 23 Jun 2019, 06:44

Invalid callback function When convert v1 script into v2

27 Apr 2024, 09:30

I fount this script from forum that suit me need, but I'm using v2 so I convert it into v2 script with AHK-v2-script-converter.

I run into an error says:

Code: Select all

Error: Invalid callback function.

	016: DllCall("RegisterShellHookWindow", "UInt", Hwnd)
	017: MsgNum := DllCall("RegisterWindowMessage", "Str", "SHELLHOOK")
▶	018: OnMessage(MsgNum, ShellMessage)
	019: Return
	021: {
I tried modified the funciton ShellMessage into ShellMessage(wParam, lParam, *), it worked once but whenever i switch focuing windows or switch IME the script reports another error:

Code: Select all

Error: Target window not found.

Specifically: ahk_id 8

	019: Return
	021: {
▶	022: title := WinGetTitle("ahk_id " lParam)
	024: If (wParam = 4 || wParam = 32772)
	024: {

It looks like the lParam get different value between v1 and v2? Can somebody help me fix this error?

This is the script:

Code: Select all

; =====================================================================
; You can use the function at the end of the code to find the ID of the current keyboard layout language.
	; Cultures can be fetched from here: https://msdn.microsoft.com/en-us/library/windows/desktop/dd318693(v=vs.85).aspx
	; They must be set twice in the language ID;
	;   Ar-TN: "0xf0291c01" this is the ID for the Arabic Tunisia keyboard layout language.
	;   En-US: "0x4090409" this is the ID for the English US keyboard layout language.
  global DefaultLanguage := "Ar-TN"
  global DefaultLanguageIndentifier := "0xf0291c01"
  global SecondaryLanguage := "En-US"
  global SecondaryLanguageIndentifier := "0x4090409"
  global SecondaryLanguageWindowTitles := "Visual Studio"
  ; And the code itself (you should not have to change this)
  Gui +LastFound 
  hWnd := WinExist()
  DllCall( "RegisterShellHookWindow", UInt,Hwnd )
  MsgNum := DllCall( "RegisterWindowMessage", Str,"SHELLHOOK" )
  OnMessage( MsgNum, "ShellMessage" )
  Return
  ShellMessage( wParam,lParam )
  {
   WinGetTitle, title, ahk_id %lParam%
  ; 4 is HSHELL_WINDOWACTIVATED, 32772 is HSHELL_RUDEAPPACTIVATED
   If (wParam=4 || wParam=32772) {
    If title contains %SecondaryLanguageWindowTitles%
      SetKeyboard( title, SecondaryLanguage )
    Else
      SetKeyboard( title, DefaultLanguage )
   }
  }
  SetKeyboard( title, culture )
  {
    ; 0x50 is WM_INPUTLANGCHANGEREQUEST.
    Try
    {
      If (culture = SecondaryLanguage)
      {
        PostMessage, 0x50, 0, %SecondaryLanguageIndentifier%,, A
        ; To debug:
        ; ToolTip, Using secondary language %SecondaryLanguage%
        ; Sleep 1000
        ; ToolTip
      }
      Else (culture = DefaultLanguage)
      {
        PostMessage, 0x50, 0, %DefaultLanguageIndentifier%,, A
        ; To debug:
        ; ToolTip, Using default language %DefaultLanguage%
        ; Sleep 1000
        ; ToolTip
      }

}
}
; .....................................................................
;  You can use this to find the id of the current language:
 ^i::MsgBox, % GetDefaultKeyboard()
;  get default keyboard language
 GetDefaultKeyboard() {
   ThreadID := DllCall("GetWindowThreadProcessId", "UInt", WinExist("A"), "UInt", 0)
   InputLocaleID := DllCall("GetKeyboardLayout", "UInt", ThreadID, "UInt")
   return Format("{:#x}", InputLocaleID)
 }
; =====================================================================
User avatar
mikeyww
Posts: 27130
Joined: 09 Sep 2014, 18:38

Re: Invalid callback function When convert v1 script into v2

27 Apr 2024, 10:29

One example is below.

Code: Select all

#Requires AutoHotkey v2.0
Persistent
DllCall('RegisterShellHookWindow', 'UInt', A_ScriptHwnd)
OnMessage DllCall('RegisterWindowMessage', 'Str', 'SHELLHOOK'), shellMessage
Return

shellMessage(wParam, lParam, msg, hWnd) {
 Static HSHELL_WINDOWCREATED := 1
      , WS_EX_TOPMOST        := 262144
 If wParam = HSHELL_WINDOWCREATED && WinExist(lParam) && !InStr(WinGetProcessName(), 'AutoHotkey')
  MsgBox WinGetTitle(), 'Created', 'Iconi ' WS_EX_TOPMOST
}
If your target window is not found, then you may want to add code to ignore that error. WinExist is one way to do it.
reborn
Posts: 10
Joined: 23 Jun 2019, 06:44

Re: Invalid callback function When convert v1 script into v2

27 Apr 2024, 12:34

mikeyww wrote:
27 Apr 2024, 10:29
One example is below.

Code: Select all

#Requires AutoHotkey v2.0
Persistent
DllCall('RegisterShellHookWindow', 'UInt', A_ScriptHwnd)
OnMessage DllCall('RegisterWindowMessage', 'Str', 'SHELLHOOK'), shellMessage
Return

shellMessage(wParam, lParam, msg, hWnd) {
 Static HSHELL_WINDOWCREATED := 1
      , WS_EX_TOPMOST        := 262144
 If wParam = HSHELL_WINDOWCREATED && WinExist(lParam) && !InStr(WinGetProcessName(), 'AutoHotkey')
  MsgBox WinGetTitle(), 'Created', 'Iconi ' WS_EX_TOPMOST
}
If your target window is not found, then you may want to add code to ignore that error. WinExist is one way to do it.
Thanks for your answer, it's about the same solution compare to what I got from MS copilot by adding WinExist check before title match!

Return to “Ask for Help (v2)”

Who is online

Users browsing this forum: No registered users and 45 guests