1

Тема: AHK: Перенести функцию с AHK v2 в v1

Нашел такую функцию для AHK v2:

GetCurrencyFormat(Value, Locale := 0x0400)
{
	if (Size := DllCall("GetCurrencyFormatW", "UInt", Locale, "UInt", 0, "Str", Value, "Ptr", 0, "Ptr", 0, "Int", 0))
	{
		Size := VarSetStrCapacity(&CurrencyStr, Size)
		if (Size := DllCall("GetCurrencyFormatW", "UInt", Locale, "UInt", 0, "Str", Value, "Ptr", 0, "Str", CurrencyStr, "Int", Size))
		{
			return CurrencyStr
		}
	}
	return ""
}

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

MsgBox GetCurrencyFormat(1149.99)            ; 1.149,99 €    ( LANG_USER_DEFAULT | SUBLANG_DEFAULT    )    (GERMAN HERE)
MsgBox GetCurrencyFormat(1149.99, 0x0409)    ; $1,149.99     ( LANG_ENGLISH      | SUBLANG_ENGLISH_US )
MsgBox GetCurrencyFormat(1149.99, 0x0809)    ; £1,149.99     ( LANG_ENGLISH      | SUBLANG_ENGLISH_UK )
MsgBox GetCurrencyFormat(1149.99, 0x0407)    ; 1.149,99 €    ( LANG_GERMAN       | SUBLANG_GERMAN     )

Как ее перенести в v1? Мои познания в DllCall нулевые.
Значение первого Size пустое.

GetCurrencyFormat(Value, Locale := 0x0400)
{
	if (Size := DllCall("GetCurrencyFormatW", "UInt", Locale, "UInt", 0, "Str", Value, "Ptr", 0, "Ptr", 0, "Int", 0))
	{
		Size := VarSetCapacity(&CurrencyStr, Size)
		if (Size := DllCall("GetCurrencyFormatW", "UInt", Locale, "UInt", 0, "Str", Value, "Ptr", 0, "Str", CurrencyStr, "Int", Size))
		{
			return CurrencyStr
		}
	}
	return ""
}

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

MsgBox % GetCurrencyFormat(1149.99)            ; 1.149,99 €    ( LANG_USER_DEFAULT | SUBLANG_DEFAULT    )    (GERMAN HERE)
MsgBox % GetCurrencyFormat(1149.99, 0x0409)    ; $1,149.99     ( LANG_ENGLISH      | SUBLANG_ENGLISH_US )
MsgBox % GetCurrencyFormat(1149.99, 0x0809)    ; £1,149.99     ( LANG_ENGLISH      | SUBLANG_ENGLISH_UK )
MsgBox % GetCurrencyFormat(1149.99, 0x0407)    ; 1.149,99 €    ( LANG_GERMAN       | SUBLANG_GERMAN     )
Win10: LTSC (21H2); AHK: ANSI (v1.1.36.02)

2

Re: AHK: Перенести функцию с AHK v2 в v1

Phoenixxx_Czar пишет:

Значение первого Size пустое

Почему? У меня не пустое:

MsgBox, % DllCall("GetCurrencyFormatW", "UInt", 0x400, "UInt", 0, "Str", "100", "Ptr", 0, "Ptr", 0, "Int", 0)
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

3

Re: AHK: Перенести функцию с AHK v2 в v1

Ваш код вернул 0. Я уже подозреваю, что дело в ANSI версии AHK. Если это так, то что нужно поменять?

Win10: LTSC (21H2); AHK: ANSI (v1.1.36.02)

4

Re: AHK: Перенести функцию с AHK v2 в v1

Да просто уберите W.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

5

Re: AHK: Перенести функцию с AHK v2 в v1

Данный код по прежнему возвращает пустые строки, хотя Size в обоих случаях равен 11.

GetCurrencyFormat(Value, Locale := 0x0400)
{
	Size := DllCall("GetCurrencyFormat", "UInt", Locale, "UInt", 0, "Str", Value, "Ptr", 0, "Ptr", 0, "Int", 0)

	if (Size)
	{
		Size := VarSetCapacity(&CurrencyStr, Size)
		Size := DllCall("GetCurrencyFormat", "UInt", Locale, "UInt", 0, "Str", Value, "Ptr", 0, "Str", CurrencyStr, "Int", Size)
		if (Size)
		{
			return CurrencyStr
		}
	}
	return ""
}

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

MsgBox, % GetCurrencyFormat(1149.99)            ; 1.149,99 €
MsgBox, % GetCurrencyFormat(1149.99, 0x0409)    ; $1,149.99
MsgBox, % GetCurrencyFormat(1149.99, 0x0809)    ; £1,149.99
MsgBox, % GetCurrencyFormat(1149.99, 0x0407)    ; 1.149,99 €
Win10: LTSC (21H2); AHK: ANSI (v1.1.36.02)

6

Re: AHK: Перенести функцию с AHK v2 в v1

Вместо

Size := VarSetCapacity(&CurrencyStr, Size)

нужно

VarSetCapacity(CurrencyStr, Size << !!A_IsUnicode)
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

