Jump to content

Recommended Posts

I plan to write an Au3 script to automatically install a PPT plug-in.

Because the button on the installation wizard of the PPT plug-in is not a standard control, I consider writing a while loop to constantly judge the color of a specific location on the installation wizard. When the plug-in is successfully installed, a blue "Start Software" button will appear at this location, so that I can let the script close the installation wizard window.

But when I used the PixelGetColor function, the script did not get the color of the button on the installation wizard. On the contrary, it went through this foreground window and got the color of my desktop background! However, Au3's window information tool can correctly return the color of this position.

The following is my script code (due to different configurations, some coordinates may need to be changed when testing on other devices):

;~ Run plug-in installation package
#RequireAdmin
run(@ScriptDir & "\FocoSlide.exe")
;~ In each installation, the number behind this class is different, so you need to use wildcards to match the window.
$tittle = "[REGEXPCLASS:HwndWrapper*]"
WinWait($tittle)
;~ Change the installation path
WinActivate($tittle)
Send("+{TAB}")
Send("+{TAB}")
Send("+{END}")
Send("{DELETE}")
ControlSend($tittle, "", "", "C:\Program Files (x86)\OfficePlugins\Foco")
;~ Switch focus to "Install" button and enter to confirm
Send("+{TAB}")
Send("{ENTER}")
$wh = WinGetHandle($tittle)
;~ Wait for the "Start Software" button to appear (installation is complete)
;~ Activate the window before each color acquisition to avoid potential errors.
WinActivate($tittle)
$s = PixelGetColor(763, 533, $wh)
ConsoleWrite("color is " & Hex($s, 6) & @CR)
While Hex($s) <> "0267EC"
Sleep(3000)
$s = PixelGetColor(763, 533, $wh)
ConsoleWrite("color is " & Hex($s, 6) & @CR)
WinActivate($tittle)
WEnd
;~ When the blue Start Software button is detected, the installation is completed and the installation wizard is closed.
MouseClick("left", 1043, 350)
Exit

Au3 version: 3.3.16.1
Operating system: Win11

Link to post
Share on other sites
On 11/18/2022 at 9:11 PM, Nine said:

You did not set PixelCoordMode in your script.  On default, hWnd is simply ignored. (help file is your friend you know)

I manually started the installation package again until the "Installation Complete" window appears. At this time, there is a blue button. My goal is to let the script find the existence of this button. I wrote the following code to test the above window, but the output of the script is still not satisfactory. (Before running the script each time, I will manually switch my desktop background to confirm whether it affects the output of the script.)

#RequireAdmin
Opt("PixelCoordMode", 0)
;~ The coordinate mode of the mouse is the same as that of the pixel
Opt("MouseCoordMode", 0)
$tittle = "[REGEXPCLASS:HwndWrapper*]"
WinActivate($tittle)
$wh = WinGetHandle($tittle)
;~ Use the mouse to indicate whether the pixel location is correct
MouseMove(314, 222, 20)
WinActivate($tittle)
$s = PixelGetColor(314, 222, $wh)
ConsoleWrite("color is " & Hex($s, 6) & @CR)
; output: 42300C, FFDCD6…

 

Link to post
Share on other sites
On 11/18/2022 at 8:41 PM, Danp2 said:

I suggest checking the value of @error following the call to WinGetHandle.

Thank you for your reply. This is my first time to use @error. I referred to the help document and wrote the code below. It seems that there is no error in the process of obtaining the handle, but the output color is different from the actual situation.

image.thumb.png.399611eec11d529a72845142c8059cdf.png

image.thumb.png.91592c0f7c6163a34c85b2400990767a.png

 

Link to post
Share on other sites
On 11/20/2022 at 8:04 PM, Nine said:

Did you set au3info tool at the same level of Coord Mode as Opt ?  (both should be Window or Client)

 

Yes, I confirm that the coordinate mode setting of Au3 window information tool is consistent with that described in the code.


Today, I retested my code and found that it always returns a specific color number. Even if I change the desktop background (as before), the output color will not change, although it is still not the correct color. I entered the color number on a web color conversion tool and found it was the background color of my code editor! When I move the code editor window to the right of the screen (as I did in the last test), the script returns the color of the desktop wallpaper as it did last time.


