Jump to content

Recommended Posts

Recently I was working on a script with icons using GuiCtrkCreatIcon.
I decided to change the sub folder name of the icons to a more meaning name, however made a typo.

I tested the .exe on my test computer and it worked flawlessly (because both icon folder where on my test computer) 😁
But after I installed the script on the intended computers , I got chaos!😵

Zooming into the problem, I discovered, that because the icons could not be found, the ControlID were returned with a value of 0
and thus played havoc within the GuiGetMsg() switch/case statement.
I have been able to reproduce this  (see example)

#include <GUIConstantsEx.au3>

;============================================================================================================
; PLEASE, do not save this example in the example folder:  C:\Program Files (x86)\AutoIt3\Examples\Helpfile
;============================================================================================================

Example()

Func Example()
    GUICreate(" My GUI Icons", 250, 250)

    $Icon1 = GUICtrlCreateIcon("shell32.dll", 10, 20, 20)
    $Icon2 = GUICtrlCreateIcon(@ScriptDir & '\Extras\horse.ani', -1, 20, 40, 32, 32)
    $Icon3 = GUICtrlCreateIcon("shell32.dll", 7, 20, 75, 32, 32)
    GUISetState(@SW_SHOW)

    ;$Icon2 = -1        ; ==> When this line is uncommented the script "works", so -1 could be a potential fix.
    ; Loop until the user exits.
    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                ExitLoop
            Case $Icon2
                Beep (500,500)

        EndSwitch
    WEnd

    GUIDelete()
EndFunc   ;==>Example

If you save the above script outside the Autoit example folder and run it, it will keep beeping because GuiCtrlCreatIcon did not find horse.ani and return $Icon2=0.
At the moment GUICtrlCreateIcon () only returns the conntrolID on success and 0 on failure.
I would like to propose a return of -1 on failure, so a existing and working script won't go awry when the icon can not be found.
 

Link to post
Share on other sites
  • Developers

I honestly think there should be a test in the example/script for success at control creation time in stead of making this "workaround" proposal, which goes against to general way AutoIt3 works as generically a return of 0 is failure and <> 1 is success. 

Jos 

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Link to post
Share on other sites

Yes, you are right. This the Autoit way....😊

However I feel that when an icon is not found, it should not have such a big impact on the working of the script.
My script had several other GUIs behind the connected to the icons which all got triggered after each other.
And every time those GUIs were canceled they would popup again, so actually creating an infinite loop.

But enough about me, what would be your hans-on take and proposal on this ?

Groetjes, Martijn.

Edited by Jemboy
Link to post
Share on other sites

Here a good way to add icons to a .exe file that can be exported anywhere thereafter :

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Res_Icon_Add=C:\Apps\AutoIt\ZZTemp\icon_wWw_icon.ico
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
#include <GUIConstants.au3>
#include <Constants.au3>

If Not @Compiled Then Exit MsgBox ($MB_SYSTEMMODAL, "Error", "This script must be compiled")

Example()

Func Example()
    GUICreate(" My GUI Icons", 250, 250)

    $Icon1 = GUICtrlCreateIcon("shell32.dll", 10, 20, 20)
    $Icon2 = GUICtrlCreateIcon(@ScriptFullPath, 201, 20, 40, 32, 32)
    If Not $Icon2 Then $Icon2 = -1
    $Icon3 = GUICtrlCreateIcon("shell32.dll", 7, 20, 75, 32, 32)
    GUISetState(@SW_SHOW)

    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                ExitLoop
            Case $Icon2
                Beep (500,500)
        EndSwitch
    WEnd
EndFunc   ;==>Example

 

Link to post
Share on other sites

Yes @Nine this would add minimum extra lines to check to the script and not clutter the script so much.
I hate those multi line If-Thens 😉

But would the Autoit format/protocol/design rules allow us to add this  -1 to the GUICtrlCreateIcon function and
should we want to do that ?

 

Random remark: I always found it  strange that the Autoit developpers choose use the 1 for success and 0 for failure.
his was confusing at first, having programmed with other languages 🙂
Also using a 0 based numbering (e.g. with array) has made my life difficult in the past and probaly will do so too in the future 😁

