Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 02/19/2025 in all areas

  1. Hi everybody This script displays a big MessageBox having a height higher than @DesktopHeight While the MessageBox is displayed, you can "navigate" inside it like this : * Mouse Left-click drag : to move the window up and down (displaying a new panel of lines) * Mouse Right-click : to display the window at its initial position * Up key * Down key * PageUp Key (Fn + up key on some laptops) * PageDown Key (Fn + down key on some laptops) * Home Key (Fn + left key on some laptops) * End Key (Fn + right key on some laptops) The 6 keyboard keys allow to navigate inside the window. Click on a button (placed at top of the window) to make your choice. All this could have been scripted more easily using a GUI, an Edit control containing the text to display, plus the buttons to choose from, but I just wanted to try it using a native MessageBox #include <APISysConstants.au3> ; $GCL_HCURSOR #include <ButtonConstants.au3> #include <EditConstants.au3> #include <GUIConstantsEx.au3> #include <Misc.au3> #include <MsgBoxConstants.au3> #include <StaticConstants.au3> #include <WinAPIRes.au3> ; _WinAPI_LoadCursor() #include <WinAPISysWin.au3> ; _WinAPI_SetClassLongEx() #include <WindowsConstants.au3> Opt("MustDeclareVars", 1) ;0=no, 1=require pre-declaration Opt("GUICloseOnESC", 0) ;1=ESC closes (default), 0=ESC won't close Global $g_hGUI, $g_hDLL = DllOpen("user32.dll") Global $g_aCaption, $g_sTitle Example() ;=========================================== Func Example() $g_hGUI = GUICreate("Big MsgBox example (7b)", 400, 200) GUICtrlCreateLabel("Number of lines in MsgBox (2 - 1588)", 10, 20, 180, 20, $SS_SUNKEN) Local $idNbLines = GUICtrlCreateInput("200", 200, 20, 35, 20, BitOR($GUI_SS_DEFAULT_INPUT, $ES_NUMBER)), $iNbLines GUICtrlSetLimit($idNbLines, 4) Local $idMsgBox = GUICtrlCreateButton("Big MsgBox", 10, 60, 100, 25, $BS_DEFPUSHBUTTON) Local $idExit = GUICtrlCreateButton("Exit", 10, 110, 100, 25) GUISetState() While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE, $idExit ExitLoop Case $idMsgBox Local $iRet = Prepare_MsgBox(GUICtrlRead($idNbLines)) If $iRet Then MsgBox($MB_TOPMOST, "Big MsgBox return value : " & $iRet, Retrieve_Caption($iRet), 0, $g_hGUI) GUICtrlSetState($idNbLines, $GUI_FOCUS) EndSwitch WEnd DllClose($g_hDLL) EndFunc ;==>Example ;=========================================== Func Prepare_MsgBox(Const $iNbLines) If $iNbLines < 2 Or $iNbLines > 1588 Then MsgBox($MB_TOPMOST, "Error", "Enter a number of lines between 2 and 1588", 0, $g_hGUI) Return ; 0 EndIf Local $sTxt = "Line 1 : first line" & @crlf For $i = 2 To $iNbLines - 1 $sTxt &= "Line " & $i & @crlf Next $sTxt &= "Line " & $iNbLines & " : last line" Dim $g_aCaption[3][3] = [ ["Cancel"], ["Try Again"], ["Continue"] ] ; 1st column = button caption, 2nd = button handle, 3rd = button ID $g_sTitle = "MsgBox with 3 buttons" Local $iChoice = _MsgBox(BitOr($MB_CANCELTRYCONTINUE, $MB_TOPMOST), $g_sTitle, $sTxt, 0, $g_hGUI) ;~ Dim $g_aCaption[2][3] = [ ["Yes"], ["No"] ] ;~ $g_sTitle = "MsgBox with 2 buttons" ;~ Local $iChoice = _MsgBox(BitOr($MB_YESNO, $MB_TOPMOST), $g_sTitle, $sTxt, 0, $g_hGUI) ;~ Dim $g_aCaption[1][3] = [ ["Hello"] ] ;~ $g_sTitle = "MsgBox with 1 button" ;~ Local $iChoice = _MsgBox(BitOr($MB_OK, $MB_TOPMOST), $g_sTitle, $sTxt, 0, $g_hGUI) Return $iChoice EndFunc ;==>Prepare_MsgBox ;=========================================== Func _MsgBox($iFlag, $g_sTitle, $sText, $iTimeOut = 0, $hWnd = 0) GUIRegisterMsg($WM_HELP , "WM_HELP") Local $hTimerProc = DllCallbackRegister('_MsgBoxTimerProc', 'none', 'hwnd;uint;uint_ptr;dword') Local $iTimerID = _WinAPI_SetTimer(0, 0, 10, DllCallbackGetPtr($hTimerProc)) Local $iChoice = MsgBox($iFlag, $g_sTitle, $sText, $iTimeOut, $hWnd) _WinAPI_KillTimer(0, $iTimerID) DllCallbackFree($hTimerProc) GUIRegisterMsg($WM_HELP, "") Return $iChoice EndFunc ;==>_MsgBox ;=========================================== Func _MsgBoxTimerProc($hWnd, $iMsg, $iTimerID, $iTime) If WinExists($g_sTitle) Then _WinAPI_KillTimer(0, $iTimerID) Local $hMsgBox = WinGetHandle($g_sTitle) For $i = 0 To Ubound($g_aCaption) - 1 ControlSetText($hMsgBox, "", "Button" & ($i + 1), $g_aCaption[$i][0]) $g_aCaption[$i][1] = ControlGetHandle($hMsgBox, "", "Button" & ($i + 1)) $g_aCaption[$i][2] = _WinAPI_GetDlgCtrlID($g_aCaption[$i][1]) ; remember OK button ID is 1 ($MB_OKCANCEL) or 2 ($MB_OK) ... ; ... msdn "If a message box has a Cancel button, the function returns the IDCANCEL value (2) if either the ESC key is pressed ; or the Cancel button is selected." ; "If the message box has no Cancel button, pressing ESC will no effect - unless an MB_OK button is present. ; If an MB_OK button is displayed and the user presses ESC, the return value will be IDOK (1)" [personal: only one case for this] Next Local $aPosMsgBox = WinGetPos($hMsgBox) Local $bTooHigh = ($aPosMsgBox[3] > @DesktopHeight + 15) ? True : False If $bTooHigh Then Local $aPosButton, $aPosStatic = ControlGetPos($hMsgBox, "", "Static1") ; the text area For $i = 0 To Ubound($g_aCaption) - 1 $aPosButton = ControlGetPos($hMsgBox, "", "Button" & ($i + 1)) WinMove($g_aCaption[$i][1], "", $aPosButton[0], $aPosStatic[1]) Next WinMove(ControlGetHandle($hMsgBox, "", "Static1"), "", $aPosStatic[0], $aPosStatic[1] + $aPosButton[3] + 10) _WinAPI_RedrawWindow($hMsgBox) ; +++ Send("{F1}") ; => Func WM_HELP EndIf EndIf EndFunc ;==>_MsgBoxTimerProc ;============================================== Func WM_HELP($hWnd, $iMsg, $wParam, $lParam) #forceref $hWnd, $iMsg, $wParam, $lParam If WinExists($g_sTitle) Then ; MessageBox window always exists at this stage Local $hMsgBox = WinGetHandle($g_sTitle) Local $aPosMsgBox = WinGetPos($hMsgBox), $aPosMsgBox_Init = $aPosMsgBox Local $aWinPos, $aMPos, $aMPosOld Local $hCursor = _WinAPI_LoadCursor(0, $OCR_SIZEALL) ; $OCR_SIZENS ok too Local $iPrev = _WinAPI_SetClassLongEx($hMsgBox, $GCL_HCURSOR, $hCursor) ; see "147c.au3" _ClearBuffer("0D") ; Enter key (in case pressed too long on button 'Big MsgBox' in main GUI, so it won't select a button in MsgBox) While 1 If WinActive($hMsgBox) Then Select Case _IsPressed("01", $g_hDLL) ; "01" = Left mouse button $aMPosOld = MouseGetPos() While _IsPressed("01", $g_hDLL) $aMPos = MouseGetPos() If $aMPos[1] <> $aMPosOld[1] Then $aWinpos = WinGetPos($hMsgBox) If ($aMPos[0] - 1 > $aWinpos[0]) And ($aMPos[0] + 1 < $aWinpos[0] + $aWinpos[2]) Then WinMove($hMsgBox, "", Default, $aWinpos[1] + ($aMPos[1] - $aMPosOld[1])) $aMPosOld = $aMPos EndIf EndIf Sleep(10) Wend Case _IsPressed("02", $g_hDLL) ; Right mouse button WinMove($hMsgBox, "", $aPosMsgBox_Init[0], $aPosMsgBox_Init[1]) Case _IsPressed("09", $g_hDLL) ; Tab key _ClearBuffer("09") _ChangeFocus($hMsgBox, "09") Case _IsPressed("0D", $g_hDLL) ; Enter key _ClearBuffer("0D") ControlClick($hMsgBox, "", ControlGetFocus($hMsgBox)) Case _IsPressed("1B", $g_hDLL) ; Esc key _ClearBuffer("1B") For $i = 0 To Ubound($g_aCaption) - 1 If $g_aCaption[$i][2] = 2 Then ; Cancel button (or OK button when alone : see msdn notes above) ControlClick($hMsgBox, "", $g_aCaption[$i][2]) EndIf Next Case _IsPressed("21", $g_hDLL) ; PageUp Key (Fn + up key on most laptops) _ClearBuffer("21") $aPosMsgBox = WinGetPos($hMsgBox) WinMove( $hMsgBox, "", Default, ($aPosMsgBox[1] + @DesktopHeight > 0) ? 0 : $aPosMsgBox[1] + @DesktopHeight ) Case _IsPressed("22", $g_hDLL) ; PageDown Key (Fn + down key on most laptops) _ClearBuffer("22") $aPosMsgBox = WinGetPos($hMsgBox) WinMove( $hMsgBox, "", Default, _ ($aPosMsgBox[3] + $aPosMsgBox[1] - @DesktopHeight < @DesktopHeight + 15) ? @DesktopHeight - $aPosMsgBox[3] : $aPosMsgBox[1] - @DesktopHeight ) Case _IsPressed("23", $g_hDLL) ; End Key (Fn + right key on most laptops) $aPosMsgBox = WinGetPos($hMsgBox) WinMove($hMsgBox, "", Default, @DesktopHeight - $aPosMsgBox[3]) Case _IsPressed("24", $g_hDLL) ; Home Key (Fn + left key on most laptops) WinMove($hMsgBox, "", Default, 0) Case _IsPressed("25", $g_hDLL) ; Left key _ClearBuffer("25") _ChangeFocus($hMsgBox, "25") Case _IsPressed("26", $g_hDLL) ; Up Key $aPosMsgBox = WinGetPos($hMsgBox) WinMove($hMsgBox, "", Default, ($aPosMsgBox[1] + 12 > 0) ? 0 : $aPosMsgBox[1] + 12) Case _IsPressed("27", $g_hDLL) ; Right key _ClearBuffer("27") _ChangeFocus($hMsgBox, "27") Case _IsPressed("28", $g_hDLL) ; Down Key $aPosMsgBox = WinGetPos($hMsgBox) WinMove( $hMsgBox, "", Default, _ ($aPosMsgBox[3] + $aPosMsgBox[1] - 12 < @DesktopHeight) ? @DesktopHeight - $aPosMsgBox[3] : $aPosMsgBox[1] - 12 ) EndSelect EndIf If Not BitAND(WinGetState($hMsgBox), $WIN_STATE_VISIBLE) Then ; one of MsgBox buttons was chosen by user ExitLoop EndIf Sleep(10) WEnd _WinAPI_SetClassLongEx($hMsgBox, $GCL_HCURSOR, $iPrev) ; needed, or cursor $OCR_SIZEALL will show... in final MsgBox from main loop EndIf Return $GUI_RUNDEFMSG EndFunc ;==>WM_HELP ;============================================== Func _ClearBuffer($sKey) While _IsPressed($sKey, $g_hDLL) Sleep(10) Wend EndFunc ;==>_ClearBuffer ;============================================== Func _ChangeFocus($hMsgBox, $sKey) Local $iCtrlGetFocus, $iCtrlSetFocus, $iStyle $iCtrlGetFocus = StringRight(ControlGetFocus($hMsgBox), 1) ; 1/2/3 (last char of "Button1"/"Button2"/"Button3") If $sKey = "27" Or $sKey = "09" Then ; Right key (27) or Tab (09) $iCtrlSetFocus = $iCtrlGetFocus < Ubound($g_aCaption) ? $iCtrlGetFocus + 1 : 1 Else ; Left key (25) $iCtrlSetFocus = $iCtrlGetFocus > 1 ? $iCtrlGetFocus - 1 : Ubound($g_aCaption) EndIf ControlFocus($hMsgBox, "", "Button" & $iCtrlSetFocus) $iStyle = _WinAPI_GetWindowLong($g_aCaption[$iCtrlGetFocus - 1][1], $GWL_STYLE) _WinAPI_SetWindowLong($g_aCaption[$iCtrlGetFocus - 1][1], $GWL_STYLE, BitXOR($iStyle, $BS_DEFPUSHBUTTON)) $iStyle = _WinAPI_GetWindowLong($g_aCaption[$iCtrlSetFocus - 1][1], $GWL_STYLE) _WinAPI_SetWindowLong($g_aCaption[$iCtrlSetFocus - 1][1], $GWL_STYLE, BitOR($iStyle, $BS_DEFPUSHBUTTON)) EndFunc ;==>_ChangeFocus ;=========================================== Func Retrieve_Caption($iRet) If Ubound($g_aCaption) = 1 Then ; $MB_OK Return $g_aCaption[0][0] Else For $i = 0 To Ubound($g_aCaption) - 1 If $g_aCaption[$i][2] = $iRet Then Return $g_aCaption[$i][0] ; button ID always = $iRet (except for $MB_OK, see note msdn above) Next EndIf MsgBox($MB_TOPMOST, "Warning", "This message should never be displayed", 0, $g_hGUI) EndFunc ;==>Retrieve_Caption Update Feb 24, 2025 : Left key, Right key, Tab, Enter, Spacebar, Esc These 6 keys react now like they do in any MsgBox Feb 27, 2025 : minor correction
    2 points
  2. I see now. I believe OP can manage to change the links in the loop the way he wants it to. I know it is a very difficult task but it is feasible
    2 points
  3. Here my take with SRE : #include <Array.au3> #include <Constants.au3> Local $sTarget = "sap-x64-301.exe|sap-x64-301ar.exe|sap-x64-301am.exe|sap-x64-301az.exe|sap-x64-301bg.exe|sap-x64-301ca.exe|sap-x64-301sc.exe|sap-x64-301tc.exe|sap-x64-301cro.exe|sap-x64-301cz.exe|sap-x64-301dk.exe|sap-x64-301nl.exe|sap-x64-301eu.exe|sap-x64-301fi.exe|sap-x64-301fr.exe|sap-x64-301gl.exe|sap-x64-301d.exe|sap-x64-301el.exe|sap-x64-301he.exe|sap-x64-301hu.exe|sap-x64-301id.exe|sap-x64-301it.exe|sap-x64-301jp.exe|sap-x64-301kr.exe|sap-x64-301lt.exe|sap-x64-301mn.exe|sap-x64-301no.exe|sap-x64-301pl.exe|sap-x64-301pt.exe|sap-x64-301br.exe|sap-x64-301ro.exe|sap-x64-301ru.exe|sap-x64-301srbcyr.exe|sap-x64-301sk.exe|sap-x64-301slv.exe|sap-x64-301es.exe|sap-x64-301sw.exe|sap-x64-301th.exe|sap-x64-301tr.exe|sap-x64-301uk.exe|sap-x64-301vn.exe" Local $aList = StringRegExp($sTarget, "sap-x64-301(?||ar|en|fr|d|ru|es|it|tr)\.exe", $STR_REGEXPARRAYGLOBALMATCH) $aList = _ArrayUnique($aList, Default, Default, Default, $ARRAYUNIQUE_NOCOUNT) Local $hFile = FileOpen("Down_Links.txt", $FO_OVERWRITE) FileWriteLine($hFile, "SAP x64") For $sLink In $aList FileWriteLine($hFile, "https://www.sap.com/sap/" & $sLink) Next FileClose($hFile) I get also EN link. SAP x64 https://www.sap.com/sap/sap-x64-301.exe https://www.sap.com/sap/sap-x64-301ar.exe https://www.sap.com/sap/sap-x64-301fr.exe https://www.sap.com/sap/sap-x64-301d.exe https://www.sap.com/sap/sap-x64-301it.exe https://www.sap.com/sap/sap-x64-301ru.exe https://www.sap.com/sap/sap-x64-301es.exe https://www.sap.com/sap/sap-x64-301tr.exe
    2 points
  4. Working , easy code and suitable for me. Thanks a lot for your help and this a good solution for me. By the way the links are imaginary links just to understand the code
    1 point
  5. Not sure what you mean here other than, like @Nine mentioned, you need to use your Email now to login to stop the many hacking attacks. PM me your previous account and I will merge it into this one, keeping the name&Email of this one.
    1 point
  6. No, I mean this difference @Nine: My link: https://www.sap.com/sap/SAP-301fr.exe Your linK: https://www.sap.com/sap/sap-x64-301fr.exe I cannot test any of these, because I am not logged in (I will not create an account). I believe your link should be the right one, but the OP created the link differently (so I took this over). Whatever, who knows 😂 . Best regards Sven
    1 point
  7. Thanks @Nine, I missed that one. I like your approach - it's basically the one I also had chosen. One little thing: Your URLs are not named like Davidyese want it to. @Davidyese: I adjusted my "solution". But let us know, are the created URLs valid? https://www.sap.com/sap/SAP-301fr.exe ==> can only be downloaded when you're signed in, right? Best regards Sven
    1 point
  8. Hi @Davidyese 👋 , the following is definitely not my best code, but I did not want to change your approach too much. #AutoIt3Wrapper_AU3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7 #AutoIt3Wrapper_AU3Check_Stop_OnWarning=y #include-once #include <Array.au3> _Main() Func _Main() Local Const $sSAPLocals = "ar|en|fr|d|ru|es|it|tr" Local Const $aLangfiles = StringSplit($sSAPLocals, "|", 2) Local Const $sTarget = "sap-x64-301.exe|sap-x64-301ar.exe|sap-x64-301am.exe|sap-x64-301az.exe|sap-x64-301bg.exe|sap-x64-301ca.exe|sap-x64-301sc.exe|sap-x64-301tc.exe|sap-x64-301cro.exe|sap-x64-301cz.exe|sap-x64-301dk.exe|sap-x64-301nl.exe|sap-x64-301eu.exe|sap-x64-301fi.exe|sap-x64-301fr.exe|sap-x64-301gl.exe|sap-x64-301d.exe|sap-x64-301el.exe|sap-x64-301he.exe|sap-x64-301hu.exe|sap-x64-301id.exe|sap-x64-301it.exe|sap-x64-301jp.exe|sap-x64-301kr.exe|sap-x64-301lt.exe|sap-x64-301mn.exe|sap-x64-301no.exe|sap-x64-301pl.exe|sap-x64-301pt.exe|sap-x64-301br.exe|sap-x64-301ro.exe|sap-x64-301ru.exe|sap-x64-301srbcyr.exe|sap-x64-301sk.exe|sap-x64-301slv.exe|sap-x64-301es.exe|sap-x64-301sw.exe|sap-x64-301th.exe|sap-x64-301tr.exe|sap-x64-301uk.exe|sap-x64-301vn.exe" Local Const $aFiles = StringSplit($sTarget, "|", 2) Local Const $sX64SAPValue = "301" Local $sSAPLngs Local $sGoodLatestx64 For $i = 0 To UBound($aFiles) - 1 For $ix = 0 To UBound($aLangfiles) - 1 $sSAPLngs = $aLangfiles[$ix] If StringInStr($aFiles[$i], $sX64SAPValue & '.exe') Then $sGoodLatestx64 &= 'https://www.sap.com/sap/SAP-' & $sX64SAPValue & '.exe' & @CRLF EndIf If StringInStr($aFiles[$i], $sSAPLngs & '.exe') Then $sGoodLatestx64 &= 'https://www.sap.com/sap/SAP-' & $sX64SAPValue & $sSAPLngs & '.exe' & @CRLF EndIf Next Next Local $sGoodLatestx64WithoutLastCRLF = StringTrimRight($sGoodLatestx64, 2) Local Const $aGoodLatestX64 = StringSplit($sGoodLatestx64WithoutLastCRLF, @CRLF, BitOr(1, 2)) Local $aUniqueList = _ArrayUnique($aGoodLatestX64) _ArraySort($aUniqueList) _ArrayDelete($aUniqueList, 0) $sGoodLatestx64 = _ArrayToString($aUniqueList, @CRLF) _WriteFile($sGoodLatestx64) EndFunc Func _WriteFile($sData) Local $hFileOpen = FileOpen(@ScriptDir & '\Down_Links.txt', 2) FileWrite($hFileOpen, "SAP x64" & @CRLF) FileWrite($hFileOpen, $sData) FileClose($hFileOpen) EndFunc Output: SAP x64 https://www.sap.com/sap/SAP-301.exe https://www.sap.com/sap/SAP-301ar.exe https://www.sap.com/sap/SAP-301d.exe https://www.sap.com/sap/SAP-301es.exe https://www.sap.com/sap/SAP-301fr.exe https://www.sap.com/sap/SAP-301it.exe https://www.sap.com/sap/SAP-301ru.exe https://www.sap.com/sap/SAP-301tr.exe In case you want to avoid the long unreadable files string: It works, but it's not very flexible and also without error handling. If it's still okay for your goal, fine 🤝 . Best regards Sven
    1 point
  9. There is numerous converting functions inside ntdll.dll and msvcrt.dll (you can search for it). Here what you want to achieve very easily : ConsoleWrite(_Ui32ToString(0x87654321, 2) & @CRLF) ConsoleWrite(_Ui32ToString(2684354560, 2) & @CRLF) Func _Ui32ToString($i, $base) Return DllCall("ntdll.dll", "str:cdecl", "_ultoa", "ulong", $i, "str", "", "int", $base)[0] EndFunc
    1 point
×
×
  • Create New...