Jump to content

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

AHK Functions :: InCache() - Cache List of Recent Items


  • Please log in to reply
172 replies to this topic
SKAN
  • Administrators
  • 9115 posts
  • Last active:
  • Joined: 26 Dec 2005

Question:
Is there a way to determinate the ahk_id of the window Coping... Moving... etc in Win Explorer that show the progress before (or after but I rather have it before) ShellFileOperation is called.


Windows Explorer ? I know no easy method to detect the creation of those owned windows!
Calling ShellFileOperation() from AHK : Yes it is possible to detect with SHELLHOOK

:)

Yogui
  • Guests
  • Last active:
  • Joined: --
Thanks for your reply!

I was waiting to get more understanding before going for the RegisterShellHookWindow function but well this is what I got.
Changing the expected win (title and class) it detects other windows but does not detect the window copying... probably because as you said copying... is owned by the window Explorer.

What am I doing wrong?

#Persistent
SetBatchLines, -1
Process, Priority,, High

Gui +LastFound
hWnd := WinExist()

OPERATION_WIN_TITLE = Copying...
OPERATION_WIN_CLASS = #32770

DllCall( "RegisterShellHookWindow", UInt,hWnd )
MsgNum := DllCall( "RegisterWindowMessage", Str,"SHELLHOOK" )
OnMessage( MsgNum, "ShellMessage" )
Return

ShellMessage( wParam,lParam )
	{
	If wParam = 1							;  HSHELL_WINDOWCREATED := 1
		{
		WinGetTitle, CREATED_WIN_TITLE, ahk_id %lParam%
		If CREATED_WIN_TITLE = %OPERATION_WIN_TITLE%
			{
			WinGetClass, CREATED_WIN_CLASS, ahk_id %lParam%
			If CREATED_WIN_CLASS = %OPERATION_WIN_CLASS%
				{
				MsgBox, WIN_FOUND TO SET TANS            ; 
				}
			}
		}
		
;	ToolTip wParam: %wParam%`nlparam: %lParam%        ;TO CHECK MSG
	}
	

Even if this doesn't work I already learn something to cut down a few stupid timers I've done that run at 200ms and only check new windows have been created to apply a winstyle I like. (thanks for that) :D

SKAN
  • Administrators
  • 9115 posts
  • Last active:
  • Joined: 26 Dec 2005
OPERATION_WIN_TITLE
OPERATION_WIN_CLASS

The above variables are not visible to ShellMessage()

#Persistent
SetBatchLines, -1
Process, Priority,, High

Gui +LastFound
hWnd := WinExist()

OPERATION_WIN_TITLE = Copying...
OPERATION_WIN_CLASS = #32770

DllCall( "RegisterShellHookWindow", UInt,hWnd )
MsgNum := DllCall( "RegisterWindowMessage", Str,"SHELLHOOK" )
OnMessage( MsgNum, "ShellMessage" )
Return

ShellMessage( wParam,lParam )	{

   [color=red]Global OPERATION_WIN_TITLE,OPERATION_WIN_CLASS[/color]
	If wParam = 1							;  HSHELL_WINDOWCREATED := 1
		{
		WinGetTitle, CREATED_WIN_TITLE, ahk_id %lParam%
		If CREATED_WIN_TITLE = %OPERATION_WIN_TITLE%
			{
			WinGetClass, CREATED_WIN_CLASS, ahk_id %lParam%
			If CREATED_WIN_CLASS = %OPERATION_WIN_CLASS%
				{
				MsgBox, WIN_FOUND TO SET TANS            ; 
				}
			}
		}
		
;	ToolTip wParam: %wParam%`nlparam: %lParam%        ;TO CHECK MSG
	}
	

:)

Yogui
  • Guests
  • Last active:
  • Joined: --
Hi Skan,

Even declaring the vars global still not detecting it.
I got rid of those conditions to find the win and still not working.

If I explore on a new win it detects it OK. Actually it detect all windows created but not the ones I'm after (copying etc)

#Persistent
SetBatchLines, -1
Process, Priority,, High

Gui +LastFound
hWnd := WinExist()

OPERATION_WIN_TITLE = Copying...
OPERATION_WIN_CLASS = #32770

DllCall( "RegisterShellHookWindow", UInt,hWnd )
MsgNum := DllCall( "RegisterWindowMessage", Str,"SHELLHOOK" )
OnMessage( MsgNum, "ShellMessage" )
Return

