Author Topic: Variable looping (loop blocks) - how to break the loop?  (Read 10256 times)

0 Members and 1 Guest are viewing this topic.

marcusvdt

  • Sr. Member
  • ****
  • Posts: 152
  • Karma: 6
  • Researching
    • View Profile
Variable looping (loop blocks) - how to break the loop?
« on: August 20, 2015, 04:57:37 PM »
Hi!

I'm creating a command group for Chrome (in fact I used the one that is posted in gems as a base).
I want to have a more consistent treatment as to launching the browser and making sure it is in focus before I start sending commands to it. So I've modified the launch command as below.
Instead of launching the default browser, which creates dependencies of external manual actions (ie I would need to manually set Chrome as my default browser), I wanted to launch the Chrome executable. But then I wanted to confirm it is opened before I go ahead sending the commands for it to browse to a web site.
I supposed the loop block would fit perfectly for my needs since I could keep looping until Chrome is in focus and then follow the remaining actions (check the commands attached for more details).
As per the wiki, loops blocks can't have logic blocks inside, so I thought I could have an event that would trigger a command that would set j variable to a value greater than the one set in the loop, hence breaking the loop block.

On my tests I can't get the above to work, probably because more than one characteristics of how the logic blocks have been designed. I'm not questioning this, or asking to change anything, but perhaps some of you guys can suggest a way of doing the consistency I'm trying to do.

So could you please take a look on that and eventually suggest something else that would achieve the same result?

Thanks in advance.

Code: [Select]
<?xml version="1.0" encoding="utf-16"?>
<!--VoxCommando 2.2.0.7-->
<command id="678" name="open url with payload" enabled="true" alwaysOn="False" confirm="False" requiredConfidence="0" loop="False" loopDelay="0" loopMax="0" description="">
  <if ifBlockDisabled="False" ifNot="True">
    <ifType>ProcessRunning</ifType>
    <ifParams>chrome&amp;&amp;</ifParams>
    <then>
      <action>
        <cmdType>Launch.RawParam</cmdType>
        <params>
          <param>{Path.PFx86}\Google\Chrome\Application\chrome.exe</param>
        </params>
        <cmdRepeat>1</cmdRepeat>
      </action>
      <action>
        <cmdType>TTS.SpeakSync</cmdType>
        <params>
          <param>Opening Chrome</param>
        </params>
        <cmdRepeat>1</cmdRepeat>
      </action>
    </then>
    <else />
  </if>
  <loop>
    <loopParams>
      <from>1</from>
      <to>30</to>
    </loopParams>
    <loopActions>
      <action>
        <cmdType>OSD.ShowText</cmdType>
        <params>
          <param>Waiting for Chrome: {j}/30 seconds</param>
          <param>1000</param>
          <param>1</param>
        </params>
        <cmdRepeat>1</cmdRepeat>
      </action>
      <action>
        <cmdType>VC.Pause</cmdType>
        <params>
          <param>500</param>
        </params>
        <cmdRepeat>1</cmdRepeat>
      </action>
      <action>
        <cmdType>Window.Focus</cmdType>
        <params>
          <param>chrome</param>
        </params>
        <cmdRepeat>1</cmdRepeat>
      </action>
      <action>
        <cmdType>VC.Pause</cmdType>
        <params>
          <param>500</param>
        </params>
        <cmdRepeat>1</cmdRepeat>
      </action>
    </loopActions>
  </loop>
  <if ifBlockDisabled="False" ifNot="False">
    <ifType>ProcessRunning</ifType>
    <ifParams>chrome&amp;&amp;</ifParams>
    <then>
      <action>
        <cmdType>Window.Focus</cmdType>
        <params>
          <param>chrome</param>
        </params>
        <cmdRepeat>1</cmdRepeat>
      </action>
      <action>
        <cmdType>VC.Pause</cmdType>
        <params>
          <param>5</param>
        </params>
        <cmdRepeat>1</cmdRepeat>
      </action>
      <action>
        <cmdType>SendKeys</cmdType>
        <params>
          <param>^l</param>
        </params>
        <cmdRepeat>1</cmdRepeat>
      </action>
      <action>
        <cmdType>VC.Pause</cmdType>
        <params>
          <param>5</param>
        </params>
        <cmdRepeat>1</cmdRepeat>
      </action>
      <action>
        <cmdType>DxInput.Type</cmdType>
        <params>
          <param>{1}{RETURN}</param>
        </params>
        <cmdRepeat>1</cmdRepeat>
      </action>
      <action>
        <cmdType>OSD.ShowText</cmdType>
        <params>
          <param>{1}</param>
        </params>
        <cmdRepeat>1</cmdRepeat>
      </action>
      <action>
        <cmdType>TTS.Speak</cmdType>
        <params>
          <param>Browsing to {PF.1}</param>
        </params>
        <cmdRepeat>1</cmdRepeat>
      </action>
    </then>
    <else>
      <action>
        <cmdType>TTS.Speak</cmdType>
        <params>
          <param>I couldn't open Chrome</param>
        </params>
        <cmdRepeat>1</cmdRepeat>
      </action>
      <action>
        <cmdType>OSD.ShowText</cmdType>
        <params>
          <param>I couldn't open Chrome</param>
          <param>2000</param>
          <param>1</param>
        </params>
        <cmdRepeat>1</cmdRepeat>
      </action>
    </else>
  </if>
  <phrase>open site</phrase>
  <payloadFromXML phraseOnly="False" use2partPhrase="False" phraseConnector="by" Phrase2wildcard="anyone" optional="False">payloads\url.xml</payloadFromXML>
