pixelsearch Posted Wednesday at 09:11 AM Posted Wednesday at 09:11 AM (edited) 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 expandcollapse popup#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 Global $g_hGUI, $g_hDLL = DllOpen("user32.dll") Global $g_aCaption, $g_sTitle Example() ;=========================================== Func Example() $g_hGUI = GUICreate("Big MsgBox example", 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, 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] = ["Cancel", "Try Again", "Continue"] $g_sTitle = "MsgBox with 3 buttons" Local $iChoice = _MsgBox(BitOr($MB_CANCELTRYCONTINUE, $MB_TOPMOST), $g_sTitle, $sTxt, 0, $g_hGUI) ;~ Dim $g_aCaption[2] = ["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] = ["OK"] ;~ $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) 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 ControlSetText($hMsgBox, "", "Button" & ($i + 1), $g_aCaption[$i]) $aPosButton = ControlGetPos($hMsgBox, "", "Button" & ($i + 1)) WinMove(ControlGetHandle($hMsgBox, "", "Button" & ($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 Else For $i = 0 To Ubound($g_aCaption) - 1 ControlSetText($hMsgBox, "", "Button" & ($i + 1), $g_aCaption[$i]) Next 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" HotKeySet("{SPACE}", "_Space") 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("21", $g_hDLL) ; PageUp Key While _IsPressed("21", $g_hDLL) Sleep(10) Wend $aPosMsgBox = WinGetPos($hMsgBox) WinMove( $hMsgBox, "", Default, ($aPosMsgBox[1] + @DesktopHeight > 0) ? 0 : $aPosMsgBox[1] + @DesktopHeight ) Case _IsPressed("22", $g_hDLL) ; PageDown Key While _IsPressed("22", $g_hDLL) Sleep(10) Wend $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 $aPosMsgBox = WinGetPos($hMsgBox) WinMove($hMsgBox, "", Default, @DesktopHeight - $aPosMsgBox[3]) Case _IsPressed("24", $g_hDLL) ; Home Key WinMove($hMsgBox, "", Default, 0) Case _IsPressed("26", $g_hDLL) ; Up Key $aPosMsgBox = WinGetPos($hMsgBox) WinMove($hMsgBox, "", Default, ($aPosMsgBox[1] + 12 > 0) ? 0 : $aPosMsgBox[1] + 12) 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 clicked ExitLoop EndIf Sleep(10) WEnd HotKeySet("{SPACE}") _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 _Space() HotKeySet("{SPACE}") ; deactivate Hotkey If WinActive($g_sTitle) Then HotKeySet("{SPACE}", "_DoNothing") ; this part to avoid a MsgBox button being triggered, when Spacebar key is pressed too long. While _IsPressed("20", $g_hDLL) ; Spacebar key Sleep(10) Wend Else Send("{SPACE}") EndIf HotKeySet("{SPACE}", "_Space") ; reactivate Hotkey EndFunc ;==>_Space ;============================================== Func _DoNothing() EndFunc ;==>_DoNothing Edited Wednesday at 09:19 AM by pixelsearch typo CYCho, Musashi, funkey and 1 other 4 "I think you are searching a bug where there is no bug..."
funkey Posted 11 hours ago Posted 11 hours ago Thank you. Works great. Only thing is visual issue at last line for me. But no problem. BR funkey Programming today is a race between software engineers striving tobuild bigger and better idiot-proof programs, and the Universetrying to produce bigger and better idiots.So far, the Universe is winning.
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now