7 (изменено: Phoenixxx_Czar, 2021-12-19 06:46:18)

Re: AHK: Перенести функцию с AHK v2 в v1

Да получилось, огромное спасибо.

Win10: LTSC (21H2); AHK: ANSI (v1.1.36.02)

8

Re: AHK: Перенести функцию с AHK v2 в v1

Данный код возвращает не правильные данные:

GetDurationFormat(Duration, Format := "", Locale := 0x0400)
{
	if (Size := DllCall("GetDurationFormat", "UInt", Locale, "UInt", 0, "Ptr", 0, "Int64", Duration * 10000, "Ptr", (Format ? StrPut(Format) : 0), "Ptr", 0, "Int", 0))
	{
		Size := VarSetCapacity(DurationStr, Size << !!A_IsUnicode)
		if (Size := DllCall("GetDurationFormat", "UInt", Locale, "UInt", 0, "Ptr", 0, "Int64", Duration * 10000, "Ptr", (Format ? StrPut(Format) : 0), "Str", DurationStr, "Int", Size))
		{
			return DurationStr
		}
	}
	return ""
}

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

MsgBox % GetDurationFormat(817000)                                    ; 13:37
MsgBox % GetDurationFormat(421337, "hh:mm:ss.fff")                    ; 00:07:01.337
MsgBox % GetDurationFormat(2520000, "mm' Minutes")                    ; 42 Minutes
MsgBox % GetDurationFormat(43140000, "hh' Hours and 'mm' Minutes")    ; 11 Hours and 59 Minutes

Оригинал:

GetDurationFormat(Duration, Format := "", Locale := 0x0400)
{
	if (Size := DllCall("GetDurationFormat", "UInt", Locale, "UInt", 0, "Ptr", 0, "Int64", Duration * 10000, "Ptr", (Format ? StrPtr(Format) : 0), "Ptr", 0, "Int", 0))
	{
		Size := VarSetStrCapacity(&DurationStr, Size)
		if (Size := DllCall("GetDurationFormat", "UInt", Locale, "UInt", 0, "Ptr", 0, "Int64", Duration * 10000, "Ptr", (Format ? StrPtr(Format) : 0), "Str", DurationStr, "Int", Size))
		{
			return DurationStr
		}
	}
	return ""
}

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

MsgBox GetDurationFormat(817000)                                    ; 13:37
MsgBox GetDurationFormat(421337, "hh:mm:ss.fff")                    ; 00:07:01.337
MsgBox GetDurationFormat(2520000, "mm' Minutes")                    ; 42 Minutes
MsgBox GetDurationFormat(43140000, "hh' Hours and 'mm' Minutes")    ; 11 Hours and 59 Minutes
Win10: LTSC (21H2); AHK: ANSI (v1.1.36.02)

9

Re: AHK: Перенести функцию с AHK v2 в v1

Возвращается пустота:

GetCurrencyFormatEx(Value, LocaleName := "!x-sys-default-locale")
{
	if (Size := DllCall("GetCurrencyFormatEx", "Str", LocaleName, "UInt", 0, "Str", Value, "Ptr", 0, "Ptr", 0, "Int", 0))
	{
		VarSetCapacity(CurrencyStr, Size << !!A_IsUnicode)
		if (DllCall("GetCurrencyFormatEx", "Str", LocaleName, "UInt", 0, "Str", Value, "Ptr", 0, "Str", CurrencyStr, "Int", Size))
		{
			return CurrencyStr
		}
	}
	return ""
}

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

MsgBox % GetCurrencyFormatEx(1149.99)             ; 1.149,99 €
MsgBox % GetCurrencyFormatEx(1149.99, "en-US")    ; $1,149.99
MsgBox % GetCurrencyFormatEx(1149.99, "en-GB")    ; £1,149.99
MsgBox % GetCurrencyFormatEx(1149.99, "de-DE")    ; 1.149,99 €

Оригинал:

GetCurrencyFormatEx(Value, LocaleName := "!x-sys-default-locale")
{
	if (Size := DllCall("GetCurrencyFormatEx", "Str", LocaleName, "UInt", 0, "Str", Value, "Ptr", 0, "Ptr", 0, "Int", 0))
	{
		Size := VarSetStrCapacity(&CurrencyStr, Size)
		if (Size := DllCall("GetCurrencyFormatEx", "Str", LocaleName, "UInt", 0, "Str", Value, "Ptr", 0, "Str", CurrencyStr, "Int", Size))
		{
			return CurrencyStr
		}
	}
	return ""
}

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

MsgBox GetCurrencyFormatEx(1149.99)             ; 1.149,99 €    ( LANG_USER_DEFAULT | SUBLANG_DEFAULT    )    (GERMAN HERE)
MsgBox GetCurrencyFormatEx(1149.99, "en-US")    ; $1,149.99     ( LANG_ENGLISH      | SUBLANG_ENGLISH_US )
MsgBox GetCurrencyFormatEx(1149.99, "en-GB")    ; £1,149.99     ( LANG_ENGLISH      | SUBLANG_ENGLISH_UK )
MsgBox GetCurrencyFormatEx(1149.99, "de-DE")    ; 1.149,99 €    ( LANG_GERMAN       | SUBLANG_GERMAN     )
Win10: LTSC (21H2); AHK: ANSI (v1.1.36.02)

