Link to home
Start Free TrialLog in
Avatar of fackue
fackue

asked on

setting focus on random open apps, with and inverval

Hi,

I need help on getting my program to randomly (or in order, in order according to the alt+tab menu) set focus on programs open that are shown in the taskbar. I'm trying to get it to randomly set focus on a different application every 5 minutes or so. Could that be possible, if so, could one help me out with it?

I have a check box next to this option, along 2 two others, and a start button. When I check check2, i want it to run whats under the check2 command. So, this is what I have planned:

Put the code in a Timer2, then under the start commandbutton:

If Check2.Value = 1 Then
    Timer2.Enabled = True
    Timer2.Interval = (what is the interval? in seconds?)
Else: Timer2.Enabled = False

Any help would be greatly appriciated!
Avatar of aelatik
aelatik
Flag of Netherlands image

As far as i could understand your Q

Dim CNT As Long
    CNT = 0
   
Private Sub Check2_Click()
    If Check2.Value = 1 Then
        Timer2.Enabled = True
        Timer2.Interval = 60000 ' 1 minute, because the timer control won't accept 5 minutes
    Else: Timer2.Enabled = False
End Sub

Private Sub Timer1_Timer()
    CNT = CNT + 1
    If CNT = 5 Then
        Exit Sub ' Instead of Exit Sub do something
        CNT = 0 ' Reset the counter
    End If
End Sub
Here, this one contains the ALT-TAB event....

Dim CNT As Long
    CNT = 0
   
Private Sub Check2_Click()
    If Check2.Value = 1 Then
        Timer2.Enabled = True
        Timer2.Interval = 60000 ' 1 minute, because the timer control won't accept 5 minutes
    Else: Timer2.Enabled = False
End Sub

Private Sub Timer1_Timer()
    CNT = CNT + 1
    If CNT = 5 Then
        SendKeys "%{TAB}"
        CNT = 0 ' Reset the counter
    End If
End Sub
Avatar of fackue
fackue

ASKER

OK, it doesn't seem to work (the first post).  What's the CNT supposed to do/mean?
Avatar of fackue

ASKER

Just to make your your understanding what I'm asking, take a look at this pic:
http://consolevision.com/members/fackue/images/awin.png

