 |
AutoHotkey Community Let's help each other out
|
| View previous topic :: View next topic |
| Author |
Message |
[VxE]
Joined: 07 Oct 2006 Posts: 2392
|
|
| Back to top |
|
 |
Guest
|
Posted: Sat Mar 22, 2008 7:33 am Post subject: |
|
|
this post sucks
but not as much as this thread  |
|
| Back to top |
|
 |
[VxE]
Joined: 07 Oct 2006 Posts: 2392
|
Posted: Sat Mar 22, 2008 9:12 am Post subject: Hash: MD2, MD4, MD5, SHA1, SHA256, SHA384, SHA512 |
|
|
Hash: returns a hex string which represents the cryptographic hash of the input data. Supports MD2, MD4, MD5, SHA1, SHA256, SHA384, and SHA512. Note that the last 3 may be restricted on systems older then WinXP.sp3. Special thanks to Laszlo for writing most of it. I do NOT want to hear feedback about how much whitespace is in the code. | Code: | ; Hash generation using advapi.dll (a part of windows OS).
; This function does NOT explicitly load the dll into memory.
; If you're going to be calling this function in a loop (or
; if you just want to improve performance), follow the example
; at http://www.autohotkey.com/docs/commands/DllCall.htm#load
; for loading a dll into memory.
Hash( ByRef sData, nLen=0, algorithm="MD5" ) {
; Laszlo: http://www.autohotkey.com/forum/viewtopic.php?p=113252#113252
; Tweaked by [VxE]
Static AlgAlias:=" MD2=CALG_MD2 MD4=CALG_MD4 MD5=CALG_MD5 SHA=CALG_SHA1 SHA1=CALG_SHA1 SHA256=CALG_SHA_256 SHA512=CALG_SHA_512 "
, CALG_MD2 := 0x8001
, CALG_MD4 := 0x8002
, CALG_MD5 := 0x8003
, CALG_SHA1 := 0x8004
, CALG_SHA_256 := 0x800c ; may not work on some systems
, CALG_SHA_384 := 0x800d ; may not work on some systems
, CALG_SHA_512 := 0x800e ; may not work on some systems
; See http://msdn.microsoft.com/en-us/library/aa375549%28VS.85%29.aspx for more details
, CRYPT_VERIFYCONTEXT := 0xF0000000
, PROV_RSA_FULL := 1
, PROV_RSA_AES := 24 ; we default to this one for hashes
If ( nLen <= 0 ) ; auto-detect size of data if not explicitly set
nLen := StrLen( sData )
If algorithm is not INTEGER
If ( pos := InStr( AlgAlias, " " algorithm "=" ) )
{
StringTrimLeft, Trim, AlgAlias, % Pos + 1 + StrLen( algorithm )
StringLeft, Trim, Trim, % InStr( Trim, " " ) - 1
algorithm := %Trim%
}
Else If InStr( AlgAlias, "=" algorithm " " )
algorithm := %algorithm%
If !DllCall("advapi32\CryptAcquireContextA"
, UIntP, hProv ; __out HCRYPTPROV *phProv,
, UInt, 0 ; __in LPCTSTR pszContainer,
, UInt, 0 ; __in LPCTSTR pszProvider,
, UInt, PROV_RSA_AES ; __in DWORD dwProvType,
, UInt, CRYPT_VERIFYCONTEXT ) ; __in DWORD dwFlags
; If we can't get a handle on the RSA_AES provider, try the RSA_FULL provider
DllCall("advapi32\CryptAcquireContextA"
, UIntP, hProv ; __out HCRYPTPROV *phProv,
, UInt, 0 ; __in LPCTSTR pszContainer,
, UInt, 0 ; __in LPCTSTR pszProvider,
, UInt, PROV_RSA_FULL ; __in DWORD dwProvType,
, UInt, CRYPT_VERIFYCONTEXT) ; __in DWORD dwFlags
DllCall("advapi32\CryptCreateHash"
, UInt, hProv ; __in HCRYPTPROV hProv,
, UInt, algorithm ; __in ALG_ID Algid,
, UInt, 0 ; __in HCRYPTKEY hKey,
, UInt, 0 ; __in DWORD dwFlags,
, UIntP, hHash ) ; __out HCRYPTHASH *phHash
DllCall("advapi32\CryptHashData"
, UInt, hHash ; __in HCRYPTHASH hHash,
, UInt, &sData ; __in BYTE *pbData,
, UInt, nLen ; __in DWORD dwDataLen,
, UInt, 0 ) ; __in DWORD dwFlags
DllCall("advapi32\CryptGetHashParam"
, UInt, hHash ; __in HCRYPTHASH hHash,
, UInt, 2 ; __in DWORD dwParam,
, UInt, 0 ; __out BYTE *pbData,
, UIntP, nSize ; __inout DWORD *pdwDataLen,
, UInt, 0 ) ; __in DWORD dwFlags
VarSetCapacity(HashVal, nSize, 0)
DllCall("advapi32\CryptGetHashParam"
, UInt, hHash ; __in HCRYPTHASH hHash,
, UInt, 2 ; __in DWORD dwParam,
, UInt, &HashVal ; __out BYTE *pbData,
, UIntP, nSize ; __inout DWORD *pdwDataLen,
, UInt, 0 ) ; __in DWORD dwFlags
DllCall("advapi32\CryptDestroyHash"
, UInt, hHash ) ; __in HCRYPTHASH hHash
DllCall("advapi32\CryptReleaseContext"
, UInt, hProv ; __in HCRYPTPROV hProv,
, UInt, 0 ) ; __in DWORD dwFlags
B_FormatInteger := A_FormatInteger ; remember old format
SetFormat, Integer, H ; set integer format to hex
Loop %nSize% ; for each byte in 'HashVal', append two hex digits to 'sHash'
sHash .= SubStr( 0x100 | NumGet( HashVal, A_Index - 1, "UChar" ), -1 )
SetFormat, Integer, %B_FormatInteger% ; restore previous format
Return sHash
} |
ControlGetClassName: returns the name of the control whose HWND you pass ot the function
| Code: | ControlGetClassName( hwnd )
{ ; returns HWND's class name without its instance number, e.g. "Edit" or "SysListView32"
VarSetCapacity( buff, 256, 0 )
DllCall("GetClassName", "uint", hwnd, "str", buff, "int", 255 )
return buff
} |
_________________ My Home Thread
Common Answers: [1]. It's in the FAQ [2]. Ternary ( a ? b : c ) guide [3]. Post code inside [code][/code] tags !
Last edited by [VxE] on Thu Feb 11, 2010 7:25 am; edited 4 times in total |
|
| Back to top |
|
 |
_adam Guest
|
Posted: Sat Mar 22, 2008 5:19 pm Post subject: |
|
|
somebody doesn't like you.
can't win them all though. thanks. I picked up some parts. |
|
| Back to top |
|
 |
BoBo¨ Guest
|
Posted: Wed Apr 02, 2008 10:51 am Post subject: |
|
|
Saw your 'hint' to this thread at your signature. Have you thought about to 'rearrange' the threads apperance a little with using BBCodeWriter?
Currently it's quite a tough challenge to get 'the idea behind' a script within a snap.
JM2€Cs + thanks for sharing your scripts with us. Much appreciated  |
|
| Back to top |
|
 |