Therefore, I guess that it is not the PixelGetColor function that "penetrates" the window of the installation wizard to obtain the wallpaper color, but the setting of PixelCoordMode or the handle parameter of PixelGetColor may not work, causing PixelGetColor to not obtain the color with the window I specified as the coordinate. In my case, PixelGetColor may always take the upper left corner of the screen as the coordinate origin, so the color obtained is the color of the area near the upper left corner of the screen.


However, as we can see, MouseCoordMode works when the coordinate mode is also set to the active window (parameter 0), and the mouse cursor can correctly move to the blue button. I don't know how the two functions work differently with respect to coordinates, but they do behave differently.

 

(To add, I have noticed that when the mouse hovers over the blue button of the installation wizard, the color of the button will deepen slightly, so my later test code has changed to output the color first, and then move the mouse to that position.)

Link to post
Share on other sites

Now I am almost sure that this is a bug on Windows 11.

In order to confirm the problem, I wrote a simple script to test. The tests were carried out on Windows 11 and Windows 10 respectively, and different results were obtained. The test samples and their results have been included in the attachment. The "demoWin. exe" program is compiled from "demoWin. au3", while the "demoWin. au3" code comes from Au3's help document.

2022-11-28_001730.thumb.png.7eef99ff70af52f25fd8a8e8c63161f7.png

Samples and Result.zip

Link to post
Share on other sites