</command>


marcusvdt

  • Sr. Member
  • ****
  • Posts: 152
  • Karma: 6
  • Researching
    • View Profile
Re: Variable looping (loop blocks) - how to break the loop?
« Reply #1 on: August 20, 2015, 04:58:25 PM »
This is the command that I expected to set j variable to a value that would break the loop block above. Unfortunatelly the event appears only after the loop block has finished.
Code: [Select]
<?xml version="1.0" encoding="utf-16"?>
<!--VoxCommando 2.2.0.7-->
<command id="702" name="Chrome já em foco" enabled="true" alwaysOn="False" confirm="False" requiredConfidence="0" loop="False" loopDelay="0" loopMax="0" description="This should stop the loop on the other command.">
  <action>
    <cmdType>Results.SetVar</cmdType>
    <params>
      <param>j</param>
      <param>31</param>
    </params>
    <cmdRepeat>1</cmdRepeat>
  </action>
  <event>Focused.chrome</event>
</command>


marcusvdt

  • Sr. Member
  • ****
  • Posts: 152
  • Karma: 6
  • Researching
    • View Profile
Re: Variable looping (loop blocks) - how to break the loop?
« Reply #2 on: August 20, 2015, 04:59:33 PM »
Output. I'm confused with the sequence the things appear in the log. Chrome was already opened and in focus since loop iteration 3, but then lost the focus and in the end of the macro it was not in focus anymore. The event Focused.chrome appeared only near the end of the sequence.

PegLegTV

  • $upporter
  • Hero Member
  • *****
  • Posts: 500
  • Karma: 43
    • View Profile
Re: Variable looping (loop blocks) - how to break the loop?
« Reply #3 on: August 20, 2015, 05:52:20 PM »
Quote
This is the command that I expected to set j variable to a value that would break the loop block above. Unfortunatelly the event appears only after the loop block has finished.

with program variables such as {j} {i} {#M} and so on, can not be set, at least not in a way that I know of, when your are using
Code: [Select]
Results.SetVar j 30 then in order to use that variable you would have to call it using {Var.j} which the looping block can not see,

heres your command with OSD showing what I mean,
Code: [Select]
<?xml version="1.0" encoding="utf-16"?>
<!--VoxCommando 2.2.0.7-->
<command id="702" name="Chrome já em foco" enabled="true" alwaysOn="False" confirm="False" requiredConfidence="0" loop="False" loopDelay="0" loopMax="0" description="This should stop the loop on the other command.">
  <action>
    <cmdType>Results.SetVar</cmdType>
    <params>
      <param>j</param>
      <param>31</param>
    </params>
    <cmdRepeat>1</cmdRepeat>
  </action>
  <action>
    <cmdType>OSD.ShowText</cmdType>
    <params>
      <param>program variable j = {j}</param>
    </params>
    <cmdRepeat>1</cmdRepeat>
  </action>
  <action>
    <cmdType>OSD.AddText</cmdType>
    <params>
      <param>Results.SetVar variable j = {Var.j}</param>
    </params>
    <cmdRepeat>1</cmdRepeat>
  </action>
  <event>Focused.chrome</event>
</command>


looking at your first command, it seems to just count down for 30 seconds before moving on, it sounds like your are trying to get it to stop counting down once the window is focused correct?

Kalle

  • $upporter
  • Hero Member
  • *****
  • Posts: 2319
  • Karma: 47
    • View Profile
Re: Variable looping (loop blocks) - how to break the loop?
« Reply #4 on: August 20, 2015, 07:39:56 PM »
wow, hard stuff to open a website  ::bugeyes


Why did you not use the command line parameter with the launch action?

eample code:

Code: [Select]
<?xml version="1.0" encoding="utf-16"?>
<!--VoxCommando 2.1.5.1-->
<command id="688" name="open url with payload" enabled="true" alwaysOn="False" confirm="False" requiredConfidence="0" loop="False" loopDelay="0" loopMax="0" description="">
  <action>
    <cmdType>Launch.RawParam</cmdType>
    <params>
      <param>{Path.PFx86}\AppData\Local\Google\Chrome\Application\chrome.exe</param>
      <param>{1}</param>
    </params>
    <cmdRepeat>1</cmdRepeat>
  </action>
  <action>
    <cmdType>TTS.Speak</cmdType>
    <params>
      <param>opening {PF.1}</param>
    </params>
    <cmdRepeat>1</cmdRepeat>
  </action>
  <action>
    <cmdType>OSD.ShowText</cmdType>
    <params>
      <param>opening {PF.1}</param>
    </params>
    <cmdRepeat>1</cmdRepeat>
  </action>
  <phrase>open site</phrase>
  <payloadFromXML phraseOnly="False" use2partPhrase="False" phraseConnector="by" Phrase2wildcard="anyone" optional="False">payloads\url.xml</payloadFromXML>
</command>


I think this is even better  ;)
« Last Edit: August 20, 2015, 07:42:00 PM by Kalle »
***********  get excited and make things  **********

marcusvdt

  • Sr. Member
  • ****
  • Posts: 152
  • Karma: 6
  • Researching
    • View Profile
Re: Variable looping (loop blocks) - how to break the loop?
« Reply #5 on: August 21, 2015, 12:04:31 AM »
wow, hard stuff to open a website  ::bugeyes


Why did you not use the command line parameter with the launch action?

eample code:

