
Jeemo
Active Members-
Posts
65 -
Joined
-
Last visited
Content Type
Forums
Downloads
Forum Articles
Events
Everything posted by Jeemo
-
Grouping controls to hide and show them all
Jeemo replied to Uten's topic in AutoIt GUI Help and Support
I know this post is a decade old, but for future askers of the same question: Hiding a Tab control will not hide the controls belonging to it. While this is counterintuitive, I've used this behavior much to my advantage (as described here). Anyway, one trick would be to create a dummy tab item in your tab control. When you wish to "hide" your entire tab control, if you hide the control itself and at the same time switch to your dummy tab, then that should get the desired effect. One possible drawback is if your tab control does not have a transparent background then you might not see things "beneath" it, if that's what you're going for. But if your tab control has a specific color, you should be able to work around this by setting its background color to transparent, and adding a Graphic control with the same dimensions as your tab control, and set its color to the desired background color. Then, add an instance of this graphic control to each tab item. - Jeemo -
Function inclusion in already-compiled script
Jeemo replied to Jeemo's topic in AutoIt General Help and Support
Thanks junkew, I'll have a look. -
Function inclusion in already-compiled script
Jeemo replied to Jeemo's topic in AutoIt General Help and Support
I'm almost 3,000 lines into this project in AutoIt, so there's no turning back now. Time is of the essence, so I couldn't afford the time it would take to conquer the learning curve of a different language that would do the same thing as AutoIt. The platform-independence thing would be down the road, likely a year or more. I'm fine with some (or all) of what I'm doing in AutoIt being tossed out at that time, if it's been able to provide value in the meantime. -
Function inclusion in already-compiled script
Jeemo replied to Jeemo's topic in AutoIt General Help and Support
Thanks again for your detailed response, Orbs. Given everything you've mentioned, I've decided against the approach of defining modules in XML (or any other plain text format). I may end up breaking them up into separate executables, but I'm even on the fence about that. Yes, it would be nice for all modules to have their own versions, but the engineering that would be required to get that all to work might not justify the benefits. -
Cleanest Way To Mass Hide/Show Controls
Jeemo replied to Damein's topic in AutoIt General Help and Support
I know I'm a little late here, but thought it couldn't hurt to post. I was able to accomplish something similar to what you were asking via Tab controls. I have a pretty complex GUI that I'm building for which I have a handful of static controls (a couple graphic controls and a logo form a "banner" across the top, along with a Main Menu button in the top left corner - all of which are always visible at top of the application). All other controls are created dynamically, and the vast majority of those are programmatically swapped out in groups via switching tabs. The application employs a flyover Main Menu that slides in and out of view from the left side of the master window, as well as a Module Menu that lives permanently on the left side of the master window. The contents of the Module Menu will change depending on which module is selected from the Main Menu flyover. Additionally, the contents of the "main" window changes depending on what's selected in the Module Menu. I've been able to simply show/hide different groups of controls by utilizing a couple instances of the Tab control. You can only have one Tab control per GUI, but my application consists of a master GUI and several child GUIs, which enables me to pull off this approach. The GUI stack I have is structured like this: $guiMaster (Master GUI) $guiMainMenu (flyover menu GUI) $guiModuleMenu (static GUI on the left side of $guiMaster) $tabModuleMenu (Tab control for switching between the groups of controls in the Module Menu - one group per module) $tabMM_Module1 (Tab item containing all navigation controls for "Module 1") $ctrlModule1MenuItem1 $ctrlModule1MenuItem2 etc. $tabMM_Module2 (Tab item containing all navigation controls for "Module 2") $ctrlModule2MenuItem1 $ctrlModule2MenuItem2 etc. $guiMain (everything below the top "banner" section described earlier, and to the right of the Module Menu) $tabMain $tabMain_Module1 (Tab item containing all controls in the Main section for Module 1) $Module1MainControl1 $Module1MainControl2 etc. $tabMain_Module2 (Tab item containing all controls in the Main section for Module 2) $Module2MainControl1 $Module2MainControl2 etc. Again, selecting a Module from the Main Menu programmatically changes the tab to the appropriate module in the Module Menu. You can also simply hide the master Tab control - its tabs and border will then be invisible, but all controls belonging to it will remain visible, effectively masking the fact that a tab control is being used. With all this combined, it makes for a really nice way of swapping out groups of controls with just a single command instead of having to iterate through individual controls and change their state. Hope this helps the OP or someone else. - Jeemo -
Function inclusion in already-compiled script
Jeemo replied to Jeemo's topic in AutoIt General Help and Support
@orbs, you were right about Execute() being limited to single-line commands. I have a workaround that should work: upon launching the master script, parse the full-blown functions from the XML file, decrypt them and spit them out to a temp .au3 file, compile to an executable belonging to that module and immediately delete the temp .au3 file. Calls to the functions within the module-specific executables could then employ Execute(). Then destroy the resultant executables upon exiting the script. After reading what I just wrote, I'm leaning more towards "it's too complex, and too vulnerable" (albeit possible). I'd definitely welcome any suggestions towards getting anything close to the modularity I'm seeking with less complexity. -
Function inclusion in already-compiled script
Jeemo replied to Jeemo's topic in AutoIt General Help and Support
@orbs, thank you for your reply, you bring up some great points. Security is absolutely a concern, so I was already planning to encrypt the parts of the XML file that would expose functions or code execution, and decrypt them upon import (I omitted that from the original post to keep from confusing things). While I suspect that it might be possible to crack open the master script executable to find its internal unencryption key, if a malicious actor can do that then they would pretty much "own" the master script even if it didn't have any external file dependencies, no? To your point about Execute() maybe not working on sections of code, I'm looking into a worst-case-scenario of getting multi-line functions into a single line, with some sort of new line delimiter. Not sure about the possibility of that idea, though. Lastly, I have a couple reasons for my approach: The first is that the script is a multi-purpose UI. I already have about 5 different modules in mind, and I expect that number to grow. More importantly, I expect there to be somewhat frequent changes and feature enhancements within each module, such that I'd like each one to have its own version. And with each change, I'd prefer to have the option to send the users of the utility a new version of the module as it becomes available, rather than bump the overall application version plus have users do a full rip/reinstall just to affect a potentially minuscule change to a single module. And if someone requests a one-off customization of one of the modules then I'd like to be able to provide that without having to maintain a different version of the entire script for each such custom request to a module. The other reason is that I expect many (if not all) of the modules will ultimately be migrated to a vehicle other than my my AutoIt script (no offense to AutoIt, but cross-platform usage will eventually be a requirement). I figured that defining the modules in XML would make that migration process easier. With all that being said, I admittedly have a tendency to over-engineer things. I'm not 100% married to the idea of my approach - I just started mucking around with XML in AutoIt a couple days, and I have to say it's been a pretty big headache so far. If you or anyone else think that the approach will be more effort than it's worth, or if you have any simpler alternatives to get similar flexibility to what I'm looking for then I would eagerly listen. -
Function inclusion in already-compiled script
Jeemo replied to Jeemo's topic in AutoIt General Help and Support
I think I figured it out - the Execute() function! So, I'll have my module functions defined as simple string values within my XML file(s), to then be executed by Execute(). This should not only get me what I'm looking for, but since the Execute argument is plain text that isn't evaluated until the Execute function call is instantiated within the script it also won't raise any "function not defined" flags whenever I compile my master script. I'll test the theory and report back the results. -
Hello fellow AutoIt-ers, I'm building a utility to help automate certain tasks, and my approach is to make it as modular as possible. The utility is essentially a framework upon which various task-specific modules can be stacked. I'm defining each module's attributes and actions in its own XML file so that I can make updates to each module independently of one another, as well as update them or create new ones without having to recompile the core application. Which brings me to my question: Is it possible to define functions in an external file that gets read into memory upon launch of my compiled AutoIt application? In other words, what I'm looking to do is to get the same behavior as using an #include with an .au3 file, but with the external AutoIt functions living in XML instead of au3, and being included by an AutoIt script that's already compiled into an executable. Is this at all possible? I'd even settle for having the module "import" process include a step to parse the XML file and dump all AutoIt-function-specific elements into a temporary .au3 file, if that would be the difference between this being possible or not. Thank you in advance for any potential guidance. :-)
-
In two days?! That's quite a party! Haha, enjoy.
-
I've been trying to make sense of this UDF (it seems that it's great, but without good examples or documentation I've been struggling to make good use of it), and in the process I'm pretty sure I found a bug: The function _XML_GetValue returns an array whose last element is empty, and the first value that it's supposed to retrieve is missing. The first value is missing because it's overwritten by what ends up being the Count value of the results. I was able to fix it by shifting all of the values down one element (and thus using the otherwise empty element) before the count value is added. See below for the snippet I've added near the end of the function: ; START Fix Local $i For $i = UBound($aResponse) - 1 To 1 Step - 1 $aResponse[$i] = $aResponse[$i - 1] Next ; END Fix ; Last two lines of the function $aResponse[0] = UBound($aResponse) - 1 Return SetError($XML_ERR_OK, $XML_EXT_DEFAULT, $aResponse) The first 4 lines of the snippet are what I've added, the last 2 lines are the last two lines in the function (I kept them in for context). I hope this helps. Cheers, Jeemo
-
OHB, thank you so much for this UDF. It's helped to make something I'm working on much, much easier to manage. Since I'm relying on this so heavily, I found that simply seeing the contents of my 'x' dictionary in plain text (via x_display()) was becoming increasingly difficult for me to navigate. As such, I added a couple functions that provide output in a similar way as x_display, but using a TreeView control. Thought I'd share it here as a way of giving back a little. If you add the following code to your associative-arrays.au3 file, you can call x_display_treeview() in exactly the same way as x_display() - it even takes an argument of a branch from which to start, as with the original x_display function. I didn't bother getting too fancy with being able to resize the resultant popup window, but feel free to tweak it as needed. I've also configured it to auto-expand every node by default. If that doesn't suit you, just change (or comment out) the GuiCtrlSetState line close to the end. Here's the code: Global $DictTreeview Func x_display_treeview( $key = '' ) $text = $key If $key <> '' Then $text &= " " $wHnd = GUICreate( "Array " & $key , 700 , 900, -1, -1) GUISetState( @SW_SHOW , $wHnd ) _x_display_treeview( x( $key )) While 1 If GUIGetMsg() == -3 Then ExitLoop WEnd GUISetState( @SW_HIDE , $wHnd ) GUIDelete( $wHnd ) GUICtrlDelete($DictTreeview) $DictTreeview = 0 EndFunc Func _x_display_treeview($item, $parent = 0) Local $TreeViewItem If Not $DictTreeview > 0 Then $DictTreeview = GUICtrlCreateTreeView(0, 0, 700, 900) If $parent = 0 Then $parent = GUICtrlCreateTreeViewItem("Dictionary", $DictTreeview) Endif If IsObj( $item ) Then For $i in $item _x_display_treeview($item.item($i), GUICtrlCreateTreeViewItem($i, $parent)) Next ElseIf IsArray( $item ) Then For $i in $item _x_display_treeview($item.item($i), GUICtrlCreateTreeViewItem($i, $parent)) Next Else $ParentText = GUICtrlRead($parent, 1) GUICtrlSetData($parent, $ParentText & " = " & $item) EndIf GUICtrlSetState($parent, $GUI_EXPAND) Return $TreeViewItem EndFunc I hope this comes in handy for someone. Cheers, Jeemo
-
@JohnOne, that is definitely correct. I've been able to resolve the issue by creating a temporary DLLStruct during the final iteration of the file, and defining the size of it to be equal to the size of the remaining bytes to be read, then transferring the contents of the primary DLLStruct to the temp one. Doing this truncates whatever data from the primary DLLStruct that doesn't fit in the temp one, which is exactly what I need since only the padded zeroes get truncated.
- 2 replies
-
- stdin
- dllstructgetdata
-
(and 3 more)
Tagged with:
-
Hello AutoIt community, I'm working on a project where I need to copy the bits of a file to a child process's StdIn stream. It's almost complete, but I have one final snag. The script uses DLLStructCreate to create a 64K buffer that holds the file's binary contents in memory. It iterates through the contents of the desired file in 64K segments, first pulling the bits into the buffer, then dumping the contents of the buffer out to the child process's StdIn stream. The child process then ultimately reconstitutes the file on a remote system. The child process does build the file in the target directory, but the problem is that the reconstituted file is always slightly larger than the original because it's always a multiple of 64K (when you look at the file properties, the size is always identical to the "size on disk" value). Storage consumption is not a concern since it's technically not occupying more space than the original, but file integrity is a concern. Not every file shows any signs of corruption when opening it, but some of the reconstituted files are completely useless because of this. I know that the problem lies within the last iteration of reading the source file; for example, if there are only 24K bits remaining to be read, that data gets stored in the DLLStruct along with 40K of zeros to fill the entire 64K buffer. When the file is reconstituted, this padding of zeroes is unfortunately also included. So my challenge is to try to figure out how to ignore these trailing zeroes while reading the final <64K bits of the file, or at least only send part of the contents of the DLLStruct buffer to StdIn. Does anyone know how to go about doing this? Thanks in advance, Jeemo
- 2 replies
-
- stdin
- dllstructgetdata
-
(and 3 more)
Tagged with:
-
Hi jchd, I'm using _sql.au3 modified to use the SQL Server Native Client 11.0 connector - do you think it could still be a factor?
-
I know this is a really old comment, but I just ran into the exact same problem. I finally figured it out myself, and sinceI was scratching my head for a while because of it I thought I'd share the solution. In digging into the query that was giving me the blank columns, I noticed that for all problem fields the data type of the underlying field was varchar(max). Apparently there's something that either the _SQL UDF or AutoIt itself doesn't like about working with that data type. I was able to get around it by modifying the View in the SQL table that I was referencing with my _SQL UDF functions. For each field that has a varchar(max) data type, use either CAST or CONVERT to force the data into a type that is digestible by your AutoIt script. In my case, I had to cast one field as int, one as varchar(256) (for a UNC path) and the other as decimal(16 , 10) (for a decimal-formatted timestamp value). When adding the CAST functions within SQL Server Management Studio I got a prompt warning that the conversion might not be necessary, but in my case they were safe to ignore. After saving these changes to the View, voila - the columns were no longer blank! Be mindful that you don't convert the data in a way that could produce undesired or unpredictable results, *especially* if your AutoIt script isn't the only thing that relies on the View (in my case, I built the View specifically for my AutoIt script). I would actually highly recommend that you also create a View specifically for this conversion purpose, rather than change the data types in the underlying table.
-
Mimic this shutdown blocker via AutoIT?
Jeemo replied to Jeemo's topic in AutoIt General Help and Support
Prog@ndy, I must tip my hat to you. I'm not sure if I would have ever found that ProcessShutdownParameters component that did the trick - if I were to have found it, it would not have been soon. I implemented the changes you added and it now works perfectly. Thank you so much. Jeemo -
Mimic this shutdown blocker via AutoIT?
Jeemo replied to Jeemo's topic in AutoIt General Help and Support
Friggin' sweet! I'll give that a shot and get back to you. Thanks either way for your efforts. -
Mimic this shutdown blocker via AutoIT?
Jeemo replied to Jeemo's topic in AutoIt General Help and Support
oMBRa, I appreciate the tip but I've been to that page a few times and cannot find what I'm looking for there. The contents of that page are very relevant to the guts of my posted code, but I don't think there's anything in there that has any component of timing such as what I am looking for. -
There is a utility called Shutdown Monitor that prevents users from logging off or shutting down as long as a specified process is running. A quote from the site: I really, really need to use what this program provides. I have an AutoIT script that blocks shutdown requests, but usually after the shutdown request has successfully killed processes that I need to remain running. I have tried Shutdown Monitor and it works flawlessly. However, I cannot use it because when one tries to end the Windows session the program pops up a generic, poorly-written message that cannot be modified. If I were to pitch this solution to potentially broadcast the message to thousands of users I would surely be shot down. Here is the code I have so far. I just need to modify it so that it can tell Windows to try shutting itself down first. Can anyone help? GUIRegisterMsg($WM_QUERYENDSESSION, "Cancel_Shutdown") GUICreate("PreventShutdownGUI") GUISetSTate(@SW_HIDE) Global $b_ShutdownInitiated = False While 1 If $b_ShutdownInitiated = True then EndIf If WinExists("Extracting Files") Then WinSetState("Extracting Files", "", @SW_HIDE) If WinExists($strAppMainWinTitle) Then WinSetState($strNalWinTitle, "", @SW_HIDE) sleep(10) WEnd Func Cancel_Shutdown($hWndGUI, $MsgID, $WParam, $LParam) $b_ShutdownInitiated = True MsgBox(48 + 8192 + 262144, "Installer", "Ending your user session has been disabled to allow the installation to complete." _ & @CRLF & @CRLF & "You will be able to shutdown/reboot/logoff once the installation process has completed." , 8) Return False EndFunc
-
Ahh, I see where the confusion lies: In other words, it knocks out each process as it encounters it, but once it hits a process that returns a zero it leaves that and all subsequent processes alone. This is what's happening in my case - sometimes the WM_QUERYENDSESSION request hits my helper app first (yay), sometimes it hits my main installer first (boo).
-
You may be right - all I know is that it works intermittently. The user session never ends, but sometimes the main installation is killed, sometimes it is not. I can't imagine why that would be the case unless Windows kills an app as soon as it contacts it and does not get an objection. Here's some of my code: GUIRegisterMsg($WM_QUERYENDSESSION, "Cancel_Shutdown") GUICreate("PreventShutdownGUI") GUISetSTate(@SW_HIDE) Global $b_ShutdownInitiated = False While 1 If $b_ShutdownInitiated = True then EndIf sleep(10) WEnd Func Cancel_Shutdown($hWndGUI, $MsgID, $WParam, $LParam) $b_ShutdownInitiated = True MsgBox(48 + 8192 + 262144, "Installer", "Ending your user session has been disabled to allow the installation to complete." _ & @CRLF & @CRLF & "You will be able to shutdown/reboot/logoff once the installation process has completed." , 8) Return False EndFunc
-
I'm pretty sure the case is, as you said, that it sends a request to the applications in the order in which they were started and (barring an objection) shuts them down immediately. That's my challenge - getting my helper app to pony itself into the "shut me down first" position, so that it can kill the request before Windows can squash my desired installation process. Your suggestion is good, but unfortunately the environment I work in will definitely not accommodate starting this app first for the sake of the installation "maybe" hitting during that login session. Any other suggestions?
-
I'm trying to block a user-invoked log-off or shutdown from occurring via an AutoIT script I'm using. The purpose of the block is to keep users from trying to "outsmart" The Man by logging off while a mandatory product update is working / is about to work on their system. This helper app successfully uses WM_QUERYENDSESSION to reject and cancel a shutdown request from the system, but the problem is that I cannot control the order in which Windows tries to shutdown applications. In testing, about 50% of the time the process that is doing the installation I want done is terminated before my little helper app can cancel the shutdown request, which both defeats the purpose of the helper app and also causes problems because now the system cannot (easily) be manually rebooted. My question is twofold: 1) What property of a process (CreationDate, Handle, etc.) does Windows use to determine its termination order when ending a session? 2) Would it be possible to manipulate that property so that Windows tries to kill my helper app first, thus keeping all other processes running? Any help is appreciated. Jeemo
-
/Blows dust off of the post I can't believe nobody else has commented on this. After a decent amount of searching in hopes of not having to code this myself, I came across this post. Unless I missed something, it's the only Date/Time calculation that I could find that converts values in arbitrary formats to the AutoIT format so that functions like DateAdd() will work on your otherwise "incompatible" formats. It's awesome! @seanhart, if you're still around, thanks a lot for this, and great job. The only criticism I have is that I got an error on two lines (28 and 30) for variables being re-declared. Simply commenting out these two lines did the trick, though. Jeemo