Link to post
Share on other sites
  • Developers
45 minutes ago, Jemboy said:

However I feel that when an icon is not found, it should not have such a big impact on the working of the script.

Agree, that is why you as programmer should add the appropriate checks in your script to ensure it does function as it should.
There are a zillion ways to create mistakes like that and have Autoit3 go Crazy and one can't expect AutoIt3 to fix all for you. ;) 

Jos 

Edited by Jos

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Link to post
Share on other sites

@Jemboy 

I don't know why for some ppl it is such an ugly style to check for errors.  Because in any languages, you must always try to create bullet proof applications.  All good programmers adopt this best practice.

Link to post
Share on other sites

@NineIn theory I agree with you 100%.

In any case, the problem has been brought up, so hopefully other people will find this post helpfull when they experience this same GUICtrlCreateIcon problem.
Thanks for all your insights.

Link to post
Share on other sites
  • Developers

A "simple" fix for any "wrong guimsg" woud be to add those at the top of the messageloop:

While 1
        Switch GUIGetMsg()
            Case 0
                ; skipped guimsgs.. more can be added.          
            Case $GUI_EVENT_CLOSE
                ExitLoop
            Case $Icon2
                Beep (500,500)

        EndSwitch
    WEnd

Jos

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Link to post
Share on other sites
  • Developers

I know you all like those variables, but I hardly use them. In this case the 0 makes it utterly clear what we are testing for. ;) 

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Link to post
Share on other sites

I like using variable with meaninfull names, especially when looking up an old script.
I consider them like some extra remarks (REM)

