Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

add this features of v2 to v1 and question about A_Language


  • Please log in to reply
7 replies to this topic
Flipeador
  • Members
  • 67 posts
  • Last active: Dec 29 2015 11:22 AM
  • Joined: 12 May 2014

hello
in the next update might add support for the following:

MsgBox %i(2)%+%i(3)% = %4+27% `;)
i(i) {
    return i**i
}

what do you thing?

 

 

Would not that be this a better way to get the system's default language?

MsgBox % A_Language() "`n" A_Language
A_Language() { ;https://msdn.microsoft.com/en-us/library/windows/desktop/dd318123%28v=vs.85%29.aspx
    SetFormat, IntegerFast, H
    hLang := DllCall("Kernel32.dll\GetSystemDefaultUILanguage")
    return StrReplace( hLang, "x" )
}

instead of from the registry (Or is it the same?)

 

 

thanks!

 

 

 

 



HotKeyIt
  • Moderators
  • 7439 posts
  • Last active: Jun 22 2016 09:14 PM
  • Joined: 18 Jun 2008

The first one is already supported in AutoHotkey v2.

Why would be the second one better than using RegRead, don't think the speed difference is significant?



Flipeador
  • Members
  • 67 posts
  • Last active: Dec 29 2015 11:22 AM
  • Joined: 12 May 2014
The first one is already supported in AutoHotkey v2.

but AutoHotKey v2 is not recommended for general use. He wanted to know if this could be added in the next update v1.

 

 

Why would be the second one better than using RegRead, don't think the speed difference is significant?

Well, maybe I didn't think well. I thought it was a more solid way to get the information.
 

--------------------------

it would also be interesting a variable as 'A_UserProfile' / 'A_Profiles'. Like this:

MsgBox % "UserProfile: " A_UserProfile()
    . "`nAllUsersProfile: " A_AllUsersProfile()
    . "`nProfilesDir: " A_Profiles()
    . "`nDefaultUserProfile: " A_DefaultUserProfile()
    . "`nUserDomain\UserName: " A_UserDomain()