10 (изменено: svoboden, 2021-12-19 17:01:37)

Re: AHK: Перенести функцию с AHK v2 в v1

А что сложно, даже я смог запустить пример. Autohotkey Unicode 32-bit:

TimedDuration := 421337
         VarSetCapacity(lpDurationStr, 256) 
         DllCall("GetDurationFormat", "uint", 0x400, "uint", 0, "ptr", 0, "int64", TimedDuration*10000, "wstr", "h':'mm':'ss.fff", "wstr", lpDurationStr, "int", 256)
      MsgBox % lpDurationStr

Может не слишком правильный пример, но рабочий.

11

Re: AHK: Перенести функцию с AHK v2 в v1

MsgBox % GetDurationFormat(817000)                                    ; 13:37
MsgBox % GetDurationFormat(421337, "hh:mm:ss.fff")                    ; 00:07:01.337
MsgBox % GetDurationFormat(2520000, "mm' Minutes")                    ; 42 Minutes
MsgBox % GetDurationFormat(43140000, "hh' Hours and 'mm' Minutes")    ; 11 Hours and 59 Minutes

GetDurationFormat(Duration, Format := 0, Locale := 0x0400)
{
   if !Size := DllCall("GetDurationFormat", "UInt", Locale, "UInt", 0, "Ptr", 0, "Int64", Duration * 10000, Format ? "WStr" : "Ptr", Format, "Ptr", 0, "Int", 0)
      throw "GetDurationFormat failed, error " . A_LastError
   VarSetCapacity(DurationStr, Size*2)
   DllCall("GetDurationFormat", "UInt", Locale, "UInt", 0, "Ptr", 0, "Int64", Duration * 10000, Format ? "WStr" : "Ptr", Format, "Ptr", &DurationStr, "Int", Size)
   return StrGet(&DurationStr, "UTF-16")
}
MsgBox % GetCurrencyFormatEx("1149.99")             ; 1.149,99 €
MsgBox % GetCurrencyFormatEx("1149.99", "en-US")    ; $1,149.99
MsgBox % GetCurrencyFormatEx("1149.99", "en-GB")    ; £1,149.99
MsgBox % GetCurrencyFormatEx("1149.99", "de-DE")    ; 1.149,99 €

GetCurrencyFormatEx(Value, LocaleName := "!x-sys-default-locale")
{
   if !Size := DllCall("GetCurrencyFormatEx", "WStr", LocaleName, "UInt", 0, "WStr", Value, "Ptr", 0, "Ptr", 0, "Int", 0)
      throw "GetCurrencyFormatEx failed, error " . A_LastError
   VarSetCapacity(CurrencyStr, Size*2)
   DllCall("GetCurrencyFormatEx", "WStr", LocaleName, "UInt", 0, "WStr", Value, "Ptr", 0, "Ptr", &CurrencyStr, "Int", Size)
   return StrGet(&CurrencyStr, "UTF-16")
}

Вторая функция с ANSI-интерпретатором не будет отображать рубли и фунты.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

12

Re: AHK: Перенести функцию с AHK v2 в v1

svoboden, при вашем коде у меня ничего не происходит, даже нет msgBox.
teadrinker, огромное спасибо, по небольшой аналогии и методом тыка, переделал еще две функции.

getNumberFormatEx(Value, LocaleName := "!x-sys-default-locale")
{
	if !Size := DllCall("GetNumberFormatEx", "WStr", LocaleName, "UInt", 0, "WStr", Value, "Ptr", 0, "Ptr", 0, "Int", 0)
		throw "GetNumberFormatEx failed, error " . A_LastError

	VarSetCapacity(NumberStr, Size*2)
	DllCall("GetNumberFormatEx", "WStr", LocaleName, "UInt", 0, "WStr", Value, "Ptr", 0, "Ptr", &NumberStr, "Int", Size)

	return StrGet(&NumberStr, "UTF-16")
}
getDurationFormatEx(Duration, Format := 0, LocaleName := "!x-sys-default-locale")
{
	if !Size := DllCall("GetDurationFormatEx", "WStr", LocaleName, "UInt", 0, "Ptr", 0, "Int64", Duration * 10000, Format ? "WStr" : "Ptr", Format, "Ptr", 0, "Int", 0)
		throw "GetDurationFormatEx failed, error " . A_LastError
	VarSetCapacity(DurationStr, Size*2)
	DllCall("GetDurationFormatEx", "WStr", LocaleName, "UInt", 0, "Ptr", 0, "Int64", Duration * 10000, Format ? "WStr" : "Ptr", Format, "Ptr", &DurationStr, "Int", Size)

	return StrGet(&DurationStr, "UTF-16")
}
Win10: LTSC (21H2); AHK: ANSI (v1.1.36.02)