However, @Jos very nice find to put the 0 case at the top of the switch!
Many roads lead to Rome ! 🙂

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 abberration
      Software Installer
      Version: 2.0
      It's been been a long year, but I finally got some time to rework this project. I re-wrote everything from scratch because the old version was getting too complicated with so many options and sub-menus. This new version is much easier to use and I have been testing for a few days and it seems very stable.
      For those who are new to this software, it helps you install software silently/unattended. This new version tries to determine the silent switch automatically. You can also re-organize the order in which the software installs by dragging & dropping them in the listview. It now supports creating profiles and checks for missing software (and automatically unchecks them, so it does not attempt to install non-existent software). One feature I included was because I have seen several people on Youtube talk about disliking bright screens at night. So, now you can choose from a few color theme (half of them are dark). I dabbled a bit more into GDI+ to draw a few things and show my logo with a transparent background (hint: I'm not good at GDI+).
      Under the Help menu, you will find a User Guide, which goes through most of it's features. I included a new icon if you want to use when you compile the script (in the Assets > Misc folder).
      If you have questions, comments or suggestions, all are welcome. Hope you enjoy!
      Here it is in action:

       
      Software_Installer_2.0.zip
    • By Skysnake
      This is a little tool that displays the contents of a DLL icon file. It shows how to use icons on buttons and as stand alone images. 
       
      #cs ---------------------------------------------------------------------------- AutoIt Version: 3.3.14.5 Author: Skysnake Script Function: Display content of DLL icon files #ce ---------------------------------------------------------------------------- ; Script Start - Add your code below here #include <ButtonConstants.au3> #include <GUIConstantsEx.au3> ;Local $rDLLpath = @SystemDir & "\Wmploc.dll" ;Local $rDLLpath = @SystemDir & "\imageres.dll" ;Local $rDLLpath = @SystemDir & "\shell32.dll" ;Local $rDLLpath = @SystemDir & "\pifmgr.dll" ;Local $rDLLpath = @SystemDir & "\explorer.exe" ;Local $rDLLpath = @SystemDir & "\accessibilitycpl.dll" ;Local $rDLLpath = @SystemDir & "\ddores.dll" ;Local $rDLLpath = @SystemDir & "\moricons.dll" ; ugly do not use ;Local $rDLLpath = @SystemDir & "\mmcndmgr.dll ;Local $rDLLpath = @SystemDir & "\netshell.dll" ;Local $rDLLpath = @SystemDir & "\ieframe.dll" Local $rDLLpath = @SystemDir & "\wiashext.dll" For $r = 0 To -50 Step -10 ConsoleWrite($r & @CRLF) GUICreate("Show Icons") Local $lblShowRange = GUICtrlCreateLabel("Icons " & $r - 1 & " to " & $r - 10, 8, 8, 100, 25) Local $btnIcon1 = GUICtrlCreateButton("", 8, 25, 24, 24, $BS_ICON) GUICtrlSetImage($btnIcon1, $rDLLpath, $r - 1, 0) ; GUICtrlCreateIcon($rDLLpath, $r - 1, 40, 25, 24, 24) ; 2nd Local $btnIcon2 = GUICtrlCreateButton("", 8, 50, 24, 24, $BS_ICON) GUICtrlSetImage($btnIcon2, $rDLLpath, $r - 2, 0) ; GUICtrlCreateIcon($rDLLpath, $r - 2, 40, 50, 24, 24) ; 3rd Local $btnIcon3 = GUICtrlCreateButton("", 8, 75, 24, 24, $BS_ICON) GUICtrlSetImage($btnIcon3, $rDLLpath, $r - 3, 0) ; GUICtrlCreateIcon($rDLLpath, $r - 3, 40, 75, 24, 24) ;4th Local $btnIcon4 = GUICtrlCreateButton("", 8, 100, 24, 24, $BS_ICON) GUICtrlSetImage($btnIcon4, $rDLLpath, $r - 4, 0) ; GUICtrlCreateIcon($rDLLpath, $r - 4, 40, 100, 24, 24) ;5th Local $btnIcon5 = GUICtrlCreateButton("", 8, 125, 24, 24, $BS_ICON) GUICtrlSetImage($btnIcon5, $rDLLpath, $r - 5, 0) ; GUICtrlCreateIcon($rDLLpath, $r - 5, 40, 125, 24, 24) ;6th Local $btnIcon6 = GUICtrlCreateButton("", 8, 150, 24, 24, $BS_ICON) GUICtrlSetImage($btnIcon6, $rDLLpath, $r - 6, 0) ; GUICtrlCreateIcon($rDLLpath, $r - 6, 40, 150, 24, 24) ;7th Local $btnIcon7 = GUICtrlCreateButton("", 8, 175, 24, 24, $BS_ICON) GUICtrlSetImage($btnIcon7, $rDLLpath, $r - 7, 0) ; GUICtrlCreateIcon($rDLLpath, $r - 7, 40, 175, 24, 24) ;8th Local $btnIcon8 = GUICtrlCreateButton("", 8, 200, 24, 24, $BS_ICON) GUICtrlSetImage($btnIcon8, $rDLLpath, $r - 8, 0) ; GUICtrlCreateIcon($rDLLpath, $r - 8, 40, 200, 24, 24) ;9th Local $btnIcon9 = GUICtrlCreateButton("", 8, 225, 24, 24, $BS_ICON) GUICtrlSetImage($btnIcon9, $rDLLpath, $r - 9, 0) ; GUICtrlCreateIcon($rDLLpath, $r - 9, 40, 225, 24, 24) ;10th Local $btnIcon10 = GUICtrlCreateButton("", 8, 250, 24, 24, $BS_ICON) GUICtrlSetImage($btnIcon10, $rDLLpath, $r - 10, 0) ; GUICtrlCreateIcon($rDLLpath, $r - 10, 40, 250, 24, 24) ; Display the GUI. GUISetState(@SW_SHOW) Sleep(3000) GUIDelete() Next  
    • By UEZ
      I'm searching for a way to set an icon for a system menu entry in the console window. I can add / remove entries but I didn't find a way to set an icon for the entry I made.
      Example:
      #AutoIt3Wrapper_Change2CUI=y #include <GDIPlus.au3> #include <GUIConstantsEx.au3> #include <GuiMenu.au3> #include <WindowsConstants.au3> Global $id_Test = 5000 Global $hConsole = HWnd(DllCall("kernel32.dll", "hwnd", "GetConsoleWindow")[0]) If Not $hConsole Then Exit HotKeySet("{ESC}", "_Exit") Global $hSysmenu = _GUICtrlMenu_GetSystemMenu($hConsole) Global $iCount = _GUICtrlMenu_GetItemCount ($hSysmenu) _GUICtrlMenu_InsertMenuItem($hSysmenu, $iCount, "Test", $id_Test) _GDIPlus_Startup() $hBitmap_GDI = _GDIPlus_BitmapCreateFromMemory(_Test(), True) ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $hBitmap_GDI = ' & $hBitmap_GDI & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console $hBmp1 = _WinAPI_CreateSolidBitmap($hConsole, 0xFF0000, 16, 16) ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $hBmp1 = ' & $hBmp1 & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console $hBmp2 = _WinAPI_CreateSolidBitmap($hConsole, 0x00FF00, 16, 16) ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $hBmp2 = ' & $hBmp2 & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console ;ConsoleWrite(_GUICtrlMenu_SetItemBmp($hSysmenu, $id_Test, $hBitmap_GDI, False) & @CRLF) ConsoleWrite(_GUICtrlMenu_SetItemBitmaps($hSysmenu, $id_Test, $hBmp1, $hBmp2, False) & ", " & @error & @CRLF) ;_GUICtrlMenu_SetItemBmp($hSysmenu, $id_Test, 8, False) ;set the default close icon _GDIPlus_Shutdown() Do Sleep(1000) Until False Func _Exit() ConsoleWrite("Bye..." & @CRLF) _GUICtrlMenu_DeleteMenu ($hSysmenu, $id_Test, False) _WinAPI_DeleteObject($hBitmap_GDI) _WinAPI_DeleteObject($hBmp1) _WinAPI_DeleteObject($hBmp2) Exit EndFunc ;Code below was generated by: 'File to Base64 String' Code Generator v1.20 Build 2020-06-05 Func _Test($bSaveBinary = False, $sSavePath = @ScriptDir) Local $Test $Test &= 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAA3XAAAN1wFCKJt4AAADKElEQVQ4yz2RT2gcdRTHP7+Z36y7yzZZdvJv22i0rBpiAwnWCMZrUCGIBxEvpQSEHAQhePLkyUKg6Em9iZCcahH0pFYxkIqiIdHKYmPUUHcDmU2TuJnZzc7s/H7PQ5M8ePAu7/M+X56y1hKGYY+IOEDqOI6TzWY1gFIKEcF1XRzHUWmaJnF8bHBy5pfbnz9fb0hBh2F4bm5ubjWKogudTqdVqVT0/Py853kehUKBQqHA2tqaVKtVfenS2P6HH396PDri9D9+cdC/8dkXNW2t9fb29spRFPmtVqtULBaVMYZ8Pk82m8X3farVKjdv3qCn+FbpnFuXfNpQkkwlX33z3RtaKYXW2mqtcV1XtNZks9kzQCaTIeNp4sSh8rAnzSe0HO5bt1arHR51y79pEcEYo05Aylp7OqOUIk0TRp+aYO5Ki3B3VR3s70pictzZGlC5jHW0UgprLVEU4Xke29vbLCwsoLXGcRRxYjk/2MtLz2X4/tvbaO3y9XoPlUe7CI7VAMYYPM+jXC5jrcUYAwipUeSzHhV/k59+bFK5OMytOxco9ezQTQ2A4ujoqDQ+Ph4sLS2JiNiDgwM5PDyQ3SCQ/5ptubv6rsy9XJIfvnxbNv/8W+7d+9deu/aeTE9PB2EYljSAiKje3l7SNCUIAkDQXp77f3zE4uJ1Xnv9KoWRK+zs1DlfHiCXy2OtBcA5AdDpdHBdl4F+n77BEdz2z3zw/iKvvHqVZ194h0wmz0B/Ca094jjmtE4NEBFarRa7jfvkHgqp/rrKxOQzjF6+wtY/u4g9Jo5TfL+EiGCtxVqLFhGUUhhjsNZgrcvqrU948rFhKlNvEkUdtNvBoFEqPVtUSqGUQiulaDabtNttPC/D5t3fqTU0Y5dfpNFogFhEOLsaxzHtdpsgCNT6+rrSSZIwOztrhoeH' $Test &= 'qdfrRmutJp6e4q+tKsbYs3in7+7r65OhoSE9MzNjkiRBt9ttkiRxjTHkcjl3bGxMPYhjSdP0rLvdLt1uF9d1BcDzPHdyclL0yspKuLGxcT0IgkeKxaINgsADXBFxAefEQB4ImNT3/W4Yhk6z2awtLy9H/wPnrsNEnFPl4QAAAABJRU5ErkJggg==' Local $bString = _WinAPI_Base64Decode($Test) If @error Then Return SetError(1, 0, 0) $bString = Binary($bString) If $bSaveBinary Then Local Const $hFile = FileOpen($sSavePath & "\AutoSave_16x16_04.png", 18) If @error Then Return SetError(2, 0, $bString) FileWrite($hFile, $bString) FileClose($hFile) EndIf Return $bString EndFunc ;==>_Test Func _WinAPI_Base64Decode($sB64String) Local $aCrypt = DllCall("Crypt32.dll", "bool", "CryptStringToBinaryA", "str", $sB64String, "dword", 0, "dword", 1, "ptr", 0, "dword*", 0, "ptr", 0, "ptr", 0) If @error Or Not $aCrypt[0] Then Return SetError(1, 0, "") Local $bBuffer = DllStructCreate("byte[" & $aCrypt[5] & "]") $aCrypt = DllCall("Crypt32.dll", "bool", "CryptStringToBinaryA", "str", $sB64String, "dword", 0, "dword", 1, "struct*", $bBuffer, "dword*", $aCrypt[5], "ptr", 0, "ptr", 0) If @error Or Not $aCrypt[0] Then Return SetError(2, 0, "") Return DllStructGetData($bBuffer, 1) EndFunc ;==>_WinAPI_Base64Decode  
      You must compile and run it to see the menu entry in the console window.

       
      Any idea?
    • By Colduction
      Hi guys!, i have a problem to convert Python code to AutoIt code, in fact i had not coded with Python yet!, this code is about permutation a string's case, i will be happy with your comments :)❤;

      Python code:
       
      # Python code to print all permutations # with respect to cases # Function to generate permutations def permute(inp): n = len(inp) # Number of permutations is 2^n mx = 1 << n # Converting string to lower case inp = inp.lower() # Using all subsequences and permuting them for i in range(mx): # If j-th bit is set, we convert it to upper case combination = [k for k in inp] for j in range(n): if (((i >> j) & 1) == 1): combination[j] = inp[j].upper() temp = "" # Printing current combination for i in combination: temp += i print(temp), # Driver code permute("Hello") # This code is contributed by Sachin Bisht
      My code in AutoIt:
      ; https://www.geeksforgeeks.org/permute-string-changing-case/ _PermuteCase("ABC") Func _PermuteCase($sText) If StringRegExp($sText, "^[A-Za-z]{1,}$") Then Local $iLength = StringLen($sText) ; Get length of the text. Local $iMaxPerm = 2 ^ $iLength ; Number of permutations is 2^n Local $sLow_Text = StringLower($sText) ; Converting string to lower case Local $asChrs = StringToASCIIArray($sLow_Text) ; Split the text into array of chars. For $i = 1 To $iMaxPerm Step 1 For $j = 0 To $asChrs[0] ;................................................... Next Next Else Return SetError(-1, 0, "Error: Input is incorrect!") EndIf EndFunc ;==>_PermuteCase  
       
       
       
       
       
      ====================== SOLUTION by @TheXman ======================
       
    • By therks
      So if you embed an animated cursor on a GUI with GUICtrlCreateIcon the animation goes quite slow. Is there a way to speed it up?
       
      #include <GUIConstants.au3> GUICreate('', 64, 64) GUICtrlCreateIcon('C:\windows\cursors\aero_busy_l.ani', 0, 0, 0, 64, 64) GUISetState() While GUIGetMsg() <> $GUI_EVENT_CLOSE WEnd Edit: See attached .gif for an example of the difference. On the top is the cursor viewed in an image viewer, on the bottom is in an AutoIt GUI. Notice how much slower it is in AutoIt.

×
×
  • Create New...