Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 12/09/2019 in all areas

  1. LarsJ

    UI Automation Events

    UI Automation Events In standard Windows GUI code, you can respond to Windows messages by registering and implementing a message handler function. A WM_NOTIFY message handler is registered and implemented in this way: ; Registration GUIRegisterMsg( $WM_NOTIFY, "WM_NOTIFY" ) ; Implementation Func WM_NOTIFY( $hWnd, $iMsg, $wParam, $lParam ) ; Code EndFunc The WM_NOTIFY function is a callback function. In UI Automation code, you can respond to UI Automation events by registering and implementing an event handler object. A FocusChangedEventHandler object is registered and implemented in this way: ; Registration UIAEH_FocusChangedEventHandlerCreate() $oUIAutomation.AddFocusChangedEventHandler( 0, $oUIAEH_FocusChangedEventHandler ) ; Implementation ; This is the function that receives events Func UIAEH_FocusChangedEventHandler_HandleFocusChangedEvent( $pSelf, $pSender ) ; Code EndFunc $oUIAEH_FocusChangedEventHandler is the event handler object. It's a callback object. This thread is about how to respond to UI Automation events by registering, implementing and using event handler objects. User Defined Functions Registering and implementing the event handler object in the code above is very simple. To make it that simple, it's necessary to include a few functions in a UDF. The zip-file at bottom of post contains a UIAEH_FocusChangedEventHandler.au3 UDF that allows the registration and implementation of the event handler object as simple as shown above. UIAEH_FocusChangedEventHandlerCreate() is a function in this UDF. The function creates the $oUIAEH_FocusChangedEventHandler object. Because this is a callback object it must be implemented through ObjectFromTag() (coded in ObjectFromTag.au3 in zip-file) function by trancexx and not through the usual ObjCreateInterface() which is used to create other UI Automation objects. (The warning at top of the help text is much more an error in the help text than an error in the function. Thousands of examples show that ObjCreateInterface() works flawlessly.) You don't need to use ObjectFromTag() in your own code. This function is completely handled in the UDFs. UIAEH_FocusChangedEventHandler_HandleFocusChangedEvent() is the function that receives events. This function is coded but commented out in UIAEH_FocusChangedEventHandler.au3. Copy this function to your own code. See FocusChangedEventHandler example below. UIA Event Handlers The first version of Microsoft's UI Automation code (the Windows 7 version that works on Windows XP, Windows Vista, Windows 7 and all later versions) implements four different event handler objects. In addition to the FocusChangedEventHandler object, it's the AutomationEventHandler, PropertyChangedEventHandler and StructureChangedEventHandler objects. The zip-file at the bottom contains the corresponding three event handler UDFs. By the way, these four event handlers are implemented in AutoIt several years ago in this and the following posts. FocusChangedEventHandler exposes a method to handle events that are raised when the keyboard focus moves to another UI Automation element. AutomationEventHandler exposes a method to handle Microsoft UI Automation events. These events include MenuOpened ($UIA_MenuOpenedEventId) and Window_WindowOpened ($UIA_Window_WindowOpenedEventId) events. See module UIA_EventIds in UIA_Constants.au3 for a complete list. Note that EventIds that belong to Windows 8 or later cannot be used in this version of the event handler. But they can be used after code updates over the coming weeks. 2019-12-15 If you select Desktop, AutomationEvent and all Events (Event Ids) in UI Automation Event Monitor below and click Start, you'll see the following output in SciTE console: $oUIAEH_AutomationEventHandler OK Desktop: AddAutomationEventHandler() = AsyncContentLoaded OK Desktop: AddAutomationEventHandler() = AutomationFocusChanged ERR Desktop: AddAutomationEventHandler() = AutomationPropertyChanged OK Desktop: AddAutomationEventHandler() = InputDiscarded OK Desktop: AddAutomationEventHandler() = InputReachedOtherElement OK Desktop: AddAutomationEventHandler() = InputReachedTarget OK Desktop: AddAutomationEventHandler() = Invoke_Invoked OK Desktop: AddAutomationEventHandler() = LayoutInvalidated OK Desktop: AddAutomationEventHandler() = MenuClosed OK Desktop: AddAutomationEventHandler() = MenuModeEnd OK Desktop: AddAutomationEventHandler() = MenuModeStart OK Desktop: AddAutomationEventHandler() = MenuOpened OK Desktop: AddAutomationEventHandler() = Selection_Invalidated OK Desktop: AddAutomationEventHandler() = SelectionItem_ElementAddedToSelection OK Desktop: AddAutomationEventHandler() = SelectionItem_ElementRemovedFromSelection OK Desktop: AddAutomationEventHandler() = SelectionItem_ElementSelected OK Desktop: AddAutomationEventHandler() = StructureChanged OK Desktop: AddAutomationEventHandler() = Text_TextChanged OK Desktop: AddAutomationEventHandler() = Text_TextSelectionChanged OK Desktop: AddAutomationEventHandler() = ToolTipClosed OK Desktop: AddAutomationEventHandler() = ToolTipOpened OK Desktop: AddAutomationEventHandler() = Window_WindowClosed OK Desktop: AddAutomationEventHandler() = Window_WindowOpened OK Note the error for the AutomationFocusChanged event handler (at the top of the list). I've found that there is an error, but so far have no explanation for it. PropertyChangedEventHandler exposes a method to handle Microsoft UI Automation events that occur when a property is changed. These events include Name ($UIA_NamePropertyId) and ValueValue ($UIA_ValueValuePropertyId) changes. See module UIA_PropertyIds in UIA_Constants.au3 for a complete list. Note that PropertyIds that belong to Windows 8 or later cannot be used in this version of the event handler. But they can be used after code updates over the coming weeks. StructureChangedEventHandler exposes a method to handle events that occur when the Microsoft UI Automation tree structure is changed. This event handler seems to be more valuable in eg. screen readers than in usual UI Automation code. NotificationEventHandler exposes a method to handle Microsoft UI Automation notification events. See this post. FocusChangedEventHandler example This is full code in Examples\FocusChangedEventHandlerEx.au3. Run the code in SciTE with F5. #AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7 ;#AutoIt3Wrapper_UseX64=y Opt( "MustDeclareVars", 1 ) #include "..\Includes\UIAEH_FocusChangedEventHandler.au3" Example() Func Example() UIAEH_FocusChangedEventHandlerCreate() If Not IsObj( $oUIAEH_FocusChangedEventHandler ) Then Return ConsoleWrite( "$oUIAEH_FocusChangedEventHandler ERR" & @CRLF ) ConsoleWrite( "$oUIAEH_FocusChangedEventHandler OK" & @CRLF ) Local $oUIAutomation = ObjCreateInterface( $sCLSID_CUIAutomation, $sIID_IUIAutomation, $dtag_IUIAutomation ) If Not IsObj( $oUIAutomation ) Then Return ConsoleWrite( "$oUIAutomation ERR" & @CRLF ) ConsoleWrite( "$oUIAutomation OK" & @CRLF ) Local $iError = $oUIAutomation.AddFocusChangedEventHandler( 0, $oUIAEH_FocusChangedEventHandler ) If $iError Then Return ConsoleWrite( "AddFocusChangedEventHandler() ERR" & @CRLF ) ConsoleWrite( "AddFocusChangedEventHandler() OK" & @CRLF ) HotKeySet( "{ESC}", "Quit" ) While Sleep(10) WEnd EndFunc Func Quit() UIAEH_FocusChangedEventHandlerDelete() Exit EndFunc ; This is the function that receives events Func UIAEH_FocusChangedEventHandler_HandleFocusChangedEvent( $pSelf, $pSender ) ; Ret: long Par: ptr ConsoleWrite( @CRLF & "UIAEH_FocusChangedEventHandler_HandleFocusChangedEvent: " & $pSender & @CRLF ) Local $oSender = ObjCreateInterface( $pSender, $sIID_IUIAutomationElement, $dtag_IUIAutomationElement ) $oSender.AddRef() ConsoleWrite( "Title = " & UIAEH_GetCurrentPropertyValue( $oSender, $UIA_NamePropertyId ) & @CRLF & _ "Class = " & UIAEH_GetCurrentPropertyValue( $oSender, $UIA_ClassNamePropertyId ) & @CRLF & _ "Ctrl type = " & UIAEH_GetCurrentPropertyValue( $oSender, $UIA_ControlTypePropertyId ) & @CRLF & _ "Ctrl name = " & UIAEH_GetCurrentPropertyValue( $oSender, $UIA_LocalizedControlTypePropertyId ) & @CRLF & _ "Handle = " & "0x" & Hex( UIAEH_GetCurrentPropertyValue( $oSender, $UIA_NativeWindowHandlePropertyId ) ) & @CRLF & _ "Value = " & UIAEH_GetCurrentPropertyValue( $oSender, $UIA_ValueValuePropertyId ) & @CRLF ) Return 0x00000000 ; $S_OK #forceref $pSelf EndFunc ; Auxiliary function (for simple properties only) ; There must be only one instance of this function Func UIAEH_GetCurrentPropertyValue( $oSender, $iPropertyId ) Local $vPropertyValue $oSender.GetCurrentPropertyValue( $iPropertyId, $vPropertyValue ) Return $vPropertyValue EndFunc Test the code by opening the Desktop context menu and move the mouse over the menu items. When the mouse hovers over a menu item it gets focus. Exit with Esc. AutomationEventHandlerEx.au3 Test the example by opening some windows, menus and tooltips. PropertyChangedEventHandlerEx.au3 Open Windows Task Manager (Ctrl+Shift+Esc) and you'll get a whole bunch of property changed events. Note that to access Windows Task Manager (and other programs) on Windows 10, use #RequireAdmin in the script and run SciTE as administrator. StructureChangedEventHandlerEx.au3 Clicking on a folder in File/Windows Explorer treeview generates a lot of structure changed events. New examples will be added over the coming weeks. UI Automation Event Monitor UI Automation Event Monitor is a tool to detect UI Automation events. The first group of toolbar buttons is used to set up the UI Automation event handler. The images have a PropertyChangedEventHandler set up to monitor Name ($UIA_NamePropertyId) and ValueValue ($UIA_ValueValuePropertyId) property changes in Windows Task Manager. Note that to access Windows Task Manager (and other programs) on Windows 10, use #RequireAdmin in the script (UIAEHEvents.au3) and run SciTE as administrator. These four toolbar buttons are hot-track enabled with the technique used in this example. The buttons open four listviews to set up the event handler. All listviews have multiple selections enabled. Select multiple items at once and check a single item in/out to check all selected items in/out. Use mouse or Space key to check an item in/out. In the first image, the mouse hovers over the Top Windows button so that it's selected. In the second image, the Top Windows button is clicked so that the listview is opened. Moving the mouse over the next three buttons automatically opens the corresponding listviews due to hot-tracking. Click the toolbar button again to close the listview or move the mouse above the title bar. Windows Task Manager is checked in the Top Windows listview. The Event Handlers listview is enabled when a Top Window is checked. The Event Ids listview is enabled when the AutomationEvent event handler is checked. The Property Ids listview is enabled when the PropertyChanged event handler is checked. In Event Ids and Property Ids listview you can select an item by pressing the first letter on the keyboard. The second group of toolbar buttons is used to Start/Stop the event handler (or multiple event handlers), Pause/Continue updating the Events listview, and Clear the listview. Note that the Pause button only stops updating the listview. Events are still detected and stored in $aEvents array. All new events are added at the bottom of the listview when you click Continue or Stop. The Pause Main Loop button is used to stop the GUI main loop, which significantly increases the performance of the Events listview. When the GUI main loop is paused you can only click the Continue Main Loop button (same button as Pause Main Loop) and you can close the GUI. Events listview The Events listview is a virtual listview because of performance and to make it easy to constantly add new rows to the bottom of the listview. Nevertheless, there can still be performance issues when a lot of events are generated. To remedy these issues, it's possible to stop the GUI main loop with the Pause Main Loop button. This significantly increases the performance of the Events listview. When there are a large number of events (when many new rows are added quickly at the bottom of the listview), this procedure must be followed to stop the event handler (or multiple event handlers): Make sure the GUI main loop isn't paused. Click the Pause button (second toolbar group) to pause Events listview updates. Click the Stop button to stop the event handler. When there are a small number of events you can immediately click the Stop button. To test the UI Automation Event Monitor, try performing the four examples (in Examples\, briefly described above) through the monitor GUI. There'll probably be some GUI updates in the coming weeks. UIA Menu, Tooltip and Window Events Monitor is a simpler version of UI Automation Event Monitor that detects only MenuOpened, ToolTipOpened and Window_WindowOpened events (AutomationEvents). Updates Windows 8, Windows 8.1 and Windows 10 updates Threads UI Automation UDFs contains all include files. UIASpy - UI Automation Spy Tool is a GUI tool that provides information about windows and controls and their interconnection and provides functionality to generate sample code. UIASpy is essential for creating UI Automation code. In Using UI Automation Code in AutoIt you can find and download examples and read information about using UIA code. IUIAutomation MS framework automate chrome, FF, IE, .... created by junkew August 2013 is the first AutoIt thread on UIA code. Zip-file The zip contains source files for GUIs and examples. Note that UI Automation UDFs must be installed in the Includes folder. You need AutoIt 3.3.12 or later. Tested on Windows 7 and Windows 10. Note that under Windows 7 and earlier versions, only the original four event handlers (AutomationEventHandler, FocusChangedEventHandler, PropertyChangedEventHandler, StructureChangedEventHandler) introduced in Windows 7 can be used. Comments are welcome. Let me know if there are any issues. UIAEHEvents.7z
    3 points
  2. _ReadIniSectionNames is just a little function I whipped up, that I thought I might as well share ... someone might find it useful. I had a need for it due to approaching the 32767 characters limit with the original INI function - IniReadSectionNames (see the Help file if you are not aware of this). Enjoy! Others have been there before me, and no doubt many others have also crafted their own solutions. Here is two old ones I found with a quick search ... both different but kind of similar to mine. I've gone for the simplistic approach. Test Example.au3 NOTE - It should be obvious you need to provide your own INI file and its correct path for the $file variable. #include <Array.au3> #include "ReadIniSectionNames.au3" Local $file = @ScriptDir & "\Settings.ini" Local $names = _ReadIniSectionNames($file) If Not @error Then _ArrayDisplay($names) Else MsgBox(0, "Return Error", $names) EndIf Exit ReadIniSectionNames.au3 Global $i, $INIfile, $INIlines, $INIread, $INIsection, $linetxt, $SectionNames Func _ReadIniSectionNames($INIfile) $INIread = FileRead($INIfile) $INIlines = StringSplit($INIread, @LF, 1) If @error Then Return SetError(1, 0, -1) Else $SectionNames = "" For $i = 1 To $INIlines[0] $linetxt = $INIlines[$i] If StringLeft($linetxt, 1) = "[" Then $INIsection = StringTrimLeft($linetxt, 1) $INIsection = StringStripCR($INIsection) $INIsection = StringTrimRight($INIsection, 1) If $INIsection <> "" Then If $SectionNames = "" Then $SectionNames = $INIsection Else $SectionNames = $SectionNames & "|" & $INIsection EndIf EndIf EndIf Next If $SectionNames = "" Then Return SetError(2, 0, -2) Else $SectionNames = StringSplit($SectionNames, "|", 1) Return $SectionNames EndIf EndIf EndFunc ;=> _ReadIniSectionNames
    1 point
  3. Hi I just wanted to share the tree I've made with all of you. Made it myself with a little help of the forum and google. This uses an example from @Chimp in this post, then I added the movable part, you exit by pressing 'end'. #Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_Icon=tree.ico #AutoIt3Wrapper_AU3Check_Stop_OnWarning=y #AutoIt3Wrapper_Run_Tidy=y #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #include <WinAPISysWin.au3> #include <GUIConstants.au3> #include <Misc.au3> ; for _IsPressed (23 END key) ;FileInstall("***\tree.gif", @ScriptDir & "\tree.gif") ;<<<<<<<<<< include ur gif file here Local $hDLL = DllOpen("user32.dll"), $oIE = ObjCreate("Shell.Explorer.2") Local $hBackground = GUICreate("", 350, 470, 20, 20, $WS_POPUP, $WS_EX_LAYERED + $WS_EX_TOPMOST) GUISetBkColor(0xffffff) Local $AlphaKey = 0xffffff $hLabel = GUICtrlCreateLabel("", 0, 0, 350, 450, -1, $GUI_WS_EX_PARENTDRAG) _WinAPI_SetLayeredWindowAttributes($hBackground, $AlphaKey, 0, $LWA_COLORKEY) GUISetState(@SW_SHOW, $hBackground) $hIE = GUICtrlCreateObj($oIE, -20, -5, 410, 480) ; <- embedd $oIE in the AutoIt GUI GUICtrlSetBkColor(-1, 0xffffff) $oIE.navigate(@ScriptDir & "\tree.gif") While True If _IsPressed("23", $hDLL) Then ExitLoop ; END key was pressed Sleep(50) WEnd $oIE = "" $hDLL = "" GUIDelete($hBackground) Thanks and happy holidays! xmas.au3 xmas.exe tree.ico
    1 point
  4. AutoIt can do what you're after, a simple forum search would show you countless posts around web automation. As for the forum you need, I'm guessing something like Rent-A-Coder, and just pay someone to do it.
    1 point
  5. Valik is no longer an active member or part of the development team. As mentioned, the ternary operator is alive and well in the current release. The mood when it comes to implementing new features is also much different than the response you got those many years ago. That said, I believe we will close this out for posterity. Any future feature requests can use the appropriate channel of the link below. Please be sure to read the post on what the development team won't be doing before posting any feature requests. That said, hopefully you have matured some since your previous "don't ban me or I'll spam the forum" posts. https://www.autoitscript.com/trac/autoit https://www.autoitscript.com/trac/autoit/wiki/AutoItNotOnToDoList
    1 point
  6. Maybe this : #include <Date.au3> Local $iTimeStamp = 1571259543 Local $sDate = _DateAdd('s', $iTimeStamp, '1970/01/01 00:00:00') Local $sDate2 = StringRegExpReplace($sDate, "(\d{4})/(\d{2})/(\d{2}) (\d{2}):(\d{2}):(\d{2})", "${3}/${2}/${1} ${4}:${5}:${6}") ConsoleWrite("> EpochToDate = " & $sDate & @CRLF) ConsoleWrite("> Dateformat2 = " & $sDate2 & @CRLF)
    1 point
  7. KindEbook Wishlist updated to v7.5, see Post #2. (v7.5) Major Update. Future proofed the program for greater number of entries on the list. NOTE - Depending on the number of entries for a user, loading the list could take several seconds longer now. This is of course dependent on the power of your processor etc. NOTES Basically I swapped out the IniReadSectionNames function (several instances) for some code of my own, as one of my user lists is fast approaching the 32767 characters limit of that original INI function. You can see an example of similar code here. I did briefly toy for a couple of days spending many hours updating the program to use SQL instead of INI, but in the end I wasn't satisfied enough with the result. I got the basics working well enough, but during live testing Query prices failed, and at this point I haven't bothered to troubleshoot yet, and may not. I like to keep things simple, which is why I have stayed with using INI over XML (which I dislike as it is slow etc with any sizable database file) and SQL (which I kind of like but is more complex than I really want). This was my first attempt at converting one of my INI based programs to SQL, and I doubt I will bother again. However it was one of those things I had on my to do list. Perhaps I should have tried a simpler program first. Some of you may be aware that I built an INI To SQL conversion program some time back and also a UDF that replicated INI functions using SQL instead. I used a modified version of those, and the conversion portion at least, worked well. On the third day, after having completed the SQL update to my program (bugs aside) on the second day, and having decided to do my replacement code for the IniReadSectionNames function instead, I belatedly thought of a better way to do what I had done, which would have saved a good number of hours (probably avoided the second day entirely) ... oh well, such is life ... not that those two days were full days of coding. Just for the record, the better way would have been to rename all existing INI functions doing a Replace All, using the underscore character at the front (i.e. _IniRead). Do that so all of the functions went back to my own replicated function variants, which I could then replace with the SQL ones where relevant (dependent on source file). Instead I had a dumb moment and replaced all the relevant INI functions with another generic function, carefully picking and choosing which ones to do it too ... which took an awful long time .. not helped by me changing my mind a couple of times about the formation of the parameters (another dumb moment). Basically I was using two functions for all the original INI functions, but passing a read or write parameter. Please note, I wasn't replacing every INI function, because many being used purely for the Settings.ini file, were left intact. It was only the INI functions dealing with the user database files, that needed changing. I guess the heart of the issue, was that I just jumped right in, without spending much time cogitating over how I should best do so ... a lesson to be learned there I suspect. In any case it is always easier to be smarter after the fact ... hindsight being such a lovely thing to have. As to why I decided to give up on the SQL update I spent many hours over two days on. Well, like I said, I prefer simple, and SQL takes a lot more thought than INI, plus starting and loading database files and checking things. All rather more complex than I prefer, plus I can open my INI files in a text editor like Notepad and edit manually or troubleshoot far more easily. Far easier to work with two INI files simultaneously too, for comparisons or transfers. I get the benefits of SQL, but for me there is the offsets that must always be considered too. Another thing, that really irked me, was finding blank entries in a SQL DB file, that turned out to be due to apostrophes in a couple of names. I had a to write replace and restore code to cater for that and other illegal characters. I honestly thought that in 2019, that sort of nonsense would well and truly have been catered for inside the functions themselves, with a different approach ... apostrophes are so common after all.
    1 point
  8. $time = 1571259543 $aCall = DllCall("msvcrt.dll", "str:cdecl", "ctime", "int*", $time) Msgbox(0,"", $aCall[0]) $time = 13215743943956926 / 10000000 $aCall = DllCall("msvcrt.dll", "str:cdecl", "ctime", "int*", $time) Msgbox(0,"", $aCall[0])
    1 point
  9. @seadoggie01 Thank you for pointing out my issues with FileOpen/FileWrite..., it works now. @Subz Thank you for the heads-up on _TempFile Also, I have settled with a long one liner you posted RunWait(@ComSpec & ' /c DISM /Online /Enable-Feature /FeatureName:NetFX3 /All /Source:' & StringLeft(@ScriptDir, 3) & 'Sources\sxs /LimitAccess')
    1 point
  10. Is there a reason to have multiple arrays instead of a two dimensional array with just the type 5 rows? What's the overall goal of your script?
    1 point
  11. ..no clue myself. But I never thought of going higher than $STR_STRIPALL (8), nor would find a reason to. Nonetheless is unexpected and if you feel it needs correction you can open a ticket after searching if is there any open describing that.
    1 point
  12. Ok, so today I faced the same issue as Supersonic and JoeBar described above. * A script using $tagNMLVKEYDOWN had no issue when run under AutoIt.exe on a Windows 32bits computer * Today, for the 1st time, I did run the script on a "OS:WIN_8/ CPU:X64 OS:X64" computer, the console showing that Autoit3_x64.exe was running the script. $VK_RIGHT, $VK_LEFT, nothing happened when you pressed the right or left key in the listview : it's like both keys were dead ! * Here is a list of different $tagNMLVKEYDOWN strings, found here and there : 1) Official release AutoIt 3.3.14.5 - Include file StructureConstants.au3 (file dated 15 march 2018) Global Const $tagNMLVKEYDOWN = "align 1;" & $tagNMHDR & ";word VKey;uint Flags" 2) LarsJ proposal (above) at top of _WM_NOTIFY function : Local Const $tagNMLVKEYDOWN = $tagNMHDR & ";word VKey;uint Flags" 3) Nine proposal (above) $tagNMLVKEYDOWN = "align 2;" & $tagNMHDR & ";" & (@AutoItX64 ? "uint;" : "") & "word VKey;uint Flags" 4) Beta release 3.3.15.1-1 found here - Include file StructureConstants.au3 (file dated 04 april 2018) Global Const $tagNMLVKEYDOWN = $tagNMHDR & ";align 2;word VKey;uint Flags" jpm wrote this at the end of the corresponding track ticket #1130, found there : "It has been fixed for the next Beta on my birthday ..." which is April 4th (as openly indicated in his profile) and that's the same date of StructureConstants.au3 in the Beta release, well done jpm Structures #2 #3 #4 work fine on x64 (tested them all today) but for now I'll stick to jpm's structure #4 as it should be found in the include file of the next official release... if no further change happens. Also structure #4 seems ok on 32 bits computers (just tested) So if any of you share on the Forum a script running fine on your x86 computer, where $tagNMLVKEYDOWN is found, please don't forget to add the amended structure of $tagNMLVKEYDOWN to make it compatible with x64 computers running your script, for example : Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam) ... Case $LVN_KEYDOWN Local Static $tagNMLVKEYDOWN = $tagNMHDR & ";align 2;word VKey;uint Flags" ... = DllStructCreate($tagNMLVKEYDOWN, $lParam) I hope Static is correct in this case, so $tagNMLVKEYDOWN won't need to be re-declared each time WM_NOTIFY() is called. It seems even better to follow LarsJ's advice and place it at the very top of WM_NOTIFY() in case keypress notifications need to be checked at several places within WM_NOTIFY() Please note that in the Beta file, changes done to $tagNMLVKEYDOWN have also been applied to $tagNMTCKEYDOWN and $tagNMTVKEYDOWN
    1 point
  13. boomingranny

    INI Editor

    A very simple INI editor, I use it as a "settings" button in some of my projects, to allow a simple way to change settings. It uses a slightly modified version of Melba23's GUIListViewEx UDF for the list view. Dan_GUI_frmINIEditor.zip
    1 point
  14. Here to get you started : #include <GUIConstants.au3> Local $aStates[] = ["New York", "California"] Local $aAttractions[][] = [["Statue of Liberty", "Time Square", "Brooklyn Bridge"], ["Disneyland", "Golden gate Bridge", "Alcatraz"]] GUICreate('List of attractions', 250, 250) Local $idCombo = GUICtrlCreateCombo("", 10, 30, 80, 28) For $i = 0 To UBound($aStates) - 1 GUICtrlSetData($idCombo, $aStates[$i]) Next Local $aCB[UBound($aAttractions, 2)] For $i = 0 To UBound($aAttractions, 2) - 1 $aCB[$i] = GUICtrlCreateCheckbox("", 110, 10 + $i * 30, 100, 25) GUICtrlSetState(-1, $GUI_HIDE) Next GUISetState() Local $iState While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop Case $idCombo $iState = CheckState(GUICtrlRead($idCombo)) For $i = 0 To UBound($aAttractions, 2) - 1 GUICtrlSetData($aCB[$i], $aAttractions[$iState][$i]) GUICtrlSetState($aCB[$i], $GUI_SHOW + $GUI_UNCHECKED) Next EndSwitch WEnd Func CheckState($sState) For $i = 0 To UBound($aStates) - 1 If $aStates[$i] = $sState Then Return $i Next EndFunc ;==>CheckState
    1 point
  15. Add this to top of _WM_NOTIFY function and it should work: Local Const $tagNMLVKEYDOWN = $tagNMHDR & ";word VKey;uint Flags"
    1 point
  16. DW1

    Hold Mouse Button?

    Yes, it IS clicking, did you try it? It clicks. The one that GEO posted, leaves the loop after ONE click. The one he posted where you hold down the right mouse button to click the left, worked fine, but was not what was requested. EDIT: HAHA, I guess it would serve a better point when I paste the correct code LOL. Sorry JohnOne, you are indeed right, that one DOES NOT WORK. I have edited the previous code to match this as well. Here is the one I meant to, and thought I did, paste: #include "Misc.au3" $dll = DllOpen("user32.dll") While 1 Sleep(1000) If _IsPressed("01", $dll) Then If Click() Then ExitLoop EndIf WEnd Func Click() While _IsPressed("01", $dll) MouseUp("primary") If MouseDown("primary") Then ConsoleWrite("mouse clicked" & @CRLF) Sleep(1000) WEnd Return 1 EndFunc ;==>Click DllClose($dll)
    1 point
  17. _ArrayAdd() only adds a single row, and only to a 1D array. I have a 2D version, but it still adds a single row. This will take either 1D or 2D for $avArray, and if you pass it a single value, or an array with $NestArray = True, then it gets stored as a single element at [n][0]. If $avArray is 2D and you pass a 1D array with $NestArray = False, then it adds one full row to the array with the elements from the 1D array used for each column. It is still one row at a time. To append a 2D array onto a 2D array (multiple rows), you need a 2D version of _ArrayConcatenate(), not _ArrayAdd(). This is what I have for 2D add (including full demo), __ArrayAdd(): #include <Array.au3> Global $avTesting, $avAdd, $RET, $iErrSav, $iExtSav, $avTemp ; ---------------------------------------------- ; Demonstrate normal operation ; ---------------------------------------------- $sTitle = "Demonstrate normal operation" ; Add an element to a 1D array: $sMsg = "Add an element to a 1D array:" & @CRLF Global $avTesting[3] = [1, 2, 3] $RET = __ArrayAdd($avTesting, "Four") $iErrSav = @error $iExtSav = @extended _DisplyResults() ; Add a single element to a 2D array $sMsg = "Add a single element to a 2D array:" & @CRLF Global $avTesting[3][2] = [[1, 2],[3, 4],[5, 6]] $RET = __ArrayAdd($avTesting, "Test") $iErrSav = @error $iExtSav = @extended _DisplyResults() ; Add a row of elements to a 2D array $sMsg = "Add a row of elements to a 2D array:" & @CRLF Global $avTesting[3][2] = [[1, 2],[3, 4],[5, 6]] Global $avAdd[2] = ["x", "y"] $RET = __ArrayAdd($avTesting, $avAdd, False) $iErrSav = @error $iExtSav = @extended _DisplyResults() ; Same as above, but nest array as an element $sMsg = "Same as above, but nest array as an element:" & @CRLF Global $avTesting[3][2] = [[1, 2],[3, 4],[5, 6]] Global $avAdd[2] = ["x", "y"] $RET = __ArrayAdd($avTesting, $avAdd) $iErrSav = @error $iExtSav = @extended $avTemp = $avTesting[$RET][0] $sMsg &= "$RET = " & $RET & " @error = " & $iErrSav & " @extended = " & $iExtSav SplashTextOn($sTitle, $sMsg, 400, 100, @DesktopWidth - 500, 100, 16) _ArrayDisplay($avTemp, "$avTemp") ; ---------------------------------------------- ; Demonstrate error handling ; ---------------------------------------------- $sTitle = "Demonstrate error handling" ; $avArray is not an array - @extended = 0 $sMsg = "$avArray is not an array:" & @CRLF Global $avTesting = 0 $RET = __ArrayAdd($avTesting, "Test") $iErrSav = @error $iExtSav = @extended _DisplyResults() ; $avArray is greater than 2D - @extended = 1 $sMsg = "$avArray is greater than 2D:" & @CRLF Global $avTesting[2][2][2] = [[[1, 2],[3, 4]],[[5, 6],[7, 8]]] $RET = __ArrayAdd($avTesting, "Test") $iErrSav = @error $iExtSav = @extended _DisplyResults() ; $vValue as an array is not 1D - @extended = 2 $sMsg = "$vValue as an array is not 1D:" & @CRLF Global $avTesting[3][2] = [[1, 2],[3, 4],[5, 6]] Global $avAdd[2][2] = [["w", "x"],["y", "z"]] $RET = __ArrayAdd($avTesting, $avAdd, False) $iErrSav = @error $iExtSav = @extended _DisplyResults() ; $vValue as an array is too long - @extended = 3 $sMsg = "$vValue as an array is too long:" & @CRLF Global $avTesting[3][2] = [[1, 2],[3, 4],[5, 6]] Global $avAdd[3] = ["w", "x", "y"] $RET = __ArrayAdd($avTesting, $avAdd, False) $iErrSav = @error $iExtSav = @extended _DisplyResults() Func _DisplyResults() $sMsg &= "$RET = " & $RET & " @error = " & $iErrSav & " @extended = " & $iExtSav SplashTextOn($sTitle, $sMsg, 500, 100, @DesktopWidth - 600, 100, 16) If IsArray($avTesting) And UBound($avTesting, 0) < 3 Then _ArrayDisplay($avTesting, "$avTesting") Else MsgBox(64, "Pause", "Pause") EndIf EndFunc ;==>_DisplyResults ; #FUNCTION# ==================================================================================================== ================ ; Name...........: __ArrayAdd ; Description ...: Adds a specified value or row at the end of an existing 1D or 2D array. ; Syntax.........: __ArrayAdd(ByRef $avArray, $vValue [, $NestArray = True]) ; Parameters ....: $avArray - Array to modify ByRef ; $vValue - Value to add, can be a 1D array if $avArray = 2D and $NestArray = False ; $NestArray - Optional flag if False causes array passed as $vValue to be interpreted as a 1D array ; of values to place in a single new row of a 2D array. Default = True, saves array as ; a single element. This flag is ignored if $avArray is 1D or $vValue is not an array. ; Return values .: Success - Index of last added item ; Failure - -1, sets @error to 1, and sets @extended to specify failure (see code below) ; Author ........: Jos van der Zande <jdeb at autoitscript dot com> ; Modified.......: Ultima - code cleanup ; ; PsaltyDS - Array and 2D $vValue inputs added ; Remarks .......: Each call to this function adds exactly one new row to $avArray. To add more rows use _ArrayConcatenate. ; Related .......: _ArrayConcatenate, _ArrayDelete, _ArrayInsert, _ArrayPop, _ArrayPush ; Link ..........; ; Example .......; Yes ; ==================================================================================================== =========================== Func __ArrayAdd(ByRef $avArray, $vValue, $NestArray = True) Local $iBoundArray0, $iBoundArray1, $iBoundArray2, $iBoundValue1 If IsArray($avArray) = 0 Then Return SetError(1, 0, -1); $avArray is not an array $iBoundArray0 = UBound($avArray, 0); No. of dimesions in array If $iBoundArray0 > 2 Then Return SetError(1, 1, -1); $avArray is more than 2D $iBoundArray1 = UBound($avArray, 1); Size of array in first dimension If $iBoundArray0 = 2 Then $iBoundArray2 = UBound($avArray, 2); Size of array in second dimension If ($iBoundArray0 = 1) Or (IsArray($vValue) = 0) Or $NestArray Then ; If input array is 1D, or $vValue is not an array, or $NestArray = True (default) then save $vValue literally If $iBoundArray0 = 1 Then ; Add to 1D array ReDim $avArray[$iBoundArray1 + 1] $avArray[$iBoundArray1] = $vValue Else ; Add to 2D array at [n][0] ReDim $avArray[$iBoundArray1 + 1][$iBoundArray2] $avArray[$iBoundArray1][0] = $vValue EndIf Else ; If input array is 2D, and $vValue is an array, and $NestArray = False, ; then $vValue is a 1D array of values to add as a new row. If UBound($vValue, 0) <> 1 Then Return SetError(1, 2, -1); $vValue array is not 1D $iBoundValue1 = UBound($vValue, 1) If $iBoundArray2 < $iBoundValue1 Then Return SetError(1, 3, -1); $vValue array has too many elements ReDim $avArray[$iBoundArray1 + 1][$iBoundArray2] For $n = 0 To $iBoundValue1 - 1 $avArray[$iBoundArray1][$n] = $vValue[$n] Next EndIf ; Return index of new last row in $avArray Return $iBoundArray1 EndFunc ;==>__ArrayAdd
    1 point
×
×
  • Create New...