A_UserProfile() {
    return A_Profiles() "\" A_UserName
}
A_AllUsersProfile() {
    uSize := VarSetCapacity(lpBuffer, 261 * 2)
    DllCall("Userenv.dll\GetAllUsersProfileDirectory", "Ptr", &lpBuffer, "UInt*", 261)
    return RTrim( StrGet(&lpBuffer, uSize, "UTF-16"), "\")
}
A_Profiles() {
    uSize := VarSetCapacity(lpBuffer, 261 * 2)
    DllCall("Userenv.dll\GetProfilesDirectoryW", "Ptr", &lpBuffer, "UInt*", 261)
    return RTrim( StrGet(&lpBuffer, uSize, "UTF-16"), "\")
}
A_DefaultUserProfile() {
    uSize := VarSetCapacity(lpBuffer, 261 * 2)
    DllCall("Userenv.dll\GetDefaultUserProfileDirectoryW", "Ptr", &lpBuffer, "UInt*", 261)
    return RTrim( StrGet(&lpBuffer, uSize, "UTF-16"), "\" )
}
A_UserDomain() {
    uSize := VarSetCapacity(lpBuffer, 1023, 0) + 1
    DllCall("Secur32.dll\GetUserNameExW", "UInt", 2, "Ptr", &lpBuffer, "UInt*", uSize)
    return StrGet(&lpBuffer, uSize, "UTF-16")
}


Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006

in the next update might add support for the following:

No. This capability relies on some relatively large design changes which can't be applied to v1 without risking breaking a few things, and would require a significant investment of my time.
 

Would not that be this a better way to get the system's default language?

Thanks for the suggestion - that would reduce code size. Performance is irrelevant for A_Language, but is MUCH better using GetSystemDefaultUILanguage(), even in script, since it doesn't read the registry (confirmed with Process Monitor and benchmarks).

 

What does it return for you? I have several versions of Windows but all are English US (0409). (A_Language is for the UI language, which afaik can't be changed without a reinstall unless you have a MUI version of Windows.)

 

(Edit: MSDN says that it returns the "install language", which matches up with the registry key that AutoHotkey is using.)

Your code has an error and returns "-0FBF7" on my XP system. I would suggest this implementation:

A_Language() { ;https://msdn.microsoft.com/en-us/library/windows/desktop/dd318123(v=vs.85).aspx
    return Format("{:04X}", DllCall("GetSystemDefaultUILanguage", "UShort"))
}

A_UserProfile() {
return A_Profiles() "\" A_UserName
}


This is incorrect. I have seen many cases where the user's profile folder is not named the same as their username. (Generally in those cases there is a domain name suffix.) It is also not guaranteed that the user profile is a sub-folder of A_Profiles().

You can simply use the USERPROFILE environment variable instead. I think this one is generally more useful than the others you suggested.


Edited by Lexikos, 09 June 2015 - 08:59 AM.
Confirmed performance difference and 'install language'


jNizM
  • Members
  • 928 posts
  • Last active: Jan 12 2018 09:23 AM
  • Joined: 01 Aug 2012
For me it returns 0407 [Germany (DE)]
MsgBox % Format("{:04X}", DllCall("GetSystemDefaultUILanguage", "UShort"))

[AHK] 1.1.27.04 x64 Unicode | [WIN] 10 Pro (Version 1709)
My GitHub Profile | Donations are appreciated if I could help you

Flipeador
  • Members
  • 67 posts
  • Last active: Dec 29 2015 11:22 AM
  • Joined: 12 May 2014
No. This capability relies on some relatively large design changes [...]

thanks for your reply, I had no idea it was such a big change in the code.

 

 

What does it return for you?

MsgBox % Format("{:04X}", DllCall("GetSystemDefaultUILanguage", "UShort"))

returns 0C0A (Spanish_Modern_Sort)  ✔

 

 

You can simply use the USERPROFILE environment variable instead.

thanks, would be something like...

MsgBox % A_UserProfile()
A_UserProfile() {
    nSize := VarSetCapacity(lpBuffer, 261 * 2)
    DllCall("Kernel32.dll\GetEnvironmentVariable", "Str", "USERPROFILE", "Ptr", &lpBuffer, "UInt", nSize)
    return StrGet(&lpBuffer, nSize)
}


jNizM
  • Members
  • 928 posts
  • Last active: Jan 12 2018 09:23 AM
  • Joined: 01 Aug 2012
I translated your whole functions. I hope I did not forget/missed anything.
; ===============================================================================================================================

MsgBox % "GetEnvironmentVariable:`n" GetEnvironmentVariable()

GetEnvironmentVariable(Name := "USERPROFILE")                                     ; http://msdn.com/library/ms683188(vs.85,en-us)
{
    size := DllCall("GetEnvironmentVariable", "Str", Name, "Ptr", 0, "UInt", 0)
    VarSetCapacity(buf, size * (A_IsUnicode ? 2 : 1), 0)
    if !(DllCall("GetEnvironmentVariable", "Str", Name, "Str", buf, "UInt", size))
        return "*" A_LastError
    return buf
}

; ===============================================================================================================================

MsgBox % "GetUserNameEx:`n" GetUserNameEx()

GetUserNameEx(EX_NAME_FORMAT := 2)                                                ; http://msdn.com/library/ms724435(vs.85,en-us)
{
    DllCall("secur32.dll\GetUserNameEx", "UInt", EX_NAME_FORMAT, "Ptr", 0, "UInt*", size)
    VarSetCapacity(buf, size * (A_IsUnicode ? 2 : 1), 0)
    if !(DllCall("secur32.dll\GetUserNameEx", "UInt", EX_NAME_FORMAT, "Str", buf, "UInt*", size))
        return "*" A_LastError
    return buf
}

; ===============================================================================================================================

MsgBox % "GetDefaultUserProfileDirectory:`n" GetDefaultUserProfileDirectory()

GetDefaultUserProfileDirectory()                                                  ; http://msdn.com/library/bb762277(vs.85,en-us)
{
    DllCall("userenv.dll\GetDefaultUserProfileDirectory", "Ptr", 0, "UInt*", size)
    VarSetCapacity(buf, size * (A_IsUnicode ? 2 : 1), 0)
    if !(DllCall("userenv.dll\GetDefaultUserProfileDirectory", "Str", buf, "UInt*", size))
        return "*" A_LastError
    return buf
}

; ===============================================================================================================================

MsgBox % "GetProfilesDirectory:`n" GetProfilesDirectory()

GetProfilesDirectory()                                                            ; http://msdn.com/library/bb762278(vs.85,en-us)
{
    DllCall("userenv.dll\GetProfilesDirectory", "Ptr", 0, "UInt*", size)
    VarSetCapacity(buf, size * (A_IsUnicode ? 2 : 1), 0)
    if !(DllCall("userenv.dll\GetProfilesDirectory", "Str", buf, "UInt*", size))
        return "*" A_LastError
    return buf
}

; ===============================================================================================================================

MsgBox % "GetAllUsersProfileDirectory:`n" GetAllUsersProfileDirectory()

GetAllUsersProfileDirectory()                                                     ; http://msdn.com/library/bb762276(vs.85,en-us)
{
    DllCall("userenv.dll\GetAllUsersProfileDirectory", "Ptr", 0, "UInt*", size)
    VarSetCapacity(buf, size * (A_IsUnicode ? 2 : 1), 0)
    if !(DllCall("userenv.dll\GetAllUsersProfileDirectory", "Str", buf, "UInt*", size))
        return "*" A_LastError
    return buf
}

; ===============================================================================================================================
edit
[AHK] 1.1.27.04 x64 Unicode | [WIN] 10 Pro (Version 1709)
My GitHub Profile | Donations are appreciated if I could help you

Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006

Why GetEnvironmentVariable?

MsgBox % USERPROFILE  ; Without #NoEnv, on v1.

EnvGet UserProfile, USERPROFILE  ; With or without #NoEnv, v1 or v2.
MsgBox % UserProfile

MsgBox % EnvGet("USERPROFILE")  ; v2 only.

A couple more that you're using DllCalls for are also available as environment variables:

EnvGet UserDomain, USERDOMAIN
MsgBox % UserDomain "\" A_UserName

EnvGet AllUsersProfile, ALLUSERSPROFILE
MsgBox % AllUsersProfile

There are also several ways to get the user-domain via COM.

 

 

Also, there are errors in your A_() functions:

  • uSize contains the number of BYTES of available space, but StrGet expects a CHARACTER count.
  • GetAllUsersProfileDirectory does not return UTF-16 if called from an ANSI build of AutoHotkey.

There's no need for StrGet or the "W" suffix. Just use the "Str" type.

MsgBox % "ProfilesDir: " A_Profiles()
    . "`nDefaultUserProfile: " A_DefaultUserProfile()
A_Profiles() {
    VarSetCapacity(Buffer, 261 * 2)
    DllCall("Userenv.dll\GetProfilesDirectory", "Str", Buffer, "UInt*", 261)
    return Buffer
}
A_DefaultUserProfile() {
    VarSetCapacity(Buffer, 261 * 2)
    DllCall("Userenv.dll\GetDefaultUserProfileDirectory", "Str", Buffer, "UInt*", 261)
    return Buffer
}

There's also no need for RTrim.  These functions do not return paths with a trailing slash, and even if they did, paths like C:\Users\\Something actually do work.