FuPeiJiang / VD.ahk

Windows Virtual Desktop, AutoHotkey, Windows 11 support, Windows Server 2022, switch desktop, move window(wintitle) to current desktop; createDesktop, PinWindow, getCount, getDesktopNumOfWindow -> mute all windows in Virtual Desktop
MIT License
319 stars 45 forks source link

[OS: 10.0.19045] getNameFromDesktopNum returns empty for desktops with unset/default names #35

Closed marium0505 closed 1 year ago

marium0505 commented 1 year ago

Hey,

Just for your information, if the user hasn't set a Desktop name for a desktop the function will return empty.

When a new virtual desktop is created the name (at least the one shown in Task view) will be "[]Desktop localized] [index of desktop when created]". So the name of the first Virtual desktop will be "Desktop 1", then "Desktop 2" and so on.

FuPeiJiang commented 1 year ago

localized )::: is there any way to get the localized version of Desktop ?

FuPeiJiang commented 1 year ago

@marium0505

#SingleInstance force
ListLines 0
KeyHistory 0
SendMode "Input" ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir A_ScriptDir ; Ensures a consistent starting directory.

FindStringResourceEx(hModule, uId, langId) { ;https://stackoverflow.com/questions/2502375/find-localized-windows-strings#2588937

    debugThis := uId // 16 + 1
    hrsrc := DllCall("FindResourceExW", "Ptr",hModule, "Ptr",6, "Ptr",debugThis, "UShort",langId, "UPtr") ;RT_STRING=6
    pwsz:=0
    if (hrsrc) {
        hglob := DllCall("LoadResource", "Ptr",hModule, "Ptr",hrsrc, "Ptr")
        if (hglob) {
            pwsz := DllCall("LockResource", "Ptr",hglob, "Ptr")
            if (pwsz) {
                lolWhat := uId & 15
                j:=0
                while (j < lolWhat) {
                    pwsz += 2 + 2*NumGet(pwsz, 0, "UShort")
                    ++j
                }
                length:=NumGet(pwsz, 0, "UShort")
                pwsz+=2
            }
        }
    }
    return pwsz && StrGet(pwsz, length, "UTF-16")
}

hModule := DllCall("GetModuleHandle", "Str", "twinui.pcshell.dll", "Ptr") || DllCall("LoadLibrary", "Str", "twinui.pcshell.dll", "Ptr")
localizedString := FindStringResourceEx(hModule, 13502, DllCall("GetUserDefaultUILanguage", "UShort")) ;"Desktop"=13502
MsgBox A_Clipboard:=localizedString

ExitApp

f3::ExitApp
marium0505 commented 1 year ago

Sorry for late reply. I tried a few methods I found to attempt to get "Desktop" in the local language, without luck. Even gave the ChatGPT a few tries without luck before creating the ticket.

Seems like the code you provided return 0 for me, unfortunately.

But, this code worked for me. It is possible that the line number is different on different OS systems. I have the same OS version on both my desktop and my surface so unable to check:

DLL_File := A_WinDir "\System32\shell32.dll"
LocaleString_Desktop := DLL_ReadStringNum(DLL_File,21769)
MsgBox, % LocaleString_Desktop

DLL_ReadStringNum(DllFile, StringNum) {
    hModule := DllCall("LoadLibrary", "str", DllFile, "Ptr")
    VarSetCapacity(string, 1024)
    DllCall("LoadString", "uint", hModule, "uint", StringNum, "uint", &string, "int", 1024)
    DllCall("FreeLibrary", "Ptr", hModule)
    Return string
}
marium0505 commented 1 year ago

This one also works for me (no changes to the DLL_ReadStringNum function needed, only the file path and line number):

DLL_File := A_WinDir "\System32\twinui.pcshell.dll"
LocaleString_Desktop := DLL_ReadStringNum(DLL_File,13502)
FuPeiJiang commented 1 year ago

@marium0505 wow, this is so short, where did you find about LoadString ? I want to post this as an answer to https://stackoverflow.com/questions/2502375/find-localized-windows-strings, mention that it only gets UserDefaultUILanguage

you're sending v1 code, maybe you ran my v2 code using v1 ahk, sorry(I didn't mention it), I always use v2 when testing winapi stuff

shell32.dll(8MB) is smaller to load than twinui.pcshell.dll(9MB) so I will use shell32.dll

here is my v2 version:

#SingleInstance force
ListLines 0
KeyHistory 0
SendMode "Input" ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir A_ScriptDir ; Ensures a consistent starting directory.

getLocalizedWord_Desktop() {
    hModule := DllCall("GetModuleHandle", "Str", "shell32.dll", "Ptr") || DllCall("LoadLibrary", "Str", "shell32.dll", "Ptr")
    length:=DllCall("LoadString", "Uint", hModule, "Uint", 21769, "Ptr*", &lpBuffer:=0, "Int", 0)
    localizedStr := StrGet(lpBuffer, length, "UTF-16")
    Return localizedStr
}

MsgBox getLocalizedWord_Desktop()

Exitapp

f3::Exitapp
FuPeiJiang commented 1 year ago

seems like 4162 also gets "Desktop", I wanted to share this script:

#SingleInstance force
ListLines 0
KeyHistory 0
SendMode "Input" ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir A_ScriptDir ; Ensures a consistent starting directory.

getNumbers(hModule, stringToSearch) {
    arr:=[]
    i:=0
    while (i < 65536) {
        localizedStr:=""
        length:=DllCall("LoadString", "Uint", hModule, "Uint", i, "Ptr*", &lpBuffer:=0, "Int", 0)
        localizedStr := StrGet(lpBuffer, length, "UTF-16")
        if (localizedStr == stringToSearch) {
            arr.Push(i)
        }
        ++i
    }
    return arr
}

hModule := DllCall("LoadLibrary", "Str", "shell32.dll", "Ptr")
arr:=getNumbers(hModule, "Desktop")
finalStr:=""
for v in arr {
    finalStr.=v "`n"
}

MsgBox A_Clipboard:=finalStr

Exitapp

f3::Exitapp