Jump to content

Recommended Posts

Recently Google has  disabled all extensions not from the google extension store. That's why this UDF stopped work, cause autoit extension was disabled by chrome. There are several ways to hack this but the most appropriate for my goals was to downgrade chrome.

This politics was annonced by Google in the January 2014 so all versions of Chrome after January automatically disables non store extensions. I chose the latest stable version of Chrome before 2014, it is 31.0.1650.63. Then I modified my host file (C:WINDOWSsystem32driversetchosts) with usual Windows notepad and added this strings:

this strings prevent Chrome from upgrading.

Pros

I have working version of Chrome where I can install any extension I want and this extansions are enabled each time I start up Chrome.

Cons

I have not the latest version of Chrome with possible drawbacks, but I have this version installed on my virtual machine so for me it's not a minus at all.

P.S. One can have up-to-date Chrome and working extension, but each time you start up Chrome you will see annoying message about non store extension with suggestion to disable it.

 

And i have a easy  way to slove this problem:

1, open the chrome extension;

2, open development model;

3, drag  the plugin  into the extended chrome!

Ok! Fixed! Enjoy

For any version of chrome.

Link to post
Share on other sites
  • 3 weeks later...
  • Replies 176
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

Popular Posts

Chrome support for AutoIT is here!  This UDF includes a Chrome Extension (http://developer.chrome.com/extensions/getstarted.html) and Native Messaging Host (http://developer.chrome.com/extensions/m

Hmmm, odd that something is uploading.  There certainly isn't anything in this solution that uploads or downloads. Here's a description of exactly what the 3 components to the UDF do (in case anyone

Yes, it might seem odd that the registry value is escaped, though it must be this way or the native messaging host won't start.  That's my experience. Here's more information to help in troubleshoot

Posted Images

  • 1 month later...

Are you still supporting this.  This has been very useful but we ran into some conditions when using various constructions kits like JFace, JQuery, etc..  The html elements do not have "name" attributes but do have generated "id" attributes.  I added some additional routines to support this:

; #FUNCTION# ;===============================================================================
;
; Name...........: _ChromeLoadURL()
; Description ...: Load a URL web page based.
; Syntax.........: _ChromeLoadURL($url, $timeout = 5)
; Parameters ....: $url         - the URL to load
;     $timeout     - Optional: a number of minutes before exiting the function.
; Return values .:  On Success     - Returns "".
;                  On Failure     - Returns "", and sets @ERROR = 2.
; Author ........: seangriffin
; Modified.......:
; Remarks .......: A prerequisite is that the Chrome browser is open
;     (Window title = "[REGEXPTITLE:.*- Google Chrome]").
;
; Related .......:
; Link ..........:
; Example .......: Yes
;
; ;==========================================================================================
Func _ChromeLoadURL($url, $timeout = 30)

 Dim $response = ""

 $response = Chrome_Eval("Chrome_LoadURL=" & $url, $timeout)

 SetError(@error)

 Return $response
EndFunc


; #FUNCTION# ;===============================================================================
;
; Name...........: _ChromeInputClickByID()
; Description ...: Clicks an <input> element based on it's "ID" attribute.
; Syntax.........: _ChromeInputClickByID($objid, $timeout = 5)
; Parameters ....: $objid       - the value of the "name" attribute
;     $timeout     - Optional: a number of minutes before exiting the function.
; Return values .:  On Success     - Returns "".
;                  On Failure     - Returns "", and sets @ERROR = 2.
; Author ........: seangriffin
; Modified.......:
; Remarks .......: A prerequisite is that the Chrome browser is open
;     (Window title = "[REGEXPTITLE:.*- Google Chrome]").
;
; Related .......:
; Link ..........:
; Example .......: Yes
;
; ;==========================================================================================
Func _ChromeInputClickByID($objid, $timeout = 5)

 dim $response = ""

 $response = _ChromeEval("document.getElementByID('" & $objid & "').click();", $timeout)

 SetError(@error)

 return $response
EndFunc

; #FUNCTION# ;===============================================================================
;
; Name...........: _ChromeObjGetValueByID()
; Description ...: Gets the value of an element based on it's "id" attribute.
; Syntax.........: _ChromeObjGetValueByID($objid, $index = 0, $timeout = 5)
; Parameters ....: $objid       - the value of the "id" attribute
;     $timeout     - Optional: a number of minutes before exiting the function.
; Return values .:  On Success     - Returns $value.
;                  On Failure     - Returns "", and sets @ERROR = 2.
; Author ........: seangriffin
; Modified.......:
; Remarks .......: A prerequisite is that the Chrome browser is open
;     (Window title = "[REGEXPTITLE:.*- Google Chrome]").
;
; Related .......:
; Link ..........:
; Example .......: Yes
;
; ;==========================================================================================
Func _ChromeObjGetValueByID($objID, $timeout = 5)

 dim $response = ""

 $response = _ChromeEval("document.getElementByID('" & $objid & "').value;", $timeout)

 SetError(@error)

 return $response
EndFunc

; #FUNCTION# ;===============================================================================
;
; Name...........: _ChromeObjSetValueByID()
; Description ...: Sets the "value" attribute of a element based on it's "id" attribute.
; Syntax.........: _ChromeObjSetValueByID($objid, $value, $timeout = 5)
; Parameters ....: $objid       - the value of the "id" attribute
;     $value      - The text to set the "value" attribute to
;     $timeout     - Optional: a number of minutes before exiting the function.
; Return values .:  On Success     - Returns $value.
;                  On Failure     - Returns "", and sets @ERROR = 2.
; Author ........: seangriffin
; Modified.......:
; Remarks .......: A prerequisite is that the Chrome browser is open
;     (Window title = "[REGEXPTITLE:.*- Google Chrome]").
;
; Related .......:
; Link ..........:
; Example .......: Yes
;
; ;==========================================================================================
Func _ChromeObjSetValueByID($objid, $value, $timeout = 5)

 dim $response = ""

 $response = _ChromeEval("document.getElementByID('" & $objid & "').value = '" & $value & "';", $timeout)

 SetError(@error)

 return $response
EndFunc

 

Would you be able to add these to your base?  We also added _ChromeLoadURL to change the current URL  I added the following to contentscript.js:

 if (request.greeting.indexOf("Chrome_LoadURL=") == 0)
 {
  var arg = request.greeting.substr("Chrome_LoadURL=".length);

  window.location.assign(arg);
 }

chrome_additional.au3

contentscript.js

Link to post
Share on other sites
  • 2 weeks later...

 

And i have a easy  way to slove this problem:

1, open the chrome extension;

2, open development model;

3, drag  the plugin  into the extended chrome!

Ok! Fixed! Enjoy

For any version of chrome.

I can not activate the extension , I can not follow the steps you indicate . How I can do step 2 ??

Link to post
Share on other sites
  • 1 month later...

Wow,

This is exactly what I'm looking for, but like "conmed", I cannot get the extension enabled using the workaround. 

Can you elaborate wowxoxo? or maybe this no longer works in the latest versions of Chrome.

I don't suppose it's feasible to actually get the extension published on the Chrome Web Store? I guess Google might not allow it anyway since the tool could be used maliciously.  

Link to post
Share on other sites

I am also stuck and unable to use the extension at all.

I followed install instructions including using admin install for autoit_chrome_native_messaging_host_install.exe

I checked "Developer Mode" in Chrome when installing AutoIT for Google Chrome.crx (actually I installed it in both developer and non-developer).

I am not observing that the correct registry entries have been made during the install process.  Should I manually create these keys?  The first example script will load the form but not fill it out, and eventually times out.

Every time I check the Chrome Extensions, the "Enable" box for AutoIT for Google Chrome has been unchecked, even in developer mode, and "Not from Chrome web store" sites underneath the unchecked box.

Downgrading chrome is not an option for me as my autoit application serves an environment in which other software requires specific modern versions of Chrome.

Any hope or is Chrome automation dying off from Autoit?  Would obviously be very supportive of attempts to get the tool added to the Chrome store if that is the obstacle.

Cheers

 

Autoit v3.3.12.0

Win 7 64 bit

Chrome 44.0.2403.89 m

Edited by wliebkem
Link to post
Share on other sites
  • 1 month later...

Chrome support for AutoIT is here!  :D

This UDF includes a Chrome Extension (http://developer.chrome.com/extensions/getstarted.html) and Native Messaging Host (http://developer.chrome.com/extensions/messaging.html#native-messaging-host) that integrate with a new Chrome UDF (Chrome.au3) to provide automation support for the Chrome browser.

Several steps are required to install the Chrome Extension and Native Messaging Host prior to using the UDF.  Please read the INSTALLATION section below.

REQUIREMENTS:

  • Windows XP 32-bit, Windows 7 32-bit or Windows 7 64-bit
  • AutoIt3 3.2 or higher
  • Chrome v29 or later (earlier versions are untested)
  • AutoIT for Google Chrome (Chrome extension - see below)
  • AutoIT Chrome Native Messaging Host (see below)

INSTALLATION:

STEP 1: Install the AutoIT extension into Chrome.

Open the following link and download the file named AutoIT for Google Chrome.crx:

https://docs.google.com/file/d/0B_6JmwNIIZ06enotRTVFNVdKOXM/edit?usp=sharing

Note - you may be prompted to login with a Google account as this file is hosted on Google Drive.

In your Chrome browser click on the Chrome menu, then select Tools -> Extensions.  Drag the AutoIT for Google Chrome.crx file that you downloaded above, from Windows Explorer, into this page in Chrome.  You should now see AutoIT for Google Chrome listed in the Extensions page in Chrome.  Ensure that the Enabled checkbox next to AutoIT for Google Chrome is checkedAlso make sure the Allow access to file URLs box is checked (very important to make EXAMPLE 2 work below)!!

STEP 2: Install the AutoIT Chrome Native Messaging Host.

Open the following link and download the file named autoit_chrome_native_messaging_host_install.exe:

https://docs.google.com/file/d/0B_6JmwNIIZ06eDgxaVJPNUNxa28/edit?usp=sharing

Note - you may be prompted to login with a Google account as this file is hosted on Google Drive.

Run this file (autoit_chrome_native_messaging_host_install.exe).  An installation window will display.  Click the Install button.  The window will display "Completed" and you can click the Close button.

STEP 3: Install the Chrome UDF into AutoIT.

Scroll to the DOWNLOAD section below, and save the Chrome.au3 file into your AutoIT Include folder (C:Program FilesAutoIt3Include).

Please close your Chrome browser once you've completed these steps.

LIST OF FUNCTIONS:

 

EXAMPLE #1:

This following example starts up Chrome and navigates to the URL http://www.december.com/html/demo/form.html.  It then automatically completes the HTML form in this page (a series of text, radio, and checkbox input elements and select elements) and clicks the Send this survey button.  The script waits for the next page to load, and retrieves the various elements from the page to the AutoIT console.

chrome_example.au3

EXAMPLE #2:

The following is an example of the automation of an offline HTML page (file URL).  First, download the file named chrome_udf_example_2.html to your C: folder:

https://docs.google.com/file/d/0B_6JmwNIIZ06SWduMjZGTVViNlU/edit?usp=sharing

Then run the following AutoIT script:

chrome_example_2.au3

Note that you must have checked the Allow access to file URLs box in the Chrome extension to make this work!

DOWNLOAD:

Latest Version - v0.5 (29/09/13)

Chrome.au3

Hi Seangriffin,

I have done all these steps but when I test my script, chrome disables the Extension for AutoIt because it is not from Chrome web store. If says that uploading extension to chrome web store will resolve the issue.

Is there any other solution to it?

Thanks,

PD

Link to post
Share on other sites

This is also not working. I have same code in UDF. but when I run chrome, it opens up the page but in editor gives below error.

C:\Program Files (x86)\AutoIt3\Include\Chrome.au3 (829) : ==> Variable used without being declared.:
$response = _ChromeEval("document.getElementByID('" & $objname & "').value = '" & $value & "';", $timeout)
$response = _ChromeEval("document.getElementByID('" & ^ ERROR

Thanks,

-PD

 

 

Not getElementsById but getElementById, and maybe without $index.

Try this:

Func _ChromeObjSetValueById($objid, $value,  $timeout = 5)
    dim $response = ""
    $response = _ChromeEval("document.getElementById('" & $objid & "').value = '" & $value & "';", $timeout)
    SetError(@error)
    return $response
EndFunc

Link to post
Share on other sites
  • 2 months later...

Hi Seangriffin,

I have done all these steps but when I test my script, chrome disables the Extension for AutoIt because it is not from Chrome web store. If says that uploading extension to chrome web store will resolve the issue.

Is there any other solution to it?

Thanks,

PD

http://superuser.com/questions/767286/re-enable-extensions-not-coming-from-chrome-web-store-on-chrome-v35-with-enhan

  1. Download the crx file and unpack the extension using your favorite decompresser. Take note of the directory where you placed it.
  2. Open the extension page, activate "Developer Mode"
  3. Click "Load unpacked extension..."
  4. Search trough your directory tree for the directory where you unpacked your extension and click OK. If your extension is called "my extension" then select "my extension" directory.

Advantages: You don't have to install anything else. Disadvantages: Chrome nags you to disable the extension each start up.

 

I've tried this with Chrome 48, it keeps the extension enabled, but pops up a dialog if you want to disable it or cancel.

 

The other option is to whitelist the extension with the Windows policy editor: https://productforums.google.com/forum/#!msg/chrome/9NlMAr6uEVc/ambkrcKpi1cJ

This doesn't bother you with a popup every time you start Chrome.

Edited by JoeF
Link to post
Share on other sites
  • 2 months later...

Hey, sorry, I hope this script is still being supported. I've followed the above directions, installed the autoit extension in developer mode, and allowed it access to file URL's, however running the first example script still doesn't work. Have things changed? I'm honestly not sure where to go from here.

Link to post
Share on other sites
  • 3 months later...
On 11/2/2016 at 6:04 AM, JaysCogs said:

Hey, sorry, I hope this script is still being supported. I've followed the above directions, installed the autoit extension in developer mode, and allowed it access to file URL's, however running the first example script still doesn't work. Have things changed? I'm honestly not sure where to go from here.

 

it's very very long time ago :( i want some code the same

Link to post
Share on other sites

I like many of you started out with ffload.au3 which would pixelsearch for a green pixel at the end of the loading bar in firefox 3. I got tired of running an outdated browser and moved over to chrome, it seems better these days anyway. Here is my setup..

 

Download Pace4Chrome extention, once in set it to color 2299DD and the loading to Centeratom, now we have a fairly reliable load indicator.

Here is your modified ffload function module below, feel free to critique my poor habits in a friendly manner.

Func _FfLoadWaitTime ($x, $y)
    Global $pop = 0
    While 1
       $pop = $pop + 1
        Sleep ( 0 )
    $loading = PixelGetColor ( $x, $y )
if $loading = 0x2299DD Then
       ;MsgBox(0, "loading detected", "blue loading started")
        ExitLoop
        ;Set the pop numbe below to what you want it to wait at untill it figures the load indicato didn't load, 900 is about 9seconds, i dunno why.
     elseif $pop = 900 Then
         ;MsgBox(0, "loading not detected", "first pop")
      ExitLoop
    EndIf
 WEnd

 While 1
       $pop = $pop + 1
        Sleep ( 0 )
    $loading = PixelGetColor ( $x, $y )
;if $loading <> 0x2299DD Then
   if Not ($loading == 0x2299DD) Then
      ;MsgBox(0, "loading detected", "blue loading ended")
      ExitLoop
  ;the pop below isn't even needed but i'm just posting this as it with debug msgbox's and all
  elseif $pop = 1400 Then
      ;MsgBox(0, "loading not detected", "second pop")

      ExitLoop
   EndIf
Wend

 EndFunc;==>_FfLoadWaitTime

Your cords to use when calling the function should be obvious but vary depending on you display res. Sometime the load indicator doesn't display, like 1 outs 25, so other is a pop to bypass if pixelseach doesn't find it's thing in x amount of time, default is 900 which is about 9 seconds on my machine, not sue why, would assume 9000 would be 9 seconds.

 

Anyway I think that's it, Hope some of you can use this.

Link to post
Share on other sites
  • 5 weeks later...
  • 3 months later...

I know this is probably an old thread but I wanted to point out to anyone that treks here that THIS UDF STILL WORKS AS OF CHROME 53.

For anyone wants to know how to get back on track or up and running, it's fairly simple but rather complex as well...I'm writing a guide because there some people who come here looking to find a way to automate Chrome for their workplace (like me) but can't get going because there aren't much answers as to if this might work or not. This UDF can work WITHOUT admin rights, it theoretically can if you tune the registry to CURRENT_USER.

There's THREE IMPORTANT components that come into play in order to make it work really well:

1. The Native Messaging Host (The Author called it  autoit_chrome_native_messaging_host). I simply call it the NMH.

2. The AutoIT Chome Extension

3. The Registry

FOR PEOPLE THAT NEED TO GET THIS UP ASAP:

1. INSTALL  autoit_chrome_native_messaging_host_install.exe

2. Install the chrome extension, the MESSAGING HOST should activate (please refer to the bottom as this extension is not fully working), you can tell in the little tray icon. THIS MEANS you are good to go and the host is awaiting instructions from the AUTOIT Script.

If it doesn't activate, something is wrong! It could be the registry, it could be way you set up your system, who knows. YOU will need to read further in order to figure where something went wrong.

3. To test, do: 

_ChromeEval("alert('hello world');")

 

FOR PEOPLE NOT GETTING THE CHROME EXTENSION TO WORK PROPERLY:

Chrome has stopped supporting third party or custom extensions for awhile now. This leads to the problem of having the extension not being able to work when you check mark ALLOW ACCESS TO FILE URLS. It can work without that but seangriffin seems to imply it would work much better if it had the ability to.  JoeF proposed the correct idea of extracting the CRX file (you can use anything: winZip, WinRar, 7zip), and placing the files in a folder. From there, get Chrome to go into developer mode ,and load that folder that you extracted into. This WILL break the NMH i guarantee you that! That's okay! WE CAN FIX IT EASILY. Go to the file of where the NHM is, which is AppData/Roaming/AutoIt/Chrome Native Messaging Host/. From there, you'll see there are two files. the autoit-chrome-native-messaging-host.exe and manifest.json. Open that manifest.json with notepad or whatever edit too. Now go back into your chrome and look at the ID of the unpacked extension that you loaded, it should give you an ID. YOU NEED TO TAKE THAT ID and replace it in the manifest json. It looks somewhat like this:

chrome-extension://nmocofiopaekephdbaeokkcnplpnenkg/

replace that green looking string with your ID given from Chrome. This is for security and everyone gets a different ID. If you want consistency, you will have to read further down because there is a way to make sure the same ID can always be used (This is useful portability or deployment). Now reload and the NHM should activate by itself and you'll see it as the little tray icon.

I'm gonna have to stop right here for now due to a time strain. It's a little late over here, so once i have time, i will update this guide some more for sure.

Spoiler

 

FOR PEOPLE THAT WANT TO KNOW IT WORKS (THIS WILL HELP RESOLVE ANY RUNNING ISSUES):

The Messaging Host installer installs the files into your AppData/Roaming/AutoIt/Chrome Native Messaging Host/ directory. The NMH nstaller also leaves a registry key in which the Autoit Chrome Extension can read its location and active the NHM from that particular directory.

So this is how it communicates:

First you load Chrome. Chrome will run that extension...

 

 

 

Edited by 7121
Link to post
Share on other sites
  • 1 month later...
On 9/29/2013 at 10:23 AM, seangriffin said:

V0.5 of the UDF is now released.

Python has now been replaced with AutoIT as the Native Messaging Host.  This brings significant performance improvements over the previous Python solution, and also allows easier maintenance in the future with a complete AutoIT solution.

If you already have a previous version of the UDF installated, then you must repeat Steps 1, 2 and 3 from the INSTALLATION section of the top post.

Python has now been replaced with AutoIT as the Native Messaging Host.

If this is the case can you please post the source Au3 for the native message host?

Thanks in advance!

 

Link to post
Share on other sites
  • 2 weeks later...

Is Udf Still Wroking

I tried extracting file and loading as packet

but still m not getting it working

please help me on this

chrome startup is working correctly but no other functions are working

some one please correct me if m doing something wrong or missing something important

Edited by n3wbie
Link to post
Share on other sites
  • 1 month later...

Quick HOW TO install AutoIT for Google Chrome.crx Chrome extension.

1, Download from here: https://docs.google.com/file/d/0B_6JmwNIIZ06enotRTVFNVdKOXM/edit?usp=sharing
2, Rename the file extension  from crx to zip (result will be: AutoIT for Google Chrome.zip)
3, Unzip the file in a folder
4, Open Chrome and navigate to the Extensions (chrome://extensions/)
5, Tick the "Developer mode"
6, Click to the "Load unpacked extension..." button and navigate to your previously unzipped folder

That's it!

Tested, working in Chrome Version 55.0.2883.87 m (64-bit)

Link to post
Share on other sites
  • 4 weeks later...
On 1/23/2017 at 1:58 AM, zuliasro said:

Quick HOW TO install AutoIT for Google Chrome.crx Chrome extension.

1, Download from here: https://docs.google.com/file/d/0B_6JmwNIIZ06enotRTVFNVdKOXM/edit?usp=sharing
2, Rename the file extension  from crx to zip (result will be: AutoIT for Google Chrome.zip)
3, Unzip the file in a folder
4, Open Chrome and navigate to the Extensions (chrome://extensions/)
5, Tick the "Developer mode"
6, Click to the "Load unpacked extension..." button and navigate to your previously unzipped folder

That's it!

Tested, working in Chrome Version 55.0.2883.87 m (64-bit)

Step 3 not working.

I rename crx into zip, but 7zip, winzip, report corrupted file

Do you have another location to download it? The file on google sizes only 23k

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 noellarkin
      Other than different methodologies, are there any differences between the two? Does one work out to be faster or more reliable than the other when deployed at scale? I'm trying out both UDFs, was curious which method is preferred by the community.
    • By corvo
      Hello!

      I've been trying to launch chrome through WD,  but for some reason, the user profile is not working, it just opens up the chrome window with the "temp" user. I've also made sure that the user profile path is correct by using "chrome://version". 
      Here is what I've got so far:
      #include "wd_helper.au3" #include "wd_capabilities.au3" #include "wd_core.au3" SetupChrome() _WD_CapabilitiesStartup() Local $sCapabilities = _WD_CapabilitiesGet() $sSession = _WD_CreateSession($sCapabilities) _WD_Navigate($sSession, "https://www.google.com") Func SetupChrome() _WD_Option('Driver', 'chromedriver.exe') _WD_Option('Port', 9515) _WD_Option('DriverParams', '--verbose --log-path="' & @ScriptDir & '\chrome.log"') _WD_Option('DriverParams', '--marionette-port 2828') $sDesiredCapabilities = '{"capabilities": {"alwaysMatch": {"goog:chromeOptions": {"w3c": true, "args":["--user-data-dir=C:\\Users\\' & @UserName & '\\AppData\\Local\\Google\\Chrome\\User Data\\", "--profile-directory=Profile 2"]}}}}' $_WD_DEBUG = $_WD_DEBUG_None ; You could also use $_WD_DEBUG_Error EndFunc  
      Thanks in advance!
       
    • By SkysLastChance
      I am having trouble finding a good way to click these "button" below. 

      I only need to be able to click them when they have both yes/no. Otherwise I don't have to worry about them. For instance if they looked like this I would NOT have worry about clicking them and can just ignore them all togheter.(Below Picture)

      The problem is as mentioned in the title, all of the ID's  are dynamic. (Classes too)

      Here is what it looks like if yes is already selected.

      This is what I was using to select the the button. However, I need to know if the button has already been clicked/selected or not.
      _WD_LoadWait($sSession) $sElement = _WD_FindElement($sSession, $_WD_LOCATOR_ByXPath, "//span[text() = 'Offered access to electronic health information?']") Sleep(1000) _WD_ElementAction($sSession, $sElement, 'click') Sleep(500) _WD_Action($sSession, "actions", $sActionTab) Sleep(500) _WD_Action($sSession, "actions", $sActionEnter) Is there a way I can get the count of spans in the span class-"s_636" by tabbing over to the button? I am hoping someone might have some ideas on what I can try.
      Unfortunally, The site is for work so giving the site wont do any good. 
    • By kurtykurtyboy
      GuiFlatButton is a UDF to easily create regular buttons with different colors for background, foreground, border, hover, focus, etc..
      This started as an effort to change the background color of a button and eventually grew into a full UDF.
      If you've looked around forums for changing button background colors, you have probably noticed that each proposed workaround has its own set of issues/side-effects. The answers usually circle back to 'use ownerdrawn buttons' and 'not worth it'. Well, now it is possible for anyone to easily create ownerdrawn buttons - totally worth it!
      Some issues with other workarounds such as drawing with GDI+ or using a colored label as a 'button':
      Not 'real' buttons so you lose built-in functionality that windows gives to buttons Messy / inefficient code in the main while loop to check for mouse position Slow to respond to click, paint, etc... Having to deal with GUIRegisterMsg messages Not straight-forward to implement GuiFlatButton is not a workaround; it is a technique to respond to Windows' built-in owner-drawn button events.
      With minimal effort, we can now create true simple colored buttons.
      The idea is to create an owner-drawn button using GUICtrlCreateButton then subclass the GUI and controls to handle the button-specific events to paint it however we want.
      This UDF magically does all of this for us! No need to worry about event handling or main while loop logic.
       
      How to use
      It couldn't be any easier! Simply create a new button using the familiar syntax. This creates an ownerdrawn button with default colors.
      $mybutton1 = GuiFlatButton_Create("Button 1", 78, 20, 120, 40) If you want to change the background and text colors:
      GuiFlatButton_SetBkColor(-1, 0x5555FF) GuiFlatButton_SetColor(-1, 0xFFFFFF) Advanced Usage
      Set background/text/border all at once
      GuiFlatButton_SetColors(-1, 0x0000FF, 0xFFFFFF, 0x9999FF) Set ALL colors for ALL button states! (normal, focus, hover, selected)
      Local $aColorsEx = [0x0000FF, 0xFFFFFF, -2, 0x4444FF, 0xFFFFFF, 0xAAAAFF, 0x6666FF, 0xFFFFFF, 0xCCCCFF, 0x0000EE, 0xFFFFFF, 0x7777EE] GuiFlatButton_SetColorsEx(-1, $aColorsEx) Set default colors to apply to any future buttons
      ;set colors GuiFlatButton_SetDefaultColors(0x0000FF, 0xFFFFFF, 0x9999FF) ;create buttons $mybutton1 = GuiFlatButton_Create("Button 1", 12, 20, 120, 40) $mybutton2 = GuiFlatButton_Create("Button 2", 143, 20, 120, 40) Set ALL color defaults
      ;set colors Local $aColorsEx = [0x0000FF, 0xFFFFFF, -2, 0x4444FF, 0xFFFFFF, 0xAAAAFF, 0x6666FF, 0xFFFFFF, 0xCCCCFF, 0x0000EE, 0xFFFFFF, 0x7777EE] GuiFlatButton_SetDefaultColorsEx($aColorsEx) ;create buttons $mybutton1 = GuiFlatButton_Create("Button 1", 12, 20, 120, 40) $mybutton2 = GuiFlatButton_Create("Button 2", 143, 20, 120, 40)  
      Available Functions
       
      Simple Example

      #include <GUIConstantsEx.au3> #include <MsgBoxConstants.au3> #include "GuiFlatButton.au3" Example() ;GUI with one button Func Example() Local $hGUI, $mybutton1 $hGUI = GUICreate("GuiFlatButton Ex0", 275, 120) GUISetBkColor(0x333333) Local $idLabel = GUICtrlCreateLabel("Click the button", 10, 100, 150, 30) GUICtrlSetColor(-1, 0xFFFFFF) ;create new button then set the background and foreground colors $mybutton1 = GuiFlatButton_Create("Button 1" & @CRLF & "Line 2", 78, 20, 120, 40, $BS_MULTILINE) GuiFlatButton_SetBkColor(-1, 0x5555FF) GuiFlatButton_SetColor(-1, 0xFFFFFF) GUISetState(@SW_SHOW, $hGUI) Local $i = 0 Local $iMsg While 1 $iMsg = GUIGetMsg() Switch $iMsg Case $GUI_EVENT_CLOSE ExitLoop Case $mybutton1 $i += 1 GUICtrlSetData($idLabel, $i) ConsoleWrite($i & @CRLF) EndSwitch Sleep(10) WEnd GUIDelete() EndFunc ;==>Example
      Menu/Toolbar Example

      #include <GUIConstantsEx.au3> #include <MsgBoxConstants.au3> #include "GuiFlatButton.au3" Example() ;Example GUI with toolbar Func Example() Local $hGUI, $idLabel, $aButtons, $iTbSize $hGUI = GUICreate("GuiFlatButton Ex2", 300, 200) GUISetBkColor(0x444444) $idLabel = GUICtrlCreateLabel("Click a button", 10, 180, 150, 30) GUICtrlSetColor(-1, 0xFFFFFF) $aButtons = createToolbar() $iTbSize = UBound($aButtons) GUISetState(@SW_SHOW, $hGUI) Local $i = 0 Local $iMsg While 1 $iMsg = GUIGetMsg() Switch $iMsg Case $GUI_EVENT_CLOSE ExitLoop Case $aButtons[0] To $aButtons[$iTbSize - 1] ConsoleWrite("1") GUICtrlSetData($idLabel, GuiFlatButton_Read($iMsg)) EndSwitch Sleep(10) WEnd GUIDelete() EndFunc ;==>Example Func createToolbar() Local $aButtons[6] Local $bkColor = 0x777777 Local $textColor = 0xFFFFFF Local $borderColor = 0x999999 Local $aBtnClrs[12] = [0x777777, 0xFFFFFF, $GUI_BKCOLOR_TRANSPARENT, 0x888888, 0xFFFFFF, $GUI_BKCOLOR_TRANSPARENT, 0x999999, 0xFFFFFF, $GUI_BKCOLOR_TRANSPARENT, 0x666666, 0xFFFFFF, $GUI_BKCOLOR_TRANSPARENT] For $i = 0 To UBound($aButtons) - 1 $aButtons[$i] = GuiFlatButton_Create("B" & $i, $i * 50, 0, 50, 17) GuiFlatButton_SetColorsEx($aButtons[$i], $aBtnClrs) Next Return $aButtons EndFunc ;==>createToolbar  
      Icon Example
      You can even easily add icons to your buttons -- just create a new button and send it an icon!

      #include <GDIPlus.au3> #include "GuiFlatButton.au3" Example() ;buttons with Icon images Func Example() ;get images for demonstration _GDIPlus_Startup() ;initialize GDI+ Local $hIcon = _WinAPI_ShellExtractIcon(@SystemDir & '\shell32.dll', 258, 24, 24) ;extract the 'Save' icon Local $hBitmap = _GDIPlus_BitmapCreateFromHICON($hIcon) ;Create Bitmap from Icon (for demonstration) Local $hHBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap) ;Create HBitmap from Bitmap _GDIPlus_BitmapDispose($hBitmap) ;dispose the bitmap _GDIPlus_Shutdown() ;done with GDI+ Local $hGUI = GUICreate("GuiFlatButton Ex5", 255, 400) GUISetBkColor(0xEEEEEE) ;set default colors of future buttons Local $aColorsEx = _ [0xE2E5E8, 0X000000, 0x888888, _ ; normal : Background, Text, Border 0xE2E5E8, 0X000000, 0x333333, _ ; focus : Background, Text, Border 0xE8E8E8, 0X000000, 0x666666, _ ; hover : Background, Text, Border 0xDDDDDD, 0X000000, 0xAAAAAA] ; selected : Background, Text, Border GuiFlatButton_SetDefaultColorsEx($aColorsEx) ;normal button with icon $label1 = GUICtrlCreateLabel( "$BS_TOOLBUTTON -->", 5, 10) GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT) Local $mybutton1 = GuiFlatButton_Create("Save", 130, 5, 50, 48, $BS_TOOLBUTTON) _WinAPI_DeleteObject(_SendMessage(GUICtrlGetHandle($mybutton1), $BM_SETIMAGE, $IMAGE_ICON, $hIcon)) ;align top Local $mybuttonT = GuiFlatButton_Create("Top", 5, 65, 120, 55, $BS_TOP) _WinAPI_DeleteObject(_SendMessage(GUICtrlGetHandle($mybuttonT), $BM_SETIMAGE, $IMAGE_ICON, $hIcon)) ;align top-left Local $mybuttonTL = GuiFlatButton_Create("Top-Left", 5, 125, 120, 55, BITOR($BS_TOP, $BS_LEFT)) _WinAPI_DeleteObject(_SendMessage(GUICtrlGetHandle($mybuttonTL), $BM_SETIMAGE, $IMAGE_ICON, $hIcon)) ;align top-right Local $mybuttonTR = GuiFlatButton_Create("Top-Right", 5, 185, 120, 55, BITOR($BS_TOP, $BS_RIGHT)) _WinAPI_DeleteObject(_SendMessage(GUICtrlGetHandle($mybuttonTR), $BM_SETIMAGE, $IMAGE_ICON, $hIcon)) ;align left Local $mybuttonL = GuiFlatButton_Create("Left", 5, 245, 120, 55, $BS_LEFT) _WinAPI_DeleteObject(_SendMessage(GUICtrlGetHandle($mybuttonL), $BM_SETIMAGE, $IMAGE_ICON, $hIcon)) ;align bottom Local $mybuttonB = GuiFlatButton_Create("Bottom", 130, 65, 120, 55, $BS_BOTTOM) _WinAPI_DeleteObject(_SendMessage(GUICtrlGetHandle($mybuttonB), $BM_SETIMAGE, $IMAGE_ICON, $hIcon)) ;align bottom-left Local $mybuttonBL = GuiFlatButton_Create("Bottom-Left", 130, 125, 120, 55, BITOR($BS_BOTTOM, $BS_LEFT)) _WinAPI_DeleteObject(_SendMessage(GUICtrlGetHandle($mybuttonBL), $BM_SETIMAGE, $IMAGE_ICON, $hIcon)) ;align bottom-right Local $mybuttonBR = GuiFlatButton_Create("Bottom-Right", 130, 185, 120, 55, BITOR($BS_BOTTOM, $BS_RIGHT)) _WinAPI_DeleteObject(_SendMessage(GUICtrlGetHandle($mybuttonBR), $BM_SETIMAGE, $IMAGE_ICON, $hIcon)) ;align right Local $mybuttonR = GuiFlatButton_Create("Right", 130, 245, 120, 55, $BS_RIGHT) _WinAPI_DeleteObject(_SendMessage(GUICtrlGetHandle($mybuttonR), $BM_SETIMAGE, $IMAGE_ICON, $hIcon)) GuiFlatButton_SetState($mybuttonR, $GUI_DISABLE ) ;disabled Local $mybuttonDisable = GuiFlatButton_Create("Disabled", 130, 310, 120, 55, $BS_TOOLBUTTON) _WinAPI_DeleteObject(_SendMessage(GUICtrlGetHandle($mybuttonDisable), $BM_SETIMAGE, $IMAGE_BITMAP, $hHBitmap)) GuiFlatButton_SetState($mybuttonDisable, $GUI_DISABLE ) ;clean up! _WinAPI_DestroyIcon( $hIcon ) _WinAPI_DeleteObject( $hHBitmap ) GUISetState(@SW_SHOW, $hGUI) Local $iMsg While 1 $iMsg = GUIGetMsg() Switch $iMsg Case $GUI_EVENT_CLOSE ExitLoop EndSwitch Sleep(10) WEnd GUIDelete() EndFunc ;==>Example  
      I'm sure there are some use-cases I've forgotten, so feedback is welcome!
       
      Download the latest UDF and several more examples:
      GuiFlatButton_20220919.zip (1,121)
      Update 2022-09-19
      Added update from 05/25 back in after it was accidentally removed
      Update 2022-09-01
      Added $BS_MULTILINE button style
      Added ellipses when text is longer than the button
      Fixed compatibility with Opt("MustDeclareVars", 1)
      Update 2022-05-25
      Fixed issue, buttons disappear when a GUI containing a child window with WS_EX_MDICHILD extended style is moved
      Update 2022-05-24
      Fixed issue releasing subclassing when GUI is deleted but program is not closed
      Fixed occasional white background flicker
      Added function GuiFlatButton_GetPos
      Update 2021-01-02
      Fixed bug, not drawing correctly after deleting GUI with GUIDelete()
      Fixed bug, changing default colors changed all buttons, even previously created buttons
      Made some internal functions more efficient
      Update 2019-04-14
      Fixed bug, not showing pressed down state when clicking rapidly
      Added Icon/Bitmap support!
      Added function GuiFlatButton_SetPos to change the position and/or size of a button
      Update 2019-02-09
      Added 2 new functions to set the button colors globally for all future buttons.
      GuiFlatButton_SetDefaultColors 
      GuiFlatButton_SetDefaultColorsEx

      Credits to:
      Melba23 (UDF template)
      LarsJ (general subclassing code)
      4ggr35510n (TrackMouseEvent example)
      binhnx (disable dragging with $WS_EX_CONTROLPARENT)
      GUIRegisterMsg in AutoIt Help (owner-draw button example)
      funkey (_WinAPI_DrawState example)
       
       
       
       
    • By t0nZ
      Always searching for the "final" solution to my zipping/unzipping needs, I started years ago using WinRar with AutoIT (don't ask me why...) and for the last 10 years I worked well with the _zip.UDF , a good solution using the embedded windows zipfldr.dll.
      But often I work with a lot of data (both multi gigabytes and/or 100K+ files) and I noticed the performance of the windows zip DLL are not so good, the problem is maybe worsened by the mono thread operation using AutoIT +  zipfldr.dll.
      SO my choice is 7zip (7ZA.exe)  also for licence (freeware also for business) reasons, and I wrote a small and simple UDF:
      ; #INDEX# ======================================================================================================================= ; Title .........: _7za ; AutoIt Version : 3.3.16.0 ; Language ......: English ; Description ...: Functions for using 7za.exe archive manipulation app ; Author(s) .....: NSC ; Version .......: 1.2 ; Date ..........: 2022/06/28 ; =============================================================================================================================== ; ------------------------------------------------------------------------------ ; This software is provided 'as-is', without any express or ; implied warranty. In no event will the authors be held liable for any ; damages arising from the use of this software. ; #INCLUDES# =================================================================================================================== ; #include-once #include <AutoItConstants.au3> ; =============================================================================================================================== ; #VARIABLES# =================================================================================================================== ; Global Global $7za_exe = @ScriptDir & "\" & "7za.exe" ; =============================================================================================================================== ; #CURRENT# ===================================================================================================================== ; _EXEC7za ;_UNcompress_7za ;_COMpress_7za_7z ;_COMpress_7za_zip ; =============================================================================================================================== ; #FUNCTION# ==================================================================================================================== ; Name ..........: _EXEC7za ; Description ...: launch 7Za.exe with params and returns exit codes ; Syntax ........: EXEC7za($7zCommands, $archive, $folder[, $show]) ; Parameters ....: $7zCommands - 7zip command line params ; $archive - complete path to the archive ; $folder - the source/destination folder ; $show - optional set the state of 7za console visibility, default @SW_HIDE, ; other values as ShellExecuteWait() ; Return values .: 1 - Success ; 0 - and set @error = 1 ; and ; @extended = 1 (Warning (Non fatal error(s)) ; @extended = 2 (Fatal error) ; @extended = 7 (Command line error) ; @extended = 8 (Not enough memory for operation) ; @extended = 255 (User stopped the process) ; @extended values set by 7za.exe exit codes ; Author ........: NSC ; Modified ......: 2022/05/13 ; Remarks .......: requires 7za.exe in @scriptdir, 7za.exe (7-Zip Extra: standalone console version) ; Thanks to 7-zip.org ; Related .......: ; Link ..........: ; Examples .......: compress a folder recursive with subfolders ; EXEC7za("u -mx4 -bt", c:\folder1\archive.7z", c:\folder1\folderTOcompress\ ) ; uncompress the same folder recursive ; EXEC7za("x -aoa -bt -r", "c:\folder1\archive.7z", "-oc:\folder2\") ; =============================================================================================================================== Func _EXEC_7za($7zCommands, $archive, $folder, $show = @SW_HIDE) Local $return7za = ShellExecuteWait($7za_exe, $7zCommands & ' "' & $archive & '" "' & $folder & '"', '', $SHEX_OPEN, $show) Select Case $return7za = 0 Return 1 Case Else Return SetError(1, $return7za, 0) EndSelect EndFunc ;==>_EXEC_7za ; #FUNCTION# ==================================================================================================================== ; Name ..........: _UNcompress_7za ; Description ...: launch 7Za.exe with preset params to uncompress an archive (.7z or .zip recursively) and returns exit codes ; Syntax ........: _UNcompress_7za($archive, $folder[, $show]) ; Parameters ....: $archive - complete path to the archive ; $folder - the source/destination folder ; $show - optional set the state of 7za console visibility, default @SW_HIDE, ; other values as ShellExecuteWait() ; Return values .: 1 - Success ; 0 - and set @error = 1 ; and ; @extended = 1 (Warning (Non fatal error(s)) ; @extended = 2 (Fatal error) ; @extended = 7 (Command line error) ; @extended = 8 (Not enough memory for operation) ; @extended = 255 (User stopped the process) ; @extended values set by 7za.exe exit codes ; Author ........: NSC ; Modified ......: 2022/05/19 ; Remarks .......: requires 7za.exe in @scriptdir, 7za.exe (7-Zip Extra: standalone console version) ; Thanks to 7-zip.org ; Related .......: ; Link ..........: ; =============================================================================================================================== Func _UNcompress_7za($archive, $folder, $show = @SW_HIDE) Local $return7za = ShellExecuteWait($7za_exe, "x -aoa -bt -r" & ' "' & $archive & '" -o"' & $folder & '"', '', $SHEX_OPEN, $show) Select Case $return7za = 0 Return 1 Case Else Return SetError(1, $return7za, 0) EndSelect EndFunc ;==>_UNcompress_Folder_7za ; #FUNCTION# ==================================================================================================================== ; Name ..........: _COMpress_7za_7z ; Description ...: launch 7Za.exe with precompiled params to compress in .7z format ;a single file, a filtered (*.pdf) bunch of files or a folder (recursively) and returns exit codes ; Syntax ........: _COMpress_7za_7z($archive, $folder[, $show [, $compLvl]] ) ; Parameters ....: $archive - complete path to the archive ; $folder - the source file(s) / folder ; $show - optional set the state of 7za console visibility, default @SW_HIDE, ; other values as ShellExecuteWait() ; $CompLvl - optional compression level (1-9) default 4 ; Return values .: 1 - Success ; 0 - and set @error = 1 ; and ; @extended = 1 (Warning (Non fatal error(s)) ; @extended = 2 (Fatal error) ; @extended = 7 (Command line error) ; @extended = 8 (Not enough memory for operation) ; @extended = 255 (User stopped the process) ; @extended values set by 7za.exe exit codes ; Author ........: NSC ; Modified ......: 2022/06/22 ; Remarks .......: requires 7za.exe in @scriptdir, 7za.exe (7-Zip Extra: standalone console version) ; avoids re-compress of popular archives. ; Thanks to 7-zip.org ; Related .......: ; Link ..........: ; =============================================================================================================================== Func _COMpress_7za_7z($archive, $folder, $show = @SW_HIDE, $CompLvl = 4) If StringRight($folder, 4) = ".zip" Or StringRight($folder, 3) = ".7z" Or StringRight($folder, 4) = ".rar" Or StringRight($folder, 4) = ".lha" Or StringRight($folder, 3) = ".gz" Or StringRight($folder, 7) = ".tar.gz" Or StringRight($folder, 4) = ".iso" Then $CompLvl = 0 EndIf Local $return7za = ShellExecuteWait($7za_exe, 'u -mx' & $CompLvl & ' -mmt -bt' & ' "' & $archive & '" "' & $folder & '"', '', $SHEX_OPEN, $show) Select Case $return7za = 0 Return 1 Case Else Return SetError(1, $return7za, 0) EndSelect EndFunc ;==>_COMpress_7za_7z ; #FUNCTION# ==================================================================================================================== ; Name ..........: _COMpress_7za_zip ; Description ...: launch 7Za.exe with precompiled params to compress in zip format ; a single file, a filtered (*.pdf) bunch of files or a folder (recursively) and returns exit codes ; Syntax ........: _COMpress_7za_zip($archive, $folder[, $show [, $compLvl]] ) ; Parameters ....: $archive - complete path to the archive ; $folder - the source file(s) / folder ; $show - optional set the state of 7za console visibility, default @SW_HIDE, ; other values as ShellExecuteWait() ; $CompLvl - optional compression level (1-9) default 4 ; Return values .: 1 - Success ; 0 - and set @error = 1 ; and ; @extended = 1 (Warning (Non fatal error(s)) ; @extended = 2 (Fatal error) ; @extended = 7 (Command line error) ; @extended = 8 (Not enough memory for operation) ; @extended = 255 (User stopped the process) ; @extended values set by 7za.exe exit codes ; Author ........: NSC ; Modified ......: 2022/06/22 ; Remarks .......: requires 7za.exe in @scriptdir, 7za.exe (7-Zip Extra: standalone console version), ; avoids re-compress of popular archives. ; Thanks to 7-zip.org ; Related .......: ; Link ..........: ; =============================================================================================================================== Func _COMpress_7za_zip($archive, $folder, $show = @SW_HIDE, $CompLvl = 9) If StringRight($folder, 4) = ".zip" Or StringRight($folder, 3) = ".7z" Or StringRight($folder, 4) = ".rar" Or StringRight($folder, 4) = ".lha" Or StringRight($folder, 3) = ".gz" Or StringRight($folder, 7) = ".tar.gz" Or StringRight($folder, 4) = ".iso" Then $CompLvl = 0 EndIf Local $return7za = ShellExecuteWait($7za_exe, 'u -tzip -mx' & $CompLvl & ' -mmt -bt' & ' "' & $archive & '" "' & $folder & '"', '', $SHEX_OPEN, $show) Select Case $return7za = 0 Return 1 Case Else Return SetError(1, $return7za, 0) EndSelect EndFunc ;==>_COMpress_7za_zip You have to provide 7za.exe, in scriptdir in some way, maybe with a fileinstall or embedding in some way. 
      Daily I use most of the time:
      _UNcompress_7za
      _COMpress_7za_7z
      so I'am almost done with these funcs....
      Also I made a quick and dirty benchmark on some real world data (for me at least) , comparing the windows DLL, the zip ULTRA by 7zip and the various 7zip levels.

      My choice is level 4 (time/size) but your mileage may vary...
      Also, extracting many thousands of little files from a 7z archive with 7zip is waaaay fast in respect to other solutions.
×
×
  • Create New...