VAN0 Posted March 23 Share Posted March 23 Hello. I'm using some software that displays bunch of unnecessary messages as message box with "ok" button. I'd like to automatically "convert" these messages into toast or balloon, which is relatively easy task. Before I waste my time code it, I thought I'd ask if maybe someone already done this, I've search the forum, but nothing came up. Has anyone seen anything that would do that? Thank you. Link to comment Share on other sites More sharing options...
Andreik Posted March 23 Share Posted March 23 You can check in a loop (or a hook but I don't think it's necessary to complicate the script) when certain messageboxes appear on the screen, then grab the message, close the message box and display the message as you like. When the words fail... music speaks. Link to comment Share on other sites More sharing options...
Danyfirex Posted March 23 Share Posted March 23 Hello. Modify this code. Check for the window's Process. play with it get the text, hide it, click it etc. Saludos VAN0 1 Danysys.com AutoIt... UDFs: VirusTotal API 2.0 UDF - libZPlay UDF - Apps: Guitar Tab Tester - VirusTotal Hash Checker Examples: Text-to-Speech ISpVoice Interface - Get installed applications - Enable/Disable Network connection PrintHookProc - WINTRUST - Mute Microphone Level - Get Connected NetWorks - Create NetWork Connection ShortCut Link to comment Share on other sites More sharing options...
VAN0 Posted March 23 Author Share Posted March 23 7 minutes ago, Danyfirex said: Hello. Modify this code. Check for the window's Process. play with it get the text, hide it, click it etc. Saludos Thank you. This doesn't seem to be working for message boxes, only for unowned windows, while message boxes usually a child of a main window (?) Link to comment Share on other sites More sharing options...
ioa747 Posted March 23 Share Posted March 23 bring it to your needs expandcollapse popup; ;~ #AutoIt3Wrapper_AU3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 6 -w 7 #include <WinAPIProc.au3> #include <WinAPISysWin.au3> #include <StringConstants.au3> #include <TrayConstants.au3> Opt("TrayMenuMode", 3) ; These are options 1 and 2 for TrayMenuMode. Opt("TrayOnEventMode", 1) ; Enable TrayOnEventMode. Global $bPaused = False TraySetIcon(StringLeft(@AutoItExe, StringInStr(@AutoItExe, "\", $STR_NOCASESENSEBASIC, -1) - 1) & "\Icons\MyAutoIt3_Blue.ico") #Region === Tray_Menu === TraySetOnEvent($TRAY_EVENT_PRIMARYDOUBLE, "TogglePause") Global $idPaused = TrayCreateItem("Pause", -1, -1, $TRAY_ITEM_RADIO) TrayItemSetOnEvent(-1, "TogglePause") TrayItemSetState(-1, $TRAY_UNCHECKED) TrayCreateItem("") ; Create a separator line. Global $idExit = TrayCreateItem("Exit") TrayItemSetOnEvent(-1, "GoToExit") #EndRegion === Tray_Menu === _Main() ;---------------------------------------------------------------------------------------- Func _Main() Local $hMBox, $iPID Local $sText, $sTitle, $sProcess Local $BlackList = "C:\Program Files (x86)\AutoIt3\SciTE\SciTE.exe" ; *** <--------- ;********************************** While 1 _GetTrayStatus() If WinActive("[CLASS:#32770]") Then $hMBox = WinGetHandle("[CLASS:#32770]") ; Retrieve the identifier of the thread and pass a variable to the $iPID parameter to store the PID. $iPID = 0 $sProcess = "" _WinAPI_GetWindowThreadProcessId($hMBox, $iPID) $sProcess = _WinAPI_GetProcessFileName($iPID) If $sProcess = $BlackList Then $sText = "" $sTitle = "" $sText = ControlGetText ($hMBox, "", "Static2") ; WinGetText($hMBox) ; *** <--------- $sTitle = WinGetTitle($hMBox) WinClose($hMBox) Tip($sText, $sTitle, 7, 2060) EndIf EndIf Sleep(10) WEnd ;********************************** EndFunc ;==>_Main ;---------------------------------------------------------------------------------------- Func GoToExit() ; exit Exit EndFunc ;==>GoToExit ;---------------------------------------------------------------------------------------- Func _GetTrayStatus() While 1 If $bPaused = False Then ExitLoop Else ; calm down and stay Sleep(500) EndIf WEnd EndFunc ;==>_GetTrayStatus ;---------------------------------------------------------------------------------------- Func TogglePause() If $bPaused = False Then $bPaused = True TrayItemSetState($idPaused, $TRAY_CHECKED) ; $TRAY_UNCHECKED, $TRAY_CHECKED TraySetIcon(StringLeft(@AutoItExe, StringInStr(@AutoItExe, "\", $STR_NOCASESENSEBASIC, -1) - 1) & "\Icons\MyAutoIt3_Red.ico") Else $bPaused = False TrayItemSetState($idPaused, $TRAY_UNCHECKED) ; $TRAY_UNCHECKED, $TRAY_CHECKED TraySetIcon(StringLeft(@AutoItExe, StringInStr(@AutoItExe, "\", $STR_NOCASESENSEBASIC, -1) - 1) & "\Icons\MyAutoIt3_Blue.ico") EndIf EndFunc ;==>TogglePause ;---------------------------------------------------------------------------------------- ; https://www.autoitscript.com/forum/topic/209408-traytipgui-to-send-a-message-to-the-tray ;---------------------------------------------------------------------------------------- Func Tip($Msg, $Title = "info", $Timeout = 3, $Icon = 2060) Local $FilePath = @ScriptDir & "\TrayTipGUI.au3" Local $Param = '"' & $Title & '" "' & $Msg & '" "' & $Timeout & '" "' & $Icon & '"' Run(FileGetShortName(@AutoItExe) & " " & FileGetShortName($FilePath) & " " & $Param) EndFunc ;==>Tip ;---------------------------------------------------------------------------------------- I know that I know nothing Link to comment Share on other sites More sharing options...
VAN0 Posted March 24 Author Share Posted March 24 (edited) The detection of a popup is not an issue, however it turned out detection of the text inside become an issue... None of the #31 methods seem to be able detect any text but "OK" from the button. UWPOCR to the rescue: Works great, but it's slow because of _ScreenCapture_CaptureWnd() Is there a faster alternative? Edited March 24 by VAN0 Link to comment Share on other sites More sharing options...
Nine Posted March 24 Share Posted March 24 (edited) Another approach would be to move the window to the usual toast location and close it after 2-3 secs. Edit : made an example for the fun of it... Run("Notepad") Local $hWnd = WinWaitActive("[CLASS:Notepad]") ControlSend($hWnd, "", "Edit1", "Test") ControlSend($hWnd, "", "", "!{F4}") ; simulate a msg box While Sleep(10) $hWnd = WinGetHandle("[CLASS:#32770]") ; or title "Bloc-notes" for french Notepad If $hWnd Then ExitLoop WEnd Local $aPos = WinGetPos($hWnd) WinMove($hWnd, "", @DesktopWidth - $aPos[2] - 10, @DesktopHeight + 1) ControlHide($hWnd, "", "Button1") ControlHide($hWnd, "", "Button2") ControlHide($hWnd, "", "Button3") For $i = 15 To $aPos[3] + 50 Step 3 WinMove($hWnd, "", @DesktopWidth - $aPos[2] - 10, @DesktopHeight - $i) Sleep(10) Next SoundPlay("C:\Windows\Media\Windows Notify Messaging.wav") Sleep(2000) WinKill($hWnd) ps. changed a bit the code to make it more of toast Edited March 24 by Nine ioa747 1 “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Screen Scraping Multi-Threading Made Easy Link to comment Share on other sites More sharing options...
ioa747 Posted March 24 Share Posted March 24 check when the message box is active and press ctrl+c to see what text it receives ..if e.g. in Notepad receives: [Window Title] Notepad [Main Instruction] Do you want to save changes to Untitled? [Save] [Don't Save] [Cancel] e.g. in SciTE receives: --------------------------- SciTE --------------------------- Save changes to (Untitled)? --------------------------- Yes No Cancel --------------------------- I know that I know nothing Link to comment Share on other sites More sharing options...
VAN0 Posted March 24 Author Share Posted March 24 1 hour ago, Nine said: Another approach would be to move the window to the usual toast location and close it after 2-3 secs. I like that! didn't occur to me I can manipulate sizes, style and hide controls! Just one issue with this, it won't allow clicking in parent application until popup closed, unless there is a way make it non-modal? 1 hour ago, ioa747 said: check when the message box is active and press ctrl+c to see what text it receives ..if Unfortunately, it just makes "error" sound, and nothing being copied to clipboard. I guess it's not standard message box, although it's uses the same class Link to comment Share on other sites More sharing options...
Nine Posted March 24 Share Posted March 24 4 minutes ago, VAN0 said: unless there is a way make it non-modal? Unfortunately, it is not possible, AFAIK. Another way would be to move/hide the window like I did, make modifications to the window, use PrintWindow, kill the window, create a toast (guicreate) with a pic inside. BTW, Printwindow is really fast...I don't think user would notice. VAN0 1 “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Screen Scraping Multi-Threading Made Easy Link to comment Share on other sites More sharing options...
VAN0 Posted March 24 Author Share Posted March 24 (edited) 15 hours ago, Nine said: BTW, Printwindow is really fast...I don't think user would notice. I'm getting very promising results with this. But there are 2 issues: 1) sometimes it doesn't capture the window, because it runs too soon before popup fully painted. Is there a way detect if window has been fully painted? (I really don't want to add sleep()) [edit] this was due to me trying change style of the window: removing title bar, borders, buttons. Once I left everything intact, and just capture inside the window - it resolved this issue 2) using example from the help file: expandcollapse popup#include <GUIConstantsEx.au3> #include <SendMessage.au3> #include <StaticConstants.au3> #include <WinAPIGdi.au3> #include <WinAPIGdiDC.au3> #include <WinAPIHObj.au3> #include <WindowsConstants.au3> Run(@SystemDir & '\calc.exe') Local $hWnd = WinWaitActive("[CLASS:ApplicationFrameWindow]", '', 3) If Not $hWnd Then Exit EndIf ; Create GUI Local $iSize = WinGetPos($hWnd) Local $hForm = GUICreate('Test ' & StringReplace(@ScriptName, '.au3', '()'), $iSize[2] + 80, $iSize[3] + 80) Local $idPic = GUICtrlCreatePic('', 40, 40, $iSize[2], $iSize[3]) Local $hPic = GUICtrlGetHandle($idPic) ; Create bitmap Local $hDC = _WinAPI_GetDC($hPic) Local $hDestDC = _WinAPI_CreateCompatibleDC($hDC) Local $hBitmap = _WinAPI_CreateCompatibleBitmap($hDC, $iSize[2], $iSize[3]) Local $hDestSv = _WinAPI_SelectObject($hDestDC, $hBitmap) Local $hSrcDC = _WinAPI_CreateCompatibleDC($hDC) Local $hBmp = _WinAPI_CreateCompatibleBitmap($hDC, $iSize[2], $iSize[3]) Local $hSrcSv = _WinAPI_SelectObject($hSrcDC, $hBmp) _WinAPI_PrintWindow($hWnd, $hSrcDC) _WinAPI_BitBlt($hDestDC, 0, 0, $iSize[2], $iSize[3], $hSrcDC, 0, 0, $MERGECOPY) _WinAPI_ReleaseDC($hPic, $hDC) _WinAPI_SelectObject($hDestDC, $hDestSv) _WinAPI_SelectObject($hSrcDC, $hSrcSv) _WinAPI_DeleteDC($hDestDC) _WinAPI_DeleteDC($hSrcDC) _WinAPI_DeleteObject($hBmp) ; Set bitmap to control _SendMessage($hPic, $STM_SETIMAGE, 0, $hBitmap) Local $hObj = _SendMessage($hPic, $STM_GETIMAGE) If $hObj <> $hBitmap Then _WinAPI_DeleteObject($hBitmap) EndIf GUISetState(@SW_SHOW) Do Until GUIGetMsg() = $GUI_EVENT_CLOSE WinClose("[CLASS:ApplicationFrameWindow]", "") I re-use the $hForm window and $idPic and just change their size for each popup. However when popup is the same size as previous popup but with different content, the image shows blended both popups (merged). If I reset $idPic to 0,0 size and then to correct size, it works fine, but I'm not sure if it's the most efficient way. [EDIT] Printwindow is really fast, and unlike _ScreenCapture_CaptureWnd it allows capture window while it's outside of view! Edited March 25 by VAN0 Link to comment Share on other sites More sharing options...
Nine Posted March 25 Share Posted March 25 (edited) There is no reason to reuse the GUI (toast). Once the original window is hidden, user won't see a thing. Here my take : expandcollapse popup#include <WinAPIGdiDC.au3> #include <GUIConstants.au3> #include <SendMessage.au3> #include <Constants.au3> #include <WinAPISysWin.au3> #include <APISysConstants.au3> Run("Notepad") Local $hWnd = WinWaitActive("[CLASS:Notepad]") ControlSend($hWnd, "", "Edit1", "Test") ControlSend($hWnd, "", "", "!{F4}") ; simulate a msg box While Sleep(10) $hWnd = WinGetHandle("[CLASS:#32770]") ; or title "Bloc-notes" for french Notepad If $hWnd Then ExitLoop WEnd ; hide window and modify Local $aPos = WinGetPos($hWnd) WinMove($hWnd, "", @DesktopWidth, @DesktopHeight) ControlHide($hWnd, "", "Button1") ControlHide($hWnd, "", "Button2") ControlHide($hWnd, "", "Button3") ; create toast Local $hGUI = GUICreate("", $aPos[2], $aPos[3], @DesktopWidth - $aPos[2] - 10, @DesktopHeight - $aPos[3] - 50, $WS_POPUP) Local $idPic = GUICtrlCreatePic("", 0, 0, $aPos[2], $aPos[3]) Local $hPic = GUICtrlGetHandle($idPic) ; Create bitmap Local $hDC = _WinAPI_GetDC($hPic) Local $hDestDC = _WinAPI_CreateCompatibleDC($hDC) Local $hBitmap = _WinAPI_CreateCompatibleBitmap($hDC, $aPos[2], $aPos[3]) Local $hDestSv = _WinAPI_SelectObject($hDestDC, $hBitmap) Local $hSrcDC = _WinAPI_CreateCompatibleDC($hDC) Local $hBmp = _WinAPI_CreateCompatibleBitmap($hDC, $aPos[2], $aPos[3]) Local $hSrcSv = _WinAPI_SelectObject($hSrcDC, $hBmp) _WinAPI_PrintWindow($hWnd, $hSrcDC) _WinAPI_BitBlt($hDestDC, 0, 0, $aPos[2], $aPos[3], $hSrcDC, 0, 0, $MERGECOPY) _WinAPI_ReleaseDC($hPic, $hDC) _WinAPI_SelectObject($hDestDC, $hDestSv) _WinAPI_SelectObject($hSrcDC, $hSrcSv) _WinAPI_DeleteDC($hDestDC) _WinAPI_DeleteDC($hSrcDC) _WinAPI_DeleteObject($hBmp) WinKill($hWnd) ; close source window ; show toast _SendMessage($hPic, $STM_SETIMAGE, 0, $hBitmap) ; set GUI picture _WinAPI_AnimateWindow($hGUI, $AW_VER_NEGATIVE, 1000) SoundPlay("C:\Windows\Media\Windows Notify Messaging.wav") Sleep(2000) _WinAPI_DeleteObject($hBitmap) GUIDelete() Edited March 25 by Nine Added window animation “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Screen Scraping Multi-Threading Made Easy Link to comment Share on other sites More sharing options...
VAN0 Posted March 25 Author Share Posted March 25 3 minutes ago, Nine said: There is no reason to reuse the GUI (toast). Once the original window is hidden, user won't see a thing Well, there is, if you are planning on leaving script running and show a toast every time message box appears, at least for performance reason, it's much faster update existing GUI than destroy and recreate new one each time...is it not? Link to comment Share on other sites More sharing options...
Nine Posted March 25 Share Posted March 25 3 minutes ago, VAN0 said: is it not? FWIW, Not For Me... The time (and coding effort) you spend modifying the GUI each time is not worth it. Do your own tests...Simplicity == Elegancy. “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Screen Scraping Multi-Threading Made Easy Link to comment Share on other sites More sharing options...
VAN0 Posted March 25 Author Share Posted March 25 (edited) 54 minutes ago, Nine said: FWIW, Not For Me... The time (and coding effort) you spend modifying the GUI each time is not worth it. Do your own tests...Simplicity == Elegancy. Sorry, I disagree with this, in fact I believe this is the reason why all new software requires more and more powerful machines without adding any more functionalities, because people care about simplicity vs optimizations... My current code that updates existing GUI and shows/hides it takes about 40ms to move the popup outside view area, create an image of it, save it to disk for text recognition with UWPOCR, recognize the text, copy bitmap into GUI image and show GUI. Same process but with new GUI created for each image takes about 60ms, that's 50% increase and it doesn't really make it less complex either. Strangely it takes 250ms to close the popup with WinClose...what? Edited March 25 by VAN0 Link to comment Share on other sites More sharing options...
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