[VxE]
Joined: 07 Oct 2006 Posts: 2392
|
Posted: Wed Apr 02, 2008 9:10 pm Post subject: |
|
|
Hmmm... there is indeed a lot of housekeeping that I should do with this thread, but recently I've been up to my eyeballs in other work. I suppose I really should break each scriptlet into its own post and keep a directory in the OP.
I'm glad you found something useful here
[Edit: 3-2-2010] More Set Functions (I added the fancy ones: permutation, power, combination, and transpose) | Code: | ;
; Set functions library (Upgraded, String-Based), by [VxE]
;
; Introduction:
; Sets are an important concept in OOP, data management, and
; discrete mathematics. This function library allows you to
; define sets of string objects and perform typical set functions
; on them. Additionally, this library offers six functions for
; handling multi-dimensional sets: Set_Zip joins two sets
; on a 1:1 basis and Set_Column extracts a set from a complex
; set. Set_Combinations, Set_Permutate, and Set_Power return
; supersets of an input set ( combinations are subsets of N
; distinct members from the input set ). Set_Transpose returns
; a set with the same elements, but flipped on the diagonal.
; The real power behind this library is the ability to use
; any string as a delimiter, rather than just a single character.
; This feature makes it easy to work with data collections in
; multiple text formats and to construct multi-dimensional sets
; without limits.
;
; Definitions:
; a 'delimiter' is a string with a length greater than zero.
; a 'member' is a string within a 'set' bounded by delimiters and/or
; the ends of the string.
; a 'set' is a string containing zero or more members, each separated
; from the previous and next member by a delimiter.
;
; Functions:
; Set_Column
; Set_Combinations ( see http://en.wikipedia.org/wiki/Combination )
; Set_Delimit
; Set_GetPos
; Set_GetPosRegEx
; Set_Intersect
; Set_Member
; Set_Permutations ( see http://en.wikipedia.org/wiki/Permutation )
; Set_Power ( see http://en.wikipedia.org/wiki/Power_set )
; Set_Remove
; Set_Size
; Set_Transpose ( see http://en.wikipedia.org/wiki/Transpose )
; Set_Union
; Set_Zip
;
; Set_SampleSet
;
; Notes:
; All string comparisons are case sensitive with the exception of
; Set_GetPosRegEx, which leaves case sensitivity up to the regex.
Set_Column( Set1, column, PrimaryDelimiter="`n", SecondaryDelimiter="," ) {
; Returns a set which is comprised of the 'column'th sub-member of
; each of 'Set1's members. Essentially, if each member were like a
; row in a table, this function would yield a column from that table.
VarSetCapacity( Set, StrLen( Set1 ))
column := Floor( column ) ; truncate decimals
Set1 .= PrimaryDelimiter
Stuff := StrLen( PrimaryDelimiter )
iStuff := StrLen( SecondaryDelimiter )
Pos := 1 - Stuff
Lead := 1
Loop
If ( 0 < Pos := InStr( Set1, PrimaryDelimiter, 1, Pos + Stuff ) )
{
StringMid, member, Set1, %Lead%, Pos - Lead
Lead := Pos + Stuff
member .= SecondaryDelimiter
ilead := 1
ipos := 1 - istuff
Loop
If ( 0 < ipos := InStr( member, SecondaryDelimiter, 1, ipos + Stuff ) )
{
StringMid, imember, member, %ilead%, ipos - ilead
ilead := ipos + iStuff
If ( A_Index < column )
Continue
Set .= PrimaryDelimiter . imember
Break
}
Else Break
}
Else Break
StringTrimLeft, Set, Set, %Stuff%
Return Set
}
Set_Combinations( Set1, members=1, PrimaryDelimiter="`n", SecondaryDelimiter="," ) {
; Returns a complex set where each member is composed of 'members' members from
; Set1. The resulting set contains only unique members ( no two members will
; contains exactly the same sub-members, regardless of order ) assuming, of course,
; that the input set contains all unique members in the first place.
Size := Set_Size( Set1, PrimaryDelimiter ), Pz := 1
If ( members <= 0 ) || ( members > Size )
Return "" ; pre-check for neg/zero members
If ( members = 1 )
Return Set_Union( Set1, "", PrimaryDelimiter ) ; 1-member -> set as-is
If ( members = Size )
Return Set_Delimit( Set1, SecondaryDelimiter, PrimaryDelimiter )
Set1 .= PrimaryDelimiter
Stuff := StrLen( PrimaryDelimiter )
Pos := 1 - Stuff
Lead := 1
Loop ; separate the set into an array of members
If ( 0 < Pos := InStr( Set1, PrimaryDelimiter, 1, Pos + Stuff ) )
{
StringMid, member%A_Index%, Set1, %Lead%, Pos - Lead
Lead := Pos + Stuff
}
Else Break
StringTrimRight, Set1, Set1, %Stuff%
If ( members + 1 = Size ) ; this is the opposite of 'members' == 1
{
Loop, %Size% ; omit each member in turn and append to result
Set := Set_Delimit( Set_Remove( Set1, member%A_Index%, PrimaryDelimiter ), SecondaryDelimiter, PrimaryDelimiter ) . ( A_Index = 1 ? "" : PrimaryDelimiter . Set )
Return Set
}
Loop, %members% ; calculate the number of combinations (pascal's triangle)
Pz := Round( pz * ( Size + 1.0 - A_Index ) / ( i%A_Index% := A_Index ) )
VarSetCapacity( Set, StrLen( Set1 ) * Pz * Size, 0 ) ; a very rough estimate
Loop, %Pz% ; for each potential combination
{
Loop, %members% ; choose N members
{
m := i%A_Index%
Set .= ( A_Index = 1 ? PrimaryDelimiter : SecondaryDelimiter ) . member%m%
If ( Size - members + A_Index > i%A_Index% )
c := A_Index ; this is the thing we should increment next
}
i%c% += 1 ; increment something
Loop % members - c ; we need to adjust some things
k := c + A_Index, i%k% := i%c% + A_Index
}
StringTrimLeft, Set, Set, %Stuff%
Return Set
}
Set_Delimit( Set1, NewD, PrimaryDelimiter="`n" ) {
; Replaces every instance of 'PrimaryDelimiter' in 'Set1' with 'NewD', effectively
; changing the set's delimiter.
oel := ErrorLevel ; preserve errorlevel
StringReplace, Set1, Set1, %PrimaryDelimiter%, %NewD%, All
Return Set1, ErrorLevel := oel
}
Set_GetPos( Set1, string, PrimaryDelimiter="`n" ) {
; Returns the index of the first member of 'Set1' that is an exact
; match of 'string'. The return value is zero if there is no match.
If ( 1 >= Pos := InStr( PrimaryDelimiter . Set1 . PrimaryDelimiter, PrimaryDelimiter . string . PrimaryDelimiter, 1 ) )
Return Pos
StringLeft, Set1, Set1, % Pos - 1
Return Set_Size( Set1, PrimaryDelimiter)
}
Set_GetPosRegEx( Set1, NeedleRegex, PrimaryDelimiter="`n" ) {
; Returns the index of the first member of 'Set1' that is a match
; of 'NeedleRegex'. The return value is zero if there is no match.
; NOTE: the regex needle should NOT account for the delimiters.
; Anchors "^$" will match a delimiter boundary. For example, the
; needleregex "^$" will match the first empty member in the set.
Stuff := StrLen( PrimaryDelimiter )
Set1 .= PrimaryDelimiter
Pos := 1 - Stuff
Lead := 1
Loop
If ( 0 < Pos := InStr( Set1, PrimaryDelimiter, 1, Pos + Stuff ) )
{
StringMid, member, Set1, %Lead%, Pos - Lead
Lead := Pos + Stuff
If RegexMatch( member, NeedleRegex )
Return A_Index
}
Else Break
Return 0
}
Set_Intersect( Set1, Set2, PrimaryDelimiter="`n" ) {
; Performs a set intersection of 'Set1' and 'Set2'. Only the members
; that are in both sets will be in the resulting set.
If ( Set_Size( Set1 ) > Set_Size( Set2 ) )
Set := Set2, Set2 := Set1, Set1 := Set
VarSetCapacity( Set, StrLen( Set1 ), 0)
Set1 .= PrimaryDelimiter
Set2 := PrimaryDelimiter . Set2 . PrimaryDelimiter
Stuff := StrLen( PrimaryDelimiter )
Pos := 1 - Stuff
Lead := 1
Loop
If ( 0 < Pos := InStr( Set1, PrimaryDelimiter, 1, Pos + Stuff ) )
{
StringMid, member, Set1, %Lead%, Pos - Lead
Lead := Pos + Stuff
If InStr( Set2, PrimaryDelimiter . member . PrimaryDelimiter, 1 )
Set .= PrimaryDelimiter . member
}
Else Break
StringTrimLeft, Set, Set, %Stuff%
Return Set
}
Set_Member( Set1, Which, PrimaryDelimiter="n" ) {
; Returns the 'Which'th member of Set1. A 'Which' less than 1 is
; considered an offset from the last member ('0' being the last)
Len := Set_Size( Set1, PrimaryDelimiter )
Which := Floor( Which )
If ( Which <= 0 ) && ( Len + Which > 0 )
Which := Len + Which
If ( Which > Len ) || ( Which <= 0 )
Return ""
Set1 .= PrimaryDelimiter
Stuff := StrLen( PrimaryDelimiter )
Pos := 1 - Stuff
Lead := 1
Loop
If ( 0 < Pos := InStr( Set1, PrimaryDelimiter, 1, Pos + Stuff ) )
&& ( A_Index < which )
Lead := Pos + Stuff
Else Break
StringMid, member, Set1, %Lead%, Pos - Lead
Return member
}
Set_Permutations( Set1, PrimaryDelimiter="`n", SecondaryDelimiter=",", p="" ) {
; Returns a complex set where each member is a unique permutation of
; the input set and which contains a number of members equal to the
; factorial of the input set's membercount. Note that 'PrimaryDelimiter'
; is the primary delimiter for both the input and output sets.
; WARNING! This function's output set has a size equal to the FACTORIAL
; of the input set's size. This means that a set of 10 members will
; have 3,628,800 permutations and could easily hit AHK's default
; variable limit of 64 MB. My laptop took nearly 3½ minutes to compute
; the permutations for the 10-member sample set (with setbatchlines,-1)
Size := Set_Size( Set1, PrimaryDelimiter )
IfLess, Size, 2, Return p . SecondaryDelimiter . Set1 ; only 1 member, so return !
VarSetCapacity( Set, StrLen(Set1) * Round(Sqrt(Size*6.283)*(Size/2.718)**Size), 0)
; This VarSetCapacity mutiplies the length of the input set string
; by an approximation of the factorial of 'Size'. Check wikipedia
; for 'factorial' to find out more.
Set1 .= PrimaryDelimiter
Stuff := StrLen( PrimaryDelimiter )
Pos := 1 - Stuff
Lead := 1
Loop ; separate the set into an array of members
If ( 0 < Pos := InStr( Set1, PrimaryDelimiter, 1, Pos + Stuff ) )
{
StringMid, member%A_Index%, Set1, %Lead%, Pos - Lead
Lead := Pos + Stuff
}
Else Break
Loop %Size% ; for each member, generate the permutation of the
{ ; other members and append that onto our result
Pos := member1
Loop % Size-1
{
Lead := A_Index + 1
member%A_Index% := member%Lead%
leftover := ( A_Index = 1 ? member%A_Index%
: leftover . PrimaryDelimiter . member%A_Index% )
}
member%Size% := Pos
Set .= PrimaryDelimiter . Set_Permutations( leftover, PrimaryDelimiter, SecondaryDelimiter , ( StrLen(p) ? p SecondaryDelimiter : "" ) . member%Size% )
}
StringTrimLeft, Set, Set, %Stuff%
Return Set
}
Set_Power( Set1, PrimaryDelimiter="`n", SecondaryDelimiter="," ) {
; Returns the power set of 'Set1'. In other words, every distinct combination
; of members from 'Set1' ( separated by 'SecondaryDelimiter' ) is returned in
; a list with a size equal to 2^(||Set1||). Also, the resulting list is in
; order by number of sub-members in each member, starting with zero (null)
Size := Set_Size( Set1, PrimaryDelimiter )
VarSetCapacity( Set, StrLen(Set1) * ( 1 << Size ), 0 )
Loop, %Size%
Set .= PrimaryDelimiter . Set_Combinations( Set1, A_Index, PrimaryDelimiter, SecondaryDelimiter )
Return Set
}
Set_Remove( Set1, Set2, PrimaryDelimiter="`n" ) {
; Performs a set intersection of 'Set1' and the complement of 'Set2'
Set1 .= PrimaryDelimiter
Set2 := PrimaryDelimiter . Set2 . PrimaryDelimiter
VarSetCapacity( Set, StrLen( Set1 ) )
Stuff := StrLen( PrimaryDelimiter )
Pos := 1 - Stuff
Lead := 1
Loop
If ( 0 < Pos := InStr( Set1, PrimaryDelimiter, 1, Pos + Stuff ) )
{
StringMid, member, Set1, %Lead%, Pos - Lead
Lead := Pos + Stuff
If !InStr( Set2, PrimaryDelimiter . member . PrimaryDelimiter, 1 )
Set .= PrimaryDelimiter . member
}
Else Break
StringTrimLeft, Set, Set, %Stuff%
Return Set
}
Set_Transpose( Set1, PrimaryDelimiter="`n", SecondaryDelimiter="," ) {
; Flips a set so that the columns become the rows.
; Any mising members will be made blank.
VarSetCapacity( Set, StrLen( Set1 ))
Set1 .= PrimaryDelimiter
Stuff := StrLen( PrimaryDelimiter )
iStuff := StrLen( SecondaryDelimiter )
Pos := 1 - Stuff
Lead := 1
w := 0
Loop ; convert the set into a local array
If ( 0 < Pos := InStr( Set1, PrimaryDelimiter, 1, Pos + Stuff ) )
{
StringMid, member, Set1, %Lead%, Pos - Lead
i := A_Index
Lead := Pos + Stuff
member .= SecondaryDelimiter
ilead := 1
ipos := 1 - istuff
Loop
If ( 0 < ipos := InStr( member, SecondaryDelimiter, 1, ipos + Stuff ) )
{
StringMid, member%i%_%A_Index%, member, %ilead%, ipos - ilead
ilead := ipos + iStuff
If ( A_Index > w )
w := A_Index
}
Else Break
member := A_Index
}
Else Break
Loop, %w%
{
i := A_Index
Loop, %member%
Set .= ( A_Index = 1 ? PrimaryDelimiter : SecondaryDelimiter ) . member%A_Index%_%i%
}
StringTrimLeft, Set, Set, %Stuff%
Return Set
}
Set_Size( Set, PrimaryDelimiter="`n" ) {
; Returns the total number of members in 'Set'. NOTE: an empty string
; always contains ZERO members, while any non-empty string contains
; a MINIMUM of ONE member.
If ( StrLen( Set ) = 0 )
Return 0
oscs := A_StringCaseSense
StringCaseSense, On
oel := ErrorLevel
StringReplace, Set, Set, %PrimaryDelimiter%, %PrimaryDelimiter%, UseErrorLevel
StringCaseSense, %oscs%
Return ErrorLevel + 1, ErrorLevel := oel
}
Set_Union( Set1, Set2, PrimaryDelimiter="`n" ) {
; Returns the set which is the union of the members in Set1 and Set2
; This function also removes duplicate members in the union.
; ( Removing duplicates is really the point of this function )
Set1 .= PrimaryDelimiter
If StrLen( Set2 ) > 0
Set1 .= Set2 . PrimaryDelimiter
VarSetCapacity( Set, StrLen( Set1 ) )
Stuff := StrLen( PrimaryDelimiter )
Pos := 1 - Stuff
Lead := 1
Loop
If ( 0 < Pos := InStr( Set1, PrimaryDelimiter, 1, Pos + Stuff ) )
{
StringMid, member, Set1, %Lead%, Pos - Lead
Lead := Pos + Stuff
If !InStr( Set . PrimaryDelimiter, PrimaryDelimiter . member . PrimaryDelimiter, 1 )
Set .= PrimaryDelimiter . member
}
Else Break
StringTrimLeft, Set, Set, %Stuff%
Return Set
}
Set_Zip( Set1, Set2, PrimaryDelimiter="`n", SecondaryDelimiter="," ) {
; Returns a new set where the 'N'th member is a concatenation of
; the 'N'th member of Set1, SecondaryDelimiter, and the 'N'th member of Set2
; If a set doesn't have an 'N'th member, its 'N'th member is
; considered blank.
Set1 .= PrimaryDelimiter
Set2 .= PrimaryDelimiter
VarSetCapacity( Set, StrLen( Set1 ) + StrLen( Set2 ) )
Stuff := StrLen( PrimaryDelimiter )
Pos1 := Pos2 := 1 - Stuff
Lead1 := Lead2 := Out1 := Out2 := 1
Loop
If ( 0 < Pos1 := Out1 * InStr( Set1, PrimaryDelimiter, 1, Pos1 + Stuff ) )
+ ( 0 < Pos2 := Out2 * InStr( Set2, PrimaryDelimiter, 1, Pos2 + Stuff ) )
{
If ( Out1 := ( Pos1 != 0 ) )
StringMid, member1, Set1, %Lead1%, Pos1 - Lead1
Else
member1 := ""
Lead1 := Pos1 + Stuff
If ( Out2 := ( Pos2 != 0 ) )
StringMid, member2, Set2, %Lead2%, Pos2 - Lead2
Else
member2 := ""
Lead2 := Pos2 + Stuff
Set .= PrimaryDelimiter . member1 . SecondaryDelimiter . member2
}
Else Break
StringTrimLeft, Set, Set, %Stuff%
Return Set
}
Set_SampleSet( n ) {
; Here are 8 sample sets for use in testing various parts of this library
Return n = 3 ? "
( LTRIM
False
[VxE]
True
)" : n = 4 ? "
( LTRIM
Cherry
Tangerine
Chocolate
BubbleGum
)" : n = 5 ? "
( LTRIM
Butterfinger
3 Musketeers
Milky Way
Baby Ruth
Kit Kat
)" : n = 6 ? "
( LTRIM
Puppet
Roller Skates
Guitar
Slingshot
Bandage
Handcuffs
)" : n = 7 ? "
( LTRIM
Katar
Cutlass
Gladius
Flamberge
Dirk
Stiletto
Claymore
)" : n = 8 ? "
( LTRIM
Baby Ruth
Twix
Kit Kat
Butterfinger
100 Grand
3 Musketeers
Almond Joy
Milky Way
)" : n = 9 ? "
( LTRIM
Horse
Turtle
Gibbon
Elephant
Kitten
Chicken
Hampster
Crocodile
Pigeon
)" : n = 10 ? "
( LTRIM
Rabbit
Monkey
Pony
Kitten
Puppy
Seal
Goat
Chicken
Piglet
Donkey
)" : "0`n1"
} |
[Edit: 2-10-2010] Set functions | Code: | ;
; Set functions library (Upgraded), By [VxE]
;
; Introduction:
; Sets are an important concept in OOP, data management, and
; discrete mathematics. This function library allows you to
; define sets of string objects and perform basic set functions
; on them. Additionally, this library offers two functions for
; handling multi-dimensional sets: Set_Zip joins two sets
; on a 1:1 basis and Set_Column extracts a set from a complex
; set. The real power behind this library is the ability to use
; any string as a delimiter, rather than just a single character.
; This feature makes it easy to work with data collections in
; multiple text formats and to construct multi-dimensional sets
; without limits.
;
; Definitions:
; a 'delimiter' is a substring with a length greater than zero.
; a 'member' is a string within a 'set' bounded by delimiters and/or
; the ends of the string.
; a 'set' is a string containing zero or more members, each separated
; from the previous and next member by an instance of a delimiter.
;
; Functions:
; Set_Column
; Set_Delimit
; Set_GetPos
; Set_GetPosRegEx
; Set_Intersect
; Set_Member
; Set_Remove
; Set_Size
; Set_Union
; Set_Zip
;
; Notes:
; All string comparisons are case sensitive with the exception of
; Set_GetPosRegEx, which leaves case sensitivity up to the regex.
; When using Set_GetPosRegEx, it is highly recommended to use the
; 'S' option in the needleregex since the function loops RegexMatch
; internally and therefore can be very slow.
Set_Column( Set1, column, PD="`n", SD="," ) {
; Returns a set which is comprised of the 'column'th sub-member of
; each of 'Set1's members. Essentially, if each member were like a
; row in a table, this function would pull a column out of that table.
VarSetCapacity( Set, StrLen( Set1 ))
column := Floor( column )
Set1 .= PD
Stuff := StrLen( PD )
iStuff := StrLen( SD )
Pos := 1 - Stuff
Lead := 1
Loop
If ( 0 < Pos := InStr( Set1, PD, 1, Pos + Stuff ) )
{
StringMid, member, Set1, %Lead%, Pos - Lead
Lead := Pos + Stuff
member .= SD
ilead := 1
ipos := 1 - istuff
Loop
If ( 0 < ipos := InStr( member, SD, 1, ipos + Stuff ) )
{
StringMid, imember, member, %ilead%, ipos - ilead
ilead := ipos + iStuff
If ( A_Index < column )
Continue
Set .= PD . imember
Break
}
Else Break
}
Else Break
StringTrimLeft, Set, Set, %Stuff%
Return Set
}
Set_Delimit( Set1, NewD, PD="`n" ) {
; Replaces every instance of 'PD' in 'Set1' with 'NewD', effectively
; changing the set's delimiter.
oel := ErrorLevel
StringReplace, Set1, Set1, %PD%, %NewD%, All
Return Set1, ErrorLevel := oel
}
Set_GetPos( Set1, string, PD="`n" ) {
; Returns the index of the first member of 'Set1' that is an exact
; match of 'string'. The return value is zero if there is no match.
If ( 1 >= Pos := InStr( PD . Set1 . PD, PD . string . PD, 1 ) )
Return Pos
StringLeft, Set1, Set1, % Pos - 1
Return Set_Size( Set1, PD)
}
Set_GetPosRegEx( Set1, NeedleRegex, PD="`n" ) {
; Returns the index of the first member of 'Set1' that is a match
; of 'NeedleRegex'. The return value is zero if there is no match.
; NOTE: the regex needle should not account for the delimiters.
Stuff := StrLen( PD )
Set1 .= PD
Pos := 1 - Stuff
Lead := 1
Loop
If ( 0 < Pos := InStr( Set1, PD, 1, Pos + Stuff ) )
{
StringMid, member, Set1, %Lead%, Pos - Lead
Lead := Pos + Stuff
If RegexMatch( member, NeedleRegex )
Return A_Index
}
Else Break
Return 0
}
Set_Intersect( Set1, Set2, PD="`n" ) {
; Performs a set intersection of 'Set1' and 'Set2'. Only the members
; that are in both sets will be in the resulting set.
If ( Set_Size( Set1 ) > Set_Size( Set2 ) )
Set := Set2, Set2 := Set1, Set1 := Set
VarSetCapacity( Set, StrLen( Set1 ), 0)
Set1 .= PD
Set2 := PD . Set2 . PD
Stuff := StrLen( PD )
Pos := 1 - Stuff
Lead := 1
Loop
If ( 0 < Pos := InStr( Set1, PD, 1, Pos + Stuff ) )
{
StringMid, member, Set1, %Lead%, Pos - Lead
Lead := Pos + Stuff
If InStr( Set2, PD . member . PD, 1 )
Set .= PD . member
}
Else Break
StringTrimLeft, Set, Set, %Stuff%
Return Set
}
Set_Member( Set1, Which, PD="n" ) {
; Returns the 'Which'th member of Set1. A 'Which' less than 1 is
; considered an offset from the last member ('0' being the last)
Len := Set_Size( Set1, PD )
Which := Floor( Which )
If ( Which <= 0 ) && ( Len + Which > 0 )
Which := Len + Which
If ( Which > Len ) || ( Which <= 0 )
Return ""
Set1 .= PD
Stuff := StrLen( PD )
Pos := 1 - Stuff
Lead := 1
Loop
If ( 0 < Pos := InStr( Set1, PD, 1, Pos + Stuff ) )
&& ( A_Index < which )
Lead := Pos + Stuff
Else Break
StringMid, member, Set1, %Lead%, Pos - Lead
Return member
}
Set_Remove( Set1, Set2, PD="`n" ) {
; Performs a set intersection of 'Set1' and the complement of 'Set2'
Set1 .= PD
Set2 := PD . Set2 . PD
VarSetCapacity( Set, StrLen( Set1 ) )
Stuff := StrLen( PD )
Pos := 1 - Stuff
Lead := 1
Loop
If ( 0 < Pos := InStr( Set1, PD, 1, Pos + Stuff ) )
{
StringMid, member, Set1, %Lead%, Pos - Lead
Lead := Pos + Stuff
If !InStr( Set2, PD . member . PD, 1 )
Set .= PD . member
}
Else Break
StringTrimLeft, Set, Set, %Stuff%
Return Set
}
Set_Size( Set, PD="`n" ) {
; Returns the total number of members in 'Set'. NOTE: an empty string
; always contains ZERO members, while any non-empty string contains
; a MINIMUM of ONE member.
If ( StrLen( Set ) = 0 )
Return 0
oscs := A_StringCaseSense
StringCaseSense, On
oel := ErrorLevel
StringReplace, Set, Set, %PD%, %PD%, UseErrorLevel
StringCaseSense, %oscs%
Return ErrorLevel + 1, ErrorLevel := oel
}
Set_Union( Set1, Set2, PD="`n" ) {
; Returns the set which is the union of the members in Set1 and Set2
; This function also removes duplicate members in the union.
; ( Removing duplicates is really the point of this function )
Set1 .= PD
If StrLen( Set2 ) > 0
Set1 .= Set2 . PD
VarSetCapacity( Set, StrLen( Set1 ) )
Stuff := StrLen( PD )
Pos := 1 - Stuff
Lead := 1
Loop
If ( 0 < Pos := InStr( Set1, PD, 1, Pos + Stuff ) )
{
StringMid, member, Set1, %Lead%, Pos - Lead
Lead := Pos + Stuff
If !InStr( Set . PD, PD . member . PD, 1 )
Set .= PD . member
}
Else Break
StringTrimLeft, Set, Set, %Stuff%
Return Set
}
Set_Zip( Set1, Set2, PD="`n", SD="," ) {
; Returns a new set where the 'N'th member is a concatenation of
; the 'N'th member of Set1, SD, and the 'N'th member of Set2
; If a set doesn't have an 'N'th member, its 'N'th member is
; considered blank.
Set1 .= PD
Set2 .= PD
VarSetCapacity( Set, StrLen( Set1 ) + StrLen( Set2 ) )
Stuff := StrLen( PD )
Pos1 := Pos2 := 1 - Stuff
Lead1 := Lead2 := Out1 := Out2 := 1
Loop
If ( 0 < Pos1 := Out1 * InStr( Set1, PD, 1, Pos1 + Stuff ) )
+ ( 0 < Pos2 := Out2 * InStr( Set2, PD, 1, Pos2 + Stuff ) )
{
If ( Out1 := ( Pos1 != 0 ) )
StringMid, member1, Set1, %Lead1%, Pos1 - Lead1
Else
member1 := ""
Lead1 := Pos1 + Stuff
If ( Out2 := ( Pos2 != 0 ) )
StringMid, member2, Set2, %Lead2%, Pos2 - Lead2
Else
member2 := ""
Lead2 := Pos2 + Stuff
Set .= PD . member1 . SD . member2
}
Else Break
StringTrimLeft, Set, Set, %Stuff%
Return Set
} |
_________________ My Home Thread
Common Answers: [1]. It's in the FAQ [2]. Ternary ( a ? b : c ) guide [3]. Post code inside [code][/code] tags !
Last edited by [VxE] on Wed Mar 03, 2010 4:26 am; edited 3 times in total |
|
| Back to top |
|
 |
[VxE]
Joined: 07 Oct 2006 Posts: 2392
|
Posted: Fri Apr 04, 2008 8:38 pm Post subject: Wheel Spinners for Edit Boxes with Numbers in them. |
|
|
[Edit: Update ( 6-3-08 )] | Code: | ; [VxE]'s Number Wheel Script
; Updated version of number control spinner
; Hover the mouse over an edit control with a number in
; its text and the scrollwheel can change the number
SetTimer, CheckMouseOverControl, 50
*WheelUp::
*WheelDown::
CheckMouseOverControl:
MouseGetPos,,,oWin,oCon
ControlGetText, cs, %oCon%, AHK_ID %oWin%
If !InStr(oCon, "Edit") || StrLen(cs) > 199
{
If (WheelsOnOff != "off")
{
WheelsOnOff := "off"
Hotkey, *Wheelup, *WheelUp, % WheelsOnOff
Hotkey, *WheelDown, *WheelDown, % WheelsOnOff
}
}
else
{
If (WheelsOnOff != "on")
{
WheelsOnOff := "on"
Hotkey, *Wheelup, *WheelUp, % WheelsOnOff
Hotkey, *WheelDown, *WheelDown, % WheelsOnOff
}
If (A_ThisLabel = "CheckMouseOverControl")
return
InPos := OutPos := 0 ; operate on first number found
Loop, Parse, cs
{
np := Asc(A_LoopField)
If ( np >= 45 && np <= 57 && np != 47 )
If ( InPos = 0 )
InPos := OutPos := A_Index
else
OutPos := (A_Index-Outpos-1) ? OutPos : A_Index
}
np := SubStr( cs, InPos, OutPos - InPos + 1 )
tic := (InStr(np, ".") ? np/20 : Ceil(np/20))
If (!GetKeyState("Shift") || !tic )
tic := 1
If (GetKeyState("Ctrl"))
tic := 0.001 + GetKeyState("shift") * 0.024
np -= tic * ((!InStr(A_ThisHotkey, "up")) * 2 - 1 )
If InStr( np, "." )
Loop 9
If !SubStr(np,0)
StringTrimRight, np, np, 1
else
break
ControlSetText, %oCon%, % SubStr(cs,1,InPos-1) np SubStr(cs,OutPos+1),AHK_ID %oWin%
}
return |
new version (above) replaces old version (below).
Changes 1: Uses a timer to watch the mouse cursor to see if it's over a valid control, then if it is, the wheel keys become active and block the wheel events from reaching the target window, thus preventing any native wheel support the target app might have for such controls. To bypass this, simply put the control in focus and move the cursor off the control before using the mousewheel (that allows the wheel event to reach the app's window).
2: To adjust the rate faster (5%), hold [shift] while scrolling. To force adjustments by 0.001, hold [ctrl]. To force an increment of 0.025, hold [ctrl][shift].
3: This script is meant to make adjusting numbers in edit controls easier for someone using a laptop (no numpad) and a logitech mouse with flywheel scrolling.
[End Edit]
Numerical Control Spinner. This script simulates the ability of the scroll wheel to adjust numbers in edit boxes. This behavior is commonly seen in programs like photoshop, where there are a number of edit boxes for brush settings and stuff. This script operates on the control that is currently under the mouse cursor, so if an edit box already has the wheelie change built in, this script will interfere with that (just don't hover the mouse over those controls and it will work OK)
The Default increment is 1, although I have the script set to increase this increment to 5% of the current value if the user waits for 2 seconds between two wheel ticks. The incrementing value can be reset to 1 by activating any other non-wheel hotkey.
Additional Support Idea for Future Update: Support selecting a number in text and changing it with the scrollwheel.
| Code: | ; Auto spinners for numerical controls
~*LButton::return
~*WheelUp::
~*WheelDown::
MouseGetPos, X, Y, oWin, oCon
If !InStr(oCon, "Edit") ; we only want spinners to work on edit
return ; controls, not for things like buttons and such
ControlGetText, gvar, %oCon%, AHK_ID %oWin%
ovar := gvar ; chop up a copy
Loop 8 ; provide accomodation to remove stupid words after numbers in the
If ( ovar + 1 = "" ) ; edit box like "inches" or "pixels"
ovar := SubStr(ovar, 1, -1)
else
break
If ( ovar + 1 != "" ) ; so, our edit control contains a number, brilliant!
{
gvar := SubStr(gvar, StrLen(ovar)) ; remove the number part
If !InStr(A_PriorHotkey, "~*Whee") ; use of a non-wheel hotkey will
uinc := 1 ; reset the step size to 1
Else If A_TimeSincePriorHotkey > 2000 ; wait for 2 seconds to set the
uinc := ovar // 20 ; step size to approx 5% of the current value
ovar += ((A_ThisHotkey = "~*WheelUp")*2-1) * uinc * ((uinc > 0)*2-1) + (uinc + 0.0 = 0)
ControlSetText, %oCon%, % ovar gvar, AHK_ID %oWin% ; note the %ovar%%gvar%...
}
return |
_________________ My Home Thread
Common Answers: [1]. It's in the FAQ [2]. Ternary ( a ? b : c ) guide [3]. Post code inside [code][/code] tags !
Last edited by [VxE] on Wed Jun 04, 2008 7:37 am; edited 1 time in total |
|
| Back to top |
|
 |
[VxE]
Joined: 07 Oct 2006 Posts: 2392
|
Posted: Fri Apr 04, 2008 8:47 pm Post subject: [VxE]'s Encryption With GUI |
|
|
My Encryption Function... this examples has a simple gui but you can strip out the functions if you'd like. The function's parameters are as follows: str, str, bool.
The first parameter is the key (i.e. password), the second is the message, the third is a switch to specify wither forwards or backwards.
I have added another function () for users who desire greater readability. All that function does is call the main function with the 3rd parameter set to "1".
The only difference between 'encryption' and 'decryption' is the direction of the algorithm. In other words, 'decryption' is the inverse function of 'encryption' and vice versa ad infinitum.
| Code: | ; [VxE]'s Double-Dynamic Key-Based Encryption Script
; A fully functional security script for protecting text
; version 1.b, Optimized key handling for large keys
; last edit: [7-10-08]
#SingleInstance force
wid := A_ScreenWidth // 2
bwid := (wid - 100) // 5
cwid := wid // 5
dwid := wid - 100
edh := A_ScreenHeight //100
Gui, font, s16, Arial
Gui, Add, Text, w90, Key
Gui, Add, Edit, X100 R1 vMyKey Y10 W%dwid%
Gui, Add, Edit, +wrap R%edh% vInMessage X10 W%wid%
Gui, Add, Edit, Disabled +wrap R%edh% vOutMessage X10 W%wid%
Gui, Add, Button, w%bwid% x25 gEncrypt, Encrypt
Gui, Add, Button, w%bwid% yp xp+%cwid% gDecrypt, Decrypt
Gui, Add, Button, w%bwid% yp xp+%cwid% gSwap, Swap Fields
Gui, Add, Button, w%bwid% yp xp+%cwid% gcopy, Copy Text
Gui, Add, Button, w%bwid% yp xp+%cwid% gGuiClose, &Quit
Gui, Show, AutoSize, [VxE]'s Double-Dynamic Key-Based Encryption Function
return
GuiClose:
GuiEscape:
exitapp
copy:
Swap:
GuiControlGet, OutMessage,,
If A_ThisLabel = copy
StringReplace, clipboard, OutMessage, `n, `r`n, all
else
{
GuiControlGet, InMessage,,
StringReplace, OutMessage, OutMessage, `r`n, `n, all
StringReplace, InMessage, InMessage, `r`n, `n, all
GuiControl,, InMessage, %OutMessage%
GuiControl,, OutMessage, %InMessage%
}
return
Decrypt:
Encrypt:
GuiControlGet, MyKey,,
GuiControlGet, InMessage,,
GuiControl,, OutMessage, % Encrypt( mykey, InMessage, A_ThisLabel )
return
; Readability consideration, example:
; result := Decrypt( key, message ) ; will attempt to decrypt the message
Decrypt( key, message, optional = "" )
{
return Encrypt( key, message, !optional )
}
; Param 3 is a binary switch to determine this function's direction.
; [blank], [0], or ["e*"] yields forwards, anything else yields backwards.
; Readability consideration: simply omit the third parameter and use "Decrypt()" to decrypt.
Encrypt(key, message, CryptEvent = "")
{ ; CryptEvent defaults to 'encrypt', but really only the first letter is needed
LowerBound = 34
UpperBound = 126
StringReplace, Message, Message, `r`n, `n, all
StringLeft, CryptEvent, CryptEvent, 1
If !CryptEvent
CryptEvent = e
Loop, parse, key
key .= "`n" Asc(A_LoopField)
key := SubStr(key, InStr(Key, "`n",0,1)+1)
NewMessage =
Loop, Parse, Message
{
code := Asc(A_LoopField)
If ( code >= LowerBound ) && ( code <= UpperBound )
{
mco := code
prevc := A_Index
newkey := ""
Loop, Parse, key, `n
code := Clamp(( code - (A_LoopField * ( Mod(A_LoopField, 2)
* 2 - 1 )) * ((CryptEvent = "e") * 2 - 1) ), LowerBound, UpperBound )
If CryptEvent = e
mco := code
Loop, Parse, key, `n
newkey .= "`n" (prevc := Clamp((A_LoopField + mco * (Mod((mco
+Prevc), 2) * 2 - 1) + Prevc), 1, 255))
key := SubStr( newkey, 2 )
}
NewMessage .= Chr(code)
}
return % NewMessage
}
clamp( number, low, high ) ; altered mutation of Mod() function
{ ; 7-10-2008 edit:
span := (high - low + (high > low)*2 - 1)
return number + span * Round(((low-number)/2 + (high-number)/2)/span)
} |
_________________ My Home Thread
Common Answers: [1]. It's in the FAQ [2]. Ternary ( a ? b : c ) guide [3]. Post code inside [code][/code] tags !
Last edited by [VxE] on Thu Jul 10, 2008 10:10 pm; edited 3 times in total |
|
| Back to top |
|
 |
[VxE]
Joined: 07 Oct 2006 Posts: 2392
|
Posted: Fri Apr 04, 2008 8:52 pm Post subject: Joystick to Numberpad |
|
|
G-Functions: make your gui controls trigger a function in the same manner as they would trigger a g-label.
| Code: | ; G-Functions: Set up gui controls with a function instead of a g-label. This technique
; was proposed by yanjchan # http://www.autohotkey.com/forum/viewtopic.php?t=53227
; though there have been several threads asking for functions to be associated with
; gui controls the way g-labels can. Format a gui control's options like this example:
; Gui, Add, Edit, gGFunctionHandler vFunction[%A_Now%?#this#?#A_GuiControl#]
; In this example, 'Function' is the name of a function in the script, %A_Now% is
; resolved when the control is added to the gui. #this# is resolved when the g-label
; triggers (and it becomes the contents of the control, via GuiControlGet). Similarly,
; #A_GuiControl# is resolved when the g-label triggers and it becomes the exact string
; following the 'v' in the example. The question marks delimit the parameters the way
; commas delimit parameters in a function call.
GFunctions() { ; For library inclusion, name this file "GFunctions.ahk".
; Calling this function returns the name of the label needed to use g-functions.
Return "GFunctionHandler"
}
GFunctionHandler:
Critical
ErrorLevel := GFunctionHandler(A_GuiControl)
If InStr( ErrorLevel, "Error: " ) = 1
MsgBox, %ErrorLevel%
Return
GFunctionHandler(¿f) {
; This function examines a control's variable name and constructs a function
; call with parameters based on it.
Local ¿0, ¿1, ¿2, ¿3, ¿4, ¿5, ¿6, ¿7, ¿8, ¿9, ¿10, ¿11, ¿12, ¿13
, ¿14, ¿15, ¿16, ¿17, ¿18, ¿19, ¿20, ¿21, ¿22, ¿23, ¿24, ¿25, ¿26
, ¿27, ¿28, ¿29, ¿30, ¿31, ¿32, ¿33, ¿34, ¿35, ¿36, ¿37, ¿38, ¿39
, ¿40, ¿41, ¿42, ¿43, ¿44, ¿45, ¿46, ¿47, ¿48, ¿49, ¿50, ¿51, ¿52
, ¿53, ¿54, ¿55, ¿56, ¿57, ¿58, ¿59, ¿60, ¿61, ¿62, ¿63, ¿64, this
If RegexMatch( ¿f, "[^\w@$?#\[\]\x80-\xff]")
Return "Error: Invalid G-Function"
; error: the input contains an illegal character
GuiControlGet, ¿0, HWND, %¿f% ; get the HWND of the control
VarSetCapacity( ¿1, 256, 0 ) ; make space in this variable
; get the control class name for this control
DllCall("GetClassName", "uint", ¿0, "str", ¿1, "int", 255 )
If ( ¿1 == "SysListView32" ) ; it's a listview
Gui, Listview, %¿f%
Else If ( ¿1 == "SysTreeView32" ) ; it'a a treeview
Gui, Treeview, %¿f%
Else If ( ¿1 != "" ) ; Load the reserved variable 'this'
GuiControlGet, this,, %¿f%
If InStr( ¿f, "]", 0, 0 ) == StrLen( ¿f )
{ ; parse the parameters listed in the g-function
¿0 := SubStr( ¿f, ¿1 := InStr( ¿f, "[" ) + 1, -1 )
StringLeft, ¿f, ¿f, % ¿1 - 2
¿1 := ""
Loop, Parse, ¿0, ?
{
StringReplace, ¿0, A_LoopField, #, `%, all
Transform, ¿%A_Index%, DEREF, %¿0%
If ( 64 <= ¿0 := A_Index ) ; we have a hard limit of 64 parameters
Break
}
}
Else ; the g-function specifies no parameters
¿0 := 0
If StrLen( ¿f ) == 0
Return "Error: The G-Function name is blank"
StringReplace, ¿f, ¿f, #, #, UseErrorLevel
If !Mod( ErrorLevel, 2 ) && Errorlevel > 0
{
StringReplace, ¿f, ¿f, #, `%, All
Transform, ¿f, DEREF, %¿f%
}
; ¿0 contains the number of parameters in the g-function. Now check the function name
If ( 0 < this := IsFunc( ¿f )) ; if the function exists...
&& ( this-1 <= ¿0 ) ; ... and we have enough parameters, then do it
Return %¿f%( ¿1, ¿2, ¿3, ¿4, ¿5, ¿6, ¿7, ¿8, ¿9, ¿10, ¿11, ¿12, ¿13
, ¿14, ¿15, ¿16, ¿17, ¿18, ¿19, ¿20, ¿21, ¿22, ¿23, ¿24, ¿25, ¿26
, ¿27, ¿28, ¿29, ¿30, ¿31, ¿32, ¿33, ¿34, ¿35, ¿36, ¿37, ¿38, ¿39
, ¿40, ¿41, ¿42, ¿43, ¿44, ¿45, ¿46, ¿47, ¿48, ¿49, ¿50, ¿51, ¿52
, ¿53, ¿54, ¿55, ¿56, ¿57, ¿58, ¿59, ¿60, ¿61, ¿62, ¿63, ¿64 )
Return this ? "Error: Not enough parameters in the g-function"
: "Error: The g-function does not exist"
} |
_________________ My Home Thread
Common Answers: [1]. It's in the FAQ [2]. Ternary ( a ? b : c ) guide [3]. Post code inside [code][/code] tags !
Last edited by [VxE] on Thu Feb 11, 2010 8:29 am; edited 4 times in total |
|
| Back to top |
|
 |
[VxE]
Joined: 07 Oct 2006 Posts: 2392
|
Posted: Fri Apr 04, 2008 9:11 pm Post subject: Clipboard Execute |
|
|
A more recent manifestation of one of my earlier scripts. This script attempts to run the contents of the clipboard as an AHK script with added safeguards and self-cleaning features.
Update: 1-10-10. New version (5).
Features:
- Any number of files may be included (via #Include) in the script generated by the ClipEx function. See the comments regarding the 'ClipEx_Includes' variable
- Certain keywords are under the 'Blacklist' variable, if any of those words are found on the clipboard, a confirmation dialogue will ask whether you wish to run the code anyways.
- The script file that is generated each time the function runs is deleted if it is no longer running.
- Script files are given unique names
- When executing code with a gui, the label "GuiClose" is added if it isn't already in the code. The label is followed by "Exitapp"
- The format of this code is flow-neutral, meaning that it will not interrupt the Auto-Execute section if placed there (or anywhere else, for that matter).
| Code: | ; ClipEx5
; Clipboard Execute, version 5 (by [VxE])
; To use: call the function ClipEx() from anywhere in your script.
; Reserved global variable: "ClipEx_p" -> contains a list of active PIDs and script file paths.
; Reserved label: "ClipEx_check_existence" -> parses "ClipEx_p" and cleans up once scripts have finished.
ClipEx()
{
Global ClipEx_p
Static IsInitialized, ClipEx_Lifespan, ClipEx_CancelKey, Keywords_Blacklist
, ClipEx_Includes, Blacklist_Warning, Write_Run_Delay
If ! IsInitialized
{ ; begin static initialization
Write_Run_Delay = 50 ; milliseconds to wait between writing the clipex file and running it
ClipEx_Lifespan = 60 ; seconds until the script terminates unconditionally
ClipEx_CancelKey = Esc ; put a hotkey here to be a killswitch for the script
Keywords_Blacklist =
( ltrim C
; ClipEx will show a confirmation MsgBox before running code which contains any of these words.
regwrite
filedelete
A_Startup
shutdown
; onexit
UrlDownloadToFile
)
Blacklist_Warning =
( ltrim % join`s
The word%plural% "%Matched_Blacklist%" %was_were%
found in the clipboard.`nThis could cause
undesired or malicious effects if run.
`n`nDo you wish to continue ?
)
ClipEx_Includes =
( ltrim C
; List here all files, or directories containing .ahk files, that should be
; #included in the ClipEx script. There is no message when any of these fails.
; These are checked / updated on the fly, and non-absolute paths use the current working directory
%A_MyDocuments%\AutoHotkey\MyProject\Functions ; default example
; Also see 'libraries of functions' in AutoHotkey.chm
)
IsInitialized = 1
} ; end static initialization
Thread, NoTimers ; cuz we don't need interruptions
; Use the current working direcrtory for non-absolute paths to #include
ClipEx_included := ""
Loop, Parse, ClipEx_Includes, `n, `r %A_Tab%
If InStr( ClipEx_m := FileExist( A_LoopField ), "D" ) ; if the file is a directory
Loop, % A_LoopField . ( SubStr( A_LoopField, 0 ) = "\" ? "" : "\" ) . "*.ahk"
ClipEx_included .= "`r`n#Include, " A_LoopFileLongPath
Else If (ClipEx_m)
ClipEx_included .= "`r`n#Include, " A_LoopField
ClipEx_Template = ; load the template
( ltrim
; [VxE]'s ClipEx, version 5.
; This file was generated by inserting the clipobard's text into a template
SetTimer, ClipEx_Cleanup, -%ClipEx_LifeSpan%000
Hotkey, %ClipEx_CancelKey%, ClipEx_Cleanup, on
; This is the beginning of the clipboard's text
%Clipboard%
; This is the end of the clipboard's text.
ClipEx_Cleanup: ; this label is called by a timer set at the top of the script
critical
Exitapp
; #Included Files
%ClipEx_included%
)
; Automatically replace the cleanup label with 'guiclose' if the clipboard contains
; 'Gui' but does not contain 'guiclose'. This is simply a convenience so that the
; script will exit when you close the clipex Gui, instead of simply hiding the gui
; and waiting for its lifespan to run out
If InStr( ClipEx_Template, "Gui" ) && !InStr( ClipEx_Template, "GuiClose:" )
StringReplace, ClipEx_Template, ClipEx_Template, ClipEx_Cleanup, GuiClose, All
; Check the script text for any blacklisted words
Matched_Blacklist := "", plural := 0
Loop, parse, Keywords_Blacklist, `n
If InStr(ClipEx_Template, A_LoopField)
Matched_Blacklist .= A_Tab . A_LoopField, plural++
StringTrimLeft, Matched_Blacklist, Matched_Blacklist, 1
Loop, % plural - 2 ; replace all but the last delimiter with ", "
StringReplace, Matched_Blacklist, Matched_Blacklist, %A_Tab%, % """, """
; Replace the last delimiter with " and ". This is only a superficial feature
StringReplace, Matched_Blacklist, Matched_Blacklist, %A_Tab%, " and "
If plural ; if there are more then zero blacklisted words in the script
{
was_were := plural = 1 ? "was" : "were" ; what it is
plural := plural = 1 ? "" : "s" ; gramMaR!
Transform, text, DEREF, %Blacklist_Warning%
MsgBox, 52, Security Warning !!, %text% ; show a msgbox with the warning
IfMsgBox, No ; the user decided not to run the code after all
return
}
ClipEx := "ClipEx" . A_Now . SubStr( A_TickCount, -2 ) . ".ahk"
FileAppend, %ClipEx_Template%, %ClipEx%
Sleep %Write_Run_Delay%
Run, %A_AhkPath% "%ClipEx%",,, ClipEx_m ; keep the PID of the spawned script
ClipEx_p .= ClipEx_m . "?" . ClipEx . "`n" ; append it to our list
SetTimer, ClipEx_check_existence, 200
return
} ; end of ClipEx() function
Loop 0 ; this causes script execution to skip the following block
{
ClipEx_check_existence:
; Check our spawned ClipEx processes. Once the process terminates, delete the ClipEx file
DetectHiddenWindows, on
If ( ClipEx_p = "`n" )
SetTimer, ClipEx_check_existence, off
Else
Loop, Parse, ClipEx_p, `n ; parse through the list
{
StringSplit, ClipEx_, A_LoopField, ?
If ClipEx_0 <> 2
continue
If !WinExist( "Ahk_PID " ClipEx_1 ) ; if the script's window can't be found
{
StringReplace, ClipEx_p, ClipEx_p, `n%A_LoopField%`n, `n
FileDelete, %ClipEx_2% ; delete it and remove it from our list
}
}
return
} |
_________________ My Home Thread
Common Answers: [1]. It's in the FAQ [2]. Ternary ( a ? b : c ) guide [3]. Post code inside [code][/code] tags !
Last edited by [VxE] on Sun Jan 10, 2010 10:50 pm; edited 6 times in total |
|
| Back to top |
|
 |
[VxE]
Joined: 07 Oct 2006 Posts: 2392
|
Posted: Fri Apr 04, 2008 9:32 pm Post subject: Online Dictionary Easy Lookup Script |
|
|
Don't know what a word means? Just Control+Double-Click it (while this script is running)
The variable at the top (page) contains the URL for the results page of a dictionary or search page, some other popular ones are listed in comments below. To use a different search site, simply go to that site, type in a unique word into the search field, click 'search', then get the URL from the results page and replace your unique word with []MySearchTarget[] and put that into the script.
| Code: | ; [VxE]'s Ctrl+DblClick word lookup script
page = http://dictionary.cambridge.org/results.asp?searchword=[]MySearchTarget[]&x=48&y=1
; page = http://www.merriam-webster.com/dictionary/[]MySearchTarget[]
; page = http://www.google.com/search?hl=en&q=[]MySearchTarget[]&btnG=Google+Search
; page = http://search.yahoo.com/search?p=[]MySearchTarget[]&fr=yfp-t-501&toggle=1&cop=mss&ei=UTF-8
; page = http://en.wikipedia.org/wiki/Special:Search?search=[]MySearchTarget[]&fulltext=Search
~^LButton::
MouseGetPos, px, py
pm := px . py
If ( A_PriorHotkey = A_ThisHotkey )
&& (A_TimeSincePriorHotkey < DllCall("GetDoubleClickTime"))
&& (om = pm) ; if the mouse moved, it wasn't a double-click
{
Sleep 150
sclip := clipboardall
Clipboard := ""
Send ^c
Clipwait, 1
StringReplace, specpage, page, []MySearchTarget[], %Clipboard%
Clipboard := sclip
Run %specpage% ; open page in default browser
}
Else
om := pm
return |
_________________ My Home Thread
Common Answers: [1]. It's in the FAQ [2]. Ternary ( a ? b : c ) guide [3]. Post code inside [code][/code] tags ! |
|
| Back to top |
|
 |
[VxE]
Joined: 07 Oct 2006 Posts: 2392
|
Posted: Fri Apr 04, 2008 9:35 pm Post subject: Unicode in gui controls |
|
|
These functions are workarounds for using unicode in various circumstances. They are as follows: | Quote: | A2W( byref string ) - converts an ansi string that contains html-unicode into a bona fide wide-char string. Note that AHK will no longer be able to manipulate it as a string.
ControlSetTextW( Control OR HWND, string ) - Converts 'string' into a wide-char string and sets the designated control's text to that string.
ControlGetTextW( Control OR HWND ) - Retrieves wide-char text from a control and converts it into a mix of ascii and html-type character codes.
FileReadU( filepath ) - Returns the text inside the designated .txt file. It can handle files that contain unicode characters by converting such characters into their html-type codes. |
| Code: | A2W( byref str ) ; Ascii to Wide-char. Version 2.0
{ ; function by [VxE], changes a string into unicode format. Uses html-style
; codes for unicode characters (i.e. ሴ or 〹 ). Intended for
; external functions (via DllCall). Return value is the number of characters.
text := str
u := v := pos := 0
Loop
If (pos := InStr( text, "&#", 0, pos+1 ))
&& (pos2 := InStr( text, "`;", 0, pos ))
{
If (num := Abs("0" . SubStr( text, pos+2, pos2-pos-2 )))
{
u++
u%u% := num
StringReplace, text, text, % SubStr(text, pos, pos2-pos+1), % chr(4)
}
}
Else Break
VarSetCapacity(str, 2+2*len:=StrLen(text), 0) ; make space and wipe bits
Loop, Parse, text
If (num := Asc(A_LoopField)) = 4
v++, NumPut( u%v%, str, 2*A_Index-2, "UShort" )
Else NumPut( num, str, 2*A_Index-2, "UShort" )
return len
} |
| Code: | ; Unicode ControlSetText. Note: when using a ClassNN as the 'control' parameter
; this function tries to find it on the Last Found Window. Preceed any such calls
; with a command that updates the Last Found Window, such as IfWinExist
ControlSetTextW( control, newtext="" ) ; For best results, use the control's hwnd as the 'control' parameter
{
If control is INTEGER
hwnd := control
Else ControlGet, hwnd, hwnd,, %control%
A2W( newtext )
Return DllCall("SendMessageW", "uint", hwnd, "int", 0xC, "int", 0, "int", &newtext )
} |
| Code: | ; Unicode ControlGetText. Note: when using a ClassNN as the 'control' parameter
; this function tries to find it on the Last Found Window. Preceed any such calls
; with a command that updates the Last Found Window, such as IfWinExist
ControlGetTextW( control ) ; For best results, use the control's hwnd as the 'control' parameter
{
Static SizeLimit := 65536 ; aka 64 KB
If control is INTEGER
hwnd := control
Else ControlGet, hwnd, hwnd,, %control%
oif := A_FormatInteger
SetFormat, IntegerFast, D
VarSetCapacity( text, SizeLimit, 0 )
Size := DllCall("SendMessageW", "uint", hwnd, "int", 0xD, "int", SizeLimit//2, "int", &text )
VarSetCapacity( control, Size, 0 ) ; because of gradual concatenation
Loop %Size%
If ( Num := NumGet( text, 2*A_Index-2, "UShort" ) )
If ( Num < 0x100 )
control .= Chr(Num)
Else
control .= "&#" Num "`;"
SetFormat, IntegerFast, %oif%
return control
} |
| Code: | ; Save to file named "FileReadU.txt" in a lib folder or resource folder
; This function set reads notepad's .txt files and replaces any unicode
; characters with their html codes (i.e. "〹" )
FileReadU( filepath, ForceType="Auto: BOM" ) ; reads a txt file (notepad) even if it is in unicode format
{ ; function by [VxE], Version 1.3. Read the file and its BOM. Then, based on the BOM
; decode any unicode ( if there is any ). Supports all 4 of notepad's available formats,
; including Big-Endian Unicode and UTF-8.
; For filetypes without a BOM, specify ForceType = "UTF-8" or "Unicode" or "Big-endian Unicode"
;
FileGetSize, size, %filepath%
FileRead, file, %filepath%
oif := A_FormatInteger
SetFormat, IntegerFast, D
Type := NumGet( file, 0, "UShort" )
T2 := NumGet( file, 2, "UChar" )
ErrorLevel := Size
If Instr( ForceType, "Big" )
ErrorLevel := TxUnicodeBe( file, 0, size )
Else If InStr( ForceType, "UTF-8" ) = 1
ErrorLevel := TxUTF_8( file, 0, size )
Else If InStr(ForceType, "Unicode") = 1
ErrorLevel := TxUnicodeLe( file, 0, size )
Else If ( Type = 0xBBEF ) && ( T2 = 0xBF ) ; UTF-8 BOM
ErrorLevel := TxUTF_8( file, 2, size )
Else If (Type = 0xFEFF) ; 'normal' unicode BOM
ErrorLevel := TxUnicodeLe( file, 2, size )
Else If (Type = 0xFFFE) ; big-endian unicode BOM
ErrorLevel := TxUnicodeBe( file, 2, size )
SetFormat, Integer, %oif%
Return file
}
TxUTF_8( byref data, offset=3, size=0 ) ; Transcode a bitstream as though it were
{ ; function by [VxE]. Decode a UTF-8 string
VarSetCapacity( text, size+0 ? size : VarSetCapacity( data ), 0 )
Index := 0
Loop
If ( ch := NumGet( data, offset++, "UChar" ) )
If ( 2 = ( ch >> 6 ) ) ; this byte is part of a code sequence
code := (code << 6) | ( ch & 0x3F )
Else
{
If code
text .= code < 0x100 ? Chr(code) : "&#" code "`;"
code := 0
Index++
If ( 0x6 = ( ch >> 5 ) ) ; the beginning of a 2-byte sequence
code := ch & 0x1F
Else If ( 0xE = ( ch >> 4 ) ) ; the beginning of a 3-byte sequence
code := ch & 0xF
Else If ( 0x1E = ( ch >> 3 ) ) ; the beginning of a 4-byte sequence
code := ch & 0x7
Else text .= Chr( ch )
}
Else
{
data := text . ( code ? "&#" code "`;" : "" )
return A_Index - 1
}
}
TxUnicodeBe( byref data, offset=2, size=0 )
{ ; function by [VxE]. Decode a big-endian unicode string
VarSetCapacity( text, size+0 ? size : VarSetCapacity( data ), 0 )
Loop
If ( ch := NumGet( data, 2*A_Index-2+offset, "UShort" ) )
If !( ch & 0xFF )
text .= Chr(ch >> 8)
Else text .= "&#" (ch >> 8) | ((ch & 255) << 8) "`;"
Else
{
data := text
return A_Index-1
}
}
TxUnicodeLe( byref data, offset=2, size=0 )
{ ; function by [VxE]. Decode a little-endian unicode string
VarSetCapacity( text, size+0 ? size : VarSetCapacity( data ), 0 )
Loop
If ( ch := NumGet( data, 2*A_Index-2+offset, "UShort" ) )
If ( ch < 0x100 )
text .= Chr(ch)
Else text .= "&#" ch "`;"
Else
{
data := text
return A_Index-1
}
} |
_________________ My Home Thread
Common Answers: [1]. It's in the FAQ [2]. Ternary ( a ? b : c ) guide [3]. Post code inside [code][/code] tags !
Last edited by [VxE] on Sun Aug 09, 2009 9:43 pm; edited 10 times in total |
|
| Back to top |
|
 |
[VxE]
Joined: 07 Oct 2006 Posts: 2392
|
Posted: Fri Apr 04, 2008 9:49 pm Post subject: Vector Function Library |
|
|
This is my vector function library. I wrote it because I needed easy vector support for some of my other projects. I tried to optimize these functions for speed without sacrificing ease of use. I'm also working on a matrix function library as a companion to this vector lib.
| Code: | ; [VxE]'s vector function library [10-10-08]
; A collection of vector functions
; A formal vector has the format
; ##, ##, ##, ##;
; where ## indicates a real number.
; Formalized vector format is used internally to
; increase efficiency. Formalization optimizations
; are not strictly for internal use, if your input
; vectors are in the formal format, you may specify
; 1 as the second parameter to increase performance.
; Supported operations currently include:
; Float Vect_Item( Vector Index )
; Float Vect_Len( Vector )
; Float Vect_Dot( Vector . Vector )
; Float Vect_Angle(["deg"] Vector . Vector )
; Vector Vect_Formal( string )
; Vector Vect_Norm( Vector )
; Vector Vect_Sub( Vector ... Vector )
; Vector Vect_Add( Vector ... Vector )
; Vector Vect_Mult( Vector . Float )
; Vector Vect_Proj( Vector . Vector )
; Vector Vect_Reflect( Vector . Vector )
; Vector Vect_Cross( Vector . Vector )
;
; Returns the Nth member of the input vector
; NOTE: seperate the vector and the index
; by a semicolor or a newline character
; When using a formal vector, you may
; simply use the following format:
; result := Vect_Item( FormalVector . 3, 1 )
; This function will probably never be used
; because you can just use StringSplit and
; put all of the vector's members into vars
Vect_Item(vect, formal=0)
{
IfNotEqual, formal, 1
{
Loop, Parse, vect, `;`n, %A_Space%%A_Tab%`r`,
IfLess, A_Index, 3, SetEnv, factor%A_Index%, % Vect_Formal(A_LoopField)
Else Break
factor2 := SubStr(Factor2, 1, -1+InStr(Factor2, ","))
} Else StringSplit, factor, vect, `;, %A_Space%%A_Tab%`r`n`,
Loop, Parse, factor1, `,, %A_Space%`;
IfEqual, A_Index, % Round( factor2 ), return %A_LoopField%
return ""
}
; Returns the absolute length of the input vector
Vect_Len(vect, formal=0)
{
off := A_FormatFloat
SetFormat, Float, 0.15
IfNotEqual, formal, 1, SetEnv, vect, % Vect_Formal(vect)
Loop, Parse, vect, `,, %A_Space%`;
sum += A_LoopField**2
SetFormat, Float, %off%
return sqrt(sum)
}
; returns the dot product of the first two vectors.
; the dot product is an easy test of orthogonality
; if the dot product is zero, the two vectors are
; orthogonal (at a right-angle to each other)
Vect_Dot(vlist, formal=0)
{
off := A_FormatFloat
SetFormat, Float, 0.15
IfNotEqual, formal, 1, Loop, Parse, vlist, `;`n, %A_Space%%A_Tab%`r`,
{
IfEqual, A_LoopField,, Continue
IfEqual, True, % !(vect := Vect_Formal(A_LoopField)), continue
u++
StringSplit, v%u%d, vect, `,, %A_Space%%A_Tab%`r`;
IfLess, vorder, % v%u%d0, SetEnv, vorder, % v%u%d0
}
else Loop, Parse, vlist, `;`n, `r%A_Space%%A_Tab%
{
IfEqual, A_LoopField,, Continue
u++
StringSplit, v%u%d, A_LoopField, `,, `n%A_Space%
IfLess, vorder, % v%u%d0, SetEnv, vorder, % v%u%d0
}
Loop %vorder%
EnvAdd, acc, v1d%A_Index% * v2d%A_Index%
SetFormat, Float, %off%
return acc + 0
}
; returns the angle between the first two vectors in vlist
; Essentially, return the arccosine of the dot product of the
; normals of two vectors.
; default return value is in radians, specify "deg" before
; any vectors to return the angle in degrees. Example:
; ResultInDegrees := Vect_Angle( "deg" Vector1 Vector2 )
Vect_Angle(vlist, formal=0)
{
off := A_FormatFloat
SetFormat, Float, 0.15
deg := u := 1
IfEqual,True, % InStr(vlist,"deg")
SetEnv,vlist, % SubStr(vlist,53.3-deg:=45/ATan(1))
IfNotEqual, formal, 1, Loop, Parse, vlist, `;`n, %A_Space%%A_Tab%`r`,
{
IfEqual, A_LoopField,, Continue
IfEqual, True, % !(vect%u% := Vect_Formal(A_LoopField)), continue
else u++
}
else Loop, Parse, vlist, `;`n, `r%A_Space%%A_Tab%
IfEqual, A_LoopField,, Continue
else vect%u% := A_LoopField ";", u++
angle := ACos( Vect_Dot( Vect_Norm( vect1, 1 ) . Vect_Norm( vect2, 1 ), 1 ) )
SetFormat, Float, %off%
return angle * deg
}
; Formalize a string into a vector by parsing through
; any numeric characters (includes '-' and '.') and
; appending them according to the following rules:
; 0. Characters listed in the second parameter
; are ignored (for instance: commas in large numbers)
; 1. The first semicolon or newline reached marks
; the end of the input string. This is to stop multiple
; vectors from being formalized into a frankenvector
; 2. all non-numeric chars become item breaks
; 3. an item break preceeds every minus sign
; 4. within an unbroken numeric string, the second
; decimal point is dropped along with all chars
; following it until the next item break is reached
; 5. There are no empty vector members unless the
; input contains no numeric characters.
; NOTE: If there is a way to do this in one line
; with regex, I'm not interested! Either release
; it or append it to this library yourself.
Vect_Formal(string, ignorechars="")
{
Loop, Parse, string, , %ignorechars%
If A_LoopField !=
IfEqual, A_LoopField, `;, break
else nv .= (u := InStr("-.1234567890", A_LoopField)) ? (u
=1 ? " " : "") A_LoopField : " "
Loop, Parse, nv, %A_Space%
IfEqual, A_LoopField,, Continue
Else IfNotEqual, A_LoopField, -
{
stringsplit, q, A_LoopField, .
vect .= ", " q1 + 0 (q0>1 ? "." q2 : "")
}
return StrLen(vect) > 3 ? SubStr(vect,3) ";" : ""
}
; Returns the normal of the input vector
Vect_Norm(vect, formal=0)
{
off := A_FormatFloat
SetFormat, Float, 0.15
IfNotEqual, formal, 1, SetEnv, vect, % Vect_Formal(vect)
len := Vect_Len(vect, 1)
Loop, Parse, vect, `,, %A_Space%`;
nv .= ", " A_LoopField / len
SetFormat, Float, %off%
return substr(nv,3) ";"
}
; Returns the sum of the first vector and the negatives
; of all subsequent vectors in the list
Vect_Sub(vlist, formal=0)
{
off := A_FormatFloat
SetFormat, Float, 0.15
IfNotEqual, formal, 1, Loop, Parse, vlist, `;`n, %A_Space%%A_Tab%`r`,
{
IfEqual, A_LoopField,, Continue
IfEqual, True, % !(vect := Vect_Formal(A_LoopField)), continue
u++
StringSplit, v%u%d, vect, `,, %A_Space%%A_Tab%`r`;
IfLess, vorder, % v%u%d0, SetEnv, vorder, % v%u%d0
}
else Loop, Parse, vlist, `;`n, `r%A_Space%%A_Tab%
{
IfEqual, A_LoopField,, Continue
u++
StringSplit, v%u%d, A_LoopField, `,, `n%A_Space%
IfLess, vorder, % v%u%d0, SetEnv, vorder, % v%u%d0
}
Loop %vorder%
{
v := A_Index
Loop %u%
IfEqual, A_Index, 1, SetEnv, acc, % v1d%v%
else EnvSub, acc, % v%A_Index%d%v%
nv .= ", " acc
}
SetFormat, Float, %off%
return substr(nv,3) ";"
}
; Adds the vectors in the list.
Vect_Add(vlist, formal=0)
{
off := A_FormatFloat
SetFormat, Float, 0.15
IfNotEqual, formal, 1, Loop, Parse, vlist, `;`n, %A_Space%%A_Tab%`r`,
{
IfEqual, A_LoopField,, Continue
IfEqual, True, % !(vect := Vect_Formal(A_LoopField)), continue
u++
StringSplit, v%u%d, vect, `,, %A_Space%%A_Tab%`r`;
IfLess, vorder, % v%u%d0, SetEnv, vorder, % v%u%d0
}
else Loop, Parse, vlist, `;`n, `r%A_Space%%A_Tab%
{
IfEqual, A_LoopField,, Continue
u++
StringSplit, v%u%d, A_LoopField, `,, `n%A_Space%
IfLess, vorder, % v%u%d0, SetEnv, vorder, % v%u%d0
}
Loop %vorder%
{
v := A_Index
acc := 0
Loop %u%
EnvAdd, acc, % v%A_Index%d%v%
nv .= ", " acc
}
SetFormat, Float, %off%
return substr(nv,3) ";"
}
; Returns the input vector with length
; multiplitd by a factor. NOTE: seperate
; the vector and the factor by a
; semicolor or a newline character
; When using a formal vector, you may
; simply use the following format:
; result := Vect_Mult( FormalVector . 3, 1 )
Vect_Mult(vect, formal=0)
{
off := A_FormatFloat
SetFormat, Float, 0.15
IfNotEqual, formal, 1
{
Loop, Parse, vect, `;`n, %A_Space%%A_Tab%`r`,
IfLess, A_Index, 3, SetEnv, factor%A_Index%, % Vect_Formal(A_LoopField)
Else Break
factor2 := SubStr(Factor2, 1, -1+InStr(Factor2, ","))
} Else StringSplit, factor, vect, `;, %A_Space%%A_Tab%`r`n`,
Loop, Parse, factor1, `,, %A_Space%`;
nv .= ", " A_LoopField * factor2
SetFormat, Float, %off%
return substr(nv,3) ";"
}
; returns a vector describing the projection A onto B
; where A is the first vector in the list and B is the next
; The result is linearly dependant to vector B
Vect_Proj(vlist, formal=0)
{
u=1
IfNotEqual, formal, 1, Loop, Parse, vlist, `;`n, %A_Space%%A_Tab%`r`,
{
IfEqual, A_LoopField,, Continue
IfEqual, True, % !(vect%u% := Vect_Formal(A_LoopField)), continue
else u++
}
else Loop, Parse, vlist, `;`n, `r%A_Space%%A_Tab%
IfEqual, A_LoopField,, Continue
else vect%u% := A_LoopField ";", u++
return Vect_Mult(vect2 . Vect_Dot(vect1 . vect2, 1) / (Vect_Len(vect2, 1)**2), 1)
}
; if the second vector is normal to a plane, and
; the first vector is not paralell to that plane
; then this function returns the first vector
; after it bounces off the plane
; In essense, this function subtracts twice the
; projection of v1 onto v2 from v1, clear?
; Also, the angle between a vector and its reflection
; is exactly equal to twice the angle betwen that
; vector and the normal it is being reflected from
; so, Vect_Angle( v1 v2 ) is the same as
; Vect_Angle( Vect_Reflect( v1 v2 ) v2 )
Vect_Reflect(vlist, formal=0)
{
u=1
IfNotEqual, formal, 1, Loop, Parse, vlist, `;`n, %A_Space%%A_Tab%`r`,
{
IfEqual, A_LoopField,, Continue
IfEqual, True, % !(vect%u% := Vect_Formal(A_LoopField)), continue
else u++
}
else Loop, Parse, vlist, `;`n, `r%A_Space%%A_Tab%
IfEqual, A_LoopField,, Continue
else vect%u% := A_LoopField ";", u++
vx := Vect_Proj(vect1 . vect2, 1)
return Vect_Sub(vect1 . vx . vx, 1)
}
; returns a vector that is the cross-product of
; the first two vectors in vlist provided that
; those two vectors are independant and are in R3
; Note: the cross product in Rn requires n-1 vectors
; and is produced by calculating the determinants of
; n square matrices of size (n-1)x(n-1)
; For example, in R5...
;
; v1 = v1a, v1b, v1c, v1d, v1e
; v2 = v2a, v2b, v2c, v2d, v2e
; v3 = v3a, v3b, v3c, v3d, v3e
; v4 = v4a, v4b, v4c, v4d, v4e
; Cross = I, J, K, L, M
; I = Det( v1b, v1c, v1d, v1e; v2b, v2c, v2d, v2e; v3b, v3c, v3d, v3e; v4b, v4c, v4d, v4e)
; J = Det( v1c, v1d, v1e, v1a; v2c, v2d, v2e, v2a; v3c, v3d, v3e, v3a; v4c, v4d, v4e, v4a)
; K = Det( v1d, v1e, v1a, v1b; v2d, v2e, v2a, v2b; v3d, v3e, v3a, v3b; v4d, v4e, v4a, v4b)
; L = Det( v1e, v1a, v1b, v1c; v2e, v2a, v2b, v2c; v3e, v3a, v3b, v3c; v4e, v4a, v4b, v4c)
; M = Det( v1a, v1b, v1c, v1d; v2a, v2b, v2c, v2d; v3a, v3b, v3c, v3d; v4a, v4b, v4c, v4d)
; where Det() is the determinate of the specified matrix
; And for large n's, the fastest way to get the determinant
; is through row-reduction to row-echelon form and then
; multiply along the diagonal. Since row-reduction would
; have a big-O notation of O(n²) whereas finding
; the determinate by laplace expansion would have a
; big-O of O(n!) (and that's really bad!!)
;
Vect_Cross(vlist, formal=0) ; WARNING: R3 supported only!!!!
{
off := A_FormatFloat
SetFormat, Float, 0.15
IfNotEqual, formal, 1, Loop, Parse, vlist, `;`n, %A_Space%%A_Tab%`r`,
{
IfEqual, A_LoopField,, Continue
IfEqual, True, % !(vect := Vect_Formal(A_LoopField)), continue
u++
StringSplit, v%u%d, vect, `,, %A_Space%%A_Tab%`r`;
}
else Loop, Parse, vlist, `;`n, `r%A_Space%%A_Tab%
{
IfEqual, A_LoopField,, Continue
u++
StringSplit, v%u%d, A_LoopField, `,, `n%A_Space%
}
vr := (v1d2 * v2d3 - v1d3 * v2d2) ", "
vr .= (v1d3 * v2d1 - v1d1 * v2d3) ", "
vr .= (v1d1 * v2d2 - v1d2 * v2d1) ";"
SetFormat, Float, %off%
return vr
} |
_________________ My Home Thread
Common Answers: [1]. It's in the FAQ [2]. Ternary ( a ? b : c ) guide [3]. Post code inside [code][/code] tags !
Last edited by [VxE] on Fri Oct 10, 2008 11:13 am; edited 3 times in total |
|
| Back to top |
|
 |
[VxE]
Joined: 07 Oct 2006 Posts: 2392
|
Posted: Sat Jun 07, 2008 4:44 am Post subject: |
|
|
This script turns the 4 arrow keys into the number keys on the numberpad. Press one or two arrow keys to get the appropriate numpad number or pgup/home/end or numpadarrows (depending on the numlock state). Feel free to change the actual toggle to something other than Numlock (the appskey is pretty handy ). Also the alternate functions can be easily customized.
| Code: | ; [VxE]'s Arrow Keys To Numpad Multiplexer.
ArrowKeys = Up,Left,Down,Right
NumPadAliases = End,Down,PgDn,Left,NumpadClear,Right,Home,Up,PgUp
StringSplit, k, ArrowKeys, `,
StringSplit, NumAlias, NumPadAliases, `,
NumAlias0 = Ins ; I'd recommend 'BackSpace' as it seems more useful
Loop, Parse, ArrowKeys, `,
Hotkey, $*%A_LoopField%, $*Up, on
$*Up::
mark := SubStr(((sk1:=GetKeyState(k1,"P"))-(sk3:=GetKeyState(k3,"P"))+1)*3
+(sk4:=GetKeyState(k4,"P"))-(sk2:=GetKeyState(k2,"P"))+2-5*(!sk2 & !sk4 & sk1 & sk3),0)
If (!InThread)
{
InThread = 1
Sleep 40 ; delay to allow coordination of multiple keys
If (GetKeyState("NumLock", "T")) ; put any toggle you want
Send {blind}{NumPad%mark%}
else
Send % "{blind}{" NumAlias%mark% "}" ; "{blind}{Numpad" NumAlias%mark% "}"
InThread = 0
}
return |
_________________ My Home Thread
Common Answers: [1]. It's in the FAQ [2]. Ternary ( a ? b : c ) guide [3]. Post code inside [code][/code] tags ! |
|
| Back to top |
|
 |
[VxE]
Joined: 07 Oct 2006 Posts: 2392
|
Posted: Sun Jun 08, 2008 7:24 am Post subject: |
|
|
I know that RGB to HSV has been done before in AHK (props, tonne), but here's another manifestation of it which handles hex-code BGR (like what PixelGetColor returns) as well as the reverse: HSL to BGR
| Code: | Hue(BGR) ; Hue: output range [0,360) float
{ ; Function by [VxE], formula from wikipedia.org/wiki/HSV_color_space
OFF := A_FormatFloat
SetFormat, Float, 0.16
; pi := ATan(1) * 4
pi := 360 / 2 ; what do you consider a full circle ? 360º or 2pi ?
hex := pi / 3
blue := (BGR >> 16) / 256
green := ((BGR >> 8) & 255) / 256
red := (BGR & 255) / 256
max := ((blue > green) && (blue > red)) ? blue : (green > red ? green : red)
min := ((blue < green) && (blue < red)) ? blue : (green < red ? green : red)
If (min = max)
res := 0
else If (max = red)
res := hex * ((green - blue) / (max - min))
else If (max = green)
res := hex * ((blue - red) / (max - min)) + 2 * hex
else If (max = blue)
res := hex * ((red - green) / (max - min)) + 4 * hex
If (res >= 2 * pi )
res -= 2 * pi
If (res < 0 )
res += 2 * pi
SetFormat, Float, %OFF%
return res
} |
| Code: | Sat(BGR) ; Saturation: output range [0,1)
{ ; Function by [VxE], formula from wikipedia.org/wiki/HSV_color_space
OFF := A_FormatFloat
SetFormat, Float, 0.16
blue := (BGR >> 16) / 256
green := ((BGR >> 8) & 255) / 256
red := (BGR & 255) / 256
max := ((blue > green) && (blue > red)) ? blue : (green > red ? green : red)
min := ((blue < green) && (blue < red)) ? blue : (green < red ? green : red)
lum := (min + max) / 2
If (min = max)
res := 0
else If (lum <= 0.5)
res := (max - min) / (2*lum)
else
res := (max - min) / (2-2*lum)
SetFormat, Float, %OFF%
return res
} |
| Code: | Lum(BGR) ; output range [0,1)
{ ; Function by [VxE], formula from wikipedia.org/wiki/HSV_color_space
OFF := A_FormatFloat
SetFormat, Float, 0.16
blue := (BGR >> 16) / 256
green := ((BGR >> 8) & 255) / 256
red := (BGR & 255) / 256
max := ((blue > green) && (blue > red)) ? blue : (green > red ? green : red)
min := ((blue < green) && (blue < red)) ? blue : (green < red ? green : red)
res := (min + max) / 2
SetFormat, Float, %OFF%
return res
} |
| Code: | HSL_to_RGB( hue, sat, lum ) ; inputs should be [0,360) : [0,1) : [0,1), output = 24b hex BGR
{ ; Function by [VxE], formula from wikipedia.org/wiki/HSV_color_space
OFF := A_FormatFloat
SetFormat, Float, 0.16
If ( lum < 0.5 )
weight := Lum + Lum * Sat
else
weight := Lum + Sat - Lum * Sat
size := 2 * Lum - weight
value := hue / 360
red := value + 1/3 - (value > 2/3)
green := value
blue := value - 1/3 + (value < 1/3)
If (blue < 1/6)
blue := (blue * 6 * (weight - size)) + size
else if (blue < 1/2)
blue := weight
else if (blue < 2/3)
blue := ((2/3 - blue) * 6 * (weight - size)) + size
else
blue := size
If (green < 1/6)
green := (green * 6 * (weight - size)) + size
else if (green < 1/2)
green := weight
else if (green < 2/3)
green := ((2/3 - green) * 6 * (weight - size)) + size
else
green := size
If (red < 1/6)
red := (red * 6 * (weight - size)) + size
else if (red < 1/2)
red := weight
else if (red < 2/3)
red := ((2/3 - red) * 6 * (weight - size)) + size
else
red := size
OIF := A_FormatInteger
SetFormat, Integer, Hex
ret := (Round(blue*256) << 16) | (Round(green*256) << 8) | Round(red*256)
SetFormat, Float, %OFF%
SetFormat, Integer, %OIF%
ret := "0x" SubStr( "00000" SubStr(ret, 3), -5 )
StringUpper, ret, ret
return ret
} |
And of course, the accessory function | Code: | FlipBlueAndRed(c) ; takes RGB or BGR and swaps the R and B
{
return (c&255)<<16 | (c&65280) | (c>>16)
} |
_________________ My Home Thread
Common Answers: [1]. It's in the FAQ [2]. Ternary ( a ? b : c ) guide [3]. Post code inside [code][/code] tags ! |
|
| Back to top |
|
 |
|
|
You can post new topics in this forum You can reply to topics in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|