Code: [Select]
<?xml version="1.0" encoding="utf-16"?>
<!--VoxCommando 2.1.5.1-->
<command id="688" name="open url with payload" enabled="true" alwaysOn="False" confirm="False" requiredConfidence="0" loop="False" loopDelay="0" loopMax="0" description="">
  <action>
    <cmdType>Launch.RawParam</cmdType>
    <params>
      <param>{Path.PFx86}\AppData\Local\Google\Chrome\Application\chrome.exe</param>
      <param>{1}</param>
    </params>
    <cmdRepeat>1</cmdRepeat>
  </action>
  <action>
    <cmdType>TTS.Speak</cmdType>
    <params>
      <param>opening {PF.1}</param>
    </params>
    <cmdRepeat>1</cmdRepeat>
  </action>
  <action>
    <cmdType>OSD.ShowText</cmdType>
    <params>
      <param>opening {PF.1}</param>
    </params>
    <cmdRepeat>1</cmdRepeat>
  </action>
  <phrase>open site</phrase>
  <payloadFromXML phraseOnly="False" use2partPhrase="False" phraseConnector="by" Phrase2wildcard="anyone" optional="False">payloads\url.xml</payloadFromXML>
</command>


I think this is even better  ;)
thanks, yes that's better,  but still does not guarantee that chrome is in focus. If another software takes the focus from chrome,  then the remaining actions could be sent to another window. In some cases I'll be using the same type of commands for things not so simple as opening a Web page, hence the reason for developing a method in which I can trust to make sure what is the window I'm sending the keyboard actions to.  By the way, the window.focus action did not work for chrome anyway (using windows 8.1 and latest version of Chrome).
I'd like to avoid having to use an external script for this purpose.

marcusvdt

  • Sr. Member
  • ****
  • Posts: 152
  • Karma: 6
  • Researching
    • View Profile