ShellMessage( wParam,lParam )
	{
	Global OPERATION_WIN_TITLE,OPERATION_WIN_CLASS				;DECLARE GLOBAL TO BE SEEN BE FUNCTION
	If wParam = 1							;  HSHELL_WINDOWCREATED := 1
		{
;		WinGetTitle, CREATED_WIN_TITLE, ahk_id %lParam%
;		If CREATED_WIN_TITLE = %OPERATION_WIN_TITLE%
;			{
;			WinGetClass, CREATED_WIN_CLASS, ahk_id %lParam%
;			If CREATED_WIN_CLASS = %OPERATION_WIN_CLASS%
;				{
				MsgBox, WIN "Copying... ahk_class #32770" FOUND
;				}
;			}
		}
		
	ToolTip wParam: %wParam%`nlparam: %lParam%
	}


Seems like the function does not see any wParam = 1 (win created) when child win like copying, deleting,confirm file replace etc are created.

Is there a was to see them from the shell?

Help appreciated,

Yogui

Yogui
  • Guests
  • Last active:
  • Joined: --
Hi,

I keept playing with some tooltips inside the function and I found that hooking to sheel it's so quick that the created win hasn't have it's Title yet

I got the copying... and moving... windows but not the deleting...

(Actually now I'm running an other script (I'll post it when looks less like frankkestain) from my main that launches with parameters and then call ShellFileOperation().
That has the advantaje that the main script can do something else and even reload without afecting the copy, move etc.)

I think I don't get deleting... because I'm not using ShellFileOperation() for Deleting.

I'm sending {Del} or +{Del} to Win Explorer

Do you know the flags on the ShellFileOperation() for deleting to Recycle and deleting without sending in to the recycle bin????

Any help there appreciated!!!

So this is how the complete function looks like now, a few vars comes from my main script.

This funtion is on a separate script that check New wins created and Redraw it (wParam 1 and 6)
An does a variaty of things
1) Apply styles
2) Set list view in win Explorer to current choice (icons, list, details etc)
3) block some nasty pop ups

Still testing any ideas wellcome
(this is not stand allone function you need to set the variables to run it properly)

ShellMessage( wParam,lParam )
	{
	If wParam not in 1,6												;ALL WPARAM THAT THIS AHK WORKS WITH OTHERWISE RETURN
		Return
		
	WinGetClass, ACTIVE_WIN_CLASS, ahk_id %lParam%						;TO CHECK THAT THIS WIN BELONGS TO ONE OF ALL CLASSES THAT THIS AHK WORKS WITH, OTHERWISE RETURN

	If ACTIVE_WIN_CLASS not in IEFrame,MozillaUIWindowClass,CabinetWClass,ExploreWClass,Notepad,Notepad++,AU3Reveal,HH Parent,TForm_Main,TMainForm.UnicodeClass
	,ShImgVw:CPreviewWnd,AutohotKey,AutoHotkeyGUI,OpusApp,XLMAIN,rctrl_renwnd32,#32770,WMPlayerApp
		{	
		If ACTIVE_WIN_CLASS <>
		If ACTIVE_WIN_CLASS not Contains Afx:00400000:b:
		If ACTIVE_WIN_CLASS not in TApplication,gdkWindowToplevel
			{
			ToolTip, Wrong Win Class`nClass: %ACTIVE_WIN_CLASS%`nTitle: %ACTIVE_WIN_TITLE%
			SetTimer, RemoveToolTip, 4000
			SoundBeep, 100, 200
			}
		Return
		}
		
	If ACTIVE_WIN_CLASS in CabinetWClass,ExploreWClass							;FIRST TO RETURN BECAUSE FOR EXPLORER CLASSES BOTH WPARAM 1 AND 6 SHOLD TRIGGER THIS
		{
		WinGetTitle, ACTIVE_WIN_TITLE, ahk_id %lParam%

		ControlGetText, ACTIVE_WE_CURRENT_PATH, Edit1, ahk_id %lParam%			;GET WORKING PATH
		EnvGet, SET_WE_VIEW_TO_MSG, SET_WE_VIEW_TO_MSG_CHOSEN					;THIS WILL BE THE MESSAGE SENT UNLESS IS MODIFYED BY FOLDER
		EnvGet, CUSTOM_WE_VIEW_STATUS, CUSTOM_WE_VIEW_STATUS					;REPLACE FOR PARAMETERS


			If CUSTOM_WE_VIEW_STATUS = MERGE									;THIS IS DEFAULT OPTION AND WILL MERGE SELECTED VIEW WITH CUSTOM ONES
				{
				IfInString, ACTIVE_WE_CURRENT_PATH, \My Music							;NEED TO BE IN THIS PARTICULAR ORDER TO AUTO FILTER ITSELF
					SET_WE_VIEW_TO_MSG = 28715								;List
				IfInString, ACTIVE_WE_CURRENT_PATH, \My Music\
					{
					SET_WE_VIEW_TO_MSG = 28717								;Thumbnails
					;COUNT "\" to go back to list when inside albums
					}
				IfInString, ACTIVE_WE_CURRENT_PATH, \My Pictures
					SET_WE_VIEW_TO_MSG = 28715								;List
				IfInString, ACTIVE_WE_CURRENT_PATH, \My Pictures\
					SET_WE_VIEW_TO_MSG = 28717								;Thumbnails
				IfInString, ACTIVE_WE_CURRENT_PATH, \DVD Covers
					SET_WE_VIEW_TO_MSG = 28715								;List
				IfInString, ACTIVE_WE_CURRENT_PATH, \DVD Covers\
					SET_WE_VIEW_TO_MSG = 28717								;Thumbnails
				}

			If ACTIVE_WE_CURRENT_PATH in My Computer,My Documents
				SET_WE_VIEW_TO_MSG = 28715									;List

			If ACTIVE_WE_CURRENT_PATH = C:\Documents and Settings\%A_UserName%\My Documents
				SET_WE_VIEW_TO_MSG = 28715

			If ACTIVE_WE_CURRENT_PATH = %A_MyDocuments%\
				SET_WE_VIEW_TO_MSG = 28715															;Thumbnails UP TO THIS SETTINGS CAN NOT BE OVERIDE AS CUSTOM SETTINGS

			If ACTIVE_WIN_TITLE = Search Results
				SET_WE_VIEW_TO_MSG = 28716															;Details
		
			If SET_WE_VIEW_TO_MSG in 28713,28715,28716,28717,28718									;CHECK IN MATCHING LIST BEFORE SEND
				{
				IfWinExist, ahk_id %lParam%
					{
					PostMessage, 0x111, %SET_WE_VIEW_TO_MSG%, 0 , , ahk_id %lParam%				;SET VIEW WIN EXPLORER TO TIMMER SETTINGS
;					ToolTip, List Style Appled
;					SetTimer, RemoveToolTip, 1000
					}
				}
		Return
		}
		
	If wParam = 1														;  HSHELL_WINDOWCREATED := 1
		{
;		Critical

		If ACTIVE_WIN_CLASS in IEFrame,MozillaUIWindowClass				;INTERNET EXPLORER NEEDS MORE TIME TO GET THE FINAL WIN TITLE
			LOOP_LENGTH = 400
		Else
			LOOP_LENGTH = 150

		Loop,
			{
			Sleep 10															;Helps to see the title AND REDUCE CPU
			
			WinGetClass, ACTIVE_WIN_CLASS, ahk_id %lParam%
			WinGetTitle, ACTIVE_WIN_TITLE, ahk_id %lParam%
			
			If ACTIVE_WIN_CLASS not in TApplication
			If (ACTIVE_WIN_TITLE <> "") && (ACTIVE_WIN_TITLE <> "Microsoft Internet Explorer") && (ACTIVE_WIN_TITLE <> "Microsoft Internet Explorer provided by COMPANY_NAME")
				Break
				
			If (A_Index > LOOP_LENGTH)
				{
				ToolTip, Win Data Not Found`nTitle: %ACTIVE_WIN_TITLE%`nClass: %ACTIVE_WIN_CLASS%
				SetTimer, RemoveToolTip, 4000
				SoundBeep, 100, 200
				Return
				}
			}
		
		SoundBeep, 4800, 50
		ToolTip, New Win Open`nTitle: %ACTIVE_WIN_TITLE%`nClass: %ACTIVE_WIN_CLASS%
		SetTimer, RemoveToolTip, 4000
		

		If ACTIVE_WIN_CLASS = #32770
		If ACTIVE_WIN_TITLE in Copying...,Deleting...
			{
			Control, Disable, , Button1, ahk_id %lParam%
			WinSet, Transparent, 200, ahk_id %lParam%
			WinSet, AlwaysOnTop, On, ahk_id %lParam%

			ControlGetPos, CONTROL_0_X, CONTROL_0_Y, CONTROL_0_W, CONTROL_0_H, SysAnimate321, ahk_id %lParam%
			ControlGetPos, CONTROL_1_X, CONTROL_1_Y, CONTROL_1_W, CONTROL_1_H, Button1, ahk_id %lParam%

			WinGetPos, WIN_X, WIN_Y, WIN_W, WIN_H, ahk_id %lParam%

			X0 := CONTROL_0_X - 6
			Y0 := CONTROL_0_Y + CONTROL_0_H - 1					;MAY NEED ADJUSTMENTS IF SYS FONT IS NORMAL ETC

			X1 := CONTROL_1_X - X0
			Y1 := CONTROL_1_Y + CONTROL_1_H - Y0 + 14

			WinSet, Region, %X0%-%Y0% W%X1% H%Y1% R20-20, ahk_id %lParam%

			MCRD_WIN_ENABLED = 0			;RESET VALUE

			WinGet, MCDR_WIN_GROUP_ID_LIST, list, ahk_group MCDR_WIN_GROUP

			Loop, %MCDR_WIN_GROUP_ID_LIST%
				{
				MCDR_WIN_GROUP_ID_LIST_CURRENT := MCDR_WIN_GROUP_ID_LIST%A_Index%
				ControlGet, MCRD_WIN_ENABLED, Enabled, , Button1, ahk_id %MCDR_WIN_GROUP_ID_LIST_CURRENT%
				MCRD_WIN_ENABLED += MCRD_WIN_ENABLED			;ZERO ID DISABLE
				}
	
			MCRD_WIN_DISABLED := MCDR_WIN_GROUP_ID_LIST - MCRD_WIN_ENABLED
			
			SysGet, MonitorWorkArea1, MonitorWorkArea, 1
				
			WIN_MOVE_X := MonitorWorkArea1Right - X0 - X1
			WIN_MOVE_Y := MonitorWorkArea1Bottom - Y0 - (Y1 * MCRD_WIN_DISABLED) 		;MULT BY THE NUMBER OF MCDR WINS

			WinMove, ahk_id %lParam%, , WIN_MOVE_X,  WIN_MOVE_Y
			}
		
		If ACTIVE_WIN_CLASS in IEFrame,MozillaUIWindowClass				;INTERNET EXPLORER, FIREFOX ETC
			{
			If ACTIVE_WIN_TITLE Contains media.fastclick.net,BestDietForMe.com,adserving.cpxinteractive.com
			,casalemedia.com,partypoker,ezytones.net,You've Won,%COMPANY_NAME% - Access Denied
				{
				WinClose, ahk_id %lParam%
				ToolTip, Pop Up Win Closed`nTitle: %ACTIVE_WIN_TITLE%`nClass: %ACTIVE_WIN_CLASS%
				SetTimer, RemoveToolTip, 3000
				}
			}
				
		If ACTIVE_WIN_CLASS not in ThunderRT6FormDC,gdkWindowToplevel					;,#32770
			{
			WinSet, Style, ^0x40000, ahk_id %lParam%									; MAKE WINDOW BORDERLESS
			;		ToolTip, Win Style Aplyed
			;		SetTimer, RemoveToolTip, 1000
			}
		}

	}


SKAN
  • Administrators
  • 9115 posts
  • Last active:
  • Joined: 26 Dec 2005

ConvertGraphicsFile()

Converts image file format between GIF/BMP/JPG/PNG. However, this is a wrapper for the
undocumented SHConvertGraphicsFile function found in shlwapi.dll version >= 6.00, works fine
when tested in XP SP2 and Vista Home Premium. This was my source

Parameter 1 : Source file
Parameter 2 : Target file
Parameter 3 : Overwrite existing? ( true / false )

Here is a working demo along with the wrapped function:

#SingleInstance, Force
SetWorkingDir %A_ScriptDir%  

IfNotExist, ahk.gif 
     UrlDownloadToFile, http://www.autohotkey.com/docs/images/AutoHotkey_logo.gif, ahk.gif
          
ConvertGraphicsFile( "ahk.gif", "ahk.png" )
ConvertGraphicsFile( "ahk.png", "ahk.bmp" )
ConvertGraphicsFile( "ahk.bmp", "ahk.jpg" )

Gui, Add, Picture, x5 , ahk.gif
Gui, Add, Picture, x+5, ahk.png
Gui, Add, Picture, x5 , ahk.bmp
Gui, Add, Picture, x+5, ahk.jpg

Gui, Add, Text, x5, Does this window looks slightly tilted or is it just an illusion ?
Gui, Show,, Demo : Convert image files between GIF/BMP/JPG/PNG

Return                                        ; // end of demo and auto-execute section //

[color=#4040EE]ConvertGraphicsFile( Src, Trg, Ov=True ) {
  Static shlwapi,SHConvertGraphicsFile 
  if ( shlwapi = "" )  {
    shlwapi := DllCall( "LoadLibrary",Str,"shlwapi.dll" )
    SHConvertGraphicsFile := DllCall( "GetProcAddress", UInt,shlwapi, UInt,488 )
                       }  
  VarSetCapacity( uSrc, ( sSz := StrLen(Src)*2+1) )
  DllCall( "MultiByteToWideChar", Int,0, Int,0, Str,Src, Int,-1, Str,uSrc, Int,sSz )
  VarSetCapacity( uTrg, ( tSz := StrLen(Trg)*2+1) )
  DllCall( "MultiByteToWideChar", Int,0, Int,0, Str,Trg, Int,-1, Str,uTrg, Int,tSz )
  Return ! DllCall( SHConvertGraphicsFile, Str,uSrc, Str,uTrg, Uint,Ov )
}[/color]

:)



Laszlo
  • Moderators
  • 4713 posts
  • Last active: Mar 31 2012 03:17 AM
  • Joined: 14 Feb 2005
Nice and compact!
Any way to set the jpeg quality?

SKAN
  • Administrators
  • 9115 posts
  • Last active:
  • Joined: 26 Dec 2005

Any way to set the jpeg quality?


Unfortunately, there seems to be none. I can find no other info other than this link. It seems to use compression value of 20 for JPG.
I have been searching hard for something else and have been landing on such findings.

:)

SKAN
  • Administrators
  • 9115 posts
  • Last active:
  • Joined: 26 Dec 2005

Affinity_Set()

Sets the CPU to be used in Dual/Quad/Multi core processors / Effectively, this function allows you to choose which AHK script uses what
processor.

Usage: Use Affinity_Set( n ) on the top of your script, where n will be 1 if you want the script to use the first processor, 2 if you want the script to use the second processor.. and 3 to utilise both of them

MSDN Links: SetProcessAffinityMask , GetProcessAffinityMask


Some old applications do not run properly when run with dual/multi core mode and require the Affinity to be set to a single processor.
Here is an example to set Affinity manually: To set the Affinity for Calculator, start the Windows Task Manager, find the process Calc.exe, right click and select Affinity, and set the affinity by checking on/off the relevant CPU's.

Posted Image___________Posted Image
To achieve the same programmatically,

Process, Exist, calc.exe
PID := errorLevel
Affinity_Set( 3, PID ) ; presuming Affinity.ahk is available in User Library

Download the User Library : Affinity.ahk or you may copy/paste the following code:

Affinity_Set( CPU=1, PID=0x0 ) { ; CPU0=1 CPU1=2 | to use both, CPU should be 3
  Process, Exist, %PID%
  IfEqual,ErrorLevel,0,  SetEnv,PID,% DllCall( "GetCurrentProcessId" )
  hPr := DllCall( "OpenProcess",Int,1536,Int,0,Int,PID )  
  DllCall( "GetProcessAffinityMask", Int,hPr, IntP,PAM, IntP,SAM )
  If ( CPU>0 && CPU<=SAM )
     Res := DllCall( "SetProcessAffinityMask", Int,hPr, Int,CPU )
  DllCall( "CloseHandle", Int,hPr )
Return ( Res="" ) ? 0 : Res
}

:)



Oberon
  • Members
  • 442 posts
  • Last active: Jul 03 2008 11:34 PM
  • Joined: 18 Feb 2008
Would it make a difference if the application is not multithreaded like AutoHotkey?

SKAN
  • Administrators
  • 9115 posts
  • Last active:
  • Joined: 26 Dec 2005

Would it make a difference if the application is not multithreaded like AutoHotkey?


I have already answered that. From what I have seen in Google, certain applications/games designed prior to Win XP do not even load in multi-CPU mode. The only way is start those process suspended and change the affinity to single processor mode and then resume.
My interest is in AHK mainly. The following script would hang my AMD Sempron. Nothing would help other than the reset button!

SetBatchLines -1
Loop
 a=

Interestingly, with my newer Dual Core, the above script uses 50% of each CPU ( as seen in the graphs of Windows Task Manager )
Instead, If I run the following two scripts concurrently, Then both the graphs shoot to the top resulting in 100% CPU usage:

SetBatchLines -1
Affinity_Set( [color=red]1[/color] )
Loop
 a=

SetBatchLines -1
Affinity_Set( [color=red]2[/color] )
Loop
 a=

I do not have much experience in this area. I have to experiment with ShellHook and force every app to run in CPU0 and test how ShFileOperation() performs in CPU1.

:)
kWo4Lk1.png

SKAN
  • Administrators
  • 9115 posts
  • Last active:
  • Joined: 26 Dec 2005

RandStr()

Generates and returns a Random string

RandStr( L=0,N=0,U=0 ) { ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  Loop % (L+(Z:=0)) {    ;   [color=indigo]** Simple Random String Generator **[/color] [color=black]by SKAN,  02-Sep-2008[/color]
   Random,R,97,122       ;     www.autohotkey.com/forum/viewtopic.php?p=217712#217712
   P.=Chr(R) Z           ;
} Loop %N% {             ;
   Random,R,1,9          ;    RandStr( 10 )           10 character all lower case
   P.=R Z                ;    RandStr( 0,10,0 )       10 character numeric string
} Loop %U% {             ;    RandStr( 0,0,10 )       10 character all upper case
   Random,R,65,90        ;    RandStr( 5,0,5 )        10 character mixed case
   P.=Chr(R) Z           ; 
} StringTrimRight,P,P,1  ;    RandStr( 4,4 )           8 character lower alphanumeric
Sort,P,Random D%Z%       ;    RandStr( 0,4,4 )         8 character upper alphanumeric         
Return RegExReplace(P,Z) ;    RandStr( 3,3,3 )         9 character mixed alphanumeric
} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 

SetBatchLines -1
Loop 10000
  pList .= RandStr( 4,4,2 ) Chr(10)
MsgBox,64,% "4 Lower / 4 Numbers / 2 Upper", %pList%



SKAN
  • Administrators
  • 9115 posts
  • Last active:
  • Joined: 26 Dec 2005

HashStr()  and Hash()

Refer MSDN: UrlHash(),    HashData()

My sincere thanks to Mr.Laszlo Hars for helping me with these couple of functions by his replies in forum/PM

HashStr() hashes a String and returns value as hex.

MsgBox,% HashStr( "The Quick Brown Fox Jumps Over The Lazy Dog" )

HashStr( sStr="" ) {
 Static hHash=12345678
 DllCall( "shlwapi\UrlHashA",  Str,sStr, UIntP,dHash, UInt,4 )
 DllCall( "msvcrt.dll\sprintf", Str,hHash, Str,"%08X", UInt,dHash )
 Return ( sStr<>"" ) ? hHash :
}

Hash() hashes a Byte-array and returns value as hex.

Hash( nPtr, nSz=0, L=4 ) {
  ; [color=red]Original by Laszlo Hars, Post: [/color] www.autohotkey.com/forum/viewtopic.php?p=231847#231847
  Static HashData, sprintf, S=1234567890123456           
  If ( HashData="" )
  HashData := DllCall( "GetProcAddress", UInt, DllCall( "LoadLibrary", Str,"shlwapi.dll" )
  , Str,"HashData" ), sprintf := DllCall( "GetProcAddress", UInt, DllCall( "LoadLibrary"
  , Str,"msvcrt.dll" ),  Str,"sprintf" )
  DllCall( HashData, UInt,nPtr, UInt,nSz, Int64P,Hash, UInt,8 )     ;  8-Byte= 64-bit hash
  DllCall(sprintf, Str,S, Str,"%016I64X", Int64,Hash)     ; 0-padded (left), 16 HEX digits
Return SubStr(S, 1-2*L) ; only 2L digits
}

FileGetSize, BinSz, %A_AhkPath%
FileRead,    Bin,   %A_AhkPath%
MsgBox, % Hash( &Bin, BinSz )



Laszlo
  • Moderators
  • 4713 posts
  • Last active: Mar 31 2012 03:17 AM
  • Joined: 14 Feb 2005

Wrapped up to return value as Hex

Hash( Str, nSz=0 ) { 
  Static HashData
  If ( HashData="" ) {
       HashData := DllCall( "LoadLibrary", Str,"shlwapi.dll")
       HashData := DllCall( "GetProcAddress", UInt,HashData, Str, "HashData" )      
} IfLess,nSz,1, SetEnv,nSz, % StrLen(Str) 
  DllCall( HashData, UInt,Ptr, UInt,Sz, UIntP,Hash, UInt,4 )
  IfEqual,A_FormatInteger,D, SetFormat,Integer,% "H" ((Flag:="D")+WM_NULL)
  DllCall( "shlwapi.dll\HashData", UInt,&Str, UInt,StrLen(Str), UIntP,Hash, UInt,4 )
  Hash := SubStr(Hash+0x1000000000,-7)
  StringUpper, Hash, Hash
  IfEqual,Flag,D, SetFormat,Integer,D
  Return Hash
}

MsgBox, % Hash( "The Quick Brown Fox" )


Nice wrapper! The Windows HashData function is not a cryptographic hash, so don't use this in security critical applications.

A few points, though:
- The input string cannot contain NUL characters, therefore you cannot handle binary data. A pointer parameter or ByRef could allow hashing more general data.
- The DllCall( HashData... seems to be superfluous, its result (0) is not used, its input is the empty string.
- You have the address of HashData, but it is not used in the DllCall( "shlwapi.dll\HashData"...
- In this dll call you should use nSz, not the length of the string
- There seem to be no reason for using WM_NULL. “SetFormat Integer” only looks at the first char of the second parameter, so HD sets hex mode, too. Of course, using an extra line you could make the script shorter and more readable.

This is what I mean (w/o ByRef)
Hash(Str, nSz=0) {
  Static HashData
  If (HashData="")
      HashData := DllCall("GetProcAddress", UInt,DllCall("LoadLibrary", Str,"shlwapi.dll"), Str,"HashData")
  DllCall(HashData, UInt,&Str, UInt,nSz<1 ? StrLen(Str):nSz, UIntP,Hash, UInt,4 )
  FI := A_FormatInteger
  SetFormat Integer, H
  Hash := SubStr(Hash+0x1000000000,-7)
  StringUpper Hash, Hash
  SetFormat Integer, %FI%
  Return Hash
}
The HashData function can return any length (<=256B) hash. You could easily handle 1..7 byte lengths with an extra parameter.

SKAN
  • Administrators
  • 9115 posts
  • Last active:
  • Joined: 26 Dec 2005

The Windows HashData function is not a cryptographic hash, so don't use this in security critical applications.


I thought of using this function for single variable Associative array.
MD5 is 16 bytes long and makes my structure very long. What do you suggest, Sir?

I do not know how test HashData() for collisions. I hashed around 99000 unique strings ( A_LoopFileLongPath of all files in HDD ) and there were no collisions.

- The input string cannot contain NUL characters, therefore you cannot handle binary data. A pointer parameter or ByRef could allow hashing more general data.


:oops: A pointer parameter would be better. Thank you.

- The DllCall( HashData... seems to be superfluous, its result (0) is not used, its input is the empty string.
- You have the address of HashData, but it is not used in the DllCall( "shlwapi.dll\HashData"...
- In this dll call you should use nSz, not the length of the string


:oops: I mixed two variants into one in a very stupid manner.

- There seem to be no reason for using WM_NULL. “SetFormat Integer” only looks at the first char of the second parameter, so HD sets hex mode, too.


I knew not about this. Great. Thanks!

Of course, using an extra line you could make the script shorter and more readable.


My idea was different. When Hash() is called from a loop.. as many times, I would want to Set the hex format outside the function, so in the function both lines become non-functional. I do not know if there would be any increase in performance though!

The HashData function can return any length (<=256B) hash. You could easily handle 1..7 byte lengths with an extra parameter.


er. when I tried with 7 the hash value was not any different. Can you please explain with a DllCall() ?. I like to add it as a function parameter

Nice wrapper!


:oops: :oops: :oops:
kWo4Lk1.png