Solved

setting focus on random open apps, with and inverval

Posted on 2003-11-08
21
322 Views
Last Modified: 2010-05-03
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!
0
Comment
Question by:fackue
  • 12
  • 7
  • 2
21 Comments
 
LVL 14

Expert Comment

by:aelatik
ID: 9707916
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
0
 
LVL 14

Expert Comment

by:aelatik
ID: 9707930
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
0
 

Author Comment

by:fackue
ID: 9708099
OK, it doesn't seem to work (the first post).  What's the CNT supposed to do/mean?
0
 

Author Comment

by:fackue
ID: 9708132
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.
0
 

Author Comment

by:fackue
ID: 9708189
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
0
 
LVL 17

Expert Comment

by:zzzzzooc
ID: 9708986
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
0
 

Author Comment

by:fackue
ID: 9709165
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?
0
 

Author Comment

by:fackue
ID: 9709199
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.
0
 

Author Comment

by:fackue
ID: 9709270
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
0
 
LVL 17

Expert Comment

by:zzzzzooc
ID: 9709330
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.

0
Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

 

Author Comment

by:fackue
ID: 9709368
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)
0
 
LVL 17

Expert Comment

by:zzzzzooc
ID: 9709517
>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).
0
 

Author Comment

by:fackue
ID: 9711425
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
0
 
LVL 17

Expert Comment

by:zzzzzooc
ID: 9714339
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
0
 
LVL 17

Expert Comment

by:zzzzzooc
ID: 9714344
> 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.
0
 

Author Comment

by:fackue
ID: 9719193
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.
0
 
LVL 17

Accepted Solution

by:
zzzzzooc earned 105 total points
ID: 9727088
This should solve that issue.

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 Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd 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)
    Call SetForegroundWindow(MyApps.Item(Int(Rnd * MyApps.Count) + 1))
End Sub
0
 

Author Comment

by:fackue
ID: 9727732
That's awesome man, thanks a lot for your help.
0
 
LVL 17

Expert Comment

by:zzzzzooc
ID: 9731668
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)
0
 

Author Comment

by:fackue
ID: 9735612
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...
0
 

Author Comment

by:fackue
ID: 9735622
Also, in debug mode, MyVariable = 0
0

Featured Post

What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

Introduction While answering a recent question about filtering a custom class collection, I realized that this could be accomplished with very little code by using the ScriptControl (SC) library.  This article will introduce you to the SC library a…
This article describes some techniques which will make your VBA or Visual Basic Classic code easier to understand and maintain, whether by you, your replacement, or another Experts-Exchange expert.
As developers, we are not limited to the functions provided by the VBA language. In addition, we can call the functions that are part of the Windows operating system. These functions are part of the Windows API (Application Programming Interface). U…
Get people started with the process of using Access VBA to control Outlook using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Microsoft Outlook. Using automation, an Access applic…

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now