nago Posted November 27, 2007 Share Posted November 27, 2007 (edited) Erm, skip down to post #10 if you would Edited December 1, 2007 by nago Link to comment Share on other sites More sharing options...
Bowmore Posted November 27, 2007 Share Posted November 27, 2007 (edited) Hey, I'm new to AutoIt scripting and while I have found a way to accomplish what I was trying to do, I have the sneaking suspicion there is a more efficient way lurking around the corner. I have a GUI I constructed with the Koda window tool (it's very nice!) and I have created a slider called $processpriority_adv which ranges from 0-5. I created a label with a border next to it called $label1, which I intend to use to show what the processpriority slider correlates to. So, at the end of my main GUI loop, I have something like: if GuiCtrlRead($processpriority_adv) = "0" AND GuiCtrlRead($label1) <> "Idle" Then GuiCtrlSetData($label1,"Idle") if GuiCtrlRead($processpriority_adv) = "1" AND GuiCtrlRead($label1) <> "Below Normal" Then GuiCtrlSetData($label1,"Below Normal") if GuiCtrlRead($processpriority_adv) = "2" AND GuiCtrlRead($label1) <> "Normal" Then GuiCtrlSetData($label1,"Normal") if GuiCtrlRead($processpriority_adv) = "3" AND GuiCtrlRead($label1) <> "Above Normal" Then GuiCtrlSetData($label1,"Above Normal") if GuiCtrlRead($processpriority_adv) = "4" AND GuiCtrlRead($label1) <> "High" Then GuiCtrlSetData($label1,"High") if GuiCtrlRead($processpriority_adv) = "5" AND GuiCtrlRead($label1) <> "Realtime" Then GuiCtrlSetData($label1,"Realtime") And this does the trick without flicker, but I was wondering if there was a more intelligent way to do it? I wasn't sure if there was a way to change it 'only if the slider was touched', or something that made more sense. I don't want to settle into bad habits! You've definitely got the right idea by only updating the label when required so you wont get any flicker. The code below may be a more efficient way of doing it for the following reasons. The controls $processpriority_adv and $label1 are only read when the position of the slider has been moved. The values of the two controls are only read once and then checked against the possible values. Global $sLabelValue = '' While 1 Switch GUIGetMsg() Case $processpriority_adv $sLabelValue = GuiCtrlRead($label1) Switch GuiCtrlRead($processpriority_adv) Case "0" If $sLabelValue <> "Idle" Then GuiCtrlSetData($label1,"Idle") Case "1" If $sLabelValue <> "Below Normal" Then GuiCtrlSetData($label1,"Below Normal") Case "2" If $sLabelValue <> "Normal" Then GuiCtrlSetData($label1,"Normal") Case "3" If $sLabelValue <> "Above Normal" Then GuiCtrlSetData($label1,"Above Normal") Case "4" If $sLabelValue <> "High" Then GuiCtrlSetData($label1,"High") Case "5" If $sLabelValue <> "Realtime" Then GuiCtrlSetData($label1,"Realtime") Case Else ; Invalid value do nothing EndSwitch Case Else EndSwitch WEnd Edited: I missed reading the GUIGetMsg() in my original code. Hence my code was running for every message. Edited November 30, 2007 by Bowmore "Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to build bigger and better idiots. So far, the universe is winning."- Rick Cook Link to comment Share on other sites More sharing options...
MrCreatoR Posted November 27, 2007 Share Posted November 27, 2007 You can set variable according to slider position, instead of check and set data every time: $sLabelData = "" Switch GuiCtrlRead($processpriority_adv) Case 0 $sLabelData = "Idle" Case 1 $sLabelData = "Below Normal" Case 2 $sLabelData = "Normal" Case 3 $sLabelData = "Above Normal" Case 4 $sLabelData = "High" Case 5 $sLabelData = "Realtime" EndSwitch If $sLabelData <> "" Then _GuiCtrlSetData($label1, $sLabelData) Func _GUICtrlSetData($CtrlID, $sData, $sDefault="", $iCheck=1) If $iCheck = 0 Or ($iCheck = 1 And GUICtrlRead($CtrlID) <> $sData) Then Return GUICtrlSetData($CtrlID, $sData, $sDefault) Return 0 EndFunc Spoiler Using OS: Win 7 Professional, Using AutoIt Ver(s): 3.3.6.1 / 3.3.8.1 AutoIt Russian Community My Work... Spoiler Projects: ATT - Application Translate Tool {new}| BlockIt - Block files & folders {new}| SIP - Selected Image Preview {new}| SISCABMAN - SciTE Abbreviations Manager {new}| AutoIt Path Switcher | AutoIt Menu for Opera! | YouTube Download Center! | Desktop Icons Restorator | Math Tasks | KeyBoard & Mouse Cleaner | CaptureIt - Capture Images Utility | CheckFileSize ProgramUDFs: OnAutoItErrorRegister - Handle AutoIt critical errors {new}| AutoIt Syntax Highlight {new}| Opera Library! | Winamp Library | GetFolderToMenu | Custom_InputBox()! | _FileRun UDF | _CheckInput() UDF | _GUIInputSetOnlyNumbers() UDF | _FileGetValidName() UDF | _GUICtrlCreateRadioCBox UDF | _GuiCreateGrid() | _PathSplitByRegExp() | _GUICtrlListView_MoveItems - UDF | GUICtrlSetOnHover_UDF! | _ControlTab UDF! | _MouseSetOnEvent() UDF! | _ProcessListEx - UDF | GUICtrl_SetResizing - UDF! | Mod. for _IniString UDFs | _StringStripChars UDF | _ColorIsDarkShade UDF | _ColorConvertValue UDF | _GUICtrlTab_CoverBackground | CUI_App_UDF | _IncludeScripts UDF | _AutoIt3ExecuteCode | _DragList UDF | Mod. for _ListView_Progress | _ListView_SysLink | _GenerateRandomNumbers | _BlockInputEx | _IsPressedEx | OnAutoItExit Handler | _GUICtrlCreateTFLabel UDF | WinControlSetEvent UDF | Mod. for _DirGetSizeEx UDF Examples: ScreenSaver Demo - Matrix included | Gui Drag Without pause the script | _WinAttach()! | Turn Off/On Monitor | ComboBox Handler Example | Mod. for "Thinking Box" | Cool "About" Box | TasksBar Imitation Demo Like the Projects/UDFs/Examples? Please rate the topic (up-right corner of the post header: Rating ) * === My topics === * ================================================== ================================================== AutoIt is simple, subtle, elegant. © AutoIt Team Link to comment Share on other sites More sharing options...
Uten Posted November 27, 2007 Share Posted November 27, 2007 And before you decide what's the fastest solution profile your code! Take a look at the code profile link in my signature. When I wrote it I tested If..ElseIf..., case and switch. At the time switch was way slower than if. But that can have changed by now as the AutoIt developers are tuning bottlenecks when they find the time and intrest.. Please keep your sig. small! Use the help file. Search the forum. Then ask unresolved questions :) Script plugin demo, Simple Trace udf, TrayMenuEx udf, IOChatter demo, freebasic multithreaded dll sample, PostMessage, Aspell, Code profiling Link to comment Share on other sites More sharing options...
nago Posted November 28, 2007 Author Share Posted November 28, 2007 You've definitely got the right idea by only updating the label when required so you wont get any flicker. The code below may be a more efficient way of doing it for the following reasons.The controls $processpriority_adv and $label1 are only read when the position of the slider has been moved.The values of the two controls are only read once and then checked against the possible values.Hi, your approach seems to work well, though I changed the main select/case part to just "if $processpriority_adv then / etc / endif"mostly to see if that would work all the same and it seems to. I find myself more comfortable in the company of "if/then/else/then" over these newfangled switch/select/case dealies My new question is; $processpriority_adv isn't only true when the slider is being touched, is it? I tried testing it out and it seems to evaluate even when it's not being touched... or is my understanding wrong?MSCreator: Thank you for your code too, but I have to admit that I didn't understand it as well as Bowmore's code, so I went with his because I was more familiar with the method... Still a bit fuzzy on this Link to comment Share on other sites More sharing options...
smashly Posted November 28, 2007 Share Posted November 28, 2007 Hi, If MsCreatoR's version bamboozled you then wonder what my effort at a working example will do...lol #include <GuiConstants.au3> Global $OldValue Dim $Value = StringSplit("Idle|Below Normal|Normal|Above Normal|High|Realtime", "|") $Gui = GUICreate(":-)", 170, 80) $Label = GUICtrlCreateLabel("", 5, 5, 160, 20, $SS_CENTER) GUICtrlSetFont(-1, 12, 700) $Slider = GUICtrlCreateSlider(5, 30, 160, 45, $TBS_BOTH) GUICtrlSetLimit(-1, 6, 1) GUICtrlSetData(-1, 1) GUISetState(@SW_SHOW, $Gui) While 1 If GUICtrlRead($Slider) <> $OldValue Then GUICtrlSetData($Label, $Value[GUICtrlRead($Slider)]) $OldValue = GUICtrlRead($Slider) EndIf If GUIGetMsg() = -3 Then ExitLoop WEnd Cheers Link to comment Share on other sites More sharing options...
nago Posted November 30, 2007 Author Share Posted November 30, 2007 (edited) I actually found myself needing to switch over to OnEvent mode, and while I need to worry about re-coding this behaviour as discussed in this thread, I ran into some other problems. I decided not to start a new topic to avoid clutter, but basically I had to switch to OnEvent mode because my window intends to be just an "addon" gui to an existing AU3 script that may be doing other things in the meanwhile; so I figured OnEvent made a better fit for what I was trying to do.. The problem I've run into is that I'm trying to call my little GUI with a hotkey, which seems to work. Currently, I use a function (called by the hotkey) that looks like: Func fKeyIniCfgGui() if not $IniCfgGui Then fCreateIniCfgGui() fShowIniCfgGui() Else fShowIniCfgGui() Endif EndFunc where $IniCfgGui is the handle (is that the right term?) for my window. This seemed to work great when I had my window "close" by using SetGuiState(@SW_HIDE,$IniCfgGui); but I've decided that actually Deleting the entire GUI is a more proper fit for closing the gui, and I've now found that my hotkey function doesn't work as expected anymore. Ultimately, how can I tell if a window exists? Edit: I just realized my code may look a little extraneous if I'm deleting the GUI every time, but I'm trying to prevent launching multiple copies of the window at a time. Edited November 30, 2007 by nago Link to comment Share on other sites More sharing options...
Uten Posted November 30, 2007 Share Posted November 30, 2007 Just a hunch, but do you change the value of $IniCfgGui when you destroy the window? You could also try: Local $gui = GUICreate("TEST") GUISetState(@SW_SHOW, $gui) ConsoleWrite("EXISTS:=" & WinExists($gui) & @CRLF) Exit Happy Scripting.. Please keep your sig. small! Use the help file. Search the forum. Then ask unresolved questions :) Script plugin demo, Simple Trace udf, TrayMenuEx udf, IOChatter demo, freebasic multithreaded dll sample, PostMessage, Aspell, Code profiling Link to comment Share on other sites More sharing options...
nago Posted November 30, 2007 Author Share Posted November 30, 2007 Just a hunch, but do you change the value of $IniCfgGui when you destroy the window?I wasn't changing the value, no. I thought the variable that corresponded to the window itself would be false if the window was destroyed, but that didn't seem to be the case.WinExists though, eh? That's what I'm lookin' fer! Thanks Link to comment Share on other sites More sharing options...
nago Posted December 1, 2007 Author Share Posted December 1, 2007 I was trying to switch my previous attempt at a GUI to using OnEvent mode, since I felt it was a better fit for what I was trying to accomplish than the default messageloop, as the main script should be free to do things while this Gui is open. That said, I have a slider with a ctrlID assigned to $processpriority_adv and a label next to it under $prioritylabel_adv . The general idea is that the user can configure the process priority of the script with the slider, so the slider goes from 0 to 5. The label is for showing what the number of the slider actually corresponds to, so I have two things in place at the moment; 1) In the gui creation function: GuiCtrlSetOnEvent($processpriority_adv,"fProcessSlider") 2) and the corresponding function: Func fProcessSlider() local $sLabelValue = $prioritylabel_adv Switch GuiCtrlRead($processpriority_adv) Case "0" If $sLabelValue <> "Idle" Then GuiCtrlSetData($prioritylabel_adv,"Idle") Case "1" If $sLabelValue <> "Below Normal" Then GuiCtrlSetData($prioritylabel_adv,"Below Normal") Case "2" If $sLabelValue <> "Normal" Then GuiCtrlSetData($prioritylabel_adv,"Normal") Case "3" If $sLabelValue <> "Above Normal" Then GuiCtrlSetData($prioritylabel_adv,"Above Normal") Case "4" If $sLabelValue <> "High" Then GuiCtrlSetData($prioritylabel_adv,"High") Case "5" If $sLabelValue <> "Realtime" Then GuiCtrlSetData($prioritylabel_adv,"Realtime") EndSwitch EndFunc The issue here is that the GuiCtrlSetOnEvent seems to be triggered for the slider only after the slider is RELEASED from the mouseclick, so I can't update the label in realtime, just as a reaction to when the user lets go. Is there either another way to call a loop to change my label that will be called when the slider is first clicked (and ends the loop when it's let go) or a parameter to give to GuiCtrlSetOnEvent to tell it to be a little more proactive? Link to comment Share on other sites More sharing options...
Generator Posted December 1, 2007 Share Posted December 1, 2007 A mini example.. #include <GUIConstants.au3> GUICreate("slider",220,100, 100,200) GUISetBkColor (0x00E0FFFF) ; will change background color $slider1 = GUICtrlCreateSlider (10,10,200,20) GUICtrlSetLimit(-1,200,0) ; change min/max value $button = GUICtrlCreateButton ("Value?",75,70,70,20) GUISetState() GUICtrlSetData($slider1,45) ; set cursor Do $n=GUIGetMsg() $Info=GUIGetCursorInfo() If $Info[4]=$slider1 And $Info[2] Then $Bool=True GUICtrLSetData($button,GUICtrlRead($slider1)) EndIf Until $n = $GUI_EVENT_CLOSE NassauSky 1 Link to comment Share on other sites More sharing options...
nago Posted December 1, 2007 Author Share Posted December 1, 2007 Not to seem ungrateful, but I do really need to keep my GUI using the OnEvent mode instead of MessageLoop; there are other things going on elsewhere in the script that my GUI shouldn't be interrupting. If, as a side effect of needing to run in OnEvent mode I can't update a little label in realtime, that's OK; but I'd really like to know if I can have my cake and eat it too. Thanks, Nago Link to comment Share on other sites More sharing options...
Generator Posted December 1, 2007 Share Posted December 1, 2007 Not to seem ungrateful, but I do really need to keep my GUI using the OnEvent mode instead of MessageLoop; there are other things going on elsewhere in the script that my GUI shouldn't be interrupting. If, as a side effect of needing to run in OnEvent mode I can't update a little label in realtime, that's OK; but I'd really like to know if I can have my cake and eat it too.Thanks, NagoYou can put that in a while loop Link to comment Share on other sites More sharing options...
GaryFrost Posted December 1, 2007 Share Posted December 1, 2007 Far as I know there is only one event for slider control "releasedcapture". The _GUICtrlSlider_Create shows an example of this using the wm_notify event. SciTE for AutoItDirections for Submitting Standard UDFs Don't argue with an idiot; people watching may not be able to tell the difference. Link to comment Share on other sites More sharing options...
nago Posted December 1, 2007 Author Share Posted December 1, 2007 You can put that in a while loopHow do I call that loop, though? I don't want my GUI hogging the spotlight, as the script is going to be doing other things elsewhile... so just creating a loop after the creation of the GUI won't work out for me, I think? Since if it's listening and waiting to hear about the slider, it's not going to be worrying about the rest of the script. Unless I am grossly misunderstanding you, and for that I apologize. Honest.I have a pretty good idea of how to check what the slider's value is and update the label based on that, but what I'm having issue with is when and how to call that function in a way that doesn't tie up my script. Currently I call the function by setting GuiCtrlSetOnEvent($processpriority_adv,"fProcessSlider") in advance, but this merely reacts to the button being released.If there were, say, a way to specify to GuiCtrlSetOnEvent that the event I am linking it to is the button press and not the button release, then I could easily link that to a loop that does what it needs to and just checks to see when the button is released, and when it is, cease the loop. Far as I know there is only one event for slider control "releasedcapture".The _GUICtrlSlider_Create shows an example of this using the wm_notify event.Do you have a link to the relevant docs? I'm really terribly ...erm, Not so bright with AU3 yet. I googled for wm_notify on autoitscript.com and found only one reference to it in the docs under the winmsg list, which I don't really know what to do with...yet.I'm sorry I'm such a newb at this, but believe me that your help is appreciated. Sorry if I'm frustratingly dumb. Link to comment Share on other sites More sharing options...
therks Posted December 1, 2007 Share Posted December 1, 2007 Have a look at this: #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> Opt('GUIOnEventMode', 1) GUICreate('Test', 250, 100) GUISetOnEvent($GUI_EVENT_CLOSE, '_Exit') $label = GUICtrlCreateLabel('', 0, 0, 50, 20) $slider = GUICtrlCreateSlider(50, 0, 200, 20) GUISetState() GUIRegisterMsg($WM_NOTIFY, 'WM_NOTIFY') Do Sleep(100) Until 0 Func WM_NOTIFY($hWnd, $iMsg, $iWParam, $iLParam) Local $iWLoWord = BitAND($iWParam, 0xFFFF) If $iWLoWord = $slider Then GUICtrlSetData($label, GUICtrlRead($slider)) EndIf Return $GUI_RUNDEFMSG EndFunc Func _Exit() Exit EndFunc My AutoIt Stuff | My Github Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now