Does it work if you remove the hWnd of the GUI ?  (I don't have W11, so I cannot test it)

In any case, you could use my Screen Scraping UDF (see my signature).

Link to post
Share on other sites
11 hours ago, Nine said:

Does it work if you remove the hWnd of the GUI ?  (I don't have W11, so I cannot test it)

In any case, you could use my Screen Scraping UDF (see my signature).

Disappointingly, even if I delete hWND, PixelGetColor still returns an incorrect color code.


I tried to use your UDF, and it did return the correct color!  Before the developers of AutoIt3 solve the bug of PixelGetColor function, the UDF you wrote will become my preferred solution. (By the way, I'm not sure whether it's appropriate to submit a bug on the "AutoIt General Help and Support" forum, or whether the developer will notice it.)

I have never used UDF imported externally before, and now I only test by modifying the code in the compressed package. In order to use it well, I will spend some time to understand these things. I suggest providing a simple help document written by Markdown in the UDF compressed package, including how to correctly configure the extracted files(may point to a webpage link), function parameter descriptions, and so on.

image.png.21a730f3f6cdf9d0525346e75cf69d58.png

Link to post
Share on other sites
  • jiaojiaodubai changed the title to PixelGetColor() returns wrong color on Win11

Glad my UDF works for you.  Thank you for providing positive feedback.  As for making a long and extensive help file, I will not doing it.  The UDF  is meant to be an example of the code that can be written in AutoIt. It is not intended to be a basic part of the package.

Link to post
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By BillDennis
      I was having problems with dates so I copied the example for _DateAdd from the docs, and THAT wouldn't compile. Am I missing a library or something?

    • By argumentum
      #include <GUIConstantsEx.au3> Global $iExitLoop = 0, $hGUIParent1, $hGUIParent2, $iLoadGuiTwo = 0 Example1() ;~ Example2() ; not an example but a GUI ? Func Example1($iParent = 0) Opt("GUIOnEventMode", 1) $hGUIParent1 = GUICreate("Parent", 400, 300, -1, -1, -1, -1, $iParent) GUISetOnEvent($GUI_EVENT_CLOSE, "OnEvent_CLOSE_ONE", $hGUIParent1) GUICtrlCreateButton("load GUI TWO", 8, 8, 100) GUICtrlSetOnEvent(-1, "LoadGuiTwoFromGuiOne") GUISetState(@SW_SHOW) While 1 ; Loop until the user exits. Sleep(100) ;~ If $iLoadGuiTwo Then ; .......... solution 1 ;~ Example2($hGUIParent1) ; .... ;~ $iLoadGuiTwo = 0 ; .......... ;~ EndIf ; ......................... If $iExitLoop Then ExitLoop WEnd $iExitLoop = 0 GUIDelete($hGUIParent1) EndFunc ;==>Example1 Func Example2($iParent = 0) Opt("GUIOnEventMode", 1) $hGUIParent2 = GUICreate("Child", 300, 400, -1, -1, -1, -1, $iParent) GUISetOnEvent($GUI_EVENT_CLOSE, "OnEvent_CLOSE_TWO", $hGUIParent2) GUICtrlCreateButton("say hi", 8, 8) GUICtrlSetOnEvent(-1, "GuiTwoSayHi") GUISetState(@SW_SHOW) While 1 ; Loop until the user exits. Sleep(100) If $iExitLoop Then ExitLoop WEnd $iExitLoop = 0 GUIDelete($hGUIParent2) EndFunc ;==>Example2 Func OnEvent_CLOSE_ONE() ConsoleWrite('- Func OnEvent_CLOSE_ONE()' & @CRLF) $iExitLoop = 1 EndFunc ;==>OnEvent_CLOSE_ONE Func OnEvent_CLOSE_TWO() ConsoleWrite('- Func OnEvent_CLOSE_TWO()' & @CRLF) $iExitLoop = 1 EndFunc ;==>OnEvent_CLOSE_TWO Func LoadGuiTwoFromGuiOne() Example2($hGUIParent1) ; no solution. ;~ $iLoadGuiTwo = 1 ; solution 1 ;~ AdlibRegister("LoadGuiTwoRunner", 10) ; solution 2 EndFunc ;==>LoadGuiTwoFromGuiOne Func LoadGuiTwoRunner() AdlibUnRegister("LoadGuiTwoRunner") Example2($hGUIParent1) EndFunc ;==>LoadGuiTwoRunner Func GuiTwoSayHi() ConsoleWrite('--- HI' & @CRLF) EndFunc ;==>GuiTwoSayHi ..I was using map[] and beta and is this a bug ?. But I coded this sampler and is not a beta thing, is an production thing too.
      Is the code as presented supposed to fail ? ( found viable solutions, so this is not an OMG! kind of thing )
      I believe that the logic would work if not GuiOnEvent mode.
      Edit: Tried in v3.2.12.x and v3.3.8.1 and is a design thing. Not new. I just never noticed it.
    • By argumentum
      #include <EditConstants.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> Opt("GUIOnEventMode", 1) Global $edit, $GuiChild = 0 GuiExample() Func GuiExample() ; https://www.autoitscript.com/forum/topic/202986-parent-child-guis-and-input-control-fails/ Local $GuiMain = GUICreate("GuiExample w/child (parent)", 350, 300) GUISetOnEvent($GUI_EVENT_CLOSE, "GuiOnEvent_CLOSE", $GuiMain) GUISetState(@SW_SHOW, $GuiMain) $edit = GUICtrlCreateEdit("", 10, 70, 300, 200) ; It does not matter what GUI is on, GUICtrlSetData($edit, "play around with the inputs" & _ ; the parent's controls will @CRLF & "and press enter." & _ ; bleed through a $WS_CHILD gui. @CRLF & @CRLF & "It should trigger the" & _ @CRLF & " GUICtrlSetOnEvent()") GUICtrlCreateButton("reload alt.", 225, 40, 120, 25) ; run alternate versions, GUICtrlSetOnEvent(-1, "OnBttnRunAlt") ; with and without child GUI. GUICtrlSetTip(-1, "run alternate versions," & @LF & "with and without child GUI.") ;I need this child(s), but with it, it does not behave as expected. ;..for this test you can comment it out, to see that it should work. ;..but with the child, instead it executes after clicking another control. If Not StringInStr($CmdLineRaw, "/ExampleOnlyParent") Then $GuiChild = GUICreate("GuiExample w/child (child)", 320, 280, 5, 5, $WS_CHILD, $WS_TABSTOP, $GuiMain) EndIf If $GuiChild Then GUISetBkColor(0x888888, $GuiChild) ; for the dramatic effect :) If $GuiChild Then GUISwitch($GuiChild) ; ..just in case.. tho should not matter. GUICtrlCreateInput("This text 1", 5, 10, 200, 21, BitOR($GUI_SS_DEFAULT_INPUT, $ES_WANTRETURN)) GUICtrlSetOnEvent(-1, "OnInputEnterKeyOne") GUICtrlCreateInput("This text 2", 5, 35, 200, 21, BitOR($GUI_SS_DEFAULT_INPUT, $ES_WANTRETURN)) GUICtrlSetOnEvent(-1, "OnInputEnterKeyTwo") If $GuiChild Then GUICtrlCreateButton("flash child", 220, 8, 120, 25) GUICtrlSetOnEvent(-1, "OnFlashBttn") GUISetState(@SW_SHOW, $GuiChild) OnFlashBttn() EndIf MainLoopExample() EndFunc Func MainLoopExample() While 1 Sleep(100) WEnd EndFunc Func OnInputEnterKeyOne() GUICtrlSetData($edit, @SEC &'.' & @MSEC& ' - Func OnInputEnterKey One ()' & @CRLF) EndFunc Func OnInputEnterKeyTwo() GUICtrlSetData($edit, @SEC &'.' & @MSEC& ' - Func OnInputEnterKey Two ()' & @CRLF) EndFunc Func OnFlashBttn() WinSetTrans($GuiChild, "", 50) Sleep(300) WinSetTrans($GuiChild, "", 255) EndFunc Func OnBttnRunAlt() If StringInStr($CmdLineRaw, "/ExampleOnlyParent") Then ShellExecute(@ScriptFullPath, "") Else ShellExecute(@ScriptFullPath, "/ExampleOnlyParent") EndIf GuiOnEvent_CLOSE() EndFunc Func GuiOnEvent_CLOSE() GUIDelete() Exit EndFunc I need this child(s), but with it, it does not behave as expected.
      ..for this test you can comment the child GUI out, to see that it should work.
      With the child, instead it executes after clicking another control.
      Thanks
      Edit: Modified the example for dramatic effect  
      Edit 2: Solved my problems at a post somewhere down this thread.
    • By Colduction
      Hi guys!, recently i needed to measure two functions and detect fastest one then i decided to write and share this tiny script for compare, measure and detect fastest functions easily.

      It's such as snippets, i hope you find it useful :)❤
       
      #AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w- 4 -w 5 -w 6 -w- 7 #include-once ; #FUNCTION# ==================================================================================================================== ; Name...........: _FuncSpeedComparator ; Description ...: Compares and measures speed of two functions and shows fastest one. ; Syntax.........: _FuncSpeedComparator($s1stFunc, $s2ndFunc [,$iCallNum, $iResultType]) ; Parameters ....: $s1stFunc - First function that should be compared and measured ; $s2ndFunc - Second function that should be compared and measured ; $iCallNum - [Optional] Number of times function should be called ; Default value is 100 ; $iResultType - [Optional] Type of output must be one of the following numbers: ; 1 ; Results will written in AutoIt Console Output ; 2 ; Results will be as a Message Box ; 3 ; Results will written in AutoIt Console Output and then shows as a Message Box ; Default value is 1 ; Return values .: Success - Returns string ; Failure - Returns False or empty string ; Author ........: Colduction (Ho3ein) ; Modified.......: ; Remarks .......: Function names should be written as string (inside of two Double Quotation or Quotation) to be executed and be measured ; Example .......; _FuncSpeedComparator('ConsoleWrite("10101010101")', 'ConsoleWrite("Hello World!")', 500, 3) ; =============================================================================================================================== Func _FuncSpeedComparator($s1stFunc = "", $s2ndFunc = "", $iCallNum = 100, $iResultType = 1) If Not StringRegExp($s1stFunc, "^[a-zA-Z0-9_]+\x28(.*?)\x29$") Or Not StringRegExp($s2ndFunc, "^[a-zA-Z0-9_]+\x28(.*?)\x29$") Or Not StringRegExp($iCallNum, "^\p{Nd}*$") Or Not StringRegExp($iResultType, "^\p{Nd}*$") Then ; Human mistake preventative stage. Return False Else ; Measure stage. ;; First function measurement. Local $hTimer_1stFunc = TimerInit() For $i = 1 To $iCallNum Execute($s1stFunc) Next Local $iDiff_1stFunc = TimerDiff($hTimer_1stFunc) ;; Second function measurement. Local $hTimer_2ndFunc = TimerInit() For $i = 1 To $iCallNum Execute($s2ndFunc) Next Local $iDiff_2ndFunc = TimerDiff($hTimer_2ndFunc) ; Fastest function detector stage. Local $sFastestFunc = "" If $iDiff_1stFunc = $iDiff_2ndFunc Then $sFastestFunc = "Both of them" ElseIf $iDiff_1stFunc < $iDiff_2ndFunc Then $sFastestFunc = StringRegExpReplace($s1stFunc, "(\x28).*", "") Else $sFastestFunc = StringRegExpReplace($s2ndFunc, "(\x28).*", "") EndIf ; Results stage. Local $sResultText = @CRLF & '#Fastest Function: "' & $sFastestFunc & '"' & @CRLF & @CRLF & '1) "' & StringRegExpReplace($s1stFunc, "(\x28).*", "") & '" time elapsed: (' & $iDiff_1stFunc & ") ms" & @CRLF & '2) "' & StringRegExpReplace($s2ndFunc, "(\x28).*", "") & '" time elapsed: ' & "(" & $iDiff_2ndFunc & ") ms" & @CRLF If $iResultType = 1 Or Not StringRegExp($iResultType, '^[1|2|3]{1}$') Then ; Output as ConsoleWrite. ConsoleWrite($sResultText) ElseIf $iResultType = 2 Then ; Output as MsgBox. MsgBox(64, "Result: " & $sFastestFunc, $sResultText) ElseIf $iResultType = 3 Then ; Output as both ConsoleWrite & MsgBox. ConsoleWrite($sResultText) MsgBox(64, "Result: " & $sFastestFunc, $sResultText) EndIf EndIf EndFunc ;==>_FuncSpeedComparator  
      _FuncSpeedComparator.au3
    • By EmilyLove
      What is Rollbar?
      Rollbar provides real-time error alerting & debugging tools for developers. Learn more about it at https://rollbar.com/product/
      Demo: https://rollbar.com/demo/demo/
      Screenshot:
      Instructions: (RollbarTest.au3)
      ; Include RollbarSDK #include "RollbarSDK.au3" ;Turns on ConsoleWrite debugging override. ;Global $Rollbar_Debug=False ; Initialize RollbarSDK with the project's API key. ; Parameters ....: $__Rollbar_sToken - [Required] Go to https://rollbar.com/<User>/<ProjectName>/settings/access_tokens/ for your project. Use the token for post_server_item. _Rollbar_Init("eaa8464a4082eeabd9454465b8f0c0af") ; Write code that causes an error you want to catch, then call ; _Rollbar_Send ; Parameters ....: $__Rollbar_sErrorLevel - [Required] Must be one of the following values: Debug, Info, Warning, Error, Critical. ; $__Rollbar_sMessage - [Required] The message to be sent. This should contain any useful debugging info that will help you debug. ; $__Rollbar_sMessageSummary - [Optional] A string that will be used as the title of the Item occurrences will be grouped into. Max length 255 characters. If omitted, Rollbar will determine this on the backend. _Rollbar_Send("Debug", "This is an debug message. If you received this, you were successful!", "Debug Message") _Rollbar_Send("Info", "This is a test message. If you received this, you were successful!", "Info Message") _Rollbar_Send("Warning", "This is an warning message. If you received this, you were successful!", "Warning Message") _Rollbar_Send("Error", "This is an error message. If you received this, you were successful!", "Error Message") _Rollbar_Send("Critical", "This is an critical message. If you received this, you were successful!", "Critical Message") _Rollbar_Send("Info", "This is a test message. If you received this, you were successful!") ;No Message ; Rollbar_Send's helper functions ; Parameters ....: $__Rollbar_sMessage - [Required] The message to be sent. This should contain any useful debugging info that will help you debug. ; $__Rollbar_sMessageSummary - [Optional] A string that will be used as the title of the Item occurrences will be grouped into. Max length 255 characters. If omitted, Rollbar will determine this on the backend. _Rollbar_SendDebug("This is an debug message. If you received this, you were successful!", "Debug Message") _Rollbar_SendInfo("This is a test message. If you received this, you were successful!", "Info Message") _Rollbar_SendWarning("This is an warning message. If you received this, you were successful!", "Warning Message") _Rollbar_SendError("This is an error message. If you received this, you were successful!", "Error Message") _Rollbar_SendCritical("This is an critical message. If you received this, you were successful!", "Critical Message") ; Usable Example Local $sImportantFile = "C:\NOTAREALFILE_1234554321.txt" Switch FileExists($sImportantFile) Case True MsgBox(0, "Example Script", "An important file was found. Continuing...") Case Else _Rollbar_SendCritical('An important file was missing. Halting... File: "' & $sImportantFile & '"', 'Important file "' & $sImportantFile & '" is missing.') EndSwitch Notes: Please comment your feedback, advice, & suggestions below. While this is only a proof of concept, I will expand its feature set for everyone to use. 
      Right now, it is fully functional but not tested in production.
       
       
      Changelog:
      RollbarSDK.au3
      RollbarTest.au3
      v0.2
       
      v0.1.1
       
×
×
  • Create New...