Leaderboard
Popular Content
Showing content with the highest reputation on 11/26/2022 in all areas
-
Centered FileOpenDialog() using self-terminating WM_TIMER call
pixelsearch reacted to KaFu for a topic
Hiho Team, attached a small example for a self-centering FileOpenDialog() using a self-terminating timer call. In the past I used _Timer_SetTimer() with a callback function, which works on x86, but does not under x64. So here's an example working for x64 too, using a global variable and WM_TIMER calls. What I just realized is that the doc for _WinAPI_SetTimer(), but also the MSDN doc for SetTimer, seem to be false. Success: The timer identifier. An application can pass this value to the _WinAPI_KillTimer() function to destroy the timer. _WinAPI_KillTimer() does not work when used with a hWnd and no callback func, _WinAPI_SetTimer() needs to be fed a dedicated TimerID (see "9876" used below). When I use the TimerID returned by _WinAPI_SetTimer() then _WinAPI_KillTimer() does not work. Hopefully useful for someone 😉. Edit: Replace fixed TimerID value 9876 with a TimerInit() call, I like the idea of a unique ID more. #Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_UseX64=y #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <WinAPISysWin.au3> Global $a_Global_FileOpenDialog_Wrapper[3] ; 0 = Title, 1 = hWnd, 2 = TimerID Local $s_Selected_File = _FileOpenDialog_Wrapper("Select File", @ScriptDir, "All (*.*)", 1 + 2 + 4) If Not @error Then MsgBox(0, "", $s_Selected_File) Func _FileOpenDialog_Wrapper($sTitle, $sInitDir, $sFilter, $iOptions = 0, $sDefaultName = "", $hWnd = 0) ; https://groups.google.com/forum/?hl=en&fromgroups=#!topic/microsoft.public.vc.mfc/HafQr4gIRY0 ; The problem is that GetOpenFileName changes the current directory to the last browsed one. The current directory and any of its parents cannot be deleted. If Not $sInitDir Then $sInitDir = "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}" ; CLSID for "My Computer" Local $sWorkingDir = @WorkingDir $a_Global_FileOpenDialog_Wrapper[0] = $sTitle Local $old_GUISwitch = GUISwitch(0) $a_Global_FileOpenDialog_Wrapper[1] = GUICreate("_FileOpenDialog_Wrapper") GUISwitch($old_GUISwitch) GUIRegisterMsg($WM_TIMER, "WM_TIMER") $a_Global_FileOpenDialog_Wrapper[2] = _WinAPI_SetTimer($a_Global_FileOpenDialog_Wrapper[1], TimerInit(), 10, 0) Local $sFilename = FileOpenDialog($sTitle, $sInitDir, $sFilter, $iOptions, $sDefaultName, $hWnd) Local $iError = @error ConsoleWrite("_WinAPI_KillTimer-2= " & _WinAPI_KillTimer($a_Global_FileOpenDialog_Wrapper[1], $a_Global_FileOpenDialog_Wrapper[2]) & @CRLF) GUIRegisterMsg($WM_TIMER, "") GUIDelete($a_Global_FileOpenDialog_Wrapper[1]) FileChangeDir($sWorkingDir) If Not $iError Then If StringInStr($sFilename, "|", 2) Then ; multiple selection Local $aFilename = StringSplit($sFilename, "|") Else Local $sPath = StringTrimRight($sFilename, StringLen($sFilename) - StringInStr($sFilename, "\", 2, -1)) EndIf EndIf Return SetError($iError, 0, $sFilename) EndFunc ;==>_FileOpenDialog_Wrapper Func WM_TIMER($hWnd, $iMsg, $iwParam, $ilParam) #forceref $hWnd, $iMsg, $iwParam, $ilParam ConsoleWrite("WM_TIMER " & @TAB & TimerInit() & @TAB & $hWnd & @TAB & $iMsg & @TAB & $iwParam & @TAB & $ilParam & @CRLF) Local $hWnd_Timer_Move_FileOpenDialog = WinGetHandle("[TITLE:" & $a_Global_FileOpenDialog_Wrapper[0] & ";CLASS:#32770]", "") If IsHWnd($hWnd_Timer_Move_FileOpenDialog) Then ConsoleWrite("WinMove= " & WinMove($hWnd_Timer_Move_FileOpenDialog, "", (@DesktopWidth - (@DesktopWidth / 4 * 3)) / 2, (@DesktopHeight - (@DesktopHeight / 4 * 3)) / 2, @DesktopWidth / 4 * 3, @DesktopHeight / 4 * 3) & @CRLF) ConsoleWrite("_WinAPI_KillTimer-1= " & _WinAPI_KillTimer($a_Global_FileOpenDialog_Wrapper[1], $a_Global_FileOpenDialog_Wrapper[2]) & @CRLF) ConsoleWrite(_WinAPI_GetLastErrorMessage() & @CRLF) EndIf Return $GUI_RUNDEFMSG EndFunc ;==>WM_TIMER Different approach, same result as with1 point -
Hiho Forum, different approach, same result as with Hopefully useful for someone 😉. Global $__a_Global_SHEx[3] ; $__a_Global_SHEx[0] = SHELLHOOK registered ; $__a_Global_SHEx[1] = hWnd for Hook ; $__a_Global_SHEx[2] = Dialog title _SHEx_RegisterWindowMessage_Init() Local $s_Selected_File = _FileOpenDialog_Wrapper("Select File", @ScriptDir, "All (*.*)", 1 + 2 + 4) If Not @error Then MsgBox(0, "", $s_Selected_File) Func _FileOpenDialog_Wrapper($sTitle, $sInitDir, $sFilter, $iOptions = 0, $sDefaultName = "", $hWnd = 0) ; https://groups.google.com/forum/?hl=en&fromgroups=#!topic/microsoft.public.vc.mfc/HafQr4gIRY0 ; The problem is that GetOpenFileName changes the current directory to the last browsed one. The current directory and any of its parents cannot be deleted. If Not $sInitDir Then $sInitDir = "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}" ; CLSID for "My Computer" Local $sWorkingDir = @WorkingDir $__a_Global_SHEx[2] = $sTitle _SHEx_ShellHookWindow($__a_Global_SHEx[1], 1) ; activate hook Local $sFilename = FileOpenDialog($sTitle, $sInitDir, $sFilter, $iOptions, $sDefaultName, $hWnd) Local $iError = @error _SHEx_ShellHookWindow($__a_Global_SHEx[1], 0) ; de-activate hook FileChangeDir($sWorkingDir) If Not $iError Then If StringInStr($sFilename, "|", 2) Then ; multiple selection Local $aFilename = StringSplit($sFilename, "|") Else Local $sPath = StringTrimRight($sFilename, StringLen($sFilename) - StringInStr($sFilename, "\", 2, -1)) EndIf EndIf Return SetError($iError, 0, $sFilename) EndFunc ;==>_FileOpenDialog_Wrapper Func _SHEx_RegisterWindowMessage_Init() $__a_Global_SHEx[0] = GUIRegisterMsg(_SHEx_RegisterWindowMessage("SHELLHOOK"), "_SHEx_HShellWndProc") Local $old_GUISwitch = GUISwitch(0) $__a_Global_SHEx[1] = GUICreate("SHELLHOOK GUI - " & @ScriptName) GUISwitch($old_GUISwitch) EndFunc ;==>_SHEx_RegisterWindowMessage_Init Func _SHEx_RegisterWindowMessage($sText) Local $aRet = DllCall('user32.dll', 'int', 'RegisterWindowMessage', 'str', $sText) Return $aRet[0] EndFunc ;==>_SHEx_RegisterWindowMessage Func _SHEx_ShellHookWindow($hWnd, $bFlag) Local $sFunc = 'DeregisterShellHookWindow' If $bFlag Then $sFunc = 'RegisterShellHookWindow' Local $aRet = DllCall('user32.dll', 'int', $sFunc, 'hwnd', $hWnd) ; ConsoleWrite("_SHEx_ShellHookWindow: " & $aRet[0] & @crlf) Return $aRet[0] EndFunc ;==>_SHEx_ShellHookWindow Func _SHEx_HShellWndProc($hWnd, $Msg, $wParam, $lParam) ; ShellProc callback function ; https://learn.microsoft.com/en-us/previous-versions/windows/desktop/legacy/ms644991(v=vs.85) ConsoleWrite($hWnd & @TAB & $Msg & @TAB & $wParam & @TAB & $lParam & @CRLF) If $wParam = 1 Then ; 1 = $HSHELL_WINDOWCREATED If $lParam = WinGetHandle("[TITLE:" & $__a_Global_SHEx[2] & ";CLASS:#32770]", "") Then ConsoleWrite("WinMove= " & WinMove($lParam, "", (@DesktopWidth - (@DesktopWidth / 4 * 3)) / 2, (@DesktopHeight - (@DesktopHeight / 4 * 3)) / 2, @DesktopWidth / 4 * 3, @DesktopHeight / 4 * 3) & @CRLF) EndIf EndIf ; https://learn.microsoft.com/en-us/previous-versions/windows/desktop/legacy/ms644991(v=vs.85) Return 0 ; The return value should be zero unless the value of nCode is HSHELL_APPCOMMAND and the shell procedure handles the WM_COMMAND message. In this case, the return should be nonzero. EndFunc ;==>_SHEx_HShellWndProc1 point
-
_Base64Encode, _Base64Decode
argumentum reacted to garbb for a topic
From https://learn.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptbinarytostringa If you want, you can add CRYPT_STRING_NOCRLF (0x40000000) to the flags parameter to prevent the CRLF's in the output. Like this: Func _Base64Encode($input) $input = Binary($input) Local $struct = DllStructCreate("byte[" & BinaryLen($input) & "]") DllStructSetData($struct, 1, $input) Local $strc = DllStructCreate("int") Local $a_Call = DllCall("Crypt32.dll", "int", "CryptBinaryToString", _ "ptr", DllStructGetPtr($struct), _ "int", DllStructGetSize($struct), _ "int", 1 + 0x40000000, _ "ptr", 0, _ "ptr", DllStructGetPtr($strc)) If @error Or Not $a_Call[0] Then Return SetError(1, 0, "") ; error calculating the length of the buffer needed EndIf Local $a = DllStructCreate("char[" & DllStructGetData($strc, 1) & "]") $a_Call = DllCall("Crypt32.dll", "int", "CryptBinaryToString", _ "ptr", DllStructGetPtr($struct), _ "int", DllStructGetSize($struct), _ "int", 1 + 0x40000000, _ "ptr", DllStructGetPtr($a), _ "ptr", DllStructGetPtr($strc)) If @error Or Not $a_Call[0] Then Return SetError(2, 0, ""); error encoding EndIf Return DllStructGetData($a, 1) EndFunc ;==>_Base64Encode1 point -
#include <array2.au3> $res=_SplitByChar("1234567890",2) _ArrayDisplay($res) Func _SplitByChar($String, $Chrs) $len = StringLen($string) $Parts = Round($len/$chrs,0)+1 $split1 = StringSplit($String, "") Local $Split2[$parts] = [""], $i = 0 For $a = 1 to $Parts-1 For $b = 1 to $chrs $Split2[$a] &= $Split1[$b+($i*$chrs)] Next $i +=1 Next $Split2[0] = $Parts-1 Return $Split2 EndFunc1 point