Re: Variable looping (loop blocks) - how to break the loop?
« Reply #6 on: August 21, 2015, 12:19:42 AM »
with program variables such as {j} {i} {#M} and so on, can not be set, at least not in a way that I know of, when your are using
Code: [Select]
Results.SetVar j 30 then in order to use that variable you would have to call it using {Var.j} which the looping block can not see,

heres your command with OSD showing what I mean,
Code: [Select]
<?xml version="1.0" encoding="utf-16"?>
<!--VoxCommando 2.2.0.7-->
<command id="702" name="Chrome já em foco" enabled="true" alwaysOn="False" confirm="False" requiredConfidence="0" loop="False" loopDelay="0" loopMax="0" description="This should stop the loop on the other command.">
  <action>
    <cmdType>Results.SetVar</cmdType>
    <params>
      <param>j</param>
      <param>31</param>
    </params>
    <cmdRepeat>1</cmdRepeat>
  </action>
  <action>
    <cmdType>OSD.ShowText</cmdType>
    <params>
      <param>program variable j = {j}</param>
    </params>
    <cmdRepeat>1</cmdRepeat>
  </action>
  <action>
    <cmdType>OSD.AddText</cmdType>
    <params>
      <param>Results.SetVar variable j = {Var.j}</param>
    </params>
    <cmdRepeat>1</cmdRepeat>
  </action>
  <event>Focused.chrome</event>
</command>
I guess I can not assign a value to the j variable that is used on the for loop enen if I try to do that inside the loop. It seems I can only read it. Will test it tomorrow, but if I'm right,  then I don't see any way of breaking the loop.

Quote
looking at your first command, it seems to just count down for 30 seconds before moving on, it sounds like your are trying to get it to stop counting down once the window is focused correct?
yes, exactly. As per what I see on the log, it can't be done since an event never gets registered while the loop is running. Instead, I guess any events that occur while the loop is running will be queued and processed only after the loop finishes.

I think I will have to try something else tomorrow.

Thanks.

PegLegTV

  • $upporter
  • Hero Member
  • *****
  • Posts: 500
  • Karma: 43
    • View Profile
Re: Variable looping (loop blocks) - how to break the loop?
« Reply #7 on: August 21, 2015, 01:06:48 AM »
maybe you can create your own loop by using VC.SetEventTimer with a 3s wait, and then have another command check focus of chrome

IF Focused then send the actions,
IF Not then trigger VC.SetEventTimer,

I would be carefull doing to short of a wait as it can cause VC to get stuck in a loop,  :bigno

Simple Example:
Code: [Select]
<?xml version="1.0" encoding="utf-16"?>
<!--VoxCommando 2.2.0.7-->
<commandGroup open="True" name="Chrome focus" enabled="True" prefix="" priority="0" requiredProcess="" description="">
  <command id="734" name="make sure chrome is open then execute me" enabled="true" alwaysOn="False" confirm="False" requiredConfidence="0" loop="False" loopDelay="0" loopMax="0" description="">
    <action>
      <cmdType>VC.SetEventTimer</cmdType>
      <params>
        <param>3s</param>
        <param>Chrome Test</param>
      </params>
      <cmdRepeat>1</cmdRepeat>
    </action>
  </command>
  <command id="742" name="Chrome focus test" enabled="true" alwaysOn="False" confirm="False" requiredConfidence="0" loop="False" loopDelay="0" loopMax="0" description="">
    <if ifBlockDisabled="False" ifNot="False">
      <ifType>ProgramFocused</ifType>
      <ifParams>chrome&amp;&amp;</ifParams>
      <then>
        <action>
          <cmdType>OSD.ShowText</cmdType>
          <params>
            <param>Chrome is now Focused</param>
          </params>
          <cmdRepeat>1</cmdRepeat>
        </action>
      </then>
      <else>
        <action>
          <cmdType>Window.Focus</cmdType>
          <params>
            <param>chrome</param>
          </params>
          <cmdRepeat>1</cmdRepeat>
        </action>
        <action>
          <cmdType>VC.SetEventTimer</cmdType>
          <params>
            <param>3s</param>
            <param>Chrome Test</param>
          </params>
          <cmdRepeat>1</cmdRepeat>
        </action>
      </else>
    </if>
    <event>Chrome Test</event>
  </command>
</commandGroup>

Quote
By the way, the window.focus action did not work for chrome anyway (using windows 8.1 and latest version of Chrome).
I'd like to avoid having to use an external script for this purpose.

I tested Window.Focus chrome (all lower case letters) on windows 8.1 and it worked for me every time, I did notice that using kalle's method for me focused Chrome every time, however it does open a new tab when I open another URL, not sure if that would cause problems with what you are doing


« Last Edit: December 29, 2015, 12:55:20 AM by PegLegTV »

Kalle

  • $upporter
  • Hero Member
  • *****
  • Posts: 2319
  • Karma: 47
    • View Profile
Re: Variable looping (loop blocks) - how to break the loop?
« Reply #8 on: August 21, 2015, 05:49:25 AM »
I can confirm, my method focused Chrome every time.
***********  get excited and make things  **********

marcusvdt

  • Sr. Member
  • ****
  • Posts: 152
  • Karma: 6
  • Researching
    • View Profile
Re: Variable looping (loop blocks) - how to break the loop?
« Reply #9 on: August 21, 2015, 10:51:44 AM »
Thanks guys!
I ended up with a command that can be used for confirming any program is in focus. You pass the the process name and the max # of loops in payloads. Now works like a charm!
For automating critical applications it is essential that the focus is reinforced and confirmed at every command. Windows applications sometime get the focus (ie anti virus update dialog pops up in the screen), so confirming the focus before sending commands to a window is desirable.

Thanks for the ideas! This is exactly the help that I was looking for! You rock big time!


Code: [Select]
<?xml version="1.0" encoding="utf-16"?>
<!--VoxCommando 2.2.0.7-->
<groupCollection open="True" name="Share">
  <commandGroup open="True" name="Launch Chrome" enabled="True" prefix="" priority="0" requiredProcess="" description="">
    <command id="733" name="open url with payload" enabled="true" alwaysOn="False" confirm="False" requiredConfidence="0" loop="False" loopDelay="0" loopMax="0" description="">
      <if ifBlockDisabled="False" ifNot="True">
        <ifType>ProcessRunning</ifType>
        <ifParams>chrome&amp;&amp;</ifParams>
        <then>
          <action>
            <cmdType>Launch.RawParam</cmdType>
            <params>
              <param>{Path.PFx86}\Google\Chrome\Application\chrome.exe</param>
              <param>{1}</param>
            </params>
            <cmdRepeat>1</cmdRepeat>
          </action>
          <action>
            <cmdType>TTS.SpeakSync</cmdType>
            <params>
              <param>Launching Chrome</param>
            </params>
            <cmdRepeat>1</cmdRepeat>
          </action>
          <action>
            <cmdType>VC.Pause</cmdType>
            <params>
              <param>500</param>
            </params>
            <cmdRepeat>1</cmdRepeat>
          </action>
        </then>
        <else />
      </if>
      <if ifBlockDisabled="False" ifNot="False">
        <ifType>ProcessRunning</ifType>
        <ifParams>chrome&amp;&amp;</ifParams>
        <then>
          <action>
            <cmdType>Results.SetVar</cmdType>
            <params>
              <param>loopsfocus</param>
              <param>0</param>
            </params>
            <cmdRepeat>1</cmdRepeat>
          </action>
          <action>
            <cmdType>VC.SetEventTimer</cmdType>
            <params>
              <param>2s</param>
              <param>FocusTest</param>
              <param>chrome</param>
              <param>10</param>
            </params>
            <cmdRepeat>1</cmdRepeat>
          </action>
          <action>
            <cmdType>OSD.ShowText</cmdType>
            <params>
              <param>{1}</param>
            </params>
            <cmdRepeat>1</cmdRepeat>
          </action>
          <action>
            <cmdType>TTS.Speak</cmdType>
            <params>
              <param>Browsing to {PF.1}</param>
            </params>
            <cmdRepeat>1</cmdRepeat>
          </action>
        </then>
        <else>
          <action>
            <cmdType>TTS.Speak</cmdType>
            <params>
              <param>I couldn't open Chrome</param>
            </params>
            <cmdRepeat>1</cmdRepeat>
          </action>
          <action>
            <cmdType>OSD.ShowText</cmdType>
            <params>
              <param>I couldn't open Chrome</param>
              <param>2000</param>
              <param>1</param>
            </params>
            <cmdRepeat>1</cmdRepeat>
          </action>
        </else>
      </if>
      <phrase>abrir site</phrase>
      <payloadFromXML phraseOnly="False" use2partPhrase="False" phraseConnector="by" Phrase2wildcard="anyone" optional="False">payloads\url.xml</payloadFromXML>
    </command>
  </commandGroup>
  <commandGroup open="True" name="Generic focus confirmation" enabled="True" prefix="" priority="0" requiredProcess="" description="">
    <command id="761" name="{1} focus test" enabled="true" alwaysOn="False" confirm="False" requiredConfidence="0" loop="False" loopDelay="0" loopMax="0" description="">
      <if ifBlockDisabled="False" ifNot="False">
        <ifType>(A)Contains(B)</ifType>
        <ifParams>{1}&amp;&amp;{1</ifParams>
        <then>
          <action>
            <cmdType>OSD.ShowText</cmdType>
            <params>
              <param>Can't check focus. Wrong use of my logics!</param>
            </params>
            <cmdRepeat>1</cmdRepeat>
          </action>
          <action>
            <cmdType>VC.StopMacro</cmdType>
            <params />
            <cmdRepeat>1</cmdRepeat>
          </action>
        </then>
        <else />
      </if>
      <if ifBlockDisabled="False" ifNot="False">
        <ifType>(A)Contains(B)</ifType>
        <ifParams>{2}&amp;&amp;{2</ifParams>
        <then>
          <action>
            <cmdType>OSD.ShowText</cmdType>
            <params>
              <param>Can't check focus. Wrong use of my logics!</param>
            </params>
            <cmdRepeat>1</cmdRepeat>
          </action>
          <action>
            <cmdType>VC.StopMacro</cmdType>
            <params />
            <cmdRepeat>1</cmdRepeat>
          </action>
        </then>
        <else />
      </if>
      <if ifBlockDisabled="False" ifNot="False">
        <ifType>ProgramFocused</ifType>
        <ifParams>{1}&amp;&amp;</ifParams>
        <then>
          <action>
            <cmdType>VC.StopEventTimer</cmdType>
            <params>
              <param>FocusTest</param>
            </params>
            <cmdRepeat>1</cmdRepeat>
          </action>
          <action>
            <cmdType>OSD.ShowText</cmdType>
            <params>
              <param>{1} is now focused</param>
            </params>
            <cmdRepeat>1</cmdRepeat>
          </action>
          <action>
            <cmdType>VC.TriggerEvent</cmdType>
            <params>
              <param>FocusConfirmed</param>
              <param>{1}</param>
            </params>
            <cmdRepeat>1</cmdRepeat>
          </action>
          <action>
            <cmdType>VC.StopMacro</cmdType>
            <params />
            <cmdRepeat>1</cmdRepeat>
          </action>
        </then>
        <else>
          <action>
            <cmdType>Window.Focus</cmdType>
            <params>
              <param>{1}</param>
            </params>
            <cmdRepeat>1</cmdRepeat>
          </action>
          <action>
            <cmdType>VC.StopEventTimer</cmdType>
            <params>
              <param>FocusTest</param>
            </params>
            <cmdRepeat>1</cmdRepeat>
          </action>
          <action>
            <cmdType>VC.SetEventTimer</cmdType>
            <params>
              <param>2s</param>
              <param>FocusTest</param>
              <param>{1}</param>
              <param>{2}</param>
            </params>
            <cmdRepeat>1</cmdRepeat>
          </action>
          <action>
            <cmdType>PY.ExecString</cmdType>
            <params>
              <param>result={Var.loopsfocus}+1</param>
            </params>
            <cmdRepeat>1</cmdRepeat>
          </action>
          <action>
            <cmdType>Results.SetVar</cmdType>
            <params>
              <param>loopsfocus</param>
              <param>{LastResult}</param>
            </params>
            <cmdRepeat>1</cmdRepeat>
          </action>
        </else>
      </if>
      <if ifBlockDisabled="False" ifNot="True">
        <ifType>(A)&lt;(B)</ifType>
        <ifParams>{Var.loopsfocus}&amp;&amp;{2}</ifParams>
        <then>
          <action>
            <cmdType>VC.StopEventTimer</cmdType>
            <params>
              <param>FocusTest</param>
            </params>
            <cmdRepeat>1</cmdRepeat>
          </action>
          <action>
            <cmdType>TTS.Speak</cmdType>
            <params>
              <param>I couldn't get {1} in focus, so stopping here.</param>
            </params>
            <cmdRepeat>1</cmdRepeat>
          </action>
        </then>
        <else />
      </if>
      <event>FocusTest</event>
    </command>
  </commandGroup>
</groupCollection>

jitterjames

  • Administrator
  • Hero Member
  • *****
  • Posts: 7715
  • Karma: 116
    • View Profile
    • VoxCommando
Re: Variable looping (loop blocks) - how to break the loop?
« Reply #10 on: August 21, 2015, 05:42:48 PM »
I've never had a need for such a command but I'm glad you found something that works for you. 
I can suggest one very minor improvement you could make to improve flexibility.

You are using {2} to pass a counter with your event and stopping after 20 iterations.

Instead of starting at 1, incrementing by 1 each time and stopping at 20, you could start by passing the maximum number of times you want to repeat, decrementing by 1 each time and stopping at 0.  That way you could initiate the events using different max repeats for different programs that you are trying to focus.  I don't know if this helps you or not, but maybe...

marcusvdt

  • Sr. Member
  • ****
  • Posts: 152
  • Karma: 6
  • Researching
    • View Profile
Re: Variable looping (loop blocks) - how to break the loop?
« Reply #11 on: August 21, 2015, 05:54:44 PM »
Thanks for the tip James. That is what it does. I pass the name of the process and the max number of loops that it can do. The max number of loops reflects half the delay between each loop, in seconds.
If the desired window gets in focus before the max loops has occurred, then I tell the user the program is in focus. If the max number of loops is achieved,  then a timeout has occured and the user is told.
hopefully we are talking the same thing,  but I am increasing the var while you thought about decreasing it?

jitterjames

  • Administrator
  • Hero Member
  • *****
  • Posts: 7715
  • Karma: 116
    • View Profile
    • VoxCommando
Re: Variable looping (loop blocks) - how to break the loop?
« Reply #12 on: August 21, 2015, 06:23:53 PM »
I see now what you are doing.  I did not realise you were creating a variable as well.

What I was proposing would still be better though for two reasons.

1 - no variable is needed.
2 - as a result, you don't need to worry about two of these commands executing at the same time and interfering with each other because of a shared global variable.

marcusvdt

  • Sr. Member
  • ****
  • Posts: 152
  • Karma: 6
  • Researching
    • View Profile
Re: Variable looping (loop blocks) - how to break the loop?
« Reply #13 on: August 21, 2015, 06:56:32 PM »
Yeah, I like the idea of not having the need for the variable. I was already considering an eventual situation where two of the same command would cause problems with that variable. Would you mind posting an example of what you proposed?
I'm not in the computer now, but I will be testing this as soon as possible.

Thanks.

jitterjames

  • Administrator
  • Hero Member
  • *****
  • Posts: 7715
  • Karma: 116
    • View Profile
    • VoxCommando
Re: Variable looping (loop blocks) - how to break the loop?
« Reply #14 on: August 21, 2015, 10:08:23 PM »
OK.  I think you could have figured this out quite easily yourself but here it is anyway. It has been a while since I wrote a command in VC so I enjoyed it. :D

This is just the command that is triggered by the event.  You should not need to modify the other command.

Code: [Select]
<?xml version="1.0" encoding="utf-16"?>
<!--VoxCommando 2.2.0.7-->
<command id="761" name="{1} focus test" enabled="true" alwaysOn="False" confirm="False" requiredConfidence="0" loop="False" loopDelay="0" loopMax="0" description="">
  <if ifBlockDisabled="False" ifNot="False">
    <ifType>(A)Contains(B)</ifType>
    <ifParams>{1}{2}&amp;&amp;{</ifParams>
    <then>
      <action>
        <cmdType>OSD.ShowText</cmdType>
        <params>
          <param>Can't check focus. Wrong use of my logics!</param>
        </params>
        <cmdRepeat>1</cmdRepeat>
      </action>
      <action>
        <cmdType>VC.StopMacro</cmdType>
        <params />
        <cmdRepeat>1</cmdRepeat>
      </action>
    </then>
    <else />
  </if>
  <if ifBlockDisabled="False" ifNot="False">
    <ifType>ProgramFocused</ifType>
    <ifParams>{1}&amp;&amp;</ifParams>
    <then>
      <action>
        <cmdType>OSD.ShowText</cmdType>
        <params>
          <param>{1} is now focused</param>
        </params>
        <cmdRepeat>1</cmdRepeat>
      </action>
      <action>
        <cmdType>VC.TriggerEvent</cmdType>
        <params>
          <param>FocusConfirmed</param>
          <param>{1}</param>
        </params>
        <cmdRepeat>1</cmdRepeat>
      </action>
      <action>
        <cmdType>VC.StopMacro</cmdType>
        <params />
        <cmdRepeat>1</cmdRepeat>
      </action>
    </then>
    <else>
      <action>
        <cmdType>Window.Focus</cmdType>
        <params>
          <param>{1}</param>
        </params>
        <cmdRepeat>1</cmdRepeat>
      </action>
      <action>
        <cmdType>PY.ExecString</cmdType>
        <params>
          <param>result={2}-1</param>
        </params>
        <cmdRepeat>1</cmdRepeat>
      </action>
    </else>
  </if>
  <if ifBlockDisabled="False" ifNot="False">
    <ifType>(A)&lt;(B)</ifType>
    <ifParams>{LastResult}&amp;&amp;1</ifParams>
    <then>
      <action>
        <cmdType>TTS.Speak</cmdType>
        <params>
          <param>I couldn't get {1} in focus, so stopping here.</param>
        </params>
        <cmdRepeat>1</cmdRepeat>
      </action>
    </then>
    <else>
      <action>
        <cmdType>VC.SetEventTimer</cmdType>
        <params>
          <param>2s</param>
          <param>FocusTest</param>
          <param>{1}</param>
          <param>{LastResult}</param>
        </params>
        <cmdRepeat>1</cmdRepeat>
      </action>
    </else>
  </if>
  <event>FocusTest</event>
</command>

marcusvdt

  • Sr. Member
  • ****
  • Posts: 152
  • Karma: 6
  • Researching
    • View Profile
Re: Variable looping (loop blocks) - how to break the loop?
« Reply #15 on: August 21, 2015, 10:35:54 PM »
True! Now it is obvious!
I'll try it when I get to my computer. Now I am in the phone.

Thank you.
btw this is one of the reasons VC is so good, you still enjoy it!

Haddood

  • $upporter
  • Hero Member
  • *****
  • Posts: 688
  • Karma: 22
    • View Profile
Re: Variable looping (loop blocks) - how to break the loop?
« Reply #16 on: August 22, 2015, 04:56:15 PM »

this comment might be very dumb ....
referring to the first post, I the the issue has 2 tiers....

first: make sure a process is launched and running ...
this I handle by setting a timer that trigger the same command again ... the command start with an if process running, ture: trigger set focus ... false: trigger timer again (I usually put a kill timer before the if, just in case)

Second: I will just use use window.focus ... then do everything I want ... it has been working like a charm since timers were introduced ...
When Voice command gets tough, use hand gestures

marcusvdt

  • Sr. Member
  • ****
  • Posts: 152
  • Karma: 6
  • Researching
    • View Profile
Re: Variable looping (loop blocks) - how to break the loop?
« Reply #17 on: August 22, 2015, 07:31:32 PM »

In the beginning of the video I show how my last command works with the enhancement proposed by James. Thanks everybody!
But then, in the end of the video I show a weird behavior with window.focus. This is the problem that I noticed accidentally and have mentioned earlier in this thread. Am I doing anything wrong?

https://youtu.be/WUOzp_8vcG8

PegLegTV

  • $upporter
  • Hero Member
  • *****
  • Posts: 500
  • Karma: 43
    • View Profile
Re: Variable looping (loop blocks) - how to break the loop?
« Reply #18 on: August 22, 2015, 11:23:55 PM »
when I use Window.focus on Chrome and Firefox it works with both and both actions are slightly greyed out in the history window,
as I said before chrome on my W8.1 PC works just fine and also works on my W7 PC, I wonder if its due to the fact that chrome runs multiple different processes so its trying to focus a hidden window,

back when I used NetfliXBMC I had problems finding the right chrome window to close using eventghost even though there was only one window open it would show 3 different windows, so maybe VC isn't focusing the right chrome window,

I tried using different window.focus such as "chrome.exe", "google chrome" and tried them capitalized but those didn't work for me, I'm not sure what may be stopping yours from working, is chrome the only window that its having trouble focusing?

marcusvdt

  • Sr. Member
  • ****
  • Posts: 152
  • Karma: 6
  • Researching
    • View Profile
Re: Variable looping (loop blocks) - how to break the loop?
« Reply #19 on: August 23, 2015, 12:02:39 AM »
I only noticed that behavior with chrome and I also believe in the same cause that you mentioned. The scripting language I'm used to program, autoit, needs the actual name of a window, ie "Untitled - Notepad" for notepad, so it can attach to such window. Actually it allows for other few things to match to a window, but none of the standard ways use the process name as James uses in VC. Then with autoit it is still possible to use other ways to enumerate all the available windows pertaining to a process and then one can attach to one of those windows.
Long story short, I'm mentioning autoit only because I suppose VC can have the same difficulty to attach to the correct window. What I used to do in autoit is to attach using what is more likely to result in the right window to be selected. But it depends on the target program.

« Last Edit: August 23, 2015, 12:06:13 AM by marcusvdt »

PegLegTV

  • $upporter
  • Hero Member
  • *****
  • Posts: 500
  • Karma: 43
    • View Profile
Re: Variable looping (loop blocks) - how to break the loop?
« Reply #20 on: August 23, 2015, 12:29:17 AM »
I've never used autoit but I have heard that its similar to AutoHotKey, and from what you just described it sounds like it is,

I know this wouldn't be the best solution but maybe instead of using Window.focus you could use autoit or AutoHotKey script to call focus to Chrome and other windows by using the cmd line parameters and just passing the window name you want to focus maybe something like this,

(for this to work you will need to install Autohotkey)
Code: [Select]
<?xml version="1.0" encoding="utf-16"?>
<!--VoxCommando 2.2.0.7-->
<command id="1299" name="Find Window AHK" enabled="true" alwaysOn="False" confirm="False" requiredConfidence="0" loop="False" loopDelay="0" loopMax="0" description="">
  <action>
    <cmdType>Launch.Hidden</cmdType>
    <params>
      <param>find window.ahk</param>
      <param>chrome</param>
    </params>
    <cmdRepeat>1</cmdRepeat>
  </action>
  <action>
    <cmdType>Launch.Hidden</cmdType>
    <params>
      <param>find window.ahk</param>
      <param>XBMC</param>
    </params>
    <cmdRepeat>0</cmdRepeat>
  </action>
</command>

place "find window.ahk" in your VC folder

marcusvdt

  • Sr. Member
  • ****
  • Posts: 152
  • Karma: 6
  • Researching
    • View Profile
Re: Variable looping (loop blocks) - how to break the loop?
« Reply #21 on: August 23, 2015, 01:34:09 AM »
Thanks PegLegTV. While I was recording this video and writing this post, you posted a response which seems to have the same purpose of what I just made. Take a look below...

This is some of the data about the chrome window which I use in my video. In autoit, I can use a combination of any of these parameters below to make sure I'm attaching to the right window:
Title:   Google - Google Chrome
Class:   Chrome_WidgetWin_1
>>>> Visible Text <<<<
Chrome Legacy Window

The video below shows how VC's method is failing and confirming the reason is probably the existence of more than one process for chrome. Btw, the wiki mentions it can fail and I'm sure James already knows the exact situations where it can fail. I'm not complaining at all.

The video also shows how I can solve that situation with external scripting, but wouldn't like to go that path because it makes the stuff more complicated because then I would need to make my script to talk with VC and vice versa. Probably will not justify the effort. Also will need to keep track of external source code, etc, etc...
The interesting thing is that both VC and autoit scripting are using some windows api to get control of windows, so maybe James can find a way to implement different matching techniques? If not, that's fine anyway as I can workaround it with scripts as shown in the video.

https://youtu.be/GI0Z981PbMQ



jitterjames

  • Administrator
  • Hero Member
  • *****
  • Posts: 7715
  • Karma: 116
    • View Profile
    • VoxCommando
Re: Variable looping (loop blocks) - how to break the loop?
« Reply #22 on: August 24, 2015, 01:03:33 PM »
I've tested the focus action with chrome on many different computers running different versions of Windows from Vista to W10 and never had a single failure in focusing chrome.  I'm not sure what is special about your system.  Chrome always creates many processes so that by itself is not necessarily the problem.

Obviously there is room for improvement with the focus action.  For a while now I have been considering a "Window" plugin that would allow us to target windows using various methods (process, window names, class etc.) and possibly do more than just focus them (monitor, or resize/reposition etc.).  I think there is probably a lot that could be done here that could be useful.  The only problem is to take the time to actually create it.

In your case, I suggest you try a few things since I think the issue you are having is somewhat unusual.  You could try uninstalling and reinstalling chrome.  Also try using admin privilege and disabling UAC just to be sure.  Otherwise you can use another solution such as autoit for now.  I will probably make this plugin but at this point I cannot say when.  It is a bad time for me with too many different things that require my time pulling me in different directions.

For the record, when I mentioned that focus was not always working in the action description, I don't think this had anything to do with multiple processes or with chrome specifically.  It was more a question of Windows deciding not to allow programmatic focusing of a window in order to "protect" the user experience somehow.  In some cases, what would happen is that the window in question would flash on the task bar but not actually focus.  I could never make sense of when Windows would decide to do this though.  There could also be issues with certain programs using true fullscreen mode and not allowing other windows to come forward but I'm not 100% sure about this anymore.  I don't use the focus actions all that much but recently it seems that they have just been working fine for me.

jitterjames

  • Administrator
  • Hero Member
  • *****
  • Posts: 7715
  • Karma: 116
    • View Profile
    • VoxCommando
Re: Variable looping (loop blocks) - how to break the loop?
« Reply #23 on: August 24, 2015, 01:07:18 PM »
If anyone else has experienced any reproducible problems using the focus action with chrome or any other programs, please let us know.

marcusvdt

  • Sr. Member
  • ****
  • Posts: 152
  • Karma: 6
  • Researching
    • View Profile
Re: Variable looping (loop blocks) - how to break the loop?
« Reply #24 on: August 24, 2015, 02:07:36 PM »
I'm not sure the problem is related to various process of chrome or not. Maybe it is the issue as you mentioned of the window flashing (but it does not flash because the window in not actually minimized). Don't know.
I'll use an autoit script in the meantime, just not sure yet how my script will send a confirmation to VC. Will try something like an exit code or something. Or maybe I can trigger an event using the API, not sure yet.

Thanks for looking at it!


PegLegTV

  • $upporter
  • Hero Member
  • *****
  • Posts: 500
  • Karma: 43
    • View Profile
Re: Variable looping (loop blocks) - how to break the loop?
« Reply #25 on: August 24, 2015, 02:27:57 PM »
I'll use an autoit script in the meantime, just not sure yet how my script will send a confirmation to VC. Will try something like an exit code or something. Or maybe I can trigger an event using the API, not sure yet.

If you want to trigger an event using Autoit, I posted an Autohotkey script that controls windows 8.1 netflix app, and I have it trigger events when it starts, stops and when you start and stop a movie as well,

This post has the AutoHotkey script, you can take a look and see an example of how to trigger an event with your autoit script
http://voxcommando.com/forum/index.php?topic=2145.msg18598#msg18598

note:: with my method the script needs to be in the main VC folder, if you wanted to put it in a different folder then you will need to add the file path


jitterjames

  • Administrator
  • Hero Member
  • *****
  • Posts: 7715
  • Karma: 116
    • View Profile
    • VoxCommando
Re: Variable looping (loop blocks) - how to break the loop?
« Reply #26 on: August 24, 2015, 02:44:53 PM »
VC automatically generates events when a new window is focused.  But I'm sure you already knew that. :)

marcusvdt

  • Sr. Member
  • ****
  • Posts: 152
  • Karma: 6
  • Researching
    • View Profile
Re: Variable looping (loop blocks) - how to break the loop?
« Reply #27 on: August 24, 2015, 02:55:33 PM »
James, yes I know!  :bonk

But as you can see in my video, such event gets triggered even when window.focus seem to fail.

But you are right, as I'll be using the autoit script to set the focus, then the "focused" event for that window truly means such window has been put in focus.
And I can double confirm also with the logic block.

Consistent enough!  ;)

marcusvdt

  • Sr. Member
  • ****
  • Posts: 152
  • Karma: 6
  • Researching
    • View Profile
Re: Variable looping (loop blocks) - how to break the loop?
« Reply #28 on: August 24, 2015, 03:10:26 PM »
If you want to trigger an event using Autoit, I posted an Autohotkey script that controls windows 8.1 netflix app, and I have it trigger events when it starts, stops and when you start and stop a movie as well,

This post has the AutoHotkey script, you can take a look and see an example of how to trigger an event with your autoit script
http://voxcommando.com/forum/index.php?topic=2145.msg18598#msg18598

note:: with my method the script needs to be in the main VC folder, if you wanted to put it in a different folder then you will need to add the file path

Thanks, I've found an example in your code. The syntax in autoit would be similar.
Btw, soon I'll probably port or adapt your Netflix script to autoit. No special reason, it's just easier to me to manage it later. Will need to translate all your commands, check what else I may need, etc. Thanks for providing the source code!

About this way of triggering events, honestly I did not notice yet this is possible. Wonderful!

Thanks guys!

jitterjames

  • Administrator
  • Hero Member
  • *****
  • Posts: 7715
  • Karma: 116
    • View Profile
    • VoxCommando
Re: Variable looping (loop blocks) - how to break the loop?
« Reply #29 on: August 24, 2015, 05:45:31 PM »
But you are right, as I'll be using the autoit script to set the focus, then the "focused" event for that window truly means such window has been put in focus.
And I can double confirm also with the logic block.

I really don't think you will need to check the focus using a logic block.  I can't think of any circumstance in which the event would be fired and then the logic block would return false on checking the focus.

Regarding the command line api, please note that it is ultimately just sending a UDP message so if you are able to send UDP easily from your own program it is probably preferable, but not a big deal either way.