OnlineLibrary
125 строк · 2.7 Кб
1package lang2
3import (4"errors"5"os"6"path/filepath"7"unsafe"8
9"OnlineLibrary/internal/config"10"github.com/leonelquinteros/gotext"11"golang.org/x/sys/windows"12)
13
14const (15LOCALE_SNATIVELANGUAGENAME = 0x0000000416)
17
18var kernel32 = windows.NewLazySystemDLL("kernel32.dll")19
20var (21procGetUserDefaultUILanguage = kernel32.NewProc("GetUserDefaultUILanguage")22procGetLocaleInfoW = kernel32.NewProc("GetLocaleInfoW")23procLocaleNameToLCID = kernel32.NewProc("LocaleNameToLCID")24procLCIDToLocaleName = kernel32.NewProc("LCIDToLocaleName")25)
26
27type Language struct {28ID string29Description string30}
31
32type LCID uint33
34func GetUserDefaultUILanguage() LCID {35lcid, _, _ := procGetUserDefaultUILanguage.Call()36return LCID(lcid)37}
38
39func GetLocaleDescription(lcid LCID) (string, error) {40buf := make([]uint16, 1024)41r, _, _ := procGetLocaleInfoW.Call(uintptr(lcid), LOCALE_SNATIVELANGUAGENAME, uintptr(unsafe.Pointer(&buf[0])), uintptr(len(buf)))42if r == 0 {43return "", errors.New("invalid lcid")44}45return windows.UTF16ToString(buf), nil46}
47
48func LocaleNameToLCID(localeName string) (LCID, error) {49buf, err := windows.UTF16FromString(localeName)50if err != nil {51return 0, err52}53lcid, _, _ := procLocaleNameToLCID.Call(uintptr(unsafe.Pointer(&buf[0])), 0)54if lcid == 0 {55return 0, errors.New("invalid locale name")56}57return LCID(lcid), nil58}
59
60func LCIDToLocaleName(lcid LCID) (string, error) {61buf := make([]uint16, 128)62r, _, _ := procLCIDToLocaleName.Call(uintptr(lcid), uintptr(unsafe.Pointer(&buf[0])), uintptr(len(buf)), 0)63if r == 0 {64return "", errors.New("invalid lcid")65}66return windows.UTF16ToString(buf), nil67}
68
69func availableLanguages(lib string) []Language {70langs := make([]Language, 0)71path, err := filepath.Abs(lib)72if err != nil {73return langs74}75
76entrys, err := os.ReadDir(path)77if err != nil {78return langs79}80
81locales := []string{"en"}82for _, e := range entrys {83if e.IsDir() && e.Name() != "en" {84locales = append(locales, e.Name())85}86}87
88for _, locale := range locales {89lcid, err := LocaleNameToLCID(locale)90if err != nil {91continue92}93description, err := GetLocaleDescription(lcid)94if err != nil {95continue96}97l := Language{ID: locale, Description: description}98langs = append(langs, l)99}100return langs101}
102
103func Init(lang string) ([]Language, bool) {104lib := "locale"105langs := availableLanguages(lib)106
107langIsAvailable := false108for _, l := range langs {109if lang == l.ID {110langIsAvailable = true111break112}113}114
115if !langIsAvailable {116lang = "en"117lcid := GetUserDefaultUILanguage()118if locale, err := LCIDToLocaleName(lcid); err == nil {119lang = locale120}121}122
123gotext.Configure(lib, lang, config.ProgramName)124return langs, langIsAvailable125}
126