Once I click on Start, I want it to switch focus (ex. internet explorer is open right now and the caption bar is blue, its focused, aol instant messagenger is on the taskbar, but it's not focused, the caption bar is grey).  I want to be able to focus through all my programs open, 1 program per the maximum, 1 minute.
Avatar of fackue

ASKER

Also, on this, whatever CNT would be, If CNT = 0, then CNT= CNT + 1, wouldn't it never = 5?  Wouldn't it always be 1?  It's not place anywhere else in the code...

Private Sub Timer2_Timer()
Dim CNT As Long
    CNT = 0
   
   CNT = CNT + 1
    If CNT = 5 Then
        SendKeys "%{TAB}"
        CNT = 0 ' Reset the counter
    End If
End Sub
Example of retrieving the application handles/titles of those in the task-bar. Forgot about your 5 min. interval when coming up with the example, sorry. Just use the timer examples above or SetTimer which should go beyond the limits of VB timers.



Form1:

Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function GetParent Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function GetWindow Lib "user32" (ByVal hwnd As Long, ByVal wCmd As Long) As Long
Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long
Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
Private Declare Function IsWindowVisible Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function ShowWindow Lib "user32" (ByVal hwnd As Long, ByVal nCmdShow As Long) As Long

Private Const GW_HWNDNEXT = 2
Private Const GW_OWNER = 4
Private Const GWL_EXSTYLE = (-20)
Private Const SW_SHOWNORMAL = 1
Private Const WS_EX_APPWINDOW = &H40000
Private Const WS_EX_TOOLWINDOW = &H80
Private Sub Form_Load()
    Dim MyApps As New Collection, iLoop As Integer, sBuff As String, iLen As Integer
    Call retTaskbarApps(MyApps)
    For iLoop = 1 To MyApps.Count
        sBuff = Space(256)
        iLen = GetWindowText(MyApps.Item(iLoop), sBuff, 256)
        sBuff = Left(sBuff, iLen)
        'Print  window's title to debug
        Debug.Print sBuff
    Next iLoop
    'Randomize Rnd() with new seed
    Randomize Timer
    'Show random application window
    Call ShowWindow(MyApps.Item(Int((Rnd * MyApps.Count) + 1)), SW_SHOWNORMAL)
End Sub
Private Function retTaskbarApps(ByRef MyApps As Collection)
    Dim lHandle As Long
    lHandle = FindWindow(vbNullString, vbNullString)
    Do Until lHandle = 0
        If IsWindowVisible(lHandle) = 1 Then
            If (GetWindowLong(lHandle, GWL_EXSTYLE) And WS_EX_APPWINDOW) > 0 Then
                MyApps.Add lHandle
            ElseIf (GetWindowLong(lHandle, GWL_EXSTYLE) And WS_EX_TOOLWINDOW) = 0 Then
                MyApps.Add lHandle
            End If
        End If
        lHandle = GetWindow(lHandle, GW_HWNDNEXT)
    Loop
End Function
Avatar of fackue

ASKER

Qucik question, what is 'MyApps As Collection'?  How is that used?  Do I have to know what apps are open?  I just have it set focus on any app open?
Avatar of fackue

ASKER

Wait... I see a window on the bottom "Immediate" with the programs open on the taskbar, how do I set focus on those?  I looked through the code, but I couldnt really understand it... I kept getting confused.
Avatar of fackue

ASKER

Looking more into it, I see the code under Private Sub Form_Load() is what's putting the title's in the debug menu.  I also see, by what it looks like, is that there's code to set the focus on a random app.  It's not focusing on anything.  I set the code from the Private Sub Form_Load() under a timer, and I call the timer is the checkbox is checked and start is pressed.

If it'll help more, heres my source:
http://www.consolevision.com/members/fackue/tools/active_windows.zip
The function retTaskbarApps() adds the window-handles of taskbar applications into a collection specified byRef.

Dim MyApps As New Collection
Call retTaskbarApps(MyApps)

Firstly, you dim the variable MyApps as a new collection object. You then pass the variable onto the function and it add an item for each window it finds.

Msgbox MyApps.Item(1)  

The above will MsgBox the window-handle of the first application it found. The For/Next loop is just an example of how to loop through the collection and get each window's title.

Avatar of fackue

ASKER

Ah, OK I see what your doing... cool, I didn't think it was going to be this complicatied... If I'm seeing this right, all I'll need to do is find a way to do a

SetAppFocus MyApps.Items (1)

SetAppFocus would be a function (not sure if said right) that would have the code to focus on MyApps.Items (1), right?

I didnt fully understand what you were saying about the looping... how to loop through the collection and get each window's title.

I was doing this to get the first 3 apps found

MsgBox MyApps.Items (1)
MsgBox MyApps.Items (2)
MsgBox MyApps.Items (3)
>I didn't think it was going to be this complicatied

Well, if you want to interact with other application's windows, it'll get complicated until you understand the basics of Win32 API (Application Programming Interface). Until then, try your best to understand the examples I give you. It's rough on me having to get down-to-the-bone on examples.


>I didnt fully understand what you were saying about the looping... how to loop through the collection and get each window's title.

Don't worry too much with the example of getting the window titles as it's not too important for your situation. When retTaskbarApps() fills the collection object MyApps with the handles of task-bar applications, you'll need to know the beginning and end of them. The collection starts from "1" and it'll end at MyApps.Count (which returns how many items are in the collection). So if you want to show the last window, you'd use:

Call ShowWindow(MyApps.Item(MyApps.Count), SW_SHOWNORMAL)


ShowWindow() is a Win32 API function which I included above (so don't forget to include it in your form/module). It'll show the specified window in the state specified by the second parameter. Which in this case is SW_SHOWNORMAL (1).
Avatar of fackue

ASKER

This is starting to get me annoying... I've tried everything, I have this, and it will not work:

Private Sub FocusTimer_Timer()
    Dim MyApps As New Collection, iLoop As Integer, sBuff As String, iLen As Integer
    Call retTaskbarApps(MyApps)
    For iLoop = 1 To MyApps.Count
        sBuff = Space(256)
        iLen = GetWindowText(MyApps.Item(iLoop), sBuff, 256)
        sBuff = Left(sBuff, iLen)
        'Print  window's title to debug
        Debug.Print sBuff
    Next iLoop
    'Randomize Rnd() with new seed
    Randomize Timer
    'Show random application window
Call ShowWindow(MyApps.Item(MyApps.Count), SW_SHOWNORMAL)

I'm really about to just stop and say it's over, I still havn't gotten anything to do anything... /me raises points to 105
Form1:


Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function GetWindow Lib "user32" (ByVal hwnd As Long, ByVal wCmd As Long) As Long
Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long
Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
Private Declare Function IsWindowVisible Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function ShowWindow Lib "user32" (ByVal hwnd As Long, ByVal nCmdShow As Long) As Long

Private Const GW_HWNDNEXT = 2
Private Const GWL_EXSTYLE = (-20)
Private Const SW_SHOWMAXIMIZED = 3
Private Const WS_EX_APPWINDOW = &H40000
Private Const WS_EX_TOOLWINDOW = &H80
Private Function retTaskbarApps(ByRef MyApps As Collection)
    Dim lHandle As Long
    lHandle = FindWindow(vbNullString, vbNullString)
    Do Until lHandle = 0
        If IsWindowVisible(lHandle) = 1 Then
            If (GetWindowLong(lHandle, GWL_EXSTYLE) And WS_EX_APPWINDOW) > 0 Then
                If retTitle(lHandle) <> "" Then MyApps.Add lHandle
            ElseIf (GetWindowLong(lHandle, GWL_EXSTYLE) And WS_EX_TOOLWINDOW) = 0 Then
                If retTitle(lHandle) <> "" Then MyApps.Add lHandle
            End If
        End If
        lHandle = GetWindow(lHandle, GW_HWNDNEXT)
    Loop
End Function
Private Function retTitle(ByVal lHandle As Long) As String
    Dim sBuff As String, iLen As Integer
    sBuff = Space(256)
    iLen = GetWindowText(lHandle, sBuff, 256)
    retTitle = Left(sBuff, iLen)
End Function
Private Sub Form_Load()
    Timer1.Interval = 2000
    Timer1.Enabled = True
End Sub
Private Sub Timer1_Timer()
    Dim MyApps As New Collection
    Call retTaskbarApps(MyApps)
    Call Randomize(Timer)
    Call ShowWindow(MyApps.Item(Int(Rnd * MyApps.Count) + 1), SW_SHOWMAXIMIZED)
End Sub
> Call ShowWindow(MyApps.Item(MyApps.Count), SW_SHOWNORMAL)
> I still havn't gotten anything to do anything

In your timer you were only showing the last window handle (which is probably your application). So, if you're basically showing your window every few seconds, you won't nothing anything. :-)   My example above shows a random window maximized every 2 seconds.
Avatar of fackue

ASKER

Awesome!  That works, but one thing, after all the windows are normal (I changed maximized to normal (= 1)), and as when it seems to of gone through the programs open, it doesn't continue looping through them again, it just stops, or if all the windows are already normal, nothing will happen, got any ideas?

Again, thanks.
ASKER CERTIFIED SOLUTION
Avatar of zzzzzooc
zzzzzooc

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of fackue

ASKER

That's awesome man, thanks a lot for your help.
Oops. It's best to set the random number into a variable and then use it for both. Otherwise, you'll get a random variable for each one most-likely.

Dim MyVariable as Long
MyVariable=MyApps.Item(Int(Rnd * MyApps.Count) + 1)
Call ShowWindow(MyVariable, SW_SHOWMAXIMIZED)
Call SetForegroundWindow(MyVariable)
Avatar of fackue

ASKER

Looking at it, I made sure you didn't make any errors (making sure I wasn't making any also, putting it in), but I ended up getting "Invalid procedure call or argument".  I looked at it a few times and figured it wasn't something I, myself, wouldn't be able to fix...
Avatar of fackue

ASKER

Also, in debug mode